44 #include "asterisk/stasis_channels.h"
45 #include "asterisk/max_forwards.h"
70 unsigned int is_running_app:1;
96 if (ast_strlen_zero(app))
100 if (!(answer_exec =
ast_calloc(1,
sizeof(*answer_exec))))
104 if ((
args = strchr(app,
','))) {
125 if (answer_exec->
args)
126 ast_free(answer_exec->
args);
129 ast_free(answer_exec);
134 static void *music_enable(
void *data)
139 static int music_disable(
void *data)
149 static void *predial_enable(
void *data)
154 static int predial_disable(
void *data)
177 ast_mutex_lock(&dial->lock);
178 if (dial->
thread != AST_PTHREADT_STOP) {
180 dial_channel->
owner = NULL;
182 ast_mutex_unlock(&dial->lock);
211 #define AST_MAX_WATCHERS 256
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])
217 #define IS_CALLER(chan, owner) (chan == owner ? 1 : 0)
235 dial->
thread = AST_PTHREADT_NULL;
242 ast_mutex_init(&dial->lock);
247 static 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)
255 if (assignedids && !ast_strlen_zero(assignedids->uniqueid)) {
258 if (!ast_strlen_zero(assignedids->uniqueid2)) {
282 struct ast_dial_channel *channel = NULL;
285 if (!dial || !tech || !device)
289 if (!(channel =
ast_calloc(1,
sizeof(*channel))))
292 return dial_append_common(dial, channel, tech, device, assignedids);
297 struct ast_dial_channel *channel;
302 if (!dial || !chan) {
310 channel->
owner = chan;
314 device = strchr(tech,
'/');
321 dash = strrchr(device,
'-');
326 return dial_append_common(dial, channel, tech, device, NULL);
343 ast_channel_lock(chan);
344 max_forwards = ast_max_forwards_get(chan);
345 requester_cap =
ao2_bump(ast_channel_nativeformats(chan));
346 ast_channel_unlock(chan);
348 if (max_forwards <= 0) {
349 ast_log(LOG_WARNING,
"Cannot dial from channel '%s'. Max forwards exceeded\n",
350 ast_channel_name(chan));
354 if (!channel->
owner) {
357 }
else if (requester_cap) {
358 cap_request = requester_cap;
362 cap_request = cap_all_audio;
367 ao2_cleanup(cap_all_audio);
371 ao2_cleanup(requester_cap);
372 ao2_cleanup(cap_all_audio);
378 ast_channel_lock(channel->
owner);
383 ast_channel_appl_set(channel->
owner,
"AppDial2");
384 ast_channel_data_set(channel->
owner,
"(Outgoing Line)");
386 memset(ast_channel_whentohangup(channel->
owner), 0,
sizeof(*ast_channel_whentohangup(channel->
owner)));
392 ast_max_forwards_decrement(channel->
owner);
401 ast_channel_language_set(channel->
owner, ast_channel_language(chan));
407 if (ast_strlen_zero(ast_channel_musicclass(channel->
owner)))
408 ast_channel_musicclass_set(channel->
owner, ast_channel_musicclass(chan));
410 ast_channel_adsicpe_set(channel->
owner, ast_channel_adsicpe(chan));
411 ast_channel_transfercapability_set(channel->
owner, ast_channel_transfercapability(chan));
412 ast_channel_unlock(chan);
416 ast_channel_unlock(channel->
owner);
418 if (!ast_strlen_zero(predial_string)) {
433 struct ast_dial_channel *channel;
459 if (forwarder_chan) {
460 ast_copy_string(forwarder, ast_channel_name(forwarder_chan),
sizeof(forwarder));
461 ast_channel_lock(channel->
owner);
463 ast_channel_unlock(channel->
owner);
470 channel->
owner = NULL;
474 ast_verb(3,
"Called %s\n", channel->
device);
483 struct ast_dial_channel *channel = NULL;
503 char *tech =
"Local", *device = tmp, *stuff;
509 channel->
owner = NULL;
514 if ((stuff = strchr(tmp,
'/'))) {
519 const char *forward_context;
522 ast_channel_lock(original);
524 snprintf(destination,
sizeof(destination),
"%s@%s", tmp,
S_OR(forward_context, ast_channel_context(original)));
525 ast_channel_unlock(original);
530 ast_free(channel->
tech);
531 ast_free(channel->
device);
543 channel->
owner = NULL;
549 ast_channel_call_forward(original));
559 struct ast_dial_channel *channel = NULL;
563 if (channel->
owner == owner)
586 ast_verb(3,
"%s answered %s\n", ast_channel_name(channel->
owner), ast_channel_name(chan));
588 ast_verb(3,
"%s answered\n", ast_channel_name(channel->
owner));
598 ast_verb(3,
"%s is busy\n", ast_channel_name(channel->
owner));
601 channel->
cause = AST_CAUSE_USER_BUSY;
602 channel->
owner = NULL;
605 ast_verb(3,
"%s is circuit-busy\n", ast_channel_name(channel->
owner));
608 channel->
cause = AST_CAUSE_NORMAL_CIRCUIT_CONGESTION;
609 channel->
owner = NULL;
612 ast_verb(3,
"%s dialed Incomplete extension %s\n", ast_channel_name(channel->
owner), ast_channel_exten(channel->
owner));
617 channel->
cause = AST_CAUSE_UNALLOCATED;
618 channel->
owner = NULL;
622 ast_verb(3,
"%s is ringing\n", ast_channel_name(channel->
owner));
631 ast_verb(3,
"%s is making progress, passing it to %s\n", ast_channel_name(channel->
owner), ast_channel_name(chan));
634 ast_verb(3,
"%s is making progress\n", ast_channel_name(channel->
owner));
642 ast_verb(3,
"%s requested a video update, passing it to %s\n", ast_channel_name(channel->
owner), ast_channel_name(chan));
649 ast_verb(3,
"%s requested a source update, passing it to %s\n", ast_channel_name(channel->
owner), ast_channel_name(chan));
656 ast_verb(3,
"%s connected line has changed, passing it to %s\n", ast_channel_name(channel->
owner), ast_channel_name(chan));
665 ast_verb(3,
"%s redirecting info has changed, passing it to %s\n", ast_channel_name(channel->
owner), ast_channel_name(chan));
673 ast_verb(3,
"%s is proceeding, passing it to %s\n", ast_channel_name(channel->
owner), ast_channel_name(chan));
676 ast_verb(3,
"%s is proceeding\n", ast_channel_name(channel->
owner));
684 ast_verb(3,
"Call on %s placed on hold\n", ast_channel_name(chan));
691 ast_verb(3,
"Call on %s left from hold\n", ast_channel_name(chan));
717 struct ast_dial_channel *channel = NULL;
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;
743 if (lowest_timeout >= 0)
744 new_timeout = lowest_timeout - diff;
751 switch(hangup_cause) {
754 case AST_CAUSE_CONGESTION:
756 case AST_CAUSE_NO_ROUTE_DESTINATION:
757 case AST_CAUSE_UNREGISTERED:
758 return "CHANUNAVAIL";
759 case AST_CAUSE_NO_ANSWER:
770 struct ast_dial_channel *channel = NULL;
772 struct timeval start;
783 char *original_moh =
ast_strdupa(ast_channel_musicclass(chan));
787 ast_channel_musicclass_set(chan, original_moh);
798 int pos = 0, count = 0;
809 if (channel->
owner) {
810 cs[pos++] = channel->
owner;
823 if (dial->
thread == AST_PTHREADT_STOP)
830 if (dial->
thread == AST_PTHREADT_STOP)
834 if (!timeout || !who) {
844 if (!ast_strlen_zero(ast_channel_call_forward(who))) {
858 channel->
owner = NULL;
878 channel->
cause = AST_CAUSE_ANSWERED_ELSEWHERE;
879 channel->
owner = NULL;
901 channel->
cause = AST_CAUSE_NORMAL_CLEARING;
902 channel->
owner = NULL;
1022 if (dial->
thread == AST_PTHREADT_NULL)
1029 ast_mutex_lock(&dial->lock);
1032 dial->
thread = AST_PTHREADT_STOP;
1039 ast_channel_lock(chan);
1041 ast_channel_unlock(chan);
1044 struct ast_dial_channel *channel = NULL;
1047 pthread_kill(thread, SIGURG);
1051 if (channel->
owner) {
1059 ast_mutex_unlock(&dial->lock);
1062 pthread_join(thread, NULL);
1065 dial->
thread = AST_PTHREADT_NULL;
1076 struct ast_dial_channel *channel = NULL;
1084 channel->
owner = NULL;
1094 struct ast_dial_channel *channel = NULL;
1106 if (option_types[i].disable)
1107 option_types[i].disable(channel->
options[i]);
1113 channel->
owner = NULL;
1116 ast_free(channel->
tech);
1117 ast_free(channel->
device);
1131 if (option_types[i].disable)
1132 option_types[i].disable(dial->
options[i]);
1137 ast_mutex_destroy(&dial->lock);
1152 if (option_types[option].enable)
1153 dial->
options[option] = option_types[option].enable(data);
1155 dial->
options[option] = (
void*)1;
1167 if (channel->
num == num)
1173 if (channel->
num == num)
1183 struct ast_dial_channel *channel = NULL;
1197 if (option_types[option].enable)
1198 channel->
options[option] = option_types[option].enable(data);
1200 channel->
options[option] = (
void*)1;
1213 if (option_types[option].disable)
1214 option_types[option].disable(dial->
options[option]);
1224 struct ast_dial_channel *channel = NULL;
1234 if (!channel->
options[option])
1238 if (option_types[option].disable)
1239 option_types[option].disable(channel->
options[option]);
1242 channel->
options[option] = NULL;
1249 struct ast_dial_channel *channel;
1255 return channel->
cause;
1260 struct ast_dial_channel *channel;
1266 return channel->
owner;
1296 struct ast_dial_channel *channel = NULL;
int ast_dial_option_global_enable(struct ast_dial *dial, enum ast_dial_option option, void *data)
Enables an option globally.
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...
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.
Main Channel structure associated with a channel.
int ast_dial_append_channel(struct ast_dial *dial, struct ast_channel *chan)
Append a channel using an actual channel object.
int ast_dial_reason(struct ast_dial *dial, int num)
Get the reason an outgoing channel has failed.
#define AST_LIST_LOCK(head)
Locks a list.
Asterisk locking-related definitions:
Asterisk main include file. File version handling, generic pbx functions.
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
int(* ast_dial_option_cb_disable)(void *data)
Typedef for dial option disable.
unsigned int is_running_app
#define AST_LIST_HEAD(name, type)
Defines a structure to be used to hold a list of specified type.
void ast_dial_set_global_timeout(struct ast_dial *dial, int timeout)
Set the maximum time (globally) allowed for trying to ring phones.
void ast_dial_set_state_callback(struct ast_dial *dial, ast_dial_state_callback callback)
Set a callback for state changes.
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
Main dialing structure. Contains global options, channels being dialed, and more! ...
void ast_dial_hangup(struct ast_dial *dial)
Hangup channels.
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.
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
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.
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...
enum ast_dial_result state
int ast_softhangup(struct ast_channel *chan, int cause)
Softly hangup up a channel.
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
struct ast_dial * ast_dial_create(void)
New dialing structure.
struct ast_channel * ast_dial_get_channel(struct ast_dial *dial, int num)
Get the dialing channel, if prerun has been executed.
int ast_call(struct ast_channel *chan, const char *addr, int timeout)
Make a call.
int ast_dial_option_disable(struct ast_dial *dial, int num, enum ast_dial_option option)
Disables an option per channel.
const char * ast_hangup_cause_to_dial_status(int hangup_cause)
Convert a hangup cause to a publishable dial status.
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Structure to pass both assignedid values to channel drivers.
void ast_dial_set_user_data(struct ast_dial *dial, void *user_data)
Set user data on a dial structure.
int ast_indicate_data(struct ast_channel *chan, int condition, const void *data, size_t datalen)
Indicates condition of channel, with payload.
int ast_callid_threadassoc_add(ast_callid callid)
Adds a known callid to thread storage of the calling thread.
struct ast_channel * ast_dial_answered_steal(struct ast_dial *dial)
Steal the channel that answered.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
static int begin_dial(struct ast_dial *dial, struct ast_channel *chan, int async)
Helper function that does the beginning dialing per dial structure.
ast_callid ast_read_threadstorage_callid(void)
extracts the callerid from the thread
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
#define FIND_RELATIVE_OPTION(dial, dial_channel, ast_dial_option)
Macro for finding the option structure to use on a dialed channel.
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
#define ast_strdup(str)
A wrapper for strdup()
#define AST_LIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
int ast_dial_append(struct ast_dial *dial, const char *tech, const char *device, const struct ast_assigned_ids *assignedids)
Append a channel.
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
#define AST_MAX_WATCHERS
Maximum number of channels we can watch at a time.
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
struct ast_frame_subclass subclass
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.
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
int ast_channel_datastore_inherit(struct ast_channel *from, struct ast_channel *to)
Inherit datastores from a parent to a child.
enum ast_dial_result ast_dial_run(struct ast_dial *dial, struct ast_channel *chan, int async)
Execute dialing synchronously or asynchronously.
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.
void * options[AST_DIAL_OPTION_MAX]
ast_dial_result
List of return codes for dial run API calls.
struct ast_dial::@347 channels
General Asterisk PBX channel definitions.
void ast_channel_stage_snapshot_done(struct ast_channel *chan)
Clear flag to indicate channel snapshot is being staged, and publish snapshot.
#define ast_strdupa(s)
duplicate a string in memory from the stack
#define AST_MAX_EXTENSION
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.
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
A set of macros to manage forward-linked lists.
#define ast_debug(level,...)
Log a DEBUG message.
struct ast_channel * ast_dial_answered(struct ast_dial *dial)
Return channel that answered.
int ast_pre_call(struct ast_channel *chan, const char *sub_args)
Execute a Gosub call on the channel before a call is placed.
ast_dial_option
List of options that are applicable either globally or per dialed channel.
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().
Core PBX routines and definitions.
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
void * options[AST_DIAL_OPTION_MAX]
void ast_channel_stage_snapshot(struct ast_channel *chan)
Set flag to indicate channel snapshot is being staged.
struct ast_channel * owner
void * ast_dial_get_user_data(struct ast_dial *dial)
Return the user data on a dial structure.
int ast_pbx_exec_application(struct ast_channel *chan, const char *app_name, const char *app_args)
Execute an application.
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
static int answer_exec_disable(void *data)
Disable function for 'ANSWER_EXEC' option.
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...
Channel datastore data for max forwards.
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
#define AST_LIST_LAST(head)
Returns the last entry contained in a list.
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...
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
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.
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
static void * async_dial(void *data)
Dial async thread function.
enum ast_dial_result ast_dial_state(struct ast_dial *dial)
Return state of dial.
union ast_frame::@224 data
void ast_channel_inherit_variables(const struct ast_channel *parent, struct ast_channel *child)
Inherits channel variable from parent to child channel.
#define AST_LIST_HEAD_INIT(head)
Initializes a list head structure.
#define ast_calloc(num, len)
A wrapper for calloc()
static void * answer_exec_enable(void *data)
Enable function for 'ANSWER_EXEC' option.
static const struct ast_option_types option_types[]
Map options to respective handlers (enable/disable).
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Structure for 'ANSWER_EXEC' option.
static enum ast_dial_result monitor_dial(struct ast_dial *dial, struct ast_channel *chan)
Helper function that basically keeps tabs on dialing attempts.
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...
enum ast_dial_result ast_dial_join(struct ast_dial *dial)
Cancel async thread.
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.
#define ast_channel_lock_both(chan1, chan2)
Lock two channels.
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.
int transit_network_select
Transit Network Select.
ast_dial_state_callback state_callback
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.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
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.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
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.
Data structure associated with a single frame of data.
Internal Asterisk hangup causes.
int ast_dial_option_global_disable(struct ast_dial *dial, enum ast_dial_option option)
Disables an option globally.
int ast_dial_option_enable(struct ast_dial *dial, int num, enum ast_dial_option option, void *data)
Enables an option per channel.
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
enum ast_frame_type frametype
struct ast_dial_channel::@348 list
int ast_dial_destroy(struct ast_dial *dial)
Destroys a dialing structure.
#define IS_CALLER(chan, owner)
Macro that determines whether a channel is the caller or not.
void *(* ast_dial_option_cb_enable)(void *data)
Typedef for dial option enable.
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
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.
Structure for mutex and tracking information.
static int handle_timeout_trip(struct ast_dial *dial, struct timeval start)
Helper function to handle when a timeout occurs on dialing attempt.
Dialing channel structure. Contains per-channel dialing options, asterisk channel, and more!