Asterisk - The Open Source Telephony Project GIT-master-7921072
dial.c
Go to the documentation of this file.
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/*** MODULEINFO
27 <support_level>core</support_level>
28 ***/
29
30#include "asterisk.h"
31
32#include <sys/time.h>
33#include <signal.h>
34
35#include "asterisk/channel.h"
36#include "asterisk/utils.h"
37#include "asterisk/lock.h"
39#include "asterisk/dial.h"
40#include "asterisk/pbx.h"
42#include "asterisk/app.h"
43#include "asterisk/causes.h"
46
47/*! \brief Main dialing structure. Contains global options, channels being dialed, and more! */
48struct ast_dial {
49 int num; /*!< Current number to give to next dialed channel */
50 int timeout; /*!< Maximum time allowed for dial attempts */
51 int actual_timeout; /*!< Actual timeout based on all factors (ie: channels) */
52 enum ast_dial_result state; /*!< Status of dial */
53 void *options[AST_DIAL_OPTION_MAX]; /*!< Global options */
54 ast_dial_state_callback state_callback; /*!< Status callback */
55 void *user_data; /*!< Attached user data */
56 AST_LIST_HEAD(, ast_dial_channel) channels; /*!< Channels being dialed */
57 pthread_t thread; /*!< Thread (if running in async) */
58 ast_callid callid; /*!< callid (if running in async) */
59 ast_mutex_t lock; /*! Lock to protect the thread information above */
60};
61
62/*! \brief Dialing channel structure. Contains per-channel dialing options, asterisk channel, and more! */
64 int num; /*!< Unique number for dialed channel */
65 int timeout; /*!< Maximum time allowed for attempt */
66 char *tech; /*!< Technology being dialed */
67 char *device; /*!< Device being dialed */
68 void *options[AST_DIAL_OPTION_MAX]; /*!< Channel specific options */
69 int cause; /*!< Cause code in case of failure */
70 unsigned int is_running_app:1; /*!< Is this running an application? */
71 char *assignedid1; /*!< UniqueID to assign channel */
72 char *assignedid2; /*!< UniqueID to assign 2nd channel */
73 struct ast_channel *owner; /*!< Asterisk channel */
74 AST_LIST_ENTRY(ast_dial_channel) list; /*!< Linked list information */
75};
76
77/*! \brief Typedef for dial option enable */
78typedef void *(*ast_dial_option_cb_enable)(void *data);
79
80/*! \brief Typedef for dial option disable */
81typedef int (*ast_dial_option_cb_disable)(void *data);
82
83/*! \brief Structure for 'ANSWER_EXEC' option */
85 char app[AST_MAX_APP]; /*!< Application name */
86 char *args; /*!< Application arguments */
87};
88
89/*! \brief Enable function for 'ANSWER_EXEC' option */
90static void *answer_exec_enable(void *data)
91{
92 struct answer_exec_struct *answer_exec = NULL;
93 char *app = ast_strdupa((char*)data), *args = NULL;
94
95 /* Not giving any data to this option is bad, mmmk? */
97 return NULL;
98
99 /* Create new data structure */
100 if (!(answer_exec = ast_calloc(1, sizeof(*answer_exec))))
101 return NULL;
102
103 /* Parse out application and arguments */
104 if ((args = strchr(app, ','))) {
105 *args++ = '\0';
106 answer_exec->args = ast_strdup(args);
107 }
108
109 /* Copy application name */
110 ast_copy_string(answer_exec->app, app, sizeof(answer_exec->app));
111
112 return answer_exec;
113}
114
115/*! \brief Disable function for 'ANSWER_EXEC' option */
116static int answer_exec_disable(void *data)
117{
118 struct answer_exec_struct *answer_exec = data;
119
120 /* Make sure we have a value */
121 if (!answer_exec)
122 return -1;
123
124 /* If arguments are present, free them too */
125 if (answer_exec->args)
126 ast_free(answer_exec->args);
127
128 /* This is simple - just free the structure */
129 ast_free(answer_exec);
130
131 return 0;
132}
133
134static void *music_enable(void *data)
135{
136 return ast_strdup(data);
137}
138
139static int music_disable(void *data)
140{
141 if (!data)
142 return -1;
143
144 ast_free(data);
145
146 return 0;
147}
148
149static void *predial_enable(void *data)
150{
151 return ast_strdup(data);
152}
153
154static int predial_disable(void *data)
155{
156 if (!data) {
157 return -1;
158 }
159
160 ast_free(data);
161
162 return 0;
163}
164
165/*! \brief Application execution function for 'ANSWER_EXEC' option */
166static void answer_exec_run(struct ast_dial *dial, struct ast_dial_channel *dial_channel, char *app, char *args)
167{
168 struct ast_channel *chan = dial_channel->owner;
169
170 /* Execute the application, if available */
171 if (ast_pbx_exec_application(chan, app, args)) {
172 /* If the application was not found, return immediately */
173 return;
174 }
175
176 /* If another thread is not taking over hang up the channel */
177 ast_mutex_lock(&dial->lock);
178 if (dial->thread != AST_PTHREADT_STOP) {
179 ast_hangup(chan);
180 dial_channel->owner = NULL;
181 }
182 ast_mutex_unlock(&dial->lock);
183
184 return;
185}
186
191};
192
193/*!
194 * \brief Map options to respective handlers (enable/disable).
195 *
196 * \note This list MUST be perfectly kept in order with enum
197 * ast_dial_option, or else madness will happen.
198 */
199static const struct ast_option_types option_types[] = {
200 { AST_DIAL_OPTION_RINGING, NULL, NULL }, /*!< Always indicate ringing to caller */
201 { AST_DIAL_OPTION_ANSWER_EXEC, answer_exec_enable, answer_exec_disable }, /*!< Execute application upon answer in async mode */
202 { AST_DIAL_OPTION_MUSIC, music_enable, music_disable }, /*!< Play music to the caller instead of ringing */
203 { AST_DIAL_OPTION_DISABLE_CALL_FORWARDING, NULL, NULL }, /*!< Disable call forwarding on channels */
204 { AST_DIAL_OPTION_PREDIAL, predial_enable, predial_disable }, /*!< Execute a subroutine on the outbound channels prior to dialing */
205 { AST_DIAL_OPTION_DIAL_REPLACES_SELF, NULL, NULL }, /*!< The dial operation is a replacement for the requester */
206 { AST_DIAL_OPTION_SELF_DESTROY, NULL, NULL}, /*!< Destroy self at end of ast_dial_run */
207 { AST_DIAL_OPTION_MAX, NULL, NULL }, /*!< Terminator of list */
208};
209
210/*! \brief Maximum number of channels we can watch at a time */
211#define AST_MAX_WATCHERS 256
212
213/*! \brief Macro for finding the option structure to use on a dialed channel */
214#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])
215
216/*! \brief Macro that determines whether a channel is the caller or not */
217#define IS_CALLER(chan, owner) (chan == owner ? 1 : 0)
218
219/*! \brief New dialing structure
220 * \note Create a dialing structure
221 * \return Returns a calloc'd ast_dial structure, NULL on failure
222 */
224{
225 struct ast_dial *dial = NULL;
226
227 /* Allocate new memory for structure */
228 if (!(dial = ast_calloc(1, sizeof(*dial))))
229 return NULL;
230
231 /* Initialize list of channels */
233
234 /* Initialize thread to NULL */
236
237 /* No timeout exists... yet */
238 dial->timeout = -1;
239 dial->actual_timeout = -1;
240
241 /* Can't forget about the lock */
242 ast_mutex_init(&dial->lock);
243
244 return dial;
245}
246
247static int dial_append_common(struct ast_dial *dial, struct ast_dial_channel *channel,
248 const char *tech, const char *device, const struct ast_assigned_ids *assignedids)
249{
250 /* Record technology and device for when we actually dial */
251 channel->tech = ast_strdup(tech);
252 channel->device = ast_strdup(device);
253
254 /* Store the assigned id */
255 if (assignedids && !ast_strlen_zero(assignedids->uniqueid)) {
256 channel->assignedid1 = ast_strdup(assignedids->uniqueid);
257
258 if (!ast_strlen_zero(assignedids->uniqueid2)) {
259 channel->assignedid2 = ast_strdup(assignedids->uniqueid2);
260 }
261 }
262
263 /* Grab reference number from dial structure */
264 channel->num = ast_atomic_fetchadd_int(&dial->num, +1);
265
266 /* No timeout exists... yet */
267 channel->timeout = -1;
268
269 /* Insert into channels list */
270 AST_LIST_INSERT_TAIL(&dial->channels, channel, list);
271
272 return channel->num;
273
274}
275
276/*! \brief Append a channel
277 * \note Appends a channel to a dialing structure
278 * \return Returns channel reference number on success, -1 on failure
279 */
280int ast_dial_append(struct ast_dial *dial, const char *tech, const char *device, const struct ast_assigned_ids *assignedids)
281{
282 struct ast_dial_channel *channel = NULL;
283
284 /* Make sure we have required arguments */
285 if (!dial || !tech || !device)
286 return -1;
287
288 /* Allocate new memory for dialed channel structure */
289 if (!(channel = ast_calloc(1, sizeof(*channel))))
290 return -1;
291
292 return dial_append_common(dial, channel, tech, device, assignedids);
293}
294
295int ast_dial_append_channel(struct ast_dial *dial, struct ast_channel *chan)
296{
297 struct ast_dial_channel *channel;
298 char *tech;
299 char *device;
300 char *dash;
301
302 if (!dial || !chan) {
303 return -1;
304 }
305
306 channel = ast_calloc(1, sizeof(*channel));
307 if (!channel) {
308 return -1;
309 }
310 channel->owner = chan;
311
313
314 device = strchr(tech, '/');
315 if (!device) {
316 ast_free(channel);
317 return -1;
318 }
319 *device++ = '\0';
320
321 dash = strrchr(device, '-');
322 if (dash) {
323 *dash = '\0';
324 }
325
326 return dial_append_common(dial, channel, tech, device, NULL);
327}
328
329/*! \brief Helper function that requests all channels */
330static int begin_dial_prerun(struct ast_dial_channel *channel, struct ast_channel *chan, struct ast_format_cap *cap, const char *predial_string)
331{
332 struct ast_format_cap *cap_all_audio = NULL;
333 struct ast_format_cap *cap_request;
334 struct ast_format_cap *requester_cap = NULL;
335 struct ast_assigned_ids assignedids = {
336 .uniqueid = channel->assignedid1,
337 .uniqueid2 = channel->assignedid2,
338 };
339
340 if (chan) {
341 int max_forwards;
342
343 ast_channel_lock(chan);
345 requester_cap = ao2_bump(ast_channel_nativeformats(chan));
346 ast_channel_unlock(chan);
347
348 if (max_forwards <= 0) {
349 ast_log(LOG_WARNING, "Cannot dial from channel '%s'. Max forwards exceeded\n",
350 ast_channel_name(chan));
351 }
352 }
353
354 if (!channel->owner) {
355 if (cap && ast_format_cap_count(cap)) {
356 cap_request = cap;
357 } else if (requester_cap) {
358 cap_request = requester_cap;
359 } else {
362 cap_request = cap_all_audio;
363 }
364
365 /* If we fail to create our owner channel bail out */
366 if (!(channel->owner = ast_request(channel->tech, cap_request, &assignedids, chan, channel->device, &channel->cause))) {
367 ao2_cleanup(cap_all_audio);
368 return -1;
369 }
370 cap_request = NULL;
371 ao2_cleanup(requester_cap);
372 ao2_cleanup(cap_all_audio);
373 }
374
375 if (chan) {
376 ast_channel_lock_both(chan, channel->owner);
377 } else {
378 ast_channel_lock(channel->owner);
379 }
380
382
383 ast_channel_appl_set(channel->owner, "AppDial2");
384 ast_channel_data_set(channel->owner, "(Outgoing Line)");
385
386 memset(ast_channel_whentohangup(channel->owner), 0, sizeof(*ast_channel_whentohangup(channel->owner)));
387
388 /* Inherit everything from he who spawned this dial */
389 if (chan) {
390 ast_channel_inherit_variables(chan, channel->owner);
391 ast_channel_datastore_inherit(chan, channel->owner);
393
394 /* Copy over callerid information */
396
398
400
401 ast_channel_language_set(channel->owner, ast_channel_language(chan));
404 } else {
406 }
408 ast_channel_musicclass_set(channel->owner, ast_channel_musicclass(chan));
409
412 ast_channel_unlock(chan);
413 }
414
416 ast_channel_unlock(channel->owner);
417
418 if (!ast_strlen_zero(predial_string)) {
419 if (chan) {
421 }
422 ast_pre_call(channel->owner, predial_string);
423 if (chan) {
425 }
426 }
427
428 return 0;
429}
430
431int ast_dial_prerun(struct ast_dial *dial, struct ast_channel *chan, struct ast_format_cap *cap)
432{
433 struct ast_dial_channel *channel;
434 int res = -1;
435 char *predial_string = dial->options[AST_DIAL_OPTION_PREDIAL];
436
437 AST_LIST_LOCK(&dial->channels);
438 AST_LIST_TRAVERSE(&dial->channels, channel, list) {
439 if ((res = begin_dial_prerun(channel, chan, cap, predial_string))) {
440 break;
441 }
442 }
444
445 return res;
446}
447
448/*! \brief Helper function that does the beginning dialing per-appended channel */
449static int begin_dial_channel(struct ast_dial_channel *channel, struct ast_channel *chan, int async, const char *predial_string, struct ast_channel *forwarder_chan)
450{
451 int res = 1;
452 char forwarder[AST_CHANNEL_NAME];
453
454 /* If no owner channel exists yet execute pre-run */
455 if (!channel->owner && begin_dial_prerun(channel, chan, NULL, predial_string)) {
456 return 0;
457 }
458
459 if (forwarder_chan) {
460 ast_copy_string(forwarder, ast_channel_name(forwarder_chan), sizeof(forwarder));
461 ast_channel_lock(channel->owner);
462 pbx_builtin_setvar_helper(channel->owner, "FORWARDERNAME", forwarder);
463 ast_channel_unlock(channel->owner);
464 }
465
466 /* Attempt to actually call this device */
467 if ((res = ast_call(channel->owner, channel->device, 0))) {
468 res = 0;
469 ast_hangup(channel->owner);
470 channel->owner = NULL;
471 } else {
472 ast_channel_publish_dial(async ? NULL : chan, channel->owner, channel->device, NULL);
473 res = 1;
474 ast_verb(3, "Called %s\n", channel->device);
475 }
476
477 return res;
478}
479
480/*! \brief Helper function that does the beginning dialing per dial structure */
481static int begin_dial(struct ast_dial *dial, struct ast_channel *chan, int async)
482{
483 struct ast_dial_channel *channel = NULL;
484 int success = 0;
485 char *predial_string = dial->options[AST_DIAL_OPTION_PREDIAL];
486
487 /* Iterate through channel list, requesting and calling each one */
488 AST_LIST_LOCK(&dial->channels);
489 AST_LIST_TRAVERSE(&dial->channels, channel, list) {
490 success += begin_dial_channel(channel, chan, async, predial_string, NULL);
491 }
493
494 /* If number of failures matches the number of channels, then this truly failed */
495 return success;
496}
497
498/*! \brief Helper function to handle channels that have been call forwarded */
499static int handle_call_forward(struct ast_dial *dial, struct ast_dial_channel *channel, struct ast_channel *chan)
500{
501 struct ast_channel *original = channel->owner;
503 char *tech = "Local", *device = tmp, *stuff;
504 char *predial_string = dial->options[AST_DIAL_OPTION_PREDIAL];
505
506 /* If call forwarding is disabled just drop the original channel and don't attempt to dial the new one */
508 ast_hangup(original);
509 channel->owner = NULL;
510 return 0;
511 }
512
513 /* Figure out the new destination */
514 if ((stuff = strchr(tmp, '/'))) {
515 *stuff++ = '\0';
516 tech = tmp;
517 device = stuff;
518 } else {
519 const char *forward_context;
520 char destination[AST_MAX_CONTEXT + AST_MAX_EXTENSION + 1];
521
522 ast_channel_lock(original);
523 forward_context = pbx_builtin_getvar_helper(original, "FORWARD_CONTEXT");
524 snprintf(destination, sizeof(destination), "%s@%s", tmp, S_OR(forward_context, ast_channel_context(original)));
525 ast_channel_unlock(original);
526 device = ast_strdupa(destination);
527 }
528
529 /* Drop old destination information */
530 ast_free(channel->tech);
531 ast_free(channel->device);
532 ast_free(channel->assignedid1);
533 channel->assignedid1 = NULL;
534 ast_free(channel->assignedid2);
535 channel->assignedid2 = NULL;
536
537 /* Update the dial channel with the new destination information */
538 channel->tech = ast_strdup(tech);
539 channel->device = ast_strdup(device);
541
542 /* Drop the original channel */
543 channel->owner = NULL;
544
545 /* Finally give it a go... send it out into the world */
546 begin_dial_channel(channel, chan, chan ? 0 : 1, predial_string, original);
547
548 ast_channel_publish_dial_forward(chan, original, channel->owner, NULL, "CANCEL",
549 ast_channel_call_forward(original));
550
551 ast_hangup(original);
552
553 return 0;
554}
555
556/*! \brief Helper function that finds the dialed channel based on owner */
558{
559 struct ast_dial_channel *channel = NULL;
560
561 AST_LIST_LOCK(&dial->channels);
562 AST_LIST_TRAVERSE(&dial->channels, channel, list) {
563 if (channel->owner == owner)
564 break;
565 }
567
568 return channel;
569}
570
571static void set_state(struct ast_dial *dial, enum ast_dial_result state)
572{
573 dial->state = state;
574
575 if (dial->state_callback)
576 dial->state_callback(dial);
577}
578
579/*! \brief Helper function that handles frames */
580static void handle_frame(struct ast_dial *dial, struct ast_dial_channel *channel, struct ast_frame *fr, struct ast_channel *chan)
581{
582 if (fr->frametype == AST_FRAME_CONTROL) {
583 switch (fr->subclass.integer) {
585 if (chan) {
586 ast_verb(3, "%s answered %s\n", ast_channel_name(channel->owner), ast_channel_name(chan));
587 } else {
588 ast_verb(3, "%s answered\n", ast_channel_name(channel->owner));
589 }
590 AST_LIST_LOCK(&dial->channels);
591 AST_LIST_REMOVE(&dial->channels, channel, list);
592 AST_LIST_INSERT_HEAD(&dial->channels, channel, list);
594 ast_channel_publish_dial(chan, channel->owner, channel->device, "ANSWER");
596 break;
597 case AST_CONTROL_BUSY:
598 ast_verb(3, "%s is busy\n", ast_channel_name(channel->owner));
599 ast_channel_publish_dial(chan, channel->owner, channel->device, "BUSY");
600 ast_hangup(channel->owner);
601 channel->cause = AST_CAUSE_USER_BUSY;
602 channel->owner = NULL;
603 break;
605 ast_verb(3, "%s is circuit-busy\n", ast_channel_name(channel->owner));
606 ast_channel_publish_dial(chan, channel->owner, channel->device, "CONGESTION");
607 ast_hangup(channel->owner);
609 channel->owner = NULL;
610 break;
612 ast_verb(3, "%s dialed Incomplete extension %s\n", ast_channel_name(channel->owner), ast_channel_exten(channel->owner));
613 if (chan) {
615 } else {
616 ast_hangup(channel->owner);
617 channel->cause = AST_CAUSE_UNALLOCATED;
618 channel->owner = NULL;
619 }
620 break;
622 ast_verb(3, "%s is ringing\n", ast_channel_name(channel->owner));
623 ast_channel_publish_dial(chan, channel->owner, channel->device, "RINGING");
624 if (chan && !dial->options[AST_DIAL_OPTION_MUSIC])
627 break;
629 ast_channel_publish_dial(chan, channel->owner, channel->device, "PROGRESS");
630 if (chan) {
631 ast_verb(3, "%s is making progress, passing it to %s\n", ast_channel_name(channel->owner), ast_channel_name(chan));
633 } else {
634 ast_verb(3, "%s is making progress\n", ast_channel_name(channel->owner));
635 }
637 break;
639 if (!chan) {
640 break;
641 }
642 ast_verb(3, "%s requested a video update, passing it to %s\n", ast_channel_name(channel->owner), ast_channel_name(chan));
644 break;
646 if (!chan) {
647 break;
648 }
649 ast_verb(3, "%s requested a source update, passing it to %s\n", ast_channel_name(channel->owner), ast_channel_name(chan));
651 break;
653 if (!chan) {
654 break;
655 }
656 ast_verb(3, "%s connected line has changed, passing it to %s\n", ast_channel_name(channel->owner), ast_channel_name(chan));
657 if (ast_channel_connected_line_sub(channel->owner, chan, fr, 1)) {
659 }
660 break;
662 if (!chan) {
663 break;
664 }
665 ast_verb(3, "%s redirecting info has changed, passing it to %s\n", ast_channel_name(channel->owner), ast_channel_name(chan));
666 if (ast_channel_redirecting_sub(channel->owner, chan, fr, 1)) {
668 }
669 break;
671 ast_channel_publish_dial(chan, channel->owner, channel->device, "PROCEEDING");
672 if (chan) {
673 ast_verb(3, "%s is proceeding, passing it to %s\n", ast_channel_name(channel->owner), ast_channel_name(chan));
675 } else {
676 ast_verb(3, "%s is proceeding\n", ast_channel_name(channel->owner));
677 }
679 break;
680 case AST_CONTROL_HOLD:
681 if (!chan) {
682 break;
683 }
684 ast_verb(3, "Call on %s placed on hold\n", ast_channel_name(chan));
686 break;
688 if (!chan) {
689 break;
690 }
691 ast_verb(3, "Call on %s left from hold\n", ast_channel_name(chan));
693 break;
696 break;
698 if (chan) {
700 }
701 break;
702 case -1:
703 if (chan) {
704 /* Prod the channel */
705 ast_indicate(chan, -1);
706 }
707 break;
708 default:
709 break;
710 }
711 }
712}
713
714/*! \brief Helper function to handle when a timeout occurs on dialing attempt */
715static int handle_timeout_trip(struct ast_dial *dial, struct timeval start)
716{
717 struct ast_dial_channel *channel = NULL;
718 int diff = ast_tvdiff_ms(ast_tvnow(), start), lowest_timeout = -1, new_timeout = -1;
719
720 /* If there is no difference yet return the dial timeout so we can go again, we were likely interrupted */
721 if (!diff) {
722 return dial->timeout;
723 }
724
725 /* If the global dial timeout tripped switch the state to timeout so our channel loop will drop every channel */
726 if (diff >= dial->timeout) {
728 new_timeout = 0;
729 }
730
731 /* Go through dropping out channels that have met their timeout */
732 AST_LIST_TRAVERSE(&dial->channels, channel, list) {
733 if (dial->state == AST_DIAL_RESULT_TIMEOUT || diff >= channel->timeout) {
734 ast_hangup(channel->owner);
735 channel->cause = AST_CAUSE_NO_ANSWER;
736 channel->owner = NULL;
737 } else if ((lowest_timeout == -1) || (lowest_timeout > channel->timeout)) {
738 lowest_timeout = channel->timeout;
739 }
740 }
741
742 /* Calculate the new timeout using the lowest timeout found */
743 if (lowest_timeout >= 0)
744 new_timeout = lowest_timeout - diff;
745
746 return new_timeout;
747}
748
749const char *ast_hangup_cause_to_dial_status(int hangup_cause)
750{
751 switch(hangup_cause) {
752 case AST_CAUSE_BUSY:
753 return "BUSY";
755 return "CONGESTION";
758 return "CHANUNAVAIL";
760 default:
761 return "NOANSWER";
762 }
763}
764
765/*! \brief Helper function that basically keeps tabs on dialing attempts */
766static enum ast_dial_result monitor_dial(struct ast_dial *dial, struct ast_channel *chan)
767{
768 int timeout = -1;
769 struct ast_channel *cs[AST_MAX_WATCHERS], *who = NULL;
770 struct ast_dial_channel *channel = NULL;
771 struct answer_exec_struct *answer_exec = NULL;
772 struct timeval start;
773
775
776 /* If the "always indicate ringing" option is set, change state to ringing and indicate to the owner if present */
777 if (dial->options[AST_DIAL_OPTION_RINGING]) {
779 if (chan)
781 } else if (chan && dial->options[AST_DIAL_OPTION_MUSIC] &&
783 char *original_moh = ast_strdupa(ast_channel_musicclass(chan));
784 ast_indicate(chan, -1);
785 ast_channel_musicclass_set(chan, dial->options[AST_DIAL_OPTION_MUSIC]);
787 ast_channel_musicclass_set(chan, original_moh);
788 }
789
790 /* Record start time for timeout purposes */
791 start = ast_tvnow();
792
793 /* We actually figured out the maximum timeout we can do as they were added, so we can directly access the info */
794 timeout = dial->actual_timeout;
795
796 /* Go into an infinite loop while we are trying */
798 int pos = 0, count = 0;
799 struct ast_frame *fr = NULL;
800
801 /* Set up channel structure array */
802 pos = count = 0;
803 if (chan)
804 cs[pos++] = chan;
805
806 /* Add channels we are attempting to dial */
807 AST_LIST_LOCK(&dial->channels);
808 AST_LIST_TRAVERSE(&dial->channels, channel, list) {
809 if (channel->owner) {
810 cs[pos++] = channel->owner;
811 count++;
812 }
813 }
815
816 /* If we have no outbound channels in progress, switch state to unanswered and stop */
817 if (!count) {
819 break;
820 }
821
822 /* Just to be safe... */
823 if (dial->thread == AST_PTHREADT_STOP)
824 break;
825
826 /* Wait for frames from channels */
827 who = ast_waitfor_n(cs, pos, &timeout);
828
829 /* Check to see if our thread is being canceled */
830 if (dial->thread == AST_PTHREADT_STOP)
831 break;
832
833 /* If the timeout no longer exists OR if we got no channel it basically means the timeout was tripped, so handle it */
834 if (!timeout || !who) {
835 timeout = handle_timeout_trip(dial, start);
836 continue;
837 }
838
839 /* Find relative dial channel */
840 if (!chan || !IS_CALLER(chan, who))
841 channel = find_relative_dial_channel(dial, who);
842
843 /* See if this channel has been forwarded elsewhere */
845 handle_call_forward(dial, channel, chan);
846 continue;
847 }
848
849 /* Attempt to read in a frame */
850 if (!(fr = ast_read(who))) {
851 /* If this is the caller then we switch state to hangup and stop */
852 if (chan && IS_CALLER(chan, who)) {
854 break;
855 }
857 ast_hangup(who);
858 channel->owner = NULL;
859 continue;
860 }
861
862 /* Process the frame */
863 handle_frame(dial, channel, fr, chan);
864
865 /* Free the received frame and start all over */
866 ast_frfree(fr);
867 }
868
869 /* Do post-processing from loop */
870 if (dial->state == AST_DIAL_RESULT_ANSWERED) {
871 /* Hangup everything except that which answered */
872 AST_LIST_LOCK(&dial->channels);
873 AST_LIST_TRAVERSE(&dial->channels, channel, list) {
874 if (!channel->owner || channel->owner == who)
875 continue;
876 ast_channel_publish_dial(chan, channel->owner, channel->device, "CANCEL");
877 ast_hangup(channel->owner);
879 channel->owner = NULL;
880 }
882 /* If ANSWER_EXEC is enabled as an option, execute application on answered channel */
883 if ((channel = find_relative_dial_channel(dial, who)) && (answer_exec = FIND_RELATIVE_OPTION(dial, channel, AST_DIAL_OPTION_ANSWER_EXEC))) {
884 channel->is_running_app = 1;
885 answer_exec_run(dial, channel, answer_exec->app, answer_exec->args);
886 channel->is_running_app = 0;
887 }
888
889 if (chan && dial->options[AST_DIAL_OPTION_MUSIC] &&
891 ast_moh_stop(chan);
892 }
893 } else if (dial->state == AST_DIAL_RESULT_HANGUP) {
894 /* Hangup everything */
895 AST_LIST_LOCK(&dial->channels);
896 AST_LIST_TRAVERSE(&dial->channels, channel, list) {
897 if (!channel->owner)
898 continue;
899 ast_channel_publish_dial(chan, channel->owner, channel->device, "CANCEL");
900 ast_hangup(channel->owner);
902 channel->owner = NULL;
903 }
905 }
906
908 enum ast_dial_result state = dial->state;
909
910 ast_dial_destroy(dial);
911 return state;
912 }
913
914 return dial->state;
915}
916
917/*! \brief Dial async thread function */
918static void *async_dial(void *data)
919{
920 struct ast_dial *dial = data;
921 if (dial->callid) {
923 }
924
925 /* This is really really simple... we basically pass monitor_dial a NULL owner and it changes it's behavior */
926 monitor_dial(dial, NULL);
927
928 return NULL;
929}
930
931/*! \brief Execute dialing synchronously or asynchronously
932 * \note Dials channels in a dial structure.
933 * \return Returns dial result code. (TRYING/INVALID/FAILED/ANSWERED/TIMEOUT/UNANSWERED).
934 */
935enum ast_dial_result ast_dial_run(struct ast_dial *dial, struct ast_channel *chan, int async)
936{
938
939 /* Ensure required arguments are passed */
940 if (!dial) {
941 ast_debug(1, "invalid #1\n");
943 }
944
945 /* If there are no channels to dial we can't very well try to dial them */
946 if (AST_LIST_EMPTY(&dial->channels)) {
947 ast_debug(1, "invalid #2\n");
949 }
950
951 /* Dial each requested channel */
952 if (!begin_dial(dial, chan, async))
954
955 /* If we are running async spawn a thread and send it away... otherwise block here */
956 if (async) {
957 /* reference be released at dial destruction if it isn't NULL */
960 /* Try to create a thread */
961 if (ast_pthread_create(&dial->thread, NULL, async_dial, dial)) {
962 /* Failed to create the thread - hangup all dialed channels and return failed */
963 ast_dial_hangup(dial);
965 }
966 } else {
967 res = monitor_dial(dial, chan);
968 }
969
970 return res;
971}
972
973/*! \brief Return channel that answered
974 * \note Returns the Asterisk channel that answered
975 * \param dial Dialing structure
976 */
978{
979 if (!dial)
980 return NULL;
981
982 return ((dial->state == AST_DIAL_RESULT_ANSWERED) ? AST_LIST_FIRST(&dial->channels)->owner : NULL);
983}
984
985/*! \brief Steal the channel that answered
986 * \note Returns the Asterisk channel that answered and removes it from the dialing structure
987 * \param dial Dialing structure
988 */
990{
991 struct ast_channel *chan = NULL;
992
993 if (!dial)
994 return NULL;
995
996 if (dial->state == AST_DIAL_RESULT_ANSWERED) {
997 chan = AST_LIST_FIRST(&dial->channels)->owner;
998 AST_LIST_FIRST(&dial->channels)->owner = NULL;
999 }
1000
1001 return chan;
1002}
1003
1004/*! \brief Return state of dial
1005 * \note Returns the state of the dial attempt
1006 * \param dial Dialing structure
1007 */
1009{
1010 return dial->state;
1011}
1012
1013/*! \brief Cancel async thread
1014 * \note Cancel a running async thread
1015 * \param dial Dialing structure
1016 */
1018{
1019 pthread_t thread;
1020
1021 /* If the dial structure is not running in async, return failed */
1022 if (dial->thread == AST_PTHREADT_NULL)
1024
1025 /* Record thread */
1026 thread = dial->thread;
1027
1028 /* Boom, commence locking */
1029 ast_mutex_lock(&dial->lock);
1030
1031 /* Stop the thread */
1032 dial->thread = AST_PTHREADT_STOP;
1033
1034 /* If the answered channel is running an application we have to soft hangup it, can't just poke the thread */
1035 AST_LIST_LOCK(&dial->channels);
1036 if (AST_LIST_FIRST(&dial->channels)->is_running_app) {
1037 struct ast_channel *chan = AST_LIST_FIRST(&dial->channels)->owner;
1038 if (chan) {
1039 ast_channel_lock(chan);
1041 ast_channel_unlock(chan);
1042 }
1043 } else {
1044 struct ast_dial_channel *channel = NULL;
1045
1046 /* Now we signal it with SIGURG so it will break out of it's waitfor */
1047 pthread_kill(thread, SIGURG);
1048
1049 /* pthread_kill may not be enough, if outgoing channel has already got an answer (no more in waitfor) but is not yet running an application. Force soft hangup. */
1050 AST_LIST_TRAVERSE(&dial->channels, channel, list) {
1051 if (channel->owner) {
1053 }
1054 }
1055 }
1056 AST_LIST_UNLOCK(&dial->channels);
1057
1058 /* Yay done with it */
1059 ast_mutex_unlock(&dial->lock);
1060
1061 /* Finally wait for the thread to exit */
1062 pthread_join(thread, NULL);
1063
1064 /* Yay thread is all gone */
1065 dial->thread = AST_PTHREADT_NULL;
1066
1067 return dial->state;
1068}
1069
1070/*! \brief Hangup channels
1071 * \note Hangup all active channels
1072 * \param dial Dialing structure
1073 */
1074void ast_dial_hangup(struct ast_dial *dial)
1075{
1076 struct ast_dial_channel *channel = NULL;
1077
1078 if (!dial)
1079 return;
1080
1081 AST_LIST_LOCK(&dial->channels);
1082 AST_LIST_TRAVERSE(&dial->channels, channel, list) {
1083 ast_hangup(channel->owner);
1084 channel->owner = NULL;
1085 }
1086 AST_LIST_UNLOCK(&dial->channels);
1087
1088 return;
1089}
1090
1092{
1093 int i = 0;
1094 struct ast_dial_channel *channel = NULL;
1095
1096 if (!dial)
1097 return -1;
1098
1099 /* Hangup and deallocate all the dialed channels */
1100 AST_LIST_LOCK(&dial->channels);
1101 AST_LIST_TRAVERSE_SAFE_BEGIN(&dial->channels, channel, list) {
1102 /* Disable any enabled options */
1103 for (i = 0; i < AST_DIAL_OPTION_MAX; i++) {
1104 if (!channel->options[i])
1105 continue;
1106 if (option_types[i].disable)
1107 option_types[i].disable(channel->options[i]);
1108 channel->options[i] = NULL;
1109 }
1110
1111 /* Hang up channel if need be */
1112 ast_hangup(channel->owner);
1113 channel->owner = NULL;
1114
1115 /* Free structure */
1116 ast_free(channel->tech);
1117 ast_free(channel->device);
1118 ast_free(channel->assignedid1);
1119 ast_free(channel->assignedid2);
1120
1122 ast_free(channel);
1123 }
1125 AST_LIST_UNLOCK(&dial->channels);
1126
1127 /* Disable any enabled options globally */
1128 for (i = 0; i < AST_DIAL_OPTION_MAX; i++) {
1129 if (!dial->options[i])
1130 continue;
1131 if (option_types[i].disable)
1132 option_types[i].disable(dial->options[i]);
1133 dial->options[i] = NULL;
1134 }
1135
1136 /* Lock be gone! */
1137 ast_mutex_destroy(&dial->lock);
1138
1139 /* Free structure */
1140 ast_free(dial);
1141
1142 return 0;
1143}
1144
1145int ast_dial_option_global_enable(struct ast_dial *dial, enum ast_dial_option option, void *data)
1146{
1147 /* If the option is already enabled, return failure */
1148 if (dial->options[option])
1149 return -1;
1150
1151 /* Execute enable callback if it exists, if not simply make sure the value is set */
1152 if (option_types[option].enable)
1153 dial->options[option] = option_types[option].enable(data);
1154 else
1155 dial->options[option] = (void*)1;
1156
1157 return 0;
1158}
1159
1160/*! \brief Helper function for finding a channel in a dial structure based on number
1161 */
1162static struct ast_dial_channel *find_dial_channel(struct ast_dial *dial, int num)
1163{
1164 struct ast_dial_channel *channel = AST_LIST_LAST(&dial->channels);
1165
1166 /* We can try to predict programmer behavior, the last channel they added is probably the one they wanted to modify */
1167 if (channel->num == num)
1168 return channel;
1169
1170 /* Hrm not at the end... looking through the list it is! */
1171 AST_LIST_LOCK(&dial->channels);
1172 AST_LIST_TRAVERSE(&dial->channels, channel, list) {
1173 if (channel->num == num)
1174 break;
1175 }
1176 AST_LIST_UNLOCK(&dial->channels);
1177
1178 return channel;
1179}
1180
1181int ast_dial_option_enable(struct ast_dial *dial, int num, enum ast_dial_option option, void *data)
1182{
1183 struct ast_dial_channel *channel = NULL;
1184
1185 /* Ensure we have required arguments */
1186 if (!dial || AST_LIST_EMPTY(&dial->channels))
1187 return -1;
1188
1189 if (!(channel = find_dial_channel(dial, num)))
1190 return -1;
1191
1192 /* If the option is already enabled, return failure */
1193 if (channel->options[option])
1194 return -1;
1195
1196 /* Execute enable callback if it exists, if not simply make sure the value is set */
1197 if (option_types[option].enable)
1198 channel->options[option] = option_types[option].enable(data);
1199 else
1200 channel->options[option] = (void*)1;
1201
1202 return 0;
1203}
1204
1206{
1207 /* If the option is not enabled, return failure */
1208 if (!dial->options[option]) {
1209 return -1;
1210 }
1211
1212 /* Execute callback of option to disable if it exists */
1213 if (option_types[option].disable)
1214 option_types[option].disable(dial->options[option]);
1215
1216 /* Finally disable option on the structure */
1217 dial->options[option] = NULL;
1218
1219 return 0;
1220}
1221
1222int ast_dial_option_disable(struct ast_dial *dial, int num, enum ast_dial_option option)
1223{
1224 struct ast_dial_channel *channel = NULL;
1225
1226 /* Ensure we have required arguments */
1227 if (!dial || AST_LIST_EMPTY(&dial->channels))
1228 return -1;
1229
1230 if (!(channel = find_dial_channel(dial, num)))
1231 return -1;
1232
1233 /* If the option is not enabled, return failure */
1234 if (!channel->options[option])
1235 return -1;
1236
1237 /* Execute callback of option to disable it if it exists */
1238 if (option_types[option].disable)
1239 option_types[option].disable(channel->options[option]);
1240
1241 /* Finally disable the option on the structure */
1242 channel->options[option] = NULL;
1243
1244 return 0;
1245}
1246
1247int ast_dial_reason(struct ast_dial *dial, int num)
1248{
1249 struct ast_dial_channel *channel;
1250
1251 if (!dial || AST_LIST_EMPTY(&dial->channels) || !(channel = find_dial_channel(dial, num))) {
1252 return -1;
1253 }
1254
1255 return channel->cause;
1256}
1257
1258struct ast_channel *ast_dial_get_channel(struct ast_dial *dial, int num)
1259{
1260 struct ast_dial_channel *channel;
1261
1262 if (!dial || AST_LIST_EMPTY(&dial->channels) || !(channel = find_dial_channel(dial, num))) {
1263 return NULL;
1264 }
1265
1266 return channel->owner;
1267}
1268
1270{
1271 dial->state_callback = callback;
1272}
1273
1274void ast_dial_set_user_data(struct ast_dial *dial, void *user_data)
1275{
1276 dial->user_data = user_data;
1277}
1278
1280{
1281 return dial->user_data;
1282}
1283
1285{
1286 dial->timeout = timeout;
1287
1288 if (dial->timeout > 0 && (dial->actual_timeout > dial->timeout || dial->actual_timeout == -1))
1289 dial->actual_timeout = dial->timeout;
1290
1291 return;
1292}
1293
1294void ast_dial_set_timeout(struct ast_dial *dial, int num, int timeout)
1295{
1296 struct ast_dial_channel *channel = NULL;
1297
1298 if (!(channel = find_dial_channel(dial, num)))
1299 return;
1300
1301 channel->timeout = timeout;
1302
1303 if (channel->timeout > 0 && (dial->actual_timeout > channel->timeout || dial->actual_timeout == -1))
1304 dial->actual_timeout = channel->timeout;
1305
1306 return;
1307}
static const char app[]
Definition: app_adsiprog.c:56
pthread_t thread
Definition: app_sla.c:329
Asterisk main include file. File version handling, generic pbx functions.
#define ast_free(a)
Definition: astmm.h:180
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define ast_log
Definition: astobj2.c:42
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
static int tmp()
Definition: bt_open.c:389
Internal Asterisk hangup causes.
#define AST_CAUSE_CONGESTION
Definition: causes.h:153
#define AST_CAUSE_UNALLOCATED
Definition: causes.h:98
#define AST_CAUSE_NORMAL_CIRCUIT_CONGESTION
Definition: causes.h:120
#define AST_CAUSE_ANSWERED_ELSEWHERE
Definition: causes.h:114
#define AST_CAUSE_NO_ROUTE_DESTINATION
Definition: causes.h:100
#define AST_CAUSE_UNREGISTERED
Definition: causes.h:154
#define AST_CAUSE_BUSY
Definition: causes.h:149
#define AST_CAUSE_NO_ANSWER
Definition: causes.h:109
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:106
#define AST_CAUSE_USER_BUSY
Definition: causes.h:107
enum cc_state state
Definition: ccss.c:393
General Asterisk PBX channel definitions.
const char * ast_channel_name(const struct ast_channel *chan)
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:266
void ast_channel_appl_set(struct ast_channel *chan, const char *value)
int ast_call(struct ast_channel *chan, const char *addr, int timeout)
Make a call.
Definition: channel.c:6460
int ast_channel_connected_line_sub(struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const void *connected_info, int frame)
Run a connected line interception subroutine and update a channel's connected line information.
Definition: channel.c:10337
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2541
@ AST_CHANNEL_REQUESTOR_BRIDGE_PEER
Definition: channel.h:1477
@ AST_CHANNEL_REQUESTOR_REPLACEMENT
Definition: channel.h:1479
const char * ast_channel_musicclass(const struct ast_channel *chan)
struct ast_channel * ast_waitfor_n(struct ast_channel **chan, int n, int *ms)
Waits for input on a group of channels Wait for input on an array of channels for a given # of millis...
Definition: channel.c:3157
#define ast_channel_lock(chan)
Definition: channel.h:2922
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
void ast_channel_data_set(struct ast_channel *chan, const char *value)
struct ast_party_redirecting * ast_channel_redirecting(struct ast_channel *chan)
unsigned short ast_channel_transfercapability(const struct ast_channel *chan)
#define ast_channel_lock_both(chan1, chan2)
Lock two channels.
Definition: channel.h:2929
struct ast_party_connected_line * ast_channel_connected(struct ast_channel *chan)
int ast_channel_datastore_inherit(struct ast_channel *from, struct ast_channel *to)
Inherit datastores from a parent to a child.
Definition: channel.c:2368
void ast_channel_req_accountcodes(struct ast_channel *chan, const struct ast_channel *requestor, enum ast_channel_requestor_relationship relationship)
Setup new channel accountcodes from the requestor channel after ast_request().
Definition: channel.c:6433
const char * ast_channel_context(const struct ast_channel *chan)
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
Definition: autoservice.c:200
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition: channel.c:4256
ast_channel_adsicpe
Definition: channel.h:868
int ast_channel_redirecting_sub(struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const void *redirecting_info, int is_frame)
Run a redirecting interception subroutine and update a channel's redirecting information.
Definition: channel.c:10382
void ast_channel_inherit_variables(const struct ast_channel *parent, struct ast_channel *child)
Inherits channel variable from parent to child channel.
Definition: channel.c:6770
int ast_channel_hangupcause(const struct ast_channel *chan)
struct ast_party_dialed * ast_channel_dialed(struct ast_channel *chan)
int ast_indicate_data(struct ast_channel *chan, int condition, const void *data, size_t datalen)
Indicates condition of channel, with payload.
Definition: channel.c:4652
int ast_softhangup(struct ast_channel *chan, int cause)
Softly hangup up a channel.
Definition: channel.c:2471
#define AST_CHANNEL_NAME
Definition: channel.h:171
struct timeval * ast_channel_whentohangup(struct ast_channel *chan)
@ AST_SOFTHANGUP_EXPLICIT
Definition: channel.h:1148
#define AST_MAX_CONTEXT
Definition: channel.h:135
const char * ast_channel_language(const struct ast_channel *chan)
void ast_connected_line_copy_from_caller(struct ast_party_connected_line *dest, const struct ast_party_caller *src)
Copy the caller information to the connected line information.
Definition: channel.c:8292
const char * ast_channel_call_forward(const struct ast_channel *chan)
int ast_pre_call(struct ast_channel *chan, const char *sub_args)
Execute a Gosub call on the channel before a call is placed.
Definition: channel.c:6443
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
void ast_channel_transfercapability_set(struct ast_channel *chan, unsigned short value)
void ast_channel_adsicpe_set(struct ast_channel *chan, enum ast_channel_adsicpe value)
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4276
struct ast_channel * ast_request(const char *type, struct ast_format_cap *request_cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *addr, int *cause)
Requests a channel.
Definition: channel.c:6353
const char * ast_channel_exten(const struct ast_channel *chan)
#define ast_channel_unlock(chan)
Definition: channel.h:2923
#define AST_MAX_EXTENSION
Definition: channel.h:134
void ast_party_redirecting_copy(struct ast_party_redirecting *dest, const struct ast_party_redirecting *src)
Copy the source redirecting information to the destination redirecting.
Definition: channel.c:2135
@ AST_MEDIA_TYPE_AUDIO
Definition: codec.h:32
#define FIND_RELATIVE_OPTION(dial, dial_channel, ast_dial_option)
Macro for finding the option structure to use on a dialed channel.
Definition: dial.c:214
enum ast_dial_result ast_dial_state(struct ast_dial *dial)
Return state of dial.
Definition: dial.c:1008
static int answer_exec_disable(void *data)
Disable function for 'ANSWER_EXEC' option.
Definition: dial.c:116
static int begin_dial_prerun(struct ast_dial_channel *channel, struct ast_channel *chan, struct ast_format_cap *cap, const char *predial_string)
Helper function that requests all channels.
Definition: dial.c:330
static int predial_disable(void *data)
Definition: dial.c:154
static int dial_append_common(struct ast_dial *dial, struct ast_dial_channel *channel, const char *tech, const char *device, const struct ast_assigned_ids *assignedids)
Definition: dial.c:247
static void * async_dial(void *data)
Dial async thread function.
Definition: dial.c:918
void ast_dial_set_state_callback(struct ast_dial *dial, ast_dial_state_callback callback)
Set a callback for state changes.
Definition: dial.c:1269
int ast_dial_append(struct ast_dial *dial, const char *tech, const char *device, const struct ast_assigned_ids *assignedids)
Append a channel.
Definition: dial.c:280
int ast_dial_option_global_disable(struct ast_dial *dial, enum ast_dial_option option)
Disables an option globally.
Definition: dial.c:1205
struct ast_dial * ast_dial_create(void)
New dialing structure.
Definition: dial.c:223
struct ast_channel * ast_dial_answered(struct ast_dial *dial)
Return channel that answered.
Definition: dial.c:977
void ast_dial_set_user_data(struct ast_dial *dial, void *user_data)
Set user data on a dial structure.
Definition: dial.c:1274
int ast_dial_prerun(struct ast_dial *dial, struct ast_channel *chan, struct ast_format_cap *cap)
Request all appended channels, but do not dial.
Definition: dial.c:431
static void set_state(struct ast_dial *dial, enum ast_dial_result state)
Definition: dial.c:571
void ast_dial_set_global_timeout(struct ast_dial *dial, int timeout)
Set the maximum time (globally) allowed for trying to ring phones.
Definition: dial.c:1284
void ast_dial_hangup(struct ast_dial *dial)
Hangup channels.
Definition: dial.c:1074
static enum ast_dial_result monitor_dial(struct ast_dial *dial, struct ast_channel *chan)
Helper function that basically keeps tabs on dialing attempts.
Definition: dial.c:766
int ast_dial_option_disable(struct ast_dial *dial, int num, enum ast_dial_option option)
Disables an option per channel.
Definition: dial.c:1222
#define IS_CALLER(chan, owner)
Macro that determines whether a channel is the caller or not.
Definition: dial.c:217
const char * ast_hangup_cause_to_dial_status(int hangup_cause)
Convert a hangup cause to a publishable dial status.
Definition: dial.c:749
#define AST_MAX_WATCHERS
Maximum number of channels we can watch at a time.
Definition: dial.c:211
static int handle_call_forward(struct ast_dial *dial, struct ast_dial_channel *channel, struct ast_channel *chan)
Helper function to handle channels that have been call forwarded.
Definition: dial.c:499
enum ast_dial_result ast_dial_run(struct ast_dial *dial, struct ast_channel *chan, int async)
Execute dialing synchronously or asynchronously.
Definition: dial.c:935
int ast_dial_option_enable(struct ast_dial *dial, int num, enum ast_dial_option option, void *data)
Enables an option per channel.
Definition: dial.c:1181
enum ast_dial_result ast_dial_join(struct ast_dial *dial)
Cancel async thread.
Definition: dial.c:1017
void *(* ast_dial_option_cb_enable)(void *data)
Typedef for dial option enable.
Definition: dial.c:78
static void * answer_exec_enable(void *data)
Enable function for 'ANSWER_EXEC' option.
Definition: dial.c:90
struct ast_channel * ast_dial_answered_steal(struct ast_dial *dial)
Steal the channel that answered.
Definition: dial.c:989
static int begin_dial_channel(struct ast_dial_channel *channel, struct ast_channel *chan, int async, const char *predial_string, struct ast_channel *forwarder_chan)
Helper function that does the beginning dialing per-appended channel.
Definition: dial.c:449
static struct ast_dial_channel * find_relative_dial_channel(struct ast_dial *dial, struct ast_channel *owner)
Helper function that finds the dialed channel based on owner.
Definition: dial.c:557
void * ast_dial_get_user_data(struct ast_dial *dial)
Return the user data on a dial structure.
Definition: dial.c:1279
int ast_dial_reason(struct ast_dial *dial, int num)
Get the reason an outgoing channel has failed.
Definition: dial.c:1247
static void answer_exec_run(struct ast_dial *dial, struct ast_dial_channel *dial_channel, char *app, char *args)
Application execution function for 'ANSWER_EXEC' option.
Definition: dial.c:166
static int handle_timeout_trip(struct ast_dial *dial, struct timeval start)
Helper function to handle when a timeout occurs on dialing attempt.
Definition: dial.c:715
void ast_dial_set_timeout(struct ast_dial *dial, int num, int timeout)
Set the maximum time (per channel) allowed for trying to ring the phone.
Definition: dial.c:1294
static struct ast_dial_channel * find_dial_channel(struct ast_dial *dial, int num)
Helper function for finding a channel in a dial structure based on number.
Definition: dial.c:1162
static int begin_dial(struct ast_dial *dial, struct ast_channel *chan, int async)
Helper function that does the beginning dialing per dial structure.
Definition: dial.c:481
struct ast_channel * ast_dial_get_channel(struct ast_dial *dial, int num)
Get the dialing channel, if prerun has been executed.
Definition: dial.c:1258
static void * predial_enable(void *data)
Definition: dial.c:149
int ast_dial_destroy(struct ast_dial *dial)
Destroys a dialing structure.
Definition: dial.c:1091
int ast_dial_option_global_enable(struct ast_dial *dial, enum ast_dial_option option, void *data)
Enables an option globally.
Definition: dial.c:1145
static void * music_enable(void *data)
Definition: dial.c:134
static int music_disable(void *data)
Definition: dial.c:139
int(* ast_dial_option_cb_disable)(void *data)
Typedef for dial option disable.
Definition: dial.c:81
int ast_dial_append_channel(struct ast_dial *dial, struct ast_channel *chan)
Append a channel using an actual channel object.
Definition: dial.c:295
static void handle_frame(struct ast_dial *dial, struct ast_dial_channel *channel, struct ast_frame *fr, struct ast_channel *chan)
Helper function that handles frames.
Definition: dial.c:580
static const struct ast_option_types option_types[]
Map options to respective handlers (enable/disable).
Definition: dial.c:199
Dialing API.
ast_dial_result
List of return codes for dial run API calls.
Definition: dial.h:54
@ AST_DIAL_RESULT_FAILED
Definition: dial.h:56
@ AST_DIAL_RESULT_HANGUP
Definition: dial.h:63
@ AST_DIAL_RESULT_INVALID
Definition: dial.h:55
@ AST_DIAL_RESULT_ANSWERED
Definition: dial.h:61
@ AST_DIAL_RESULT_TIMEOUT
Definition: dial.h:62
@ AST_DIAL_RESULT_TRYING
Definition: dial.h:57
@ AST_DIAL_RESULT_PROGRESS
Definition: dial.h:59
@ AST_DIAL_RESULT_RINGING
Definition: dial.h:58
@ AST_DIAL_RESULT_PROCEEDING
Definition: dial.h:60
@ AST_DIAL_RESULT_UNANSWERED
Definition: dial.h:64
void(* ast_dial_state_callback)(struct ast_dial *)
Definition: dial.h:39
ast_dial_option
List of options that are applicable either globally or per dialed channel.
Definition: dial.h:42
@ AST_DIAL_OPTION_DIAL_REPLACES_SELF
Definition: dial.h:48
@ AST_DIAL_OPTION_ANSWER_EXEC
Definition: dial.h:44
@ AST_DIAL_OPTION_RINGING
Definition: dial.h:43
@ AST_DIAL_OPTION_MUSIC
Definition: dial.h:45
@ AST_DIAL_OPTION_PREDIAL
Definition: dial.h:47
@ AST_DIAL_OPTION_DISABLE_CALL_FORWARDING
Definition: dial.h:46
@ AST_DIAL_OPTION_SELF_DESTROY
Definition: dial.h:49
@ AST_DIAL_OPTION_MAX
Definition: dial.h:50
int ast_format_cap_append_by_type(struct ast_format_cap *cap, enum ast_media_type type)
Add all codecs Asterisk knows about for a specific type to the capabilities structure.
Definition: format_cap.c:216
@ AST_FORMAT_CAP_FLAG_DEFAULT
Definition: format_cap.h:38
#define ast_format_cap_alloc(flags)
Allocate a new ast_format_cap structure.
Definition: format_cap.h:49
size_t ast_format_cap_count(const struct ast_format_cap *cap)
Get the number of formats present within the capabilities structure.
Definition: format_cap.c:395
void ast_channel_publish_dial(struct ast_channel *caller, struct ast_channel *peer, const char *dialstring, const char *dialstatus)
Publish in the ast_channel_topic or ast_channel_topic_all topics a stasis message for the channels in...
void ast_channel_stage_snapshot_done(struct ast_channel *chan)
Clear flag to indicate channel snapshot is being staged, and publish snapshot.
void ast_channel_stage_snapshot(struct ast_channel *chan)
Set flag to indicate channel snapshot is being staged.
void ast_channel_publish_dial_forward(struct ast_channel *caller, struct ast_channel *peer, struct ast_channel *forwarded, const char *dialstring, const char *dialstatus, const char *forward)
Publish in the ast_channel_topic or ast_channel_topic_all topics a stasis message for the channels in...
Application convenience functions, designed to give consistent look and feel to Asterisk apps.
#define ast_frfree(fr)
@ AST_FRAME_CONTROL
@ AST_CONTROL_SRCUPDATE
@ AST_CONTROL_PROGRESS
@ AST_CONTROL_OFFHOOK
@ AST_CONTROL_BUSY
@ AST_CONTROL_UNHOLD
@ AST_CONTROL_VIDUPDATE
@ AST_CONTROL_PROCEEDING
@ AST_CONTROL_REDIRECTING
@ AST_CONTROL_CONGESTION
@ AST_CONTROL_ANSWER
@ AST_CONTROL_RINGING
@ AST_CONTROL_HOLD
@ AST_CONTROL_CONNECTED_LINE
@ AST_CONTROL_FLASH
@ AST_CONTROL_INCOMPLETE
@ AST_CONTROL_PVT_CAUSE_CODE
#define ast_debug(level,...)
Log a DEBUG message.
ast_callid ast_read_threadstorage_callid(void)
extracts the callerid from the thread
Definition: logger.c:2286
int ast_callid_threadassoc_add(ast_callid callid)
Adds a known callid to thread storage of the calling thread.
Definition: logger.c:2308
unsigned int ast_callid
#define ast_verb(level,...)
#define LOG_WARNING
A set of macros to manage forward-linked lists.
#define AST_LIST_LAST(head)
Returns the last entry contained in a list.
Definition: linkedlists.h:429
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:450
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
Definition: linkedlists.h:410
#define AST_LIST_HEAD_INIT(head)
Initializes a list head structure.
Definition: linkedlists.h:626
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:615
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:40
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:711
#define AST_LIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
Definition: linkedlists.h:856
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:529
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:557
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:140
#define AST_LIST_HEAD(name, type)
Defines a structure to be used to hold a list of specified type.
Definition: linkedlists.h:173
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:421
Asterisk locking-related definitions:
#define AST_PTHREADT_NULL
Definition: lock.h:66
#define ast_mutex_init(pmutex)
Definition: lock.h:186
#define AST_PTHREADT_STOP
Definition: lock.h:67
#define ast_mutex_unlock(a)
Definition: lock.h:190
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition: lock.h:757
#define ast_mutex_destroy(a)
Definition: lock.h:188
#define ast_mutex_lock(a)
Definition: lock.h:189
int ast_max_forwards_decrement(struct ast_channel *chan)
Decrement the max forwards count for a particular channel.
Definition: max_forwards.c:135
int ast_max_forwards_get(struct ast_channel *chan)
Get the current max forwards for a particular channel.
Definition: max_forwards.c:121
Music on hold handling.
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
Definition: channel.c:7765
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:7775
Core PBX routines and definitions.
#define AST_MAX_APP
Definition: pbx.h:40
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name.
int ast_pbx_exec_application(struct ast_channel *chan, const char *app_name, const char *app_args)
Execute an application.
Definition: pbx_app.c:501
#define NULL
Definition: resample.c:96
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
Structure for 'ANSWER_EXEC' option.
Definition: dial.c:84
char * args
Definition: dial.c:86
char app[AST_MAX_APP]
Definition: dial.c:85
Structure to pass both assignedid values to channel drivers.
Definition: channel.h:604
const char * uniqueid2
Definition: channel.h:606
const char * uniqueid
Definition: channel.h:605
Main Channel structure associated with a channel.
const char * data
const struct ast_channel_tech * tech
Dialing channel structure. Contains per-channel dialing options, asterisk channel,...
Definition: dial.c:63
int timeout
Definition: dial.c:65
unsigned int is_running_app
Definition: dial.c:70
struct ast_channel * owner
Definition: dial.c:73
char * assignedid2
Definition: dial.c:72
void * options[AST_DIAL_OPTION_MAX]
Definition: dial.c:68
char * assignedid1
Definition: dial.c:71
char * tech
Definition: dial.c:66
struct ast_dial_channel::@344 list
char * device
Definition: dial.c:67
Main dialing structure. Contains global options, channels being dialed, and more!
Definition: dial.c:48
pthread_t thread
Definition: dial.c:57
void * user_data
Definition: dial.c:55
enum ast_dial_result state
Definition: dial.c:52
int timeout
Definition: dial.c:50
struct ast_dial::@343 channels
ast_callid callid
Definition: dial.c:58
int num
Definition: dial.c:49
ast_dial_state_callback state_callback
Definition: dial.c:54
ast_mutex_t lock
Definition: dial.c:56
void * options[AST_DIAL_OPTION_MAX]
Definition: dial.c:53
int actual_timeout
Definition: dial.c:51
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
Data structure associated with a single frame of data.
struct ast_frame_subclass subclass
union ast_frame::@226 data
enum ast_frame_type frametype
Structure for mutex and tracking information.
Definition: lock.h:135
enum ast_dial_option option
Definition: dial.c:188
ast_dial_option_cb_enable enable
Definition: dial.c:189
ast_dial_option_cb_disable disable
Definition: dial.c:190
int transit_network_select
Transit Network Select.
Definition: channel.h:397
Channel datastore data for max forwards.
Definition: max_forwards.c:29
const char * args
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:107
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
Utility functions.
#define ast_pthread_create(a, b, c, d)
Definition: utils.h:584