Asterisk - The Open Source Telephony Project  GIT-master-a24979a
Data Structures | Macros | Typedefs | Functions | Variables
dial.c File Reference

Dialing API. More...

#include "asterisk.h"
#include <sys/time.h>
#include <signal.h>
#include "asterisk/channel.h"
#include "asterisk/utils.h"
#include "asterisk/lock.h"
#include "asterisk/linkedlists.h"
#include "asterisk/dial.h"
#include "asterisk/pbx.h"
#include "asterisk/musiconhold.h"
#include "asterisk/app.h"
#include "asterisk/causes.h"
#include "asterisk/stasis_channels.h"
#include "asterisk/max_forwards.h"
Include dependency graph for dial.c:

Go to the source code of this file.

Data Structures

struct  answer_exec_struct
 Structure for 'ANSWER_EXEC' option. More...
 
struct  ast_dial
 Main dialing structure. Contains global options, channels being dialed, and more! More...
 
struct  ast_dial_channel
 Dialing channel structure. Contains per-channel dialing options, asterisk channel, and more! More...
 
struct  ast_option_types
 

Macros

#define AST_MAX_WATCHERS   256
 Maximum number of channels we can watch at a time. More...
 
#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])
 Macro for finding the option structure to use on a dialed channel. More...
 
#define IS_CALLER(chan, owner)   (chan == owner ? 1 : 0)
 Macro that determines whether a channel is the caller or not. More...
 

Typedefs

typedef int(* ast_dial_option_cb_disable) (void *data)
 Typedef for dial option disable. More...
 
typedef void *(* ast_dial_option_cb_enable) (void *data)
 Typedef for dial option enable. More...
 

Functions

static int answer_exec_disable (void *data)
 Disable function for 'ANSWER_EXEC' option. More...
 
static void * answer_exec_enable (void *data)
 Enable function for 'ANSWER_EXEC' option. More...
 
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. More...
 
struct ast_channelast_dial_answered (struct ast_dial *dial)
 Return channel that answered. More...
 
struct ast_channelast_dial_answered_steal (struct ast_dial *dial)
 Steal the channel that answered. More...
 
int ast_dial_append (struct ast_dial *dial, const char *tech, const char *device, const struct ast_assigned_ids *assignedids)
 Append a channel. More...
 
int ast_dial_append_channel (struct ast_dial *dial, struct ast_channel *chan)
 Append a channel using an actual channel object. More...
 
struct ast_dialast_dial_create (void)
 New dialing structure. More...
 
int ast_dial_destroy (struct ast_dial *dial)
 Destroys a dialing structure. More...
 
struct ast_channelast_dial_get_channel (struct ast_dial *dial, int num)
 Get the dialing channel, if prerun has been executed. More...
 
void * ast_dial_get_user_data (struct ast_dial *dial)
 Return the user data on a dial structure. More...
 
void ast_dial_hangup (struct ast_dial *dial)
 Hangup channels. More...
 
enum ast_dial_result ast_dial_join (struct ast_dial *dial)
 Cancel async thread. More...
 
int ast_dial_option_disable (struct ast_dial *dial, int num, enum ast_dial_option option)
 Disables an option per channel. More...
 
int ast_dial_option_enable (struct ast_dial *dial, int num, enum ast_dial_option option, void *data)
 Enables an option per channel. More...
 
int ast_dial_option_global_disable (struct ast_dial *dial, enum ast_dial_option option)
 Disables an option globally. More...
 
int ast_dial_option_global_enable (struct ast_dial *dial, enum ast_dial_option option, void *data)
 Enables an option globally. More...
 
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. More...
 
int ast_dial_reason (struct ast_dial *dial, int num)
 Get the reason an outgoing channel has failed. More...
 
enum ast_dial_result ast_dial_run (struct ast_dial *dial, struct ast_channel *chan, int async)
 Execute dialing synchronously or asynchronously. More...
 
void ast_dial_set_global_timeout (struct ast_dial *dial, int timeout)
 Set the maximum time (globally) allowed for trying to ring phones. More...
 
void ast_dial_set_state_callback (struct ast_dial *dial, ast_dial_state_callback callback)
 Set a callback for state changes. More...
 
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. More...
 
void ast_dial_set_user_data (struct ast_dial *dial, void *user_data)
 Set user data on a dial structure. More...
 
enum ast_dial_result ast_dial_state (struct ast_dial *dial)
 Return state of dial. More...
 
const char * ast_hangup_cause_to_dial_status (int hangup_cause)
 Convert a hangup cause to a publishable dial status. More...
 
static void * async_dial (void *data)
 Dial async thread function. More...
 
static int begin_dial (struct ast_dial *dial, struct ast_channel *chan, int async)
 Helper function that does the beginning dialing per dial structure. More...
 
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. More...
 
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. More...
 
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)
 
static struct ast_dial_channelfind_dial_channel (struct ast_dial *dial, int num)
 Helper function for finding a channel in a dial structure based on number. More...
 
static struct ast_dial_channelfind_relative_dial_channel (struct ast_dial *dial, struct ast_channel *owner)
 Helper function that finds the dialed channel based on owner. More...
 
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. More...
 
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. More...
 
static int handle_timeout_trip (struct ast_dial *dial, struct timeval start)
 Helper function to handle when a timeout occurs on dialing attempt. More...
 
static enum ast_dial_result monitor_dial (struct ast_dial *dial, struct ast_channel *chan)
 Helper function that basically keeps tabs on dialing attempts. More...
 
static int music_disable (void *data)
 
static void * music_enable (void *data)
 
static int predial_disable (void *data)
 
static void * predial_enable (void *data)
 
static void set_state (struct ast_dial *dial, enum ast_dial_result state)
 

Variables

static const struct ast_option_types option_types []
 Map options to respective handlers (enable/disable). More...
 

Detailed Description

Dialing API.

Author
Joshua Colp jcolp.nosp@m.@dig.nosp@m.ium.c.nosp@m.om

Definition in file dial.c.

Macro Definition Documentation

◆ AST_MAX_WATCHERS

#define AST_MAX_WATCHERS   256

Maximum number of channels we can watch at a time.

Definition at line 213 of file dial.c.

◆ FIND_RELATIVE_OPTION

#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])

Macro for finding the option structure to use on a dialed channel.

Definition at line 216 of file dial.c.

◆ IS_CALLER

#define IS_CALLER (   chan,
  owner 
)    (chan == owner ? 1 : 0)

Macro that determines whether a channel is the caller or not.

Definition at line 219 of file dial.c.

Typedef Documentation

◆ ast_dial_option_cb_disable

typedef int(* ast_dial_option_cb_disable) (void *data)

Typedef for dial option disable.

Definition at line 81 of file dial.c.

◆ ast_dial_option_cb_enable

typedef void*(* ast_dial_option_cb_enable) (void *data)

Typedef for dial option enable.

Definition at line 78 of file dial.c.

Function Documentation

◆ answer_exec_disable()

static int answer_exec_disable ( void *  data)
static

Disable function for 'ANSWER_EXEC' option.

Definition at line 116 of file dial.c.

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 }
#define ast_free(a)
Definition: astmm.h:180
Structure for 'ANSWER_EXEC' option.
Definition: dial.c:84
char * args
Definition: dial.c:86

References answer_exec_struct::args, and ast_free.

◆ answer_exec_enable()

static void* answer_exec_enable ( void *  data)
static

Enable function for 'ANSWER_EXEC' option.

Definition at line 90 of file dial.c.

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? */
96  if (ast_strlen_zero(app))
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 }
static const char app[]
Definition: app_adsiprog.c:56
#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 NULL
Definition: resample.c:96
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:406
char app[AST_MAX_APP]
Definition: dial.c:85
const char * args

References app, answer_exec_struct::app, answer_exec_struct::args, args, ast_calloc, ast_copy_string(), ast_strdup, ast_strdupa, ast_strlen_zero(), and NULL.

◆ answer_exec_run()

static void answer_exec_run ( struct ast_dial dial,
struct ast_dial_channel dial_channel,
char *  app,
char *  args 
)
static

Application execution function for 'ANSWER_EXEC' option.

Definition at line 166 of file dial.c.

167 {
168  struct ast_channel *chan = dial_channel->owner;
169  struct ast_app *ast_app = pbx_findapp(app);
170 
171  /* If the application was not found, return immediately */
172  if (!ast_app)
173  return;
174 
175  /* All is well... execute the application */
176  pbx_exec(chan, ast_app, args);
177 
178  /* If another thread is not taking over hang up the channel */
179  ast_mutex_lock(&dial->lock);
180  if (dial->thread != AST_PTHREADT_STOP) {
181  ast_hangup(chan);
182  dial_channel->owner = NULL;
183  }
184  ast_mutex_unlock(&dial->lock);
185 
186  return;
187 }
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2542
#define AST_PTHREADT_STOP
Definition: lock.h:67
#define ast_mutex_unlock(a)
Definition: lock.h:188
#define ast_mutex_lock(a)
Definition: lock.h:187
int pbx_exec(struct ast_channel *c, struct ast_app *app, const char *data)
Execute an application.
Definition: pbx_app.c:471
struct ast_app * pbx_findapp(const char *app)
Look up an application.
Definition: ael_main.c:165
ast_app: A registered application
Definition: pbx_app.c:45
Main Channel structure associated with a channel.
struct ast_channel * owner
Definition: dial.c:73
pthread_t thread
Definition: dial.c:57
ast_mutex_t lock
Definition: dial.c:56

References app, args, ast_hangup(), ast_mutex_lock, ast_mutex_unlock, AST_PTHREADT_STOP, ast_dial::lock, NULL, ast_dial_channel::owner, pbx_exec(), pbx_findapp(), and ast_dial::thread.

◆ ast_dial_answered()

struct ast_channel* ast_dial_answered ( struct ast_dial dial)

Return channel that answered.

Note
Returns the Asterisk channel that answered
Parameters
dialDialing structure

Definition at line 981 of file dial.c.

982 {
983  if (!dial)
984  return NULL;
985 
986  return ((dial->state == AST_DIAL_RESULT_ANSWERED) ? AST_LIST_FIRST(&dial->channels)->owner : NULL);
987 }
@ AST_DIAL_RESULT_ANSWERED
Definition: dial.h:61
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:421
enum ast_dial_result state
Definition: dial.c:52
struct ast_dial::@373 channels

References AST_DIAL_RESULT_ANSWERED, AST_LIST_FIRST, ast_dial::channels, NULL, and ast_dial::state.

Referenced by ari_originate_dial(), dial_trunk(), page_state_callback(), and sla_handle_dial_state_event().

◆ ast_dial_answered_steal()

struct ast_channel* ast_dial_answered_steal ( struct ast_dial dial)

Steal the channel that answered.

Note
Returns the Asterisk channel that answered and removes it from the dialing structure
Parameters
dialDialing structure

Definition at line 993 of file dial.c.

994 {
995  struct ast_channel *chan = NULL;
996 
997  if (!dial)
998  return NULL;
999 
1000  if (dial->state == AST_DIAL_RESULT_ANSWERED) {
1001  chan = AST_LIST_FIRST(&dial->channels)->owner;
1002  AST_LIST_FIRST(&dial->channels)->owner = NULL;
1003  }
1004 
1005  return chan;
1006 }

References AST_DIAL_RESULT_ANSWERED, AST_LIST_FIRST, ast_dial::channels, NULL, and ast_dial::state.

Referenced by ari_originate_dial(), do_notify(), and recall_callback().

◆ ast_dial_append()

int ast_dial_append ( struct ast_dial dial,
const char *  tech,
const char *  device,
const struct ast_assigned_ids assignedids 
)

Append a channel.

Note
Appends a channel to a dialing structure
Returns
Returns channel reference number on success, -1 on failure

Definition at line 282 of file dial.c.

283 {
284  struct ast_dial_channel *channel = NULL;
285 
286  /* Make sure we have required arguments */
287  if (!dial || !tech || !device)
288  return -1;
289 
290  /* Allocate new memory for dialed channel structure */
291  if (!(channel = ast_calloc(1, sizeof(*channel))))
292  return -1;
293 
294  return dial_append_common(dial, channel, tech, device, assignedids);
295 }
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:249
Dialing channel structure. Contains per-channel dialing options, asterisk channel,...
Definition: dial.c:63
char * tech
Definition: dial.c:66
char * device
Definition: dial.c:67

References ast_calloc, ast_dial_channel::device, dial_append_common(), NULL, and ast_dial_channel::tech.

Referenced by ari_channels_handle_originate_with_id(), dial_trunk(), do_notify(), page_exec(), recalling_enter(), and sla_ring_station().

◆ ast_dial_append_channel()

int ast_dial_append_channel ( struct ast_dial dial,
struct ast_channel chan 
)

Append a channel using an actual channel object.

Parameters
dialThe ast_dial to add the channel to
chanThe channel to add to the dial
Return values
-1Failure
non-zeroThe position of the channel in the list of dialed channels
Note
The chan ref is stolen with a successful return.

Definition at line 297 of file dial.c.

298 {
299  struct ast_dial_channel *channel;
300  char *tech;
301  char *device;
302  char *dash;
303 
304  if (!dial || !chan) {
305  return -1;
306  }
307 
308  channel = ast_calloc(1, sizeof(*channel));
309  if (!channel) {
310  return -1;
311  }
312  channel->owner = chan;
313 
315 
316  device = strchr(tech, '/');
317  if (!device) {
318  ast_free(channel);
319  return -1;
320  }
321  *device++ = '\0';
322 
323  dash = strrchr(device, '-');
324  if (dash) {
325  *dash = '\0';
326  }
327 
328  return dial_append_common(dial, channel, tech, device, NULL);
329 }
const char * ast_channel_name(const struct ast_channel *chan)

References ast_calloc, ast_channel_name(), ast_free, ast_strdupa, ast_dial_channel::device, dial_append_common(), NULL, ast_dial_channel::owner, and ast_dial_channel::tech.

◆ ast_dial_create()

struct ast_dial* ast_dial_create ( void  )

New dialing structure.

Note
Create a dialing structure
Returns
Returns a calloc'd ast_dial structure, NULL on failure

Definition at line 225 of file dial.c.

226 {
227  struct ast_dial *dial = NULL;
228 
229  /* Allocate new memory for structure */
230  if (!(dial = ast_calloc(1, sizeof(*dial))))
231  return NULL;
232 
233  /* Initialize list of channels */
235 
236  /* Initialize thread to NULL */
237  dial->thread = AST_PTHREADT_NULL;
238 
239  /* No timeout exists... yet */
240  dial->timeout = -1;
241  dial->actual_timeout = -1;
242 
243  /* Can't forget about the lock */
244  ast_mutex_init(&dial->lock);
245 
246  return dial;
247 }
#define AST_LIST_HEAD_INIT(head)
Initializes a list head structure.
Definition: linkedlists.h:626
#define AST_PTHREADT_NULL
Definition: lock.h:66
#define ast_mutex_init(pmutex)
Definition: lock.h:184
Main dialing structure. Contains global options, channels being dialed, and more!
Definition: dial.c:48
int timeout
Definition: dial.c:50
int actual_timeout
Definition: dial.c:51

References ast_dial::actual_timeout, ast_calloc, AST_LIST_HEAD_INIT, ast_mutex_init, AST_PTHREADT_NULL, ast_dial::channels, ast_dial::lock, NULL, ast_dial::thread, and ast_dial::timeout.

Referenced by ari_channels_handle_originate_with_id(), dial_trunk(), do_notify(), page_exec(), recalling_enter(), and sla_ring_station().

◆ ast_dial_destroy()

int ast_dial_destroy ( struct ast_dial dial)

Destroys a dialing structure.

Note
Cancels dialing and destroys (free's) the given ast_dial structure
Parameters
dialDialing structure to free
Return values
0on success
-1on failure

Definition at line 1086 of file dial.c.

1087 {
1088  int i = 0;
1089  struct ast_dial_channel *channel = NULL;
1090 
1091  if (!dial)
1092  return -1;
1093 
1094  /* Hangup and deallocate all the dialed channels */
1095  AST_LIST_LOCK(&dial->channels);
1096  AST_LIST_TRAVERSE_SAFE_BEGIN(&dial->channels, channel, list) {
1097  /* Disable any enabled options */
1098  for (i = 0; i < AST_DIAL_OPTION_MAX; i++) {
1099  if (!channel->options[i])
1100  continue;
1101  if (option_types[i].disable)
1102  option_types[i].disable(channel->options[i]);
1103  channel->options[i] = NULL;
1104  }
1105 
1106  /* Hang up channel if need be */
1107  ast_hangup(channel->owner);
1108  channel->owner = NULL;
1109 
1110  /* Free structure */
1111  ast_free(channel->tech);
1112  ast_free(channel->device);
1113  ast_free(channel->assignedid1);
1114  ast_free(channel->assignedid2);
1115 
1117  ast_free(channel);
1118  }
1120  AST_LIST_UNLOCK(&dial->channels);
1121 
1122  /* Disable any enabled options globally */
1123  for (i = 0; i < AST_DIAL_OPTION_MAX; i++) {
1124  if (!dial->options[i])
1125  continue;
1126  if (option_types[i].disable)
1127  option_types[i].disable(dial->options[i]);
1128  dial->options[i] = NULL;
1129  }
1130 
1131  /* Lock be gone! */
1132  ast_mutex_destroy(&dial->lock);
1133 
1134  /* Free structure */
1135  ast_free(dial);
1136 
1137  return 0;
1138 }
static const struct ast_option_types option_types[]
Map options to respective handlers (enable/disable).
Definition: dial.c:201
@ AST_DIAL_OPTION_MAX
Definition: dial.h:50
#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_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_mutex_destroy(a)
Definition: lock.h:186
struct ast_dial_channel::@374 list
char * assignedid2
Definition: dial.c:72
void * options[AST_DIAL_OPTION_MAX]
Definition: dial.c:68
char * assignedid1
Definition: dial.c:71
void * options[AST_DIAL_OPTION_MAX]
Definition: dial.c:53
ast_dial_option_cb_disable disable
Definition: dial.c:192

References ast_dial_channel::assignedid1, ast_dial_channel::assignedid2, AST_DIAL_OPTION_MAX, ast_free, ast_hangup(), AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_mutex_destroy, ast_dial::channels, ast_dial_channel::device, ast_option_types::disable, ast_dial_channel::list, ast_dial::lock, NULL, option_types, ast_dial::options, ast_dial_channel::options, ast_dial_channel::owner, and ast_dial_channel::tech.

Referenced by ari_channels_handle_originate_with_id(), ari_originate_dial(), dial_trunk(), do_notify(), page_exec(), run_station(), sla_handle_dial_state_event(), sla_hangup_stations(), sla_ring_station(), and sla_stop_ringing_station().

◆ ast_dial_get_channel()

struct ast_channel* ast_dial_get_channel ( struct ast_dial dial,
int  num 
)

Get the dialing channel, if prerun has been executed.

Parameters
dialDial structure
numChannel number to get channel of
Returns
Pointer to channel, without reference

Definition at line 1253 of file dial.c.

1254 {
1255  struct ast_dial_channel *channel;
1256 
1257  if (!dial || AST_LIST_EMPTY(&dial->channels) || !(channel = find_dial_channel(dial, num))) {
1258  return NULL;
1259  }
1260 
1261  return channel->owner;
1262 }
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:1157
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:450

References AST_LIST_EMPTY, ast_dial::channels, find_dial_channel(), NULL, ast_dial_channel::num, and ast_dial_channel::owner.

Referenced by ari_channels_handle_originate_with_id(), and recalling_enter().

◆ ast_dial_get_user_data()

void* ast_dial_get_user_data ( struct ast_dial dial)

Return the user data on a dial structure.

Parameters
dialThe dial structure

Definition at line 1274 of file dial.c.

1275 {
1276  return dial->user_data;
1277 }
void * user_data
Definition: dial.c:55

References ast_dial::user_data.

Referenced by ari_originate_dial(), page_state_callback(), and recall_callback().

◆ ast_dial_hangup()

void ast_dial_hangup ( struct ast_dial dial)

Hangup channels.

Note
Hangup all active channels
Parameters
dialDialing structure

Definition at line 1069 of file dial.c.

1070 {
1071  struct ast_dial_channel *channel = NULL;
1072 
1073  if (!dial)
1074  return;
1075 
1076  AST_LIST_LOCK(&dial->channels);
1077  AST_LIST_TRAVERSE(&dial->channels, channel, list) {
1078  ast_hangup(channel->owner);
1079  channel->owner = NULL;
1080  }
1081  AST_LIST_UNLOCK(&dial->channels);
1082 
1083  return;
1084 }
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491

References ast_hangup(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_dial::channels, ast_dial_channel::list, NULL, and ast_dial_channel::owner.

Referenced by page_exec().

◆ ast_dial_join()

enum ast_dial_result ast_dial_join ( struct ast_dial dial)

Cancel async thread.

Note
Cancel a running async thread
Parameters
dialDialing structure

Definition at line 993 of file dial.c.

1022 {
1023  pthread_t thread;
1024 
1025  /* If the dial structure is not running in async, return failed */
1026  if (dial->thread == AST_PTHREADT_NULL)
1027  return AST_DIAL_RESULT_FAILED;
1028 
1029  /* Record thread */
1030  thread = dial->thread;
1031 
1032  /* Boom, commence locking */
1033  ast_mutex_lock(&dial->lock);
1034 
1035  /* Stop the thread */
1036  dial->thread = AST_PTHREADT_STOP;
1037 
1038  /* If the answered channel is running an application we have to soft hangup it, can't just poke the thread */
1039  AST_LIST_LOCK(&dial->channels);
1040  if (AST_LIST_FIRST(&dial->channels)->is_running_app) {
1041  struct ast_channel *chan = AST_LIST_FIRST(&dial->channels)->owner;
1042  if (chan) {
1043  ast_channel_lock(chan);
1045  ast_channel_unlock(chan);
1046  }
1047  } else {
1048  /* Now we signal it with SIGURG so it will break out of it's waitfor */
1049  pthread_kill(thread, SIGURG);
1050  }
1051  AST_LIST_UNLOCK(&dial->channels);
1052 
1053  /* Yay done with it */
1054  ast_mutex_unlock(&dial->lock);
1055 
1056  /* Finally wait for the thread to exit */
1057  pthread_join(thread, NULL);
1058 
1059  /* Yay thread is all gone */
1060  dial->thread = AST_PTHREADT_NULL;
1061 
1062  return dial->state;
1063 }
pthread_t thread
Definition: app_meetme.c:1091
@ AST_SOFTHANGUP_EXPLICIT
Definition: channel.h:1148
#define ast_channel_lock(chan)
Definition: channel.h:2922
int ast_softhangup(struct ast_channel *chan, int cause)
Softly hangup up a channel.
Definition: channel.c:2470
#define ast_channel_unlock(chan)
Definition: channel.h:2923
@ AST_DIAL_RESULT_FAILED
Definition: dial.h:56

Referenced by dial_trunk(), page_exec(), run_station(), sla_handle_dial_state_event(), sla_hangup_stations(), sla_ring_station(), and sla_stop_ringing_station().

◆ ast_dial_option_disable()

int ast_dial_option_disable ( struct ast_dial dial,
int  num,
enum ast_dial_option  option 
)

Disables an option per channel.

Parameters
dialDial structure
numChannel number to disable option on
optionOption to disable
Return values
0on success
-1on failure

Definition at line 1217 of file dial.c.

1218 {
1219  struct ast_dial_channel *channel = NULL;
1220 
1221  /* Ensure we have required arguments */
1222  if (!dial || AST_LIST_EMPTY(&dial->channels))
1223  return -1;
1224 
1225  if (!(channel = find_dial_channel(dial, num)))
1226  return -1;
1227 
1228  /* If the option is not enabled, return failure */
1229  if (!channel->options[option])
1230  return -1;
1231 
1232  /* Execute callback of option to disable it if it exists */
1233  if (option_types[option].disable)
1234  option_types[option].disable(channel->options[option]);
1235 
1236  /* Finally disable the option on the structure */
1237  channel->options[option] = NULL;
1238 
1239  return 0;
1240 }

References AST_LIST_EMPTY, ast_dial::channels, ast_option_types::disable, find_dial_channel(), NULL, ast_dial_channel::num, option_types, and ast_dial_channel::options.

◆ ast_dial_option_enable()

int ast_dial_option_enable ( struct ast_dial dial,
int  num,
enum ast_dial_option  option,
void *  data 
)

Enables an option per channel.

Parameters
dialDial structure
numChannel number to enable option on
optionOption to enable
dataData to pass to this option (not always needed)
Return values
0on success
-1on failure

Definition at line 1176 of file dial.c.

1177 {
1178  struct ast_dial_channel *channel = NULL;
1179 
1180  /* Ensure we have required arguments */
1181  if (!dial || AST_LIST_EMPTY(&dial->channels))
1182  return -1;
1183 
1184  if (!(channel = find_dial_channel(dial, num)))
1185  return -1;
1186 
1187  /* If the option is already enabled, return failure */
1188  if (channel->options[option])
1189  return -1;
1190 
1191  /* Execute enable callback if it exists, if not simply make sure the value is set */
1192  if (option_types[option].enable)
1193  channel->options[option] = option_types[option].enable(data);
1194  else
1195  channel->options[option] = (void*)1;
1196 
1197  return 0;
1198 }
ast_dial_option_cb_enable enable
Definition: dial.c:191

References AST_LIST_EMPTY, ast_dial::channels, ast_option_types::enable, find_dial_channel(), NULL, ast_dial_channel::num, option_types, and ast_dial_channel::options.

◆ ast_dial_option_global_disable()

int ast_dial_option_global_disable ( struct ast_dial dial,
enum ast_dial_option  option 
)

Disables an option globally.

Parameters
dialDial structure to disable option on
optionOption to disable
Return values
0on success
-1on failure

Definition at line 1200 of file dial.c.

1201 {
1202  /* If the option is not enabled, return failure */
1203  if (!dial->options[option]) {
1204  return -1;
1205  }
1206 
1207  /* Execute callback of option to disable if it exists */
1208  if (option_types[option].disable)
1209  option_types[option].disable(dial->options[option]);
1210 
1211  /* Finally disable option on the structure */
1212  dial->options[option] = NULL;
1213 
1214  return 0;
1215 }

References ast_option_types::disable, NULL, option_types, and ast_dial::options.

◆ ast_dial_option_global_enable()

int ast_dial_option_global_enable ( struct ast_dial dial,
enum ast_dial_option  option,
void *  data 
)

Enables an option globally.

Parameters
dialDial structure to enable option on
optionOption to enable
dataData to pass to this option (not always needed)
Return values
0on success
-1on failure

Definition at line 1140 of file dial.c.

1141 {
1142  /* If the option is already enabled, return failure */
1143  if (dial->options[option])
1144  return -1;
1145 
1146  /* Execute enable callback if it exists, if not simply make sure the value is set */
1147  if (option_types[option].enable)
1148  dial->options[option] = option_types[option].enable(data);
1149  else
1150  dial->options[option] = (void*)1;
1151 
1152  return 0;
1153 }

References ast_option_types::enable, option_types, and ast_dial::options.

Referenced by do_notify(), and page_exec().

◆ ast_dial_prerun()

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.

Parameters
dialDialing structure
chanOptional dialing channel
capOptional requested capabilities
Return values
-1failure
0success

Definition at line 433 of file dial.c.

434 {
435  struct ast_dial_channel *channel;
436  int res = -1;
437  char *predial_string = dial->options[AST_DIAL_OPTION_PREDIAL];
438 
439  AST_LIST_LOCK(&dial->channels);
440  AST_LIST_TRAVERSE(&dial->channels, channel, list) {
441  if ((res = begin_dial_prerun(channel, chan, cap, predial_string))) {
442  break;
443  }
444  }
445  AST_LIST_UNLOCK(&dial->channels);
446 
447  return res;
448 }
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:332
@ AST_DIAL_OPTION_PREDIAL
Definition: dial.h:47

References AST_DIAL_OPTION_PREDIAL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, begin_dial_prerun(), ast_dial::channels, ast_dial_channel::list, and ast_dial::options.

Referenced by ari_channels_handle_originate_with_id(), and recalling_enter().

◆ ast_dial_reason()

int ast_dial_reason ( struct ast_dial dial,
int  num 
)

Get the reason an outgoing channel has failed.

Parameters
dialDial structure
numChannel number to get the reason from
Returns
Numerical cause code

Definition at line 1242 of file dial.c.

1243 {
1244  struct ast_dial_channel *channel;
1245 
1246  if (!dial || AST_LIST_EMPTY(&dial->channels) || !(channel = find_dial_channel(dial, num))) {
1247  return -1;
1248  }
1249 
1250  return channel->cause;
1251 }

References AST_LIST_EMPTY, ast_dial_channel::cause, ast_dial::channels, find_dial_channel(), and ast_dial_channel::num.

◆ ast_dial_run()

enum ast_dial_result ast_dial_run ( struct ast_dial dial,
struct ast_channel chan,
int  async 
)

Execute dialing synchronously or asynchronously.

Note
Dials channels in a dial structure.
Returns
Returns dial result code. (TRYING/INVALID/FAILED/ANSWERED/TIMEOUT/UNANSWERED).

Definition at line 922 of file dial.c.

940 {
942 
943  /* Ensure required arguments are passed */
944  if (!dial) {
945  ast_debug(1, "invalid #1\n");
947  }
948 
949  /* If there are no channels to dial we can't very well try to dial them */
950  if (AST_LIST_EMPTY(&dial->channels)) {
951  ast_debug(1, "invalid #2\n");
953  }
954 
955  /* Dial each requested channel */
956  if (!begin_dial(dial, chan, async))
957  return AST_DIAL_RESULT_FAILED;
958 
959  /* If we are running async spawn a thread and send it away... otherwise block here */
960  if (async) {
961  /* reference be released at dial destruction if it isn't NULL */
964  /* Try to create a thread */
965  if (ast_pthread_create(&dial->thread, NULL, async_dial, dial)) {
966  /* Failed to create the thread - hangup all dialed channels and return failed */
967  ast_dial_hangup(dial);
969  }
970  } else {
971  res = monitor_dial(dial, chan);
972  }
973 
974  return res;
975 }
static void * async_dial(void *data)
Dial async thread function.
Definition: dial.c:922
void ast_dial_hangup(struct ast_dial *dial)
Hangup channels.
Definition: dial.c:1069
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:770
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:483
ast_dial_result
List of return codes for dial run API calls.
Definition: dial.h:54
@ AST_DIAL_RESULT_INVALID
Definition: dial.h:55
@ AST_DIAL_RESULT_TRYING
Definition: dial.h:57
#define ast_debug(level,...)
Log a DEBUG message.
ast_callid ast_read_threadstorage_callid(void)
extracts the callerid from the thread
Definition: logger.c:2048
ast_callid callid
Definition: dial.c:58
#define ast_pthread_create(a, b, c, d)
Definition: utils.h:579

References ast_callid_threadassoc_add(), ast_dial::callid, monitor_dial(), and NULL.

Referenced by ari_originate_dial(), dial_trunk(), do_notify(), page_exec(), recalling_enter(), and sla_ring_station().

◆ ast_dial_set_global_timeout()

void ast_dial_set_global_timeout ( struct ast_dial dial,
int  timeout 
)

Set the maximum time (globally) allowed for trying to ring phones.

Parameters
dialThe dial structure to apply the time limit to
timeoutMaximum time allowed in milliseconds

Definition at line 1279 of file dial.c.

1280 {
1281  dial->timeout = timeout;
1282 
1283  if (dial->timeout > 0 && (dial->actual_timeout > dial->timeout || dial->actual_timeout == -1))
1284  dial->actual_timeout = dial->timeout;
1285 
1286  return;
1287 }

References ast_dial::actual_timeout, ast_dial::timeout, and ast_dial_channel::timeout.

Referenced by ari_channels_handle_originate_with_id(), do_notify(), and page_exec().

◆ ast_dial_set_state_callback()

void ast_dial_set_state_callback ( struct ast_dial dial,
ast_dial_state_callback  callback 
)

Set a callback for state changes.

Parameters
dialThe dial structure to watch for state changes
callbackthe callback

Definition at line 1264 of file dial.c.

1265 {
1266  dial->state_callback = callback;
1267 }
ast_dial_state_callback state_callback
Definition: dial.c:54

References ast_dial::state_callback.

Referenced by page_exec(), recalling_enter(), and sla_ring_station().

◆ ast_dial_set_timeout()

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.

Parameters
dialThe dial structure the channel belongs to
numChannel number to set timeout on
timeoutMaximum time allowed in milliseconds

Definition at line 1289 of file dial.c.

1290 {
1291  struct ast_dial_channel *channel = NULL;
1292 
1293  if (!(channel = find_dial_channel(dial, num)))
1294  return;
1295 
1296  channel->timeout = timeout;
1297 
1298  if (channel->timeout > 0 && (dial->actual_timeout > channel->timeout || dial->actual_timeout == -1))
1299  dial->actual_timeout = channel->timeout;
1300 
1301  return;
1302 }
int timeout
Definition: dial.c:65

References ast_dial::actual_timeout, find_dial_channel(), NULL, ast_dial_channel::num, and ast_dial_channel::timeout.

◆ ast_dial_set_user_data()

void ast_dial_set_user_data ( struct ast_dial dial,
void *  user_data 
)

Set user data on a dial structure.

Parameters
dialThe dial structure to set a user data pointer on
user_dataThe user data pointer

Definition at line 1269 of file dial.c.

1270 {
1271  dial->user_data = user_data;
1272 }

References ast_dial::user_data.

Referenced by ari_channels_handle_originate_with_id(), page_exec(), and recalling_enter().

◆ ast_dial_state()

enum ast_dial_result ast_dial_state ( struct ast_dial dial)

Return state of dial.

Note
Returns the state of the dial attempt
Parameters
dialDialing structure

Definition at line 993 of file dial.c.

1013 {
1014  return dial->state;
1015 }

Referenced by dial_trunk(), page_state_callback(), recall_callback(), and sla_handle_dial_state_event().

◆ ast_hangup_cause_to_dial_status()

const char* ast_hangup_cause_to_dial_status ( int  hangup_cause)

Convert a hangup cause to a publishable dial status.

Since
12

Definition at line 753 of file dial.c.

754 {
755  switch(hangup_cause) {
756  case AST_CAUSE_BUSY:
757  return "BUSY";
759  return "CONGESTION";
762  return "CHANUNAVAIL";
763  case AST_CAUSE_NO_ANSWER:
764  default:
765  return "NOANSWER";
766  }
767 }
#define AST_CAUSE_CONGESTION
Definition: causes.h:153
#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

References AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CAUSE_NO_ANSWER, AST_CAUSE_NO_ROUTE_DESTINATION, and AST_CAUSE_UNREGISTERED.

Referenced by try_calling(), and wait_for_answer().

◆ async_dial()

static void* async_dial ( void *  data)
static

Dial async thread function.

Definition at line 922 of file dial.c.

923 {
924  struct ast_dial *dial = data;
925  if (dial->callid) {
927  }
928 
929  /* This is really really simple... we basically pass monitor_dial a NULL owner and it changes it's behavior */
930  monitor_dial(dial, NULL);
931 
932  return NULL;
933 }
int ast_callid_threadassoc_add(ast_callid callid)
Adds a known callid to thread storage of the calling thread.
Definition: logger.c:2070

◆ begin_dial()

static int begin_dial ( struct ast_dial dial,
struct ast_channel chan,
int  async 
)
static

Helper function that does the beginning dialing per dial structure.

Definition at line 483 of file dial.c.

484 {
485  struct ast_dial_channel *channel = NULL;
486  int success = 0;
487  char *predial_string = dial->options[AST_DIAL_OPTION_PREDIAL];
488 
489  /* Iterate through channel list, requesting and calling each one */
490  AST_LIST_LOCK(&dial->channels);
491  AST_LIST_TRAVERSE(&dial->channels, channel, list) {
492  success += begin_dial_channel(channel, chan, async, predial_string, NULL);
493  }
494  AST_LIST_UNLOCK(&dial->channels);
495 
496  /* If number of failures matches the number of channels, then this truly failed */
497  return success;
498 }
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:451

References AST_DIAL_OPTION_PREDIAL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, begin_dial_channel(), ast_dial::channels, ast_dial_channel::list, NULL, and ast_dial::options.

◆ begin_dial_channel()

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 
)
static

Helper function that does the beginning dialing per-appended channel.

Definition at line 451 of file dial.c.

452 {
453  int res = 1;
454  char forwarder[AST_CHANNEL_NAME];
455 
456  /* If no owner channel exists yet execute pre-run */
457  if (!channel->owner && begin_dial_prerun(channel, chan, NULL, predial_string)) {
458  return 0;
459  }
460 
461  if (forwarder_chan) {
462  ast_copy_string(forwarder, ast_channel_name(forwarder_chan), sizeof(forwarder));
463  ast_channel_lock(channel->owner);
464  pbx_builtin_setvar_helper(channel->owner, "FORWARDERNAME", forwarder);
465  ast_channel_unlock(channel->owner);
466  }
467 
468  /* Attempt to actually call this device */
469  if ((res = ast_call(channel->owner, channel->device, 0))) {
470  res = 0;
471  ast_hangup(channel->owner);
472  channel->owner = NULL;
473  } else {
474  ast_channel_publish_dial(async ? NULL : chan, channel->owner, channel->device, NULL);
475  res = 1;
476  ast_verb(3, "Called %s\n", channel->device);
477  }
478 
479  return res;
480 }
int ast_call(struct ast_channel *chan, const char *addr, int timeout)
Make a call.
Definition: channel.c:6539
#define AST_CHANNEL_NAME
Definition: channel.h:171
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...
#define ast_verb(level,...)
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.

References ast_call(), ast_channel_lock, AST_CHANNEL_NAME, ast_channel_name(), ast_channel_publish_dial(), ast_channel_unlock, ast_copy_string(), ast_hangup(), ast_verb, begin_dial_prerun(), ast_dial_channel::device, NULL, ast_dial_channel::owner, and pbx_builtin_setvar_helper().

Referenced by begin_dial(), and handle_call_forward().

◆ begin_dial_prerun()

static int begin_dial_prerun ( struct ast_dial_channel channel,
struct ast_channel chan,
struct ast_format_cap cap,
const char *  predial_string 
)
static

Helper function that requests all channels.

Definition at line 332 of file dial.c.

333 {
334  struct ast_format_cap *cap_all_audio = NULL;
335  struct ast_format_cap *cap_request;
336  struct ast_format_cap *requester_cap = NULL;
337  struct ast_assigned_ids assignedids = {
338  .uniqueid = channel->assignedid1,
339  .uniqueid2 = channel->assignedid2,
340  };
341 
342  if (chan) {
343  int max_forwards;
344 
345  ast_channel_lock(chan);
347  requester_cap = ao2_bump(ast_channel_nativeformats(chan));
348  ast_channel_unlock(chan);
349 
350  if (max_forwards <= 0) {
351  ast_log(LOG_WARNING, "Cannot dial from channel '%s'. Max forwards exceeded\n",
352  ast_channel_name(chan));
353  }
354  }
355 
356  if (!channel->owner) {
357  if (cap && ast_format_cap_count(cap)) {
358  cap_request = cap;
359  } else if (requester_cap) {
360  cap_request = requester_cap;
361  } else {
364  cap_request = cap_all_audio;
365  }
366 
367  /* If we fail to create our owner channel bail out */
368  if (!(channel->owner = ast_request(channel->tech, cap_request, &assignedids, chan, channel->device, &channel->cause))) {
369  ao2_cleanup(cap_all_audio);
370  return -1;
371  }
372  cap_request = NULL;
373  ao2_cleanup(requester_cap);
374  ao2_cleanup(cap_all_audio);
375  }
376 
377  if (chan) {
378  ast_channel_lock_both(chan, channel->owner);
379  } else {
380  ast_channel_lock(channel->owner);
381  }
382 
384 
385  ast_channel_appl_set(channel->owner, "AppDial2");
386  ast_channel_data_set(channel->owner, "(Outgoing Line)");
387 
388  memset(ast_channel_whentohangup(channel->owner), 0, sizeof(*ast_channel_whentohangup(channel->owner)));
389 
390  /* Inherit everything from he who spawned this dial */
391  if (chan) {
392  ast_channel_inherit_variables(chan, channel->owner);
393  ast_channel_datastore_inherit(chan, channel->owner);
395 
396  /* Copy over callerid information */
398 
400 
402 
403  ast_channel_language_set(channel->owner, ast_channel_language(chan));
406  } else {
408  }
410  ast_channel_musicclass_set(channel->owner, ast_channel_musicclass(chan));
411 
414  ast_channel_unlock(chan);
415  }
416 
418  ast_channel_unlock(channel->owner);
419 
420  if (!ast_strlen_zero(predial_string)) {
421  if (chan) {
422  ast_autoservice_start(chan);
423  }
424  ast_pre_call(channel->owner, predial_string);
425  if (chan) {
426  ast_autoservice_stop(chan);
427  }
428  }
429 
430  return 0;
431 }
#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
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:266
struct ast_party_connected_line * ast_channel_connected(struct ast_channel *chan)
void ast_channel_appl_set(struct ast_channel *chan, const char *value)
@ AST_CHANNEL_REQUESTOR_BRIDGE_PEER
Definition: channel.h:1477
@ AST_CHANNEL_REQUESTOR_REPLACEMENT
Definition: channel.h:1479
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:6432
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
void ast_channel_data_set(struct ast_channel *chan, const char *value)
unsigned short ast_channel_transfercapability(const struct ast_channel *chan)
struct ast_party_dialed * ast_channel_dialed(struct ast_channel *chan)
#define ast_channel_lock_both(chan1, chan2)
Lock two channels.
Definition: channel.h:2929
int ast_channel_datastore_inherit(struct ast_channel *from, struct ast_channel *to)
Inherit datastores from a parent to a child.
Definition: channel.c:2367
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:6512
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
Definition: autoservice.c:200
ast_channel_adsicpe
Definition: channel.h:868
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:6849
const char * ast_channel_language(const struct ast_channel *chan)
const char * ast_channel_musicclass(const struct ast_channel *chan)
struct ast_party_caller * ast_channel_caller(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:8376
struct ast_party_redirecting * ast_channel_redirecting(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:6522
void ast_channel_transfercapability_set(struct ast_channel *chan, unsigned short value)
struct timeval * ast_channel_whentohangup(struct ast_channel *chan)
void ast_channel_adsicpe_set(struct ast_channel *chan, enum ast_channel_adsicpe value)
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:2129
@ AST_MEDIA_TYPE_AUDIO
Definition: codec.h:32
@ AST_DIAL_OPTION_DIAL_REPLACES_SELF
Definition: dial.h:48
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_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.
#define LOG_WARNING
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
Structure to pass both assignedid values to channel drivers.
Definition: channel.h:604
const char * uniqueid
Definition: channel.h:605
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
int transit_network_select
Transit Network Select.
Definition: channel.h:397
Channel datastore data for max forwards.
Definition: max_forwards.c:29

References ao2_bump, ao2_cleanup, ast_dial_channel::assignedid1, ast_dial_channel::assignedid2, ast_autoservice_start(), ast_autoservice_stop(), ast_channel_adsicpe_set(), ast_channel_appl_set(), ast_channel_caller(), ast_channel_connected(), ast_channel_data_set(), ast_channel_datastore_inherit(), ast_channel_dialed(), ast_channel_inherit_variables(), ast_channel_language(), ast_channel_lock, ast_channel_lock_both, ast_channel_musicclass(), ast_channel_name(), ast_channel_nativeformats(), ast_channel_redirecting(), ast_channel_req_accountcodes(), AST_CHANNEL_REQUESTOR_BRIDGE_PEER, AST_CHANNEL_REQUESTOR_REPLACEMENT, ast_channel_stage_snapshot(), ast_channel_stage_snapshot_done(), ast_channel_transfercapability(), ast_channel_transfercapability_set(), ast_channel_unlock, ast_channel_whentohangup(), ast_connected_line_copy_from_caller(), AST_DIAL_OPTION_DIAL_REPLACES_SELF, ast_format_cap_alloc, ast_format_cap_append_by_type(), ast_format_cap_count(), AST_FORMAT_CAP_FLAG_DEFAULT, ast_log, ast_max_forwards_decrement(), ast_max_forwards_get(), AST_MEDIA_TYPE_AUDIO, ast_party_redirecting_copy(), ast_pre_call(), ast_request(), ast_strlen_zero(), ast_dial_channel::cause, ast_dial_channel::device, LOG_WARNING, NULL, ast_dial_channel::options, ast_dial_channel::owner, ast_dial_channel::tech, ast_party_dialed::transit_network_select, and ast_assigned_ids::uniqueid.

Referenced by ast_dial_prerun(), and begin_dial_channel().

◆ dial_append_common()

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 
)
static

Definition at line 249 of file dial.c.

251 {
252  /* Record technology and device for when we actually dial */
253  channel->tech = ast_strdup(tech);
254  channel->device = ast_strdup(device);
255 
256  /* Store the assigned id */
257  if (assignedids && !ast_strlen_zero(assignedids->uniqueid)) {
258  channel->assignedid1 = ast_strdup(assignedids->uniqueid);
259 
260  if (!ast_strlen_zero(assignedids->uniqueid2)) {
261  channel->assignedid2 = ast_strdup(assignedids->uniqueid2);
262  }
263  }
264 
265  /* Grab reference number from dial structure */
266  channel->num = ast_atomic_fetchadd_int(&dial->num, +1);
267 
268  /* No timeout exists... yet */
269  channel->timeout = -1;
270 
271  /* Insert into channels list */
272  AST_LIST_INSERT_TAIL(&dial->channels, channel, list);
273 
274  return channel->num;
275 
276 }
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
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:755
const char * uniqueid2
Definition: channel.h:606
int num
Definition: dial.c:49

References ast_dial_channel::assignedid1, ast_dial_channel::assignedid2, ast_atomic_fetchadd_int(), AST_LIST_INSERT_TAIL, ast_strdup, ast_strlen_zero(), ast_dial::channels, ast_dial_channel::device, ast_dial::num, ast_dial_channel::num, ast_dial_channel::tech, ast_dial_channel::timeout, ast_assigned_ids::uniqueid, and ast_assigned_ids::uniqueid2.

Referenced by ast_dial_append(), and ast_dial_append_channel().

◆ find_dial_channel()

static struct ast_dial_channel* find_dial_channel ( struct ast_dial dial,
int  num 
)
static

Helper function for finding a channel in a dial structure based on number.

Definition at line 1157 of file dial.c.

1158 {
1159  struct ast_dial_channel *channel = AST_LIST_LAST(&dial->channels);
1160 
1161  /* We can try to predict programmer behavior, the last channel they added is probably the one they wanted to modify */
1162  if (channel->num == num)
1163  return channel;
1164 
1165  /* Hrm not at the end... looking through the list it is! */
1166  AST_LIST_LOCK(&dial->channels);
1167  AST_LIST_TRAVERSE(&dial->channels, channel, list) {
1168  if (channel->num == num)
1169  break;
1170  }
1171  AST_LIST_UNLOCK(&dial->channels);
1172 
1173  return channel;
1174 }
#define AST_LIST_LAST(head)
Returns the last entry contained in a list.
Definition: linkedlists.h:429

References AST_LIST_LAST, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_dial::channels, ast_dial_channel::list, and ast_dial_channel::num.

Referenced by ast_dial_get_channel(), ast_dial_option_disable(), ast_dial_option_enable(), ast_dial_reason(), and ast_dial_set_timeout().

◆ find_relative_dial_channel()

static struct ast_dial_channel* find_relative_dial_channel ( struct ast_dial dial,
struct ast_channel owner 
)
static

Helper function that finds the dialed channel based on owner.

Definition at line 559 of file dial.c.

560 {
561  struct ast_dial_channel *channel = NULL;
562 
563  AST_LIST_LOCK(&dial->channels);
564  AST_LIST_TRAVERSE(&dial->channels, channel, list) {
565  if (channel->owner == owner)
566  break;
567  }
568  AST_LIST_UNLOCK(&dial->channels);
569 
570  return channel;
571 }

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_dial::channels, ast_dial_channel::list, NULL, and ast_dial_channel::owner.

◆ handle_call_forward()

static int handle_call_forward ( struct ast_dial dial,
struct ast_dial_channel channel,
struct ast_channel chan 
)
static

Helper function to handle channels that have been call forwarded.

Definition at line 501 of file dial.c.

502 {
503  struct ast_channel *original = channel->owner;
504  char *tmp = ast_strdupa(ast_channel_call_forward(channel->owner));
505  char *tech = "Local", *device = tmp, *stuff;
506  char *predial_string = dial->options[AST_DIAL_OPTION_PREDIAL];
507 
508  /* If call forwarding is disabled just drop the original channel and don't attempt to dial the new one */
510  ast_hangup(original);
511  channel->owner = NULL;
512  return 0;
513  }
514 
515  /* Figure out the new destination */
516  if ((stuff = strchr(tmp, '/'))) {
517  *stuff++ = '\0';
518  tech = tmp;
519  device = stuff;
520  } else {
521  const char *forward_context;
522  char destination[AST_MAX_CONTEXT + AST_MAX_EXTENSION + 1];
523 
524  ast_channel_lock(original);
525  forward_context = pbx_builtin_getvar_helper(original, "FORWARD_CONTEXT");
526  snprintf(destination, sizeof(destination), "%s@%s", tmp, S_OR(forward_context, ast_channel_context(original)));
527  ast_channel_unlock(original);
528  device = ast_strdupa(destination);
529  }
530 
531  /* Drop old destination information */
532  ast_free(channel->tech);
533  ast_free(channel->device);
534  ast_free(channel->assignedid1);
535  channel->assignedid1 = NULL;
536  ast_free(channel->assignedid2);
537  channel->assignedid2 = NULL;
538 
539  /* Update the dial channel with the new destination information */
540  channel->tech = ast_strdup(tech);
541  channel->device = ast_strdup(device);
542  AST_LIST_UNLOCK(&dial->channels);
543 
544  /* Drop the original channel */
545  channel->owner = NULL;
546 
547  /* Finally give it a go... send it out into the world */
548  begin_dial_channel(channel, chan, chan ? 0 : 1, predial_string, original);
549 
550  ast_channel_publish_dial_forward(chan, original, channel->owner, NULL, "CANCEL",
551  ast_channel_call_forward(original));
552 
553  ast_hangup(original);
554 
555  return 0;
556 }
static int tmp()
Definition: bt_open.c:389
const char * ast_channel_context(const struct ast_channel *chan)
#define AST_MAX_CONTEXT
Definition: channel.h:135
const char * ast_channel_call_forward(const struct ast_channel *chan)
#define AST_MAX_EXTENSION
Definition: channel.h:134
#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:216
@ AST_DIAL_OPTION_DISABLE_CALL_FORWARDING
Definition: dial.h:46
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...
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
#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
const struct ast_channel_tech * tech

References ast_dial_channel::assignedid1, ast_dial_channel::assignedid2, ast_channel_call_forward(), ast_channel_context(), ast_channel_lock, ast_channel_publish_dial_forward(), ast_channel_unlock, AST_DIAL_OPTION_DISABLE_CALL_FORWARDING, AST_DIAL_OPTION_PREDIAL, ast_free, ast_hangup(), AST_LIST_UNLOCK, AST_MAX_CONTEXT, AST_MAX_EXTENSION, ast_strdup, ast_strdupa, begin_dial_channel(), ast_dial::channels, ast_dial_channel::device, FIND_RELATIVE_OPTION, NULL, ast_dial::options, ast_dial_channel::owner, pbx_builtin_getvar_helper(), S_OR, ast_channel::tech, ast_dial_channel::tech, and tmp().

◆ handle_frame()

static void handle_frame ( struct ast_dial dial,
struct ast_dial_channel channel,
struct ast_frame fr,
struct ast_channel chan 
)
static

Helper function that handles frames.

Definition at line 582 of file dial.c.

583 {
584  if (fr->frametype == AST_FRAME_CONTROL) {
585  switch (fr->subclass.integer) {
586  case AST_CONTROL_ANSWER:
587  if (chan) {
588  ast_verb(3, "%s answered %s\n", ast_channel_name(channel->owner), ast_channel_name(chan));
589  } else {
590  ast_verb(3, "%s answered\n", ast_channel_name(channel->owner));
591  }
592  AST_LIST_LOCK(&dial->channels);
593  AST_LIST_REMOVE(&dial->channels, channel, list);
594  AST_LIST_INSERT_HEAD(&dial->channels, channel, list);
595  AST_LIST_UNLOCK(&dial->channels);
596  ast_channel_publish_dial(chan, channel->owner, channel->device, "ANSWER");
598  break;
599  case AST_CONTROL_BUSY:
600  ast_verb(3, "%s is busy\n", ast_channel_name(channel->owner));
601  ast_channel_publish_dial(chan, channel->owner, channel->device, "BUSY");
602  ast_hangup(channel->owner);
603  channel->cause = AST_CAUSE_USER_BUSY;
604  channel->owner = NULL;
605  break;
607  ast_verb(3, "%s is circuit-busy\n", ast_channel_name(channel->owner));
608  ast_channel_publish_dial(chan, channel->owner, channel->device, "CONGESTION");
609  ast_hangup(channel->owner);
611  channel->owner = NULL;
612  break;
614  ast_verb(3, "%s dialed Incomplete extension %s\n", ast_channel_name(channel->owner), ast_channel_exten(channel->owner));
615  if (chan) {
617  } else {
618  ast_hangup(channel->owner);
619  channel->cause = AST_CAUSE_UNALLOCATED;
620  channel->owner = NULL;
621  }
622  break;
623  case AST_CONTROL_RINGING:
624  ast_verb(3, "%s is ringing\n", ast_channel_name(channel->owner));
625  ast_channel_publish_dial(chan, channel->owner, channel->device, "RINGING");
626  if (chan && !dial->options[AST_DIAL_OPTION_MUSIC])
629  break;
631  ast_channel_publish_dial(chan, channel->owner, channel->device, "PROGRESS");
632  if (chan) {
633  ast_verb(3, "%s is making progress, passing it to %s\n", ast_channel_name(channel->owner), ast_channel_name(chan));
635  } else {
636  ast_verb(3, "%s is making progress\n", ast_channel_name(channel->owner));
637  }
639  break;
641  if (!chan) {
642  break;
643  }
644  ast_verb(3, "%s requested a video update, passing it to %s\n", ast_channel_name(channel->owner), ast_channel_name(chan));
646  break;
648  if (!chan) {
649  break;
650  }
651  ast_verb(3, "%s requested a source update, passing it to %s\n", ast_channel_name(channel->owner), ast_channel_name(chan));
653  break;
655  if (!chan) {
656  break;
657  }
658  ast_verb(3, "%s connected line has changed, passing it to %s\n", ast_channel_name(channel->owner), ast_channel_name(chan));
659  if (ast_channel_connected_line_sub(channel->owner, chan, fr, 1) &&
660  ast_channel_connected_line_macro(channel->owner, chan, fr, 1, 1)) {
662  }
663  break;
665  if (!chan) {
666  break;
667  }
668  ast_verb(3, "%s redirecting info has changed, passing it to %s\n", ast_channel_name(channel->owner), ast_channel_name(chan));
669  if (ast_channel_redirecting_sub(channel->owner, chan, fr, 1) &&
670  ast_channel_redirecting_macro(channel->owner, chan, fr, 1, 1)) {
672  }
673  break;
675  ast_channel_publish_dial(chan, channel->owner, channel->device, "PROCEEDING");
676  if (chan) {
677  ast_verb(3, "%s is proceeding, passing it to %s\n", ast_channel_name(channel->owner), ast_channel_name(chan));
679  } else {
680  ast_verb(3, "%s is proceeding\n", ast_channel_name(channel->owner));
681  }
683  break;
684  case AST_CONTROL_HOLD:
685  if (!chan) {
686  break;
687  }
688  ast_verb(3, "Call on %s placed on hold\n", ast_channel_name(chan));
690  break;
691  case AST_CONTROL_UNHOLD:
692  if (!chan) {
693  break;
694  }
695  ast_verb(3, "Call on %s left from hold\n", ast_channel_name(chan));
697  break;
698  case AST_CONTROL_OFFHOOK:
699  case AST_CONTROL_FLASH:
700  break;
702  if (chan) {
704  }
705  break;
706  case -1:
707  if (chan) {
708  /* Prod the channel */
709  ast_indicate(chan, -1);
710  }
711  break;
712  default:
713  break;
714  }
715  }
716 }
#define AST_CAUSE_UNALLOCATED
Definition: causes.h:98
#define AST_CAUSE_NORMAL_CIRCUIT_CONGESTION
Definition: causes.h:120
#define AST_CAUSE_USER_BUSY
Definition: causes.h:107
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:10524
int ast_channel_redirecting_macro(struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const void *redirecting_info, int is_caller, int is_frame)
Run a redirecting interception macro and update a channel's redirecting information.
Definition: channel.c:10472
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:10569
const char * ast_channel_exten(const 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:4688
int ast_channel_connected_line_macro(struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const void *connected_info, int is_caller, int frame)
Run a connected line interception macro and update a channel's connected line information.
Definition: channel.c:10420
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4312
static void set_state(struct ast_dial *dial, enum ast_dial_result state)
Definition: dial.c:573
@ 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_OPTION_MUSIC
Definition: dial.h:45
@ 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_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
struct ast_frame_subclass subclass
union ast_frame::@254 data
enum ast_frame_type frametype

References AST_CAUSE_NORMAL_CIRCUIT_CONGESTION, AST_CAUSE_UNALLOCATED, AST_CAUSE_USER_BUSY, ast_channel_connected_line_macro(), ast_channel_connected_line_sub(), ast_channel_exten(), ast_channel_name(), ast_channel_publish_dial(), ast_channel_redirecting_macro(), ast_channel_redirecting_sub(), AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_FLASH, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_OFFHOOK, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_PVT_CAUSE_CODE, AST_CONTROL_REDIRECTING, AST_CONTROL_RINGING, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, AST_DIAL_OPTION_MUSIC, AST_DIAL_RESULT_ANSWERED, AST_DIAL_RESULT_PROCEEDING, AST_DIAL_RESULT_PROGRESS, AST_DIAL_RESULT_RINGING, AST_FRAME_CONTROL, ast_hangup(), ast_indicate(), ast_indicate_data(), AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, ast_verb, ast_dial_channel::cause, ast_dial::channels, ast_frame::data, ast_frame::datalen, ast_dial_channel::device, ast_frame::frametype, ast_frame_subclass::integer, ast_dial_channel::list, NULL, ast_dial::options, ast_dial_channel::owner, ast_frame::ptr, set_state(), and ast_frame::subclass.

◆ handle_timeout_trip()

static int handle_timeout_trip ( struct ast_dial dial,
struct timeval  start 
)
static

Helper function to handle when a timeout occurs on dialing attempt.

Definition at line 719 of file dial.c.

720 {
721  struct ast_dial_channel *channel = NULL;
722  int diff = ast_tvdiff_ms(ast_tvnow(), start), lowest_timeout = -1, new_timeout = -1;
723 
724  /* If there is no difference yet return the dial timeout so we can go again, we were likely interrupted */
725  if (!diff) {
726  return dial->timeout;
727  }
728 
729  /* If the global dial timeout tripped switch the state to timeout so our channel loop will drop every channel */
730  if (diff >= dial->timeout) {
732  new_timeout = 0;
733  }
734 
735  /* Go through dropping out channels that have met their timeout */
736  AST_LIST_TRAVERSE(&dial->channels, channel, list) {
737  if (dial->state == AST_DIAL_RESULT_TIMEOUT || diff >= channel->timeout) {
738  ast_hangup(channel->owner);
739  channel->cause = AST_CAUSE_NO_ANSWER;
740  channel->owner = NULL;
741  } else if ((lowest_timeout == -1) || (lowest_timeout > channel->timeout)) {
742  lowest_timeout = channel->timeout;
743  }
744  }
745 
746  /* Calculate the new timeout using the lowest timeout found */
747  if (lowest_timeout >= 0)
748  new_timeout = lowest_timeout - diff;
749 
750  return new_timeout;
751 }
@ AST_DIAL_RESULT_TIMEOUT
Definition: dial.h:62
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:105
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:157

References AST_CAUSE_NO_ANSWER, AST_DIAL_RESULT_TIMEOUT, ast_hangup(), AST_LIST_TRAVERSE, ast_tvdiff_ms(), ast_tvnow(), ast_dial_channel::cause, ast_dial::channels, ast_dial_channel::list, NULL, ast_dial_channel::owner, set_state(), ast_dial::state, ast_dial::timeout, and ast_dial_channel::timeout.

◆ monitor_dial()

static enum ast_dial_result monitor_dial ( struct ast_dial dial,
struct ast_channel chan 
)
static

Helper function that basically keeps tabs on dialing attempts.

Definition at line 753 of file dial.c.

771 {
772  int timeout = -1;
773  struct ast_channel *cs[AST_MAX_WATCHERS], *who = NULL;
774  struct ast_dial_channel *channel = NULL;
775  struct answer_exec_struct *answer_exec = NULL;
776  struct timeval start;
777 
779 
780  /* If the "always indicate ringing" option is set, change state to ringing and indicate to the owner if present */
781  if (dial->options[AST_DIAL_OPTION_RINGING]) {
783  if (chan)
785  } else if (chan && dial->options[AST_DIAL_OPTION_MUSIC] &&
787  char *original_moh = ast_strdupa(ast_channel_musicclass(chan));
788  ast_indicate(chan, -1);
789  ast_channel_musicclass_set(chan, dial->options[AST_DIAL_OPTION_MUSIC]);
791  ast_channel_musicclass_set(chan, original_moh);
792  }
793 
794  /* Record start time for timeout purposes */
795  start = ast_tvnow();
796 
797  /* We actually figured out the maximum timeout we can do as they were added, so we can directly access the info */
798  timeout = dial->actual_timeout;
799 
800  /* Go into an infinite loop while we are trying */
801  while ((dial->state != AST_DIAL_RESULT_UNANSWERED) && (dial->state != AST_DIAL_RESULT_ANSWERED) && (dial->state != AST_DIAL_RESULT_HANGUP) && (dial->state != AST_DIAL_RESULT_TIMEOUT)) {
802  int pos = 0, count = 0;
803  struct ast_frame *fr = NULL;
804 
805  /* Set up channel structure array */
806  pos = count = 0;
807  if (chan)
808  cs[pos++] = chan;
809 
810  /* Add channels we are attempting to dial */
811  AST_LIST_LOCK(&dial->channels);
812  AST_LIST_TRAVERSE(&dial->channels, channel, list) {
813  if (channel->owner) {
814  cs[pos++] = channel->owner;
815  count++;
816  }
817  }
818  AST_LIST_UNLOCK(&dial->channels);
819 
820  /* If we have no outbound channels in progress, switch state to unanswered and stop */
821  if (!count) {
823  break;
824  }
825 
826  /* Just to be safe... */
827  if (dial->thread == AST_PTHREADT_STOP)
828  break;
829 
830  /* Wait for frames from channels */
831  who = ast_waitfor_n(cs, pos, &timeout);
832 
833  /* Check to see if our thread is being canceled */
834  if (dial->thread == AST_PTHREADT_STOP)
835  break;
836 
837  /* If the timeout no longer exists OR if we got no channel it basically means the timeout was tripped, so handle it */
838  if (!timeout || !who) {
839  timeout = handle_timeout_trip(dial, start);
840  continue;
841  }
842 
843  /* Find relative dial channel */
844  if (!chan || !IS_CALLER(chan, who))
845  channel = find_relative_dial_channel(dial, who);
846 
847  /* See if this channel has been forwarded elsewhere */
849  handle_call_forward(dial, channel, chan);
850  continue;
851  }
852 
853  /* Attempt to read in a frame */
854  if (!(fr = ast_read(who))) {
855  /* If this is the caller then we switch state to hangup and stop */
856  if (chan && IS_CALLER(chan, who)) {
858  break;
859  }
861  ast_hangup(who);
862  channel->owner = NULL;
863  continue;
864  }
865 
866  /* Process the frame */
867  handle_frame(dial, channel, fr, chan);
868 
869  /* Free the received frame and start all over */
870  ast_frfree(fr);
871  }
872 
873  /* Do post-processing from loop */
874  if (dial->state == AST_DIAL_RESULT_ANSWERED) {
875  /* Hangup everything except that which answered */
876  AST_LIST_LOCK(&dial->channels);
877  AST_LIST_TRAVERSE(&dial->channels, channel, list) {
878  if (!channel->owner || channel->owner == who)
879  continue;
880  ast_channel_publish_dial(chan, channel->owner, channel->device, "CANCEL");
881  ast_hangup(channel->owner);
883  channel->owner = NULL;
884  }
885  AST_LIST_UNLOCK(&dial->channels);
886  /* If ANSWER_EXEC is enabled as an option, execute application on answered channel */
887  if ((channel = find_relative_dial_channel(dial, who)) && (answer_exec = FIND_RELATIVE_OPTION(dial, channel, AST_DIAL_OPTION_ANSWER_EXEC))) {
888  channel->is_running_app = 1;
889  answer_exec_run(dial, channel, answer_exec->app, answer_exec->args);
890  channel->is_running_app = 0;
891  }
892 
893  if (chan && dial->options[AST_DIAL_OPTION_MUSIC] &&
895  ast_moh_stop(chan);
896  }
897  } else if (dial->state == AST_DIAL_RESULT_HANGUP) {
898  /* Hangup everything */
899  AST_LIST_LOCK(&dial->channels);
900  AST_LIST_TRAVERSE(&dial->channels, channel, list) {
901  if (!channel->owner)
902  continue;
903  ast_channel_publish_dial(chan, channel->owner, channel->device, "CANCEL");
904  ast_hangup(channel->owner);
905  channel->cause = AST_CAUSE_NORMAL_CLEARING;
906  channel->owner = NULL;
907  }
908  AST_LIST_UNLOCK(&dial->channels);
909  }
910 
912  enum ast_dial_result state = dial->state;
913 
914  ast_dial_destroy(dial);
915  return state;
916  }
917 
918  return dial->state;
919 }
#define AST_CAUSE_ANSWERED_ELSEWHERE
Definition: causes.h:114
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:106
enum sip_cc_notify_state state
Definition: chan_sip.c:966
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition: channel.c:4292
int ast_channel_hangupcause(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:3158
#define IS_CALLER(chan, owner)
Macro that determines whether a channel is the caller or not.
Definition: dial.c:219
#define AST_MAX_WATCHERS
Maximum number of channels we can watch at a time.
Definition: dial.c:213
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:501
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:559
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:719
const char * ast_hangup_cause_to_dial_status(int hangup_cause)
Convert a hangup cause to a publishable dial status.
Definition: dial.c:753
int ast_dial_destroy(struct ast_dial *dial)
Destroys a dialing structure.
Definition: dial.c:1086
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:582
@ AST_DIAL_RESULT_HANGUP
Definition: dial.h:63
@ AST_DIAL_RESULT_UNANSWERED
Definition: dial.h:64
@ AST_DIAL_OPTION_ANSWER_EXEC
Definition: dial.h:44
@ AST_DIAL_OPTION_RINGING
Definition: dial.h:43
@ AST_DIAL_OPTION_SELF_DESTROY
Definition: dial.h:49
#define ast_frfree(fr)
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:7849
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:7859
unsigned int is_running_app
Definition: dial.c:70
Data structure associated with a single frame of data.

Referenced by ast_dial_run().

◆ music_disable()

static int music_disable ( void *  data)
static

Definition at line 139 of file dial.c.

140 {
141  if (!data)
142  return -1;
143 
144  ast_free(data);
145 
146  return 0;
147 }

References ast_free.

◆ music_enable()

static void* music_enable ( void *  data)
static

Definition at line 134 of file dial.c.

135 {
136  return ast_strdup(data);
137 }

References ast_strdup.

◆ predial_disable()

static int predial_disable ( void *  data)
static

Definition at line 154 of file dial.c.

155 {
156  if (!data) {
157  return -1;
158  }
159 
160  ast_free(data);
161 
162  return 0;
163 }

References ast_free.

◆ predial_enable()

static void* predial_enable ( void *  data)
static

Definition at line 149 of file dial.c.

150 {
151  return ast_strdup(data);
152 }

References ast_strdup.

◆ set_state()

static void set_state ( struct ast_dial dial,
enum ast_dial_result  state 
)
static

Definition at line 573 of file dial.c.

574 {
575  dial->state = state;
576 
577  if (dial->state_callback)
578  dial->state_callback(dial);
579 }

References state, ast_dial::state, and ast_dial::state_callback.

Referenced by handle_frame(), and handle_timeout_trip().

Variable Documentation

◆ option_types

const struct ast_option_types option_types[]
static

Map options to respective handlers (enable/disable).

Note
This list MUST be perfectly kept in order with enum ast_dial_option, or else madness will happen.

Definition at line 166 of file dial.c.

Referenced by ast_dial_destroy(), ast_dial_option_disable(), ast_dial_option_enable(), ast_dial_option_global_disable(), and ast_dial_option_global_enable().