Asterisk - The Open Source Telephony Project  21.4.1
Data Structures | Typedefs | Functions | Variables
control.c File Reference

Stasis application control support. More...

#include "asterisk.h"
#include "asterisk/stasis_channels.h"
#include "asterisk/stasis_app.h"
#include "command.h"
#include "control.h"
#include "app.h"
#include "asterisk/dial.h"
#include "asterisk/bridge.h"
#include "asterisk/bridge_after.h"
#include "asterisk/bridge_basic.h"
#include "asterisk/bridge_features.h"
#include "asterisk/frame.h"
#include "asterisk/pbx.h"
#include "asterisk/musiconhold.h"
#include "asterisk/app.h"
#include <signal.h>

Go to the source code of this file.

Data Structures

struct  app_control_rules
 
struct  chanvar
 structure for queuing ARI channel variable setting More...
 
struct  control_dial_args
 
struct  stasis_app_control
 
struct  stasis_app_control_continue_data
 
struct  stasis_app_control_dtmf_data
 
struct  stasis_app_control_move_data
 
struct  stasis_app_control_mute_data
 

Typedefs

typedef int(* app_command_can_exec_cb) (struct stasis_app_control *control)
 

Functions

static int add_to_dial_bridge (struct stasis_app_control *control, struct ast_channel *chan)
 Add a channel to the singleton dial bridge. More...
 
static int app_control_add_role (struct stasis_app_control *control, struct ast_channel *chan, void *data)
 
static int app_control_can_add_channel_to_bridge (struct stasis_app_control *control)
 
static int app_control_can_remove_channel_from_bridge (struct stasis_app_control *control)
 
static enum stasis_app_control_channel_result app_control_check_rules (const struct stasis_app_control *control, struct app_control_rules *list)
 
static int app_control_clear_roles (struct stasis_app_control *control, struct ast_channel *chan, void *data)
 
static int app_control_continue (struct stasis_app_control *control, struct ast_channel *chan, void *data)
 
static int app_control_dial (struct stasis_app_control *control, struct ast_channel *chan, void *data)
 
static int app_control_dtmf (struct stasis_app_control *control, struct ast_channel *chan, void *data)
 
static int app_control_hold (struct stasis_app_control *control, struct ast_channel *chan, void *data)
 
static int app_control_moh_start (struct stasis_app_control *control, struct ast_channel *chan, void *data)
 
static int app_control_moh_stop (struct stasis_app_control *control, struct ast_channel *chan, void *data)
 
static int app_control_move (struct stasis_app_control *control, struct ast_channel *chan, void *data)
 
static int app_control_mute (struct stasis_app_control *control, struct ast_channel *chan, void *data)
 
static int app_control_redirect (struct stasis_app_control *control, struct ast_channel *chan, void *data)
 
static void app_control_register_rule (struct stasis_app_control *control, struct app_control_rules *list, struct stasis_app_control_rule *obj)
 
static int app_control_remove_channel_from_bridge (struct stasis_app_control *control, struct ast_channel *chan, void *data)
 
static int app_control_ring (struct stasis_app_control *control, struct ast_channel *chan, void *data)
 
static int app_control_ring_stop (struct stasis_app_control *control, struct ast_channel *chan, void *data)
 
static int app_control_set_channel_var (struct stasis_app_control *control, struct ast_channel *chan, void *data)
 
static int app_control_silence_start (struct stasis_app_control *control, struct ast_channel *chan, void *data)
 
static int app_control_silence_stop (struct stasis_app_control *control, struct ast_channel *chan, void *data)
 
static int app_control_unhold (struct stasis_app_control *control, struct ast_channel *chan, void *data)
 
static int app_control_unmute (struct stasis_app_control *control, struct ast_channel *chan, void *data)
 
static void app_control_unregister_rule (struct stasis_app_control *control, struct app_control_rules *list, struct stasis_app_control_rule *obj)
 
static int app_send_command_on_condition (struct stasis_app_control *control, stasis_app_command_cb command_fn, void *data, command_data_destructor_fn data_destructor, app_command_can_exec_cb can_exec_fn)
 
static void bridge_after_cb (struct ast_channel *chan, void *data)
 
static void bridge_after_cb_failed (enum ast_bridge_after_cb_reason reason, void *data)
 
static int bridge_channel_depart (struct stasis_app_control *control, struct ast_channel *chan, void *data)
 
static int bridge_timeout (struct ast_bridge_channel *bridge_channel, void *ignore)
 Dial timeout. More...
 
int control_add_channel_to_bridge (struct stasis_app_control *control, struct ast_channel *chan, void *data)
 Command callback for adding a channel to a bridge. More...
 
struct stasis_appcontrol_app (struct stasis_app_control *control)
 Returns the pointer (non-reffed) to the app associated with this control. More...
 
int control_command_count (struct stasis_app_control *control)
 Returns the count of items in a control's command queue. More...
 
struct stasis_app_controlcontrol_create (struct ast_channel *channel, struct stasis_app *app)
 Create a control object. More...
 
static struct control_dial_argscontrol_dial_args_alloc (const char *dialstring, unsigned int timeout)
 
static void control_dial_args_destroy (void *data)
 
int control_dispatch_all (struct stasis_app_control *control, struct ast_channel *chan)
 Dispatch all commands enqueued to this control. More...
 
static void control_dtor (void *obj)
 
void control_flush_queue (struct stasis_app_control *control)
 Flush the control command queue. More...
 
int control_is_done (struct stasis_app_control *control)
 Returns true if control_continue() has been called on this control. More...
 
void control_mark_done (struct stasis_app_control *control)
 
void control_move_cleanup (struct stasis_app_control *control)
 Free any memory that was allocated for switching applications via /channels/{channelId}/move. More...
 
char * control_next_app (struct stasis_app_control *control)
 Returns the name of the application we are moving to. More...
 
char ** control_next_app_args (struct stasis_app_control *control)
 Returns the list of arguments to pass to the application we are moving to. More...
 
int control_next_app_args_size (struct stasis_app_control *control)
 Returns the number of arguments to be passed to the application we are moving to. More...
 
int control_prestart_dispatch_all (struct stasis_app_control *control, struct ast_channel *chan)
 Dispatch all queued prestart commands. More...
 
void control_set_app (struct stasis_app_control *control, struct stasis_app *app)
 Set the application the control object belongs to. More...
 
void control_set_thread (struct stasis_app_control *control, pthread_t threadid)
 set the control's thread id More...
 
void control_silence_stop_now (struct stasis_app_control *control)
 Stop playing silence to a channel right now. More...
 
int control_swap_channel_in_bridge (struct stasis_app_control *control, struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap)
 Command for swapping a channel in a bridge. More...
 
void control_wait (struct stasis_app_control *control)
 Blocks until control's command queue has a command available. More...
 
static int depart_channel (struct stasis_app_control *control, struct ast_channel *chan)
 Depart a channel from a bridge, and potentially add it back to the dial bridge. More...
 
static void dial_bridge_after_cb (struct ast_channel *chan, void *data)
 after bridge callback for the dial bridge More...
 
static void dial_bridge_after_cb_failed (enum ast_bridge_after_cb_reason reason, void *data)
 
static void dtmf_in_bridge (struct ast_channel *chan, struct stasis_app_control_dtmf_data *dtmf_data)
 
static void dtmf_no_bridge (struct ast_channel *chan, struct stasis_app_control_dtmf_data *dtmf_data)
 
static struct stasis_app_commandexec_command (struct stasis_app_control *control, stasis_app_command_cb command_fn, void *data, command_data_destructor_fn data_destructor)
 
static struct stasis_app_commandexec_command_on_condition (struct stasis_app_control *control, stasis_app_command_cb command_fn, void *data, command_data_destructor_fn data_destructor, app_command_can_exec_cb can_exec_fn)
 
static void free_chanvar (void *data)
 
static struct ast_bridgeget_dial_bridge (void)
 Retrieve a reference to the dial bridge. More...
 
static int hangup_channel (struct stasis_app_control *control, struct ast_channel *chan, void *data)
 
static void internal_bridge_after_cb (struct ast_channel *chan, void *data, enum ast_bridge_after_cb_reason reason)
 
static int noop_cb (struct stasis_app_control *control, struct ast_channel *chan, void *data)
 
static void set_interval_hook (struct ast_channel *chan)
 Set a dial timeout interval hook on the channel. More...
 
static int set_timeout (struct ast_channel *chan, unsigned int timeout)
 Set dial timeout on a channel to be dialed. More...
 
void stasis_app_control_absorb_dtmf_in_bridge (struct stasis_app_control *control, int absorb)
 Set whether DTMF from the channel is absorbed instead of passing through to the bridge. More...
 
int stasis_app_control_add_channel_to_bridge (struct stasis_app_control *control, struct ast_bridge *bridge)
 Add a channel to the bridge. More...
 
int stasis_app_control_add_role (struct stasis_app_control *control, const char *role)
 Apply a bridge role to a channel controlled by a stasis app control. More...
 
int stasis_app_control_bridge_features_init (struct stasis_app_control *control)
 Initialize bridge features into a channel control. More...
 
void stasis_app_control_clear_roles (struct stasis_app_control *control)
 Clear bridge roles currently applied to a channel controlled by a stasis app control. More...
 
int stasis_app_control_continue (struct stasis_app_control *control, const char *context, const char *extension, int priority)
 Exit res_stasis and continue execution in the dialplan. More...
 
int stasis_app_control_dial (struct stasis_app_control *control, const char *dialstring, unsigned int timeout)
 Dial a channel. More...
 
int stasis_app_control_dtmf (struct stasis_app_control *control, const char *dtmf, int before, int between, unsigned int duration, int after)
 Send DTMF to the channel associated with this control. More...
 
const char * stasis_app_control_get_channel_id (const struct stasis_app_control *control)
 Returns the uniqueid of the channel associated with this control. More...
 
struct ast_channel_snapshotstasis_app_control_get_snapshot (const struct stasis_app_control *control)
 Returns the most recent snapshot for the associated channel. More...
 
void stasis_app_control_hold (struct stasis_app_control *control)
 Place the channel associated with the control on hold. More...
 
void stasis_app_control_inhibit_colp_in_bridge (struct stasis_app_control *control, int inhibit_colp)
 Set whether COLP frames should be generated when joining the bridge. More...
 
void stasis_app_control_moh_start (struct stasis_app_control *control, const char *moh_class)
 Play music on hold to a channel (does not affect hold status) More...
 
void stasis_app_control_moh_stop (struct stasis_app_control *control)
 Stop playing music on hold to a channel (does not affect hold status) More...
 
int stasis_app_control_move (struct stasis_app_control *control, const char *app_name, const char *app_args)
 Exit res_stasis and move to another Stasis application. More...
 
int stasis_app_control_mute (struct stasis_app_control *control, unsigned int direction, enum ast_frame_type frametype)
 Mute the channel associated with this control. More...
 
void stasis_app_control_mute_in_bridge (struct stasis_app_control *control, int mute)
 Set whether audio from the channel is muted instead of passing through to the bridge. More...
 
void stasis_app_control_publish (struct stasis_app_control *control, struct stasis_message *message)
 Publish a message to the control's channel's topic. More...
 
int stasis_app_control_queue_control (struct stasis_app_control *control, enum ast_control_frame_type frame_type)
 Queue a control frame without payload. More...
 
int stasis_app_control_redirect (struct stasis_app_control *control, const char *endpoint)
 Redirect a channel in res_stasis to a particular endpoint. More...
 
void stasis_app_control_register_add_rule (struct stasis_app_control *control, struct stasis_app_control_rule *rule)
 Registers an add channel to bridge rule. More...
 
void stasis_app_control_register_remove_rule (struct stasis_app_control *control, struct stasis_app_control_rule *rule)
 Registers a remove channel from bridge rule. More...
 
int stasis_app_control_remove_channel_from_bridge (struct stasis_app_control *control, struct ast_bridge *bridge)
 Remove a channel from the bridge. More...
 
int stasis_app_control_ring (struct stasis_app_control *control)
 Indicate ringing to the channel associated with this control. More...
 
int stasis_app_control_ring_stop (struct stasis_app_control *control)
 Stop locally generated ringing on the channel associated with this control. More...
 
int stasis_app_control_set_channel_var (struct stasis_app_control *control, const char *variable, const char *value)
 Set a variable on the channel associated with this control to value. More...
 
void stasis_app_control_shutdown (void)
 Let Stasis app internals shut down. More...
 
void stasis_app_control_silence_start (struct stasis_app_control *control)
 Start playing silence to a channel. More...
 
void stasis_app_control_silence_stop (struct stasis_app_control *control)
 Stop playing silence to a channel. More...
 
void stasis_app_control_unhold (struct stasis_app_control *control)
 Remove the channel associated with the control from hold. More...
 
int stasis_app_control_unmute (struct stasis_app_control *control, unsigned int direction, enum ast_frame_type frametype)
 Unmute the channel associated with this control. More...
 
void stasis_app_control_unregister_add_rule (struct stasis_app_control *control, struct stasis_app_control_rule *rule)
 UnRegister an add channel to bridge rule. More...
 
void stasis_app_control_unregister_remove_rule (struct stasis_app_control *control, struct stasis_app_control_rule *rule)
 Unregisters a remove channel from bridge rule. More...
 
struct ast_bridgestasis_app_get_bridge (struct stasis_app_control *control)
 Gets the bridge currently associated with a control object. More...
 
int stasis_app_send_command (struct stasis_app_control *control, stasis_app_command_cb command_fn, void *data, command_data_destructor_fn data_destructor)
 Invokes a command on a control's channel. More...
 
int stasis_app_send_command_async (struct stasis_app_control *control, stasis_app_command_cb command_fn, void *data, command_data_destructor_fn data_destructor)
 Asynchronous version of stasis_app_send_command(). More...
 

Variables

static struct ast_bridgedial_bridge
 Singleton dial bridge. More...
 
static ast_mutex_t dial_bridge_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
 
static int shutting_down
 Indicates if the Stasis app internals are being shut down.
 
struct ast_datastore_info timeout_datastore
 Dial timeout datastore. More...
 

Detailed Description

Stasis application control support.

Author
David M. Lee, II dlee@.nosp@m.digi.nosp@m.um.co.nosp@m.m

Definition in file control.c.

Typedef Documentation

typedef int(* app_command_can_exec_cb) (struct stasis_app_control *control)

Callback type to see if the command can execute note: command_queue is locked during callback

Definition at line 280 of file control.c.

Function Documentation

static int add_to_dial_bridge ( struct stasis_app_control control,
struct ast_channel chan 
)
static

Add a channel to the singleton dial bridge.

Parameters
controlThe Stasis control structure
chanThe channel to add to the bridge
Return values
-1Failed
0Success

Definition at line 1063 of file control.c.

References ao2_ref, ast_bridge_impart(), AST_BRIDGE_IMPART_CHAN_DEPARTABLE, ast_bridge_set_after_callback(), stasis_app_control::bridge, dial_bridge_after_cb(), and get_dial_bridge().

Referenced by depart_channel().

1064 {
1065  struct ast_bridge *bridge;
1066 
1067  bridge = get_dial_bridge();
1068  if (!bridge) {
1069  return -1;
1070  }
1071 
1072  control->bridge = bridge;
1073  ast_bridge_set_after_callback(chan, dial_bridge_after_cb, dial_bridge_after_cb_failed, control);
1074  if (ast_bridge_impart(bridge, chan, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE)) {
1075  control->bridge = NULL;
1076  ao2_ref(bridge, -1);
1077  return -1;
1078  }
1079 
1080  ao2_ref(bridge, -1);
1081 
1082  return 0;
1083 }
int ast_bridge_set_after_callback(struct ast_channel *chan, ast_bridge_after_cb callback, ast_bridge_after_cb_failed failed, void *data)
Setup an after bridge callback for when the channel leaves the bridging system.
Definition: bridge_after.c:251
static void dial_bridge_after_cb(struct ast_channel *chan, void *data)
after bridge callback for the dial bridge
Definition: control.c:1031
static struct ast_bridge * get_dial_bridge(void)
Retrieve a reference to the dial bridge.
Definition: control.c:996
int ast_bridge_impart(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features, enum ast_bridge_impart_flags flags) attribute_warn_unused_result
Impart a channel to a bridge (non-blocking)
Definition: bridge.c:1878
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
Structure that contains information about a bridge.
Definition: bridge.h:349
struct ast_bridge * bridge
Definition: control.c:66
static int bridge_timeout ( struct ast_bridge_channel bridge_channel,
void *  ignore 
)
static

Dial timeout.

This is a bridge interval hook callback. The interval hook triggering means that the dial timeout has been reached. If the channel has not been answered by the time this callback is called, then the channel is hung up

Parameters
bridge_channelBridge channel on which interval hook has been called
ignoreIgnored
Returns
-1 (i.e. remove the interval hook)

Definition at line 1237 of file control.c.

References ast_channel_datastore_find(), ast_channel_datastore_remove(), ast_datastore_free(), AST_STATE_UP, ast_bridge_channel::chan, RAII_VAR, stasis_app_control_find_by_channel(), and stasis_app_send_command_async().

Referenced by set_interval_hook().

1238 {
1239  struct ast_datastore *datastore;
1240  RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
1241 
1242  control = stasis_app_control_find_by_channel(bridge_channel->chan);
1243 
1244  ast_channel_lock(bridge_channel->chan);
1245  if (ast_channel_state(bridge_channel->chan) != AST_STATE_UP) {
1246  /* Don't bother removing the datastore because it will happen when the channel is hung up */
1247  ast_channel_unlock(bridge_channel->chan);
1248  stasis_app_send_command_async(control, hangup_channel, NULL, NULL);
1249  return -1;
1250  }
1251 
1252  datastore = ast_channel_datastore_find(bridge_channel->chan, &timeout_datastore, NULL);
1253  if (!datastore) {
1254  ast_channel_unlock(bridge_channel->chan);
1255  return -1;
1256  }
1257  ast_channel_datastore_remove(bridge_channel->chan, datastore);
1258  ast_channel_unlock(bridge_channel->chan);
1259  ast_datastore_free(datastore);
1260 
1261  return -1;
1262 }
ast_channel_state
ast_channel states
Definition: channelstate.h:35
Structure for a data store object.
Definition: datastore.h:64
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Definition: channel.c:2399
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
struct ast_channel * chan
int stasis_app_send_command_async(struct stasis_app_control *control, stasis_app_command_cb command_fn, void *data, command_data_destructor_fn data_destructor)
Asynchronous version of stasis_app_send_command().
Definition: control.c:926
struct ast_datastore_info timeout_datastore
Dial timeout datastore.
Definition: control.c:1214
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore)
Remove a datastore from a channel.
Definition: channel.c:2394
struct stasis_app_control * stasis_app_control_find_by_channel(const struct ast_channel *chan)
Returns the handler for the given channel.
Definition: res_stasis.c:338
int control_add_channel_to_bridge ( struct stasis_app_control control,
struct ast_channel chan,
void *  data 
)

Command callback for adding a channel to a bridge.

Parameters
controlThe control for chan
chanThe channel on which commands should be executed
dataBridge to be passed to the callback

Definition at line 1400 of file control.c.

References control_swap_channel_in_bridge().

Referenced by stasis_app_control_add_channel_to_bridge().

1401 {
1402  return control_swap_channel_in_bridge(control, data, chan, NULL);
1403 }
int control_swap_channel_in_bridge(struct stasis_app_control *control, struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap)
Command for swapping a channel in a bridge.
Definition: control.c:1306
void * data
Definition: datastore.h:66
struct stasis_app* control_app ( struct stasis_app_control control)

Returns the pointer (non-reffed) to the app associated with this control.

Parameters
controlControl to query.
Returns
A pointer to the associated stasis_app

Definition at line 1585 of file control.c.

References stasis_app_control::app.

Referenced by stasis_app_exec().

1586 {
1587  return control->app;
1588 }
struct stasis_app * app
Definition: control.c:92
int control_command_count ( struct stasis_app_control control)

Returns the count of items in a control's command queue.

Parameters
controlControl to count commands on
Returns
number of commands in the command que

Definition at line 365 of file control.c.

References ao2_container_count(), and stasis_app_control::command_queue.

Referenced by stasis_app_control_execute_until_exhausted().

366 {
367  return ao2_container_count(control->command_queue);
368 }
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
struct ao2_container * command_queue
Definition: control.c:56
struct stasis_app_control* control_create ( struct ast_channel channel,
struct stasis_app app 
)

Create a control object.

Parameters
channelChannel to control.
appstasis_app for which this control is being created.
Returns
New control object.
Return values
NULLon error.

Definition at line 129 of file control.c.

References stasis_app_control::add_rules, AO2_ALLOC_OPT_LOCK_MUTEX, ao2_bump, ao2_container_alloc_list, ao2_ref, stasis_app_control::app, ast_channel_ref, AST_LIST_HEAD_INIT, AST_VECTOR_INIT, stasis_app_control::channel, stasis_app_control::command_queue, control_set_thread(), stasis_app_control::next_app, stasis_app_control::next_app_args, and stasis_app_control::remove_rules.

Referenced by stasis_app_control_create(), and stasis_app_exec().

130 {
131  struct stasis_app_control *control;
132  int res;
133 
134  control = ao2_alloc(sizeof(*control), control_dtor);
135  if (!control) {
136  return NULL;
137  }
138 
139  AST_LIST_HEAD_INIT(&control->add_rules);
140  AST_LIST_HEAD_INIT(&control->remove_rules);
141 
142  res = ast_cond_init(&control->wait_cond, NULL);
143  if (res != 0) {
144  ast_log(LOG_ERROR, "Error initializing ast_cond_t: %s\n",
145  strerror(errno));
146  ao2_ref(control, -1);
147  return NULL;
148  }
149 
150  control->app = ao2_bump(app);
151 
152  ast_channel_ref(channel);
153  control->channel = channel;
154 
156  AO2_ALLOC_OPT_LOCK_MUTEX, 0, NULL, NULL);
157  if (!control->command_queue) {
158  ao2_ref(control, -1);
159  return NULL;
160  }
161 
162  control->next_app = NULL;
163  AST_VECTOR_INIT(&control->next_app_args, 0);
164 
165  control_set_thread(control, AST_PTHREADT_NULL);
166 
167  return control;
168 }
char * next_app
Definition: control.c:96
struct app_control_rules remove_rules
Definition: control.c:82
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a list container.
Definition: astobj2.h:1327
struct stasis_app * app
Definition: control.c:92
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
void control_set_thread(struct stasis_app_control *control, pthread_t threadid)
set the control's thread id
Definition: control.c:196
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113
struct stasis_app_control::@497 next_app_args
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
struct ast_channel * channel
Definition: control.c:62
struct ao2_container * command_queue
Definition: control.c:56
#define AST_LIST_HEAD_INIT(head)
Initializes a list head structure.
Definition: linkedlists.h:626
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2947
struct app_control_rules add_rules
Definition: control.c:78
int control_dispatch_all ( struct stasis_app_control control,
struct ast_channel chan 
)

Dispatch all commands enqueued to this control.

Parameters
controlControl object to dispatch.
chanAssociated channel.
Returns
Number of commands executed

Definition at line 1517 of file control.c.

References ao2_iterator_destroy(), ao2_iterator_init(), AO2_ITERATOR_UNLINK, ao2_ref, stasis_app_control::channel, and stasis_app_control::command_queue.

Referenced by stasis_app_control_execute_until_exhausted(), and stasis_app_exec().

1519 {
1520  int count = 0;
1521  struct ao2_iterator iter;
1522  struct stasis_app_command *command;
1523 
1524  ast_assert(control->channel == chan);
1525 
1527  while ((command = ao2_iterator_next(&iter))) {
1528  command_invoke(command, control, chan);
1529  ao2_ref(command, -1);
1530  ++count;
1531  }
1532  ao2_iterator_destroy(&iter);
1533 
1534  return count;
1535 }
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
struct ast_channel * channel
Definition: control.c:62
struct ao2_container * command_queue
Definition: control.c:56
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
void control_flush_queue ( struct stasis_app_control control)

Flush the control command queue.

Since
13.9.0
Parameters
controlControl object to flush command queue.

Definition at line 1504 of file control.c.

References ao2_iterator_destroy(), ao2_iterator_init(), AO2_ITERATOR_UNLINK, ao2_ref, and stasis_app_control::command_queue.

Referenced by stasis_app_control_flush_queue(), and stasis_app_exec().

1505 {
1506  struct ao2_iterator iter;
1507  struct stasis_app_command *command;
1508 
1510  while ((command = ao2_iterator_next(&iter))) {
1511  command_complete(command, -1);
1512  ao2_ref(command, -1);
1513  }
1514  ao2_iterator_destroy(&iter);
1515 }
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
struct ao2_container * command_queue
Definition: control.c:56
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
int control_is_done ( struct stasis_app_control control)

Returns true if control_continue() has been called on this control.

Parameters
controlControl to query.
Return values
True(non-zero) if control_continue() has been called.
False(zero) otherwise.

Definition at line 370 of file control.c.

References stasis_app_control::is_done.

Referenced by stasis_app_control_execute_until_exhausted(), stasis_app_control_is_done(), and stasis_app_exec().

371 {
372  /* Called from stasis_app_exec thread; no lock needed */
373  return control->is_done;
374 }
unsigned int is_done
Definition: control.c:108
void control_move_cleanup ( struct stasis_app_control control)

Free any memory that was allocated for switching applications via /channels/{channelId}/move.

Parameters
controlThe control for the channel

Definition at line 1724 of file control.c.

References ast_free_ptr(), AST_VECTOR_RESET, stasis_app_control::next_app, and stasis_app_control::next_app_args.

Referenced by stasis_app_exec().

1725 {
1726  ast_free(control->next_app);
1727  control->next_app = NULL;
1728 
1730 }
char * next_app
Definition: control.c:96
void ast_free_ptr(void *ptr)
free() wrapper
Definition: main/astmm.c:1739
struct stasis_app_control::@497 next_app_args
#define AST_VECTOR_RESET(vec, cleanup)
Reset vector.
Definition: vector.h:625
char* control_next_app ( struct stasis_app_control control)

Returns the name of the application we are moving to.

Parameters
controlThe control for the channel
Returns
The name of the application we are moving to

Definition at line 1719 of file control.c.

References stasis_app_control::next_app.

Referenced by stasis_app_exec().

1720 {
1721  return control->next_app;
1722 }
char * next_app
Definition: control.c:96
char** control_next_app_args ( struct stasis_app_control control)

Returns the list of arguments to pass to the application we are moving to.

Note
If you wish to get the size of the list, control_next_app_args_size should be called before this, as this function will steal the elements from the string vector and set the size to 0.
Parameters
controlThe control for the channel
Returns
The arguments to pass to the application we are moving to

Definition at line 1732 of file control.c.

References AST_VECTOR_STEAL_ELEMENTS, and stasis_app_control::next_app_args.

Referenced by stasis_app_exec().

1733 {
1734  return AST_VECTOR_STEAL_ELEMENTS(&control->next_app_args);
1735 }
struct stasis_app_control::@497 next_app_args
#define AST_VECTOR_STEAL_ELEMENTS(vec)
Steal the elements from a vector and reinitialize.
Definition: vector.h:140
int control_next_app_args_size ( struct stasis_app_control control)

Returns the number of arguments to be passed to the application we are moving to.

Note
This should always be called before control_next_app_args, as calling that function will steal all elements from the string vector and set the size to 0.
Parameters
controlThe control for the channel
Returns
The number of arguments to be passed to the application we are moving to

Definition at line 1737 of file control.c.

References AST_VECTOR_SIZE, and stasis_app_control::next_app_args.

Referenced by stasis_app_exec().

1738 {
1739  return AST_VECTOR_SIZE(&control->next_app_args);
1740 }
struct stasis_app_control::@497 next_app_args
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:609
int control_prestart_dispatch_all ( struct stasis_app_control control,
struct ast_channel chan 
)

Dispatch all queued prestart commands.

Parameters
controlThe control for chan
chanThe channel on which commands should be executed
Returns
The number of commands executed

Definition at line 1557 of file control.c.

References ao2_iterator_destroy(), ao2_iterator_init(), AO2_ITERATOR_UNLINK, command_prestart_get_container(), and stasis_app_control::command_queue.

Referenced by stasis_app_exec().

1559 {
1560  struct ao2_container *command_queue;
1561  int count = 0;
1562  struct ao2_iterator iter;
1563  struct stasis_app_command *command;
1564 
1565  ast_channel_lock(chan);
1566  command_queue = command_prestart_get_container(chan);
1567  ast_channel_unlock(chan);
1568  if (!command_queue) {
1569  return 0;
1570  }
1571 
1572  iter = ao2_iterator_init(command_queue, AO2_ITERATOR_UNLINK);
1573 
1574  while ((command = ao2_iterator_next(&iter))) {
1575  command_invoke(command, control, chan);
1576  ao2_cleanup(command);
1577  ++count;
1578  }
1579 
1580  ao2_iterator_destroy(&iter);
1581  ao2_cleanup(command_queue);
1582  return count;
1583 }
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
struct ao2_container * command_prestart_get_container(struct ast_channel *chan)
Get the Stasis() prestart commands for a channel.
Definition: command.c:160
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
Generic container type.
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
void control_set_app ( struct stasis_app_control control,
struct stasis_app app 
)

Set the application the control object belongs to.

Parameters
controlThe control for the channel
appThe application this control will now belong to
Note
This will unref control's previous app by 1, and bump app by 1

Definition at line 1713 of file control.c.

References ao2_bump, and stasis_app_control::app.

Referenced by stasis_app_exec().

1714 {
1715  ao2_cleanup(control->app);
1716  control->app = ao2_bump(app);
1717 }
struct stasis_app * app
Definition: control.c:92
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
void control_set_thread ( struct stasis_app_control control,
pthread_t  threadid 
)

set the control's thread id

Since
18
Parameters
controlControl object on which to set the thread id.
threadidid to set

Definition at line 196 of file control.c.

References stasis_app_control::command_queue, and stasis_app_control::control_thread.

Referenced by control_create(), and stasis_app_exec().

197 {
198  ao2_lock(control->command_queue);
199  control->control_thread = threadid;
200  ao2_unlock(control->command_queue);
201 }
struct ao2_container * command_queue
Definition: control.c:56
pthread_t control_thread
Definition: control.c:100
void control_silence_stop_now ( struct stasis_app_control control)

Stop playing silence to a channel right now.

Since
13.9.0
Parameters
controlThe control for chan

Definition at line 859 of file control.c.

References ast_channel_stop_silence_generator(), ast_debug, stasis_app_control::channel, stasis_app_control::silgen, and stasis_app_control_get_channel_id().

Referenced by stasis_app_exec().

860 {
861  if (control->silgen) {
862  ast_debug(3, "%s: Stopping silence generator\n",
865  control->channel, control->silgen);
866  control->silgen = NULL;
867  }
868 }
struct ast_channel * channel
Definition: control.c:62
#define ast_debug(level,...)
Log a DEBUG message.
const char * stasis_app_control_get_channel_id(const struct stasis_app_control *control)
Returns the uniqueid of the channel associated with this control.
Definition: control.c:1452
void ast_channel_stop_silence_generator(struct ast_channel *chan, struct ast_silence_generator *state)
Stops a previously-started silence generator on the given channel.
Definition: channel.c:8210
struct ast_silence_generator * silgen
Definition: control.c:86
int control_swap_channel_in_bridge ( struct stasis_app_control control,
struct ast_bridge bridge,
struct ast_channel chan,
struct ast_channel swap 
)

Command for swapping a channel in a bridge.

Parameters
controlThe control for chan
chanThe channel on which commands should be executed
bridgeBridge to be passed to the callback
swapChannel to swap with when joining the bridge

Definition at line 1306 of file control.c.

References stasis_app_control::app, app_subscribe_bridge(), ast_bridge_depart(), ast_bridge_impart(), AST_BRIDGE_IMPART_CHAN_DEPARTABLE, AST_BRIDGE_IMPART_INHIBIT_JOIN_COLP, ast_bridge_set_after_callback(), ast_debug, stasis_app_control::bridge, stasis_app_control::bridge_features, ast_bridge_features::inhibit_colp, stasis_app_control::pbx, set_interval_hook(), stasis_app_control_get_channel_id(), stasis_app_get_bridge(), and ast_bridge::uniqueid.

Referenced by control_add_channel_to_bridge().

1307 {
1308  int res;
1309  struct ast_bridge_features *features;
1311 
1312  if (!control || !bridge) {
1313  return -1;
1314  }
1315 
1316  ast_debug(3, "%s: Adding to bridge %s\n",
1318  bridge->uniqueid);
1319 
1320  ast_assert(chan != NULL);
1321 
1322  /* Depart whatever Stasis bridge we're currently in. */
1323  if (stasis_app_get_bridge(control)) {
1324  /* Note that it looks like there's a race condition here, since
1325  * we don't have control locked. But this happens from the
1326  * control callback thread, so there won't be any other
1327  * concurrent attempts to bridge.
1328  */
1329  ast_bridge_depart(chan);
1330  }
1331 
1332 
1333  res = ast_bridge_set_after_callback(chan, bridge_after_cb,
1334  bridge_after_cb_failed, control);
1335  if (res != 0) {
1336  ast_log(LOG_ERROR, "Error setting after-bridge callback\n");
1337  return -1;
1338  }
1339 
1340  ao2_lock(control);
1341 
1342  /* Ensure the controlling application is subscribed early enough
1343  * to receive the ChannelEnteredBridge message. This works in concert
1344  * with the subscription handled in the Stasis application execution
1345  * loop */
1346  app_subscribe_bridge(control->app, bridge);
1347 
1348  /* Save off the channel's PBX */
1349  ast_assert(control->pbx == NULL);
1350  if (!control->pbx) {
1351  control->pbx = ast_channel_pbx(chan);
1352  ast_channel_pbx_set(chan, NULL);
1353  }
1354 
1355  /* Pull bridge features from the control */
1356  features = control->bridge_features;
1357  control->bridge_features = NULL;
1358  if (features && features->inhibit_colp) {
1360  }
1361 
1362  ast_assert(stasis_app_get_bridge(control) == NULL);
1363  /* We need to set control->bridge here since bridge_after_cb may be run
1364  * before ast_bridge_impart returns. bridge_after_cb gets a reason
1365  * code so it can tell if the bridge is actually valid or not.
1366  */
1367  control->bridge = bridge;
1368 
1369  /* We can't be holding the control lock while impart is running
1370  * or we could create a deadlock with bridge_after_cb which also
1371  * tries to lock control.
1372  */
1373  ao2_unlock(control);
1374  res = ast_bridge_impart(bridge,
1375  chan,
1376  swap,
1377  features, /* features */
1378  flags);
1379  if (res != 0) {
1380  /* ast_bridge_impart failed before it could spawn the depart
1381  * thread. The callbacks aren't called in this case.
1382  * The impart could still fail even if ast_bridge_impart returned
1383  * ok but that's handled by bridge_after_cb.
1384  */
1385  ast_log(LOG_ERROR, "Error adding channel to bridge\n");
1386  ao2_lock(control);
1387  ast_channel_pbx_set(chan, control->pbx);
1388  control->pbx = NULL;
1389  control->bridge = NULL;
1390  ao2_unlock(control);
1391  } else {
1392  ast_channel_lock(chan);
1393  set_interval_hook(chan);
1394  ast_channel_unlock(chan);
1395  }
1396 
1397  return res;
1398 }
unsigned int inhibit_colp
const ast_string_field uniqueid
Definition: bridge.h:401
Structure that contains features information.
struct ast_bridge * stasis_app_get_bridge(struct stasis_app_control *control)
Gets the bridge currently associated with a control object.
Definition: control.c:953
int ast_bridge_set_after_callback(struct ast_channel *chan, ast_bridge_after_cb callback, ast_bridge_after_cb_failed failed, void *data)
Setup an after bridge callback for when the channel leaves the bridging system.
Definition: bridge_after.c:251
int app_subscribe_bridge(struct stasis_app *app, struct ast_bridge *bridge)
Add a bridge subscription to an existing channel subscription.
struct stasis_app * app
Definition: control.c:92
int ast_bridge_impart(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features, enum ast_bridge_impart_flags flags) attribute_warn_unused_result
Impart a channel to a bridge (non-blocking)
Definition: bridge.c:1878
#define ast_debug(level,...)
Log a DEBUG message.
struct ast_bridge_features * bridge_features
Definition: control.c:70
static void set_interval_hook(struct ast_channel *chan)
Set a dial timeout interval hook on the channel.
Definition: control.c:1276
int ast_bridge_depart(struct ast_channel *chan)
Depart a channel from a bridge.
Definition: bridge.c:1906
struct ast_pbx * pbx
Definition: control.c:74
const char * stasis_app_control_get_channel_id(const struct stasis_app_control *control)
Returns the uniqueid of the channel associated with this control.
Definition: control.c:1452
struct ast_bridge * bridge
Definition: control.c:66
void control_wait ( struct stasis_app_control control)

Blocks until control's command queue has a command available.

Parameters
controlControl to block on.

Definition at line 1537 of file control.c.

References ao2_container_count(), ao2_object_get_lockaddr(), and stasis_app_control::command_queue.

Referenced by stasis_app_exec().

1538 {
1539  if (!control) {
1540  return;
1541  }
1542 
1543  ast_assert(control->command_queue != NULL);
1544 
1545  ao2_lock(control->command_queue);
1546  while (ao2_container_count(control->command_queue) == 0) {
1547  int res = ast_cond_wait(&control->wait_cond,
1549  if (res < 0) {
1550  ast_log(LOG_ERROR, "Error waiting on command queue\n");
1551  break;
1552  }
1553  }
1554  ao2_unlock(control->command_queue);
1555 }
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
void * ao2_object_get_lockaddr(void *obj)
Return the mutex lock address of an object.
Definition: astobj2.c:476
struct ao2_container * command_queue
Definition: control.c:56
static int depart_channel ( struct stasis_app_control control,
struct ast_channel chan 
)
static

Depart a channel from a bridge, and potentially add it back to the dial bridge.

Parameters
controlTake a guess
chanTake another guess

Definition at line 1091 of file control.c.

References add_to_dial_bridge(), ast_bridge_depart(), ast_check_hangup(), and AST_STATE_UP.

1092 {
1093  ast_bridge_depart(chan);
1094 
1095  /* Channels which have a PBX are not ones that have been created and dialed from ARI. They
1096  * have externally come in from the dialplan, and thus should not be placed into the dial
1097  * bridge. Only channels which are created and dialed in ARI should go into the dial bridge.
1098  */
1099  if (!ast_check_hangup(chan) && ast_channel_state(chan) != AST_STATE_UP && !ast_channel_pbx(chan)) {
1100  /* Channel is still being dialed, so put it back in the dialing bridge */
1101  add_to_dial_bridge(control, chan);
1102  }
1103 
1104  return 0;
1105 }
ast_channel_state
ast_channel states
Definition: channelstate.h:35
static int add_to_dial_bridge(struct stasis_app_control *control, struct ast_channel *chan)
Add a channel to the singleton dial bridge.
Definition: control.c:1063
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:445
int ast_bridge_depart(struct ast_channel *chan)
Depart a channel from a bridge.
Definition: bridge.c:1906
static void dial_bridge_after_cb ( struct ast_channel chan,
void *  data 
)
static

after bridge callback for the dial bridge

The only purpose of this callback is to ensure that the control structure's bridge pointer is NULLed

Definition at line 1031 of file control.c.

References __ao2_cleanup(), ast_channel_get_bridge_channel(), ast_debug, stasis_app_control::bridge, stasis_app_control::channel, and stasis_app_send_command_async().

Referenced by add_to_dial_bridge().

1032 {
1033  struct stasis_app_control *control = data;
1034  struct ast_bridge_channel *bridge_channel;
1035 
1036  ast_channel_lock(chan);
1037  bridge_channel = ast_channel_get_bridge_channel(chan);
1038  ast_channel_unlock(chan);
1039 
1040  ast_debug(3, "Channel: <%s> Reason: %d\n", ast_channel_name(control->channel), ast_channel_hangupcause(chan));
1041 
1042  stasis_app_send_command_async(control, bridge_channel_depart, bridge_channel, __ao2_cleanup);
1043 
1044  control->bridge = NULL;
1045 }
void __ao2_cleanup(void *obj)
Definition: astobj2.c:677
struct ast_channel * channel
Definition: control.c:62
#define ast_debug(level,...)
Log a DEBUG message.
struct ast_bridge * bridge
Definition: control.c:66
struct ast_bridge_channel * ast_channel_get_bridge_channel(struct ast_channel *chan)
Get a reference to the channel's bridge pointer.
Definition: channel.c:10582
Structure that contains information regarding a channel in a bridge.
int stasis_app_send_command_async(struct stasis_app_control *control, stasis_app_command_cb command_fn, void *data, command_data_destructor_fn data_destructor)
Asynchronous version of stasis_app_send_command().
Definition: control.c:926
static struct ast_bridge* get_dial_bridge ( void  )
static

Retrieve a reference to the dial bridge.

If the dial bridge has not been created yet, it will be created, otherwise, a reference to the existing bridge will be returned.

The caller will need to unreference the dial bridge once they are finished with it.

Return values
NULLUnable to find/create the dial bridge
non-NULLA reference to the dial bridge

Definition at line 996 of file control.c.

References ao2_bump, shutting_down, and stasis_app_bridge_create_invisible().

Referenced by add_to_dial_bridge().

997 {
998  struct ast_bridge *ret_bridge = NULL;
999 
1000  ast_mutex_lock(&dial_bridge_lock);
1001 
1002  if (shutting_down) {
1003  goto end;
1004  }
1005 
1006  if (dial_bridge) {
1007  ret_bridge = ao2_bump(dial_bridge);
1008  goto end;
1009  }
1010 
1011  dial_bridge = stasis_app_bridge_create_invisible("holding", "dial_bridge", NULL);
1012  if (!dial_bridge) {
1013  goto end;
1014  }
1015  ret_bridge = ao2_bump(dial_bridge);
1016 
1017 end:
1018  ast_mutex_unlock(&dial_bridge_lock);
1019  return ret_bridge;
1020 }
struct ast_bridge * stasis_app_bridge_create_invisible(const char *type, const char *name, const char *id)
Create an invisible bridge of the specified type.
Definition: res_stasis.c:859
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
Structure that contains information about a bridge.
Definition: bridge.h:349
static int shutting_down
Indicates if the Stasis app internals are being shut down.
Definition: control.c:51
static struct ast_bridge * dial_bridge
Singleton dial bridge.
Definition: control.c:980
static void set_interval_hook ( struct ast_channel chan)
static

Set a dial timeout interval hook on the channel.

The absolute time that the timeout should occur is stored on a datastore on the channel. This time is converted into a relative number of milliseconds in the future. Then an interval hook is set to trigger in that number of milliseconds.

Precondition
chan is locked
Parameters
chanThe channel on which to set the interval hook

Definition at line 1276 of file control.c.

References ao2_ref, ast_bridge_interval_hook(), ast_channel_datastore_find(), ast_channel_get_bridge_channel(), ast_null_frame, ast_queue_frame(), ast_tvdiff_ms(), ast_tvnow(), bridge_timeout(), ast_bridge_channel::chan, ast_datastore::data, and ast_bridge_channel::features.

Referenced by control_swap_channel_in_bridge(), and set_timeout().

1277 {
1278  struct ast_datastore *datastore;
1279  struct timeval *hangup_time;
1280  int64_t ms;
1281  struct ast_bridge_channel *bridge_channel;
1282 
1283  datastore = ast_channel_datastore_find(chan, &timeout_datastore, NULL);
1284  if (!datastore) {
1285  return;
1286  }
1287 
1288  hangup_time = datastore->data;
1289 
1290  ms = ast_tvdiff_ms(*hangup_time, ast_tvnow());
1291  bridge_channel = ast_channel_get_bridge_channel(chan);
1292  if (!bridge_channel) {
1293  return;
1294  }
1295 
1296  if (ast_bridge_interval_hook(bridge_channel->features, 0, ms > 0 ? ms : 1,
1297  bridge_timeout, NULL, NULL, 0)) {
1298  ao2_ref(bridge_channel, -1);
1299  return;
1300  }
1301 
1302  ast_queue_frame(bridge_channel->chan, &ast_null_frame);
1303  ao2_ref(bridge_channel, -1);
1304 }
struct ast_bridge_features * features
static int bridge_timeout(struct ast_bridge_channel *bridge_channel, void *ignore)
Dial timeout.
Definition: control.c:1237
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:107
Structure for a data store object.
Definition: datastore.h:64
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Definition: channel.c:2399
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
int ast_bridge_interval_hook(struct ast_bridge_features *features, enum ast_bridge_hook_timer_option flags, unsigned int interval, ast_bridge_hook_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
Attach an interval hook to a bridge features structure.
Definition: bridge.c:3319
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel's frame queue.
Definition: channel.c:1139
struct ast_bridge_channel * ast_channel_get_bridge_channel(struct ast_channel *chan)
Get a reference to the channel's bridge pointer.
Definition: channel.c:10582
struct ast_frame ast_null_frame
Definition: main/frame.c:79
void * data
Definition: datastore.h:66
struct ast_channel * chan
Structure that contains information regarding a channel in a bridge.
struct ast_datastore_info timeout_datastore
Dial timeout datastore.
Definition: control.c:1214
static int set_timeout ( struct ast_channel chan,
unsigned int  timeout 
)
static

Set dial timeout on a channel to be dialed.

Parameters
chanThe channel on which to set the dial timeout
timeoutThe timeout in seconds

Definition at line 1625 of file control.c.

References ast_channel_datastore_add(), ast_channel_is_bridged(), ast_malloc, ast_samp2tv(), ast_tvadd(), ast_tvnow(), ast_datastore::data, and set_interval_hook().

1626 {
1627  struct ast_datastore *datastore;
1628  struct timeval *hangup_time;
1629 
1630  hangup_time = ast_malloc(sizeof(struct timeval));
1631 
1632  datastore = ast_datastore_alloc(&timeout_datastore, NULL);
1633  if (!datastore) {
1634  return -1;
1635  }
1636  *hangup_time = ast_tvadd(ast_tvnow(), ast_samp2tv(timeout, 1));
1637  datastore->data = hangup_time;
1638 
1639  ast_channel_lock(chan);
1640  ast_channel_datastore_add(chan, datastore);
1641 
1642  if (ast_channel_is_bridged(chan)) {
1643  set_interval_hook(chan);
1644  }
1645  ast_channel_unlock(chan);
1646 
1647  return 0;
1648 }
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
Structure for a data store object.
Definition: datastore.h:64
struct timeval ast_samp2tv(unsigned int _nsamp, unsigned int _rate)
Returns a timeval corresponding to the duration of n samples at rate r. Useful to convert samples to ...
Definition: time.h:282
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
static void set_interval_hook(struct ast_channel *chan)
Set a dial timeout interval hook on the channel.
Definition: control.c:1276
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: extconf.c:2282
int ast_channel_is_bridged(const struct ast_channel *chan)
Determine if a channel is in a bridge.
Definition: channel.c:10545
void * data
Definition: datastore.h:66
struct ast_datastore_info timeout_datastore
Dial timeout datastore.
Definition: control.c:1214
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2385
void stasis_app_control_absorb_dtmf_in_bridge ( struct stasis_app_control control,
int  absorb 
)

Set whether DTMF from the channel is absorbed instead of passing through to the bridge.

Parameters
controlControl whose channel should have its DTMF absorbed when bridged
absorbWhether DTMF should be absorbed (1) instead of passed through (0).

Definition at line 1486 of file control.c.

References stasis_app_control::bridge_features, and ast_bridge_features::dtmf_passthrough.

Referenced by ast_ari_bridges_add_channel().

1488 {
1489  control->bridge_features->dtmf_passthrough = !absorb;
1490 }
struct ast_bridge_features * bridge_features
Definition: control.c:70
unsigned int dtmf_passthrough
int stasis_app_control_add_channel_to_bridge ( struct stasis_app_control control,
struct ast_bridge bridge 
)

Add a channel to the bridge.

Parameters
controlControl whose channel should be added to the bridge
bridgePointer to the bridge
Returns
non-zero on failure
zero on success

Definition at line 1405 of file control.c.

References ast_debug, control_add_channel_to_bridge(), and stasis_app_control_get_channel_id().

Referenced by ast_ari_bridges_add_channel().

1407 {
1408  ast_debug(3, "%s: Sending channel add_to_bridge command\n",
1410 
1411  return app_send_command_on_condition(
1412  control, control_add_channel_to_bridge, bridge, NULL,
1413  app_control_can_add_channel_to_bridge);
1414 }
int control_add_channel_to_bridge(struct stasis_app_control *control, struct ast_channel *chan, void *data)
Command callback for adding a channel to a bridge.
Definition: control.c:1400
#define ast_debug(level,...)
Log a DEBUG message.
const char * stasis_app_control_get_channel_id(const struct stasis_app_control *control)
Returns the uniqueid of the channel associated with this control.
Definition: control.c:1452
int stasis_app_control_add_role ( struct stasis_app_control control,
const char *  role 
)

Apply a bridge role to a channel controlled by a stasis app control.

Parameters
controlControl for res_stasis
roleRole to apply
Returns
0 for success
-1 for error.

Definition at line 338 of file control.c.

References ast_free_ptr(), ast_strdup, and stasis_app_send_command_async().

Referenced by ast_ari_bridges_add_channel().

339 {
340  char *role_dup;
341 
342  role_dup = ast_strdup(role);
343  if (!role_dup) {
344  return -1;
345  }
346 
347  stasis_app_send_command_async(control, app_control_add_role, role_dup, ast_free_ptr);
348 
349  return 0;
350 }
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
void ast_free_ptr(void *ptr)
free() wrapper
Definition: main/astmm.c:1739
int stasis_app_send_command_async(struct stasis_app_control *control, stasis_app_command_cb command_fn, void *data, command_data_destructor_fn data_destructor)
Asynchronous version of stasis_app_send_command().
Definition: control.c:926
int stasis_app_control_bridge_features_init ( struct stasis_app_control control)

Initialize bridge features into a channel control.

Note
Bridge features on a control are destroyed after each bridge session, so new features need to be initialized before each bridge add.
Parameters
controlControl in which to store the features
Returns
non-zero on failure
zero on success

Definition at line 1473 of file control.c.

References ast_bridge_features_new(), and stasis_app_control::bridge_features.

Referenced by ast_ari_bridges_add_channel().

1475 {
1476  struct ast_bridge_features *features;
1477 
1478  features = ast_bridge_features_new();
1479  if (!features) {
1480  return 1;
1481  }
1482  control->bridge_features = features;
1483  return 0;
1484 }
Structure that contains features information.
struct ast_bridge_features * bridge_features
Definition: control.c:70
struct ast_bridge_features * ast_bridge_features_new(void)
Allocate a new bridge features struct.
Definition: bridge.c:3683
void stasis_app_control_clear_roles ( struct stasis_app_control control)

Clear bridge roles currently applied to a channel controlled by a stasis app control.

Parameters
controlControl for res_stasis

Definition at line 360 of file control.c.

References stasis_app_send_command_async().

Referenced by ast_ari_bridges_add_channel().

361 {
362  stasis_app_send_command_async(control, app_control_clear_roles, NULL, NULL);
363 }
int stasis_app_send_command_async(struct stasis_app_control *control, stasis_app_command_cb command_fn, void *data, command_data_destructor_fn data_destructor)
Asynchronous version of stasis_app_send_command().
Definition: control.c:926
int stasis_app_control_continue ( struct stasis_app_control control,
const char *  context,
const char *  extension,
int  priority 
)

Exit res_stasis and continue execution in the dialplan.

If the channel is no longer in res_stasis, this function does nothing.

Parameters
controlControl for res_stasis
contextAn optional context to continue to
extensionAn optional extension to continue to
priorityAn optional priority to continue to
Returns
0 for success
-1 for error.

Definition at line 411 of file control.c.

References ast_calloc, ast_copy_string(), ast_free_ptr(), S_OR, and stasis_app_send_command_async().

Referenced by ast_ari_channels_continue_in_dialplan().

412 {
413  struct stasis_app_control_continue_data *continue_data;
414 
415  if (!(continue_data = ast_calloc(1, sizeof(*continue_data)))) {
416  return -1;
417  }
418  ast_copy_string(continue_data->context, S_OR(context, ""), sizeof(continue_data->context));
419  ast_copy_string(continue_data->extension, S_OR(extension, ""), sizeof(continue_data->extension));
420  if (priority > 0) {
421  continue_data->priority = priority;
422  } else {
423  continue_data->priority = -1;
424  }
425 
426  stasis_app_send_command_async(control, app_control_continue, continue_data, ast_free_ptr);
427 
428  return 0;
429 }
void ast_free_ptr(void *ptr)
free() wrapper
Definition: main/astmm.c:1739
structure to hold extensions
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
#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
int stasis_app_send_command_async(struct stasis_app_control *control, stasis_app_command_cb command_fn, void *data, command_data_destructor_fn data_destructor)
Asynchronous version of stasis_app_send_command().
Definition: control.c:926
int stasis_app_control_dial ( struct stasis_app_control control,
const char *  dialstring,
unsigned int  timeout 
)

Dial a channel.

Parameters
controlControl for res_stasis.
dialstringThe dialstring to pass to the channel driver
timeoutOptional timeout in milliseconds

Definition at line 1688 of file control.c.

References stasis_app_send_command_async().

Referenced by ast_ari_channels_dial().

1690 {
1691  struct control_dial_args *args;
1692 
1693  args = control_dial_args_alloc(dialstring, timeout);
1694  if (!args) {
1695  return -1;
1696  }
1697 
1698  return stasis_app_send_command_async(control, app_control_dial,
1699  args, control_dial_args_destroy);
1700 }
int stasis_app_send_command_async(struct stasis_app_control *control, stasis_app_command_cb command_fn, void *data, command_data_destructor_fn data_destructor)
Asynchronous version of stasis_app_send_command().
Definition: control.c:926
int stasis_app_control_dtmf ( struct stasis_app_control control,
const char *  dtmf,
int  before,
int  between,
unsigned int  duration,
int  after 
)

Send DTMF to the channel associated with this control.

Parameters
controlControl for res_stasis.
dtmfDTMF string.
beforeAmount of time to wait before sending DTMF digits.
betweenAmount of time between each DTMF digit.
durationAmount of time each DTMF digit lasts for.
afterAmount of time to wait after sending DTMF digits.
Returns
0 for success.
-1 for error.

Definition at line 587 of file control.c.

References ast_calloc, ast_free_ptr(), and stasis_app_send_command_async().

Referenced by ast_ari_channels_send_dtmf().

588 {
589  struct stasis_app_control_dtmf_data *dtmf_data;
590 
591  if (!(dtmf_data = ast_calloc(1, sizeof(*dtmf_data) + strlen(dtmf) + 1))) {
592  return -1;
593  }
594 
595  dtmf_data->before = before;
596  dtmf_data->between = between;
597  dtmf_data->duration = duration;
598  dtmf_data->after = after;
599  strcpy(dtmf_data->dtmf, dtmf);
600 
601  stasis_app_send_command_async(control, app_control_dtmf, dtmf_data, ast_free_ptr);
602 
603  return 0;
604 }
void ast_free_ptr(void *ptr)
free() wrapper
Definition: main/astmm.c:1739
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
int stasis_app_send_command_async(struct stasis_app_control *control, stasis_app_command_cb command_fn, void *data, command_data_destructor_fn data_destructor)
Asynchronous version of stasis_app_send_command().
Definition: control.c:926
const char* stasis_app_control_get_channel_id ( const struct stasis_app_control control)

Returns the uniqueid of the channel associated with this control.

Parameters
controlControl object.
Returns
Uniqueid of the associate channel.
Return values
NULLif control is NULL.

Definition at line 1452 of file control.c.

References stasis_app_control::channel.

Referenced by control_compare(), control_hash(), control_silence_stop_now(), control_swap_channel_in_bridge(), stasis_app_control_add_channel_to_bridge(), stasis_app_control_answer(), stasis_app_control_get_snapshot(), stasis_app_control_play_uri(), stasis_app_control_record(), and stasis_app_control_remove_channel_from_bridge().

1454 {
1455  return ast_channel_uniqueid(control->channel);
1456 }
struct ast_channel * channel
Definition: control.c:62
struct ast_channel_snapshot* stasis_app_control_get_snapshot ( const struct stasis_app_control control)

Returns the most recent snapshot for the associated channel.

The returned pointer is AO2 managed, so ao2_cleanup() when you're done.

Parameters
controlControl for res_stasis.
Returns
Most recent snapshot. ao2_cleanup() when done.
Return values
NULLif channel isn't in cache.

Definition at line 882 of file control.c.

References ast_channel_snapshot_get_latest(), and stasis_app_control_get_channel_id().

Referenced by ari_bridges_play_helper(), ast_ari_channels_continue_in_dialplan(), and channel_state_invalid().

884 {
886 }
const char * stasis_app_control_get_channel_id(const struct stasis_app_control *control)
Returns the uniqueid of the channel associated with this control.
Definition: control.c:1452
struct ast_channel_snapshot * ast_channel_snapshot_get_latest(const char *uniqueid)
Obtain the latest ast_channel_snapshot from the Stasis Message Bus API cache. This is an ao2 object...
void stasis_app_control_hold ( struct stasis_app_control control)

Place the channel associated with the control on hold.

Parameters
controlControl for res_stasis.

Definition at line 770 of file control.c.

References stasis_app_send_command_async().

Referenced by ast_ari_channels_hold().

771 {
772  stasis_app_send_command_async(control, app_control_hold, NULL, NULL);
773 }
int stasis_app_send_command_async(struct stasis_app_control *control, stasis_app_command_cb command_fn, void *data, command_data_destructor_fn data_destructor)
Asynchronous version of stasis_app_send_command().
Definition: control.c:926
void stasis_app_control_inhibit_colp_in_bridge ( struct stasis_app_control control,
int  inhibit_colp 
)

Set whether COLP frames should be generated when joining the bridge.

Since
18
Parameters
controlControl whose channel should have its COLP frames inhibited when bridged
inhibit_colpWhether COLP frames should be generated (0) or not (1).

Definition at line 1498 of file control.c.

References stasis_app_control::bridge_features, and ast_bridge_features::inhibit_colp.

Referenced by ast_ari_bridges_add_channel().

1500 {
1501  control->bridge_features->inhibit_colp = inhibit_colp;
1502 }
unsigned int inhibit_colp
struct ast_bridge_features * bridge_features
Definition: control.c:70
void stasis_app_control_moh_start ( struct stasis_app_control control,
const char *  moh_class 
)

Play music on hold to a channel (does not affect hold status)

Parameters
controlControl for res_stasis.
moh_classclass of music on hold to play (NULL allowed)

Definition at line 802 of file control.c.

References ast_free_ptr(), ast_strdup, and stasis_app_send_command_async().

Referenced by ast_ari_channels_start_moh().

803 {
804  char *data = NULL;
805 
806  if (!ast_strlen_zero(moh_class)) {
807  data = ast_strdup(moh_class);
808  }
809 
810  stasis_app_send_command_async(control, app_control_moh_start, data, ast_free_ptr);
811 }
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
void ast_free_ptr(void *ptr)
free() wrapper
Definition: main/astmm.c:1739
int stasis_app_send_command_async(struct stasis_app_control *control, stasis_app_command_cb command_fn, void *data, command_data_destructor_fn data_destructor)
Asynchronous version of stasis_app_send_command().
Definition: control.c:926
void stasis_app_control_moh_stop ( struct stasis_app_control control)

Stop playing music on hold to a channel (does not affect hold status)

Parameters
controlControl for res_stasis.

Definition at line 820 of file control.c.

References stasis_app_send_command_async().

Referenced by ast_ari_channels_stop_moh().

821 {
822  stasis_app_send_command_async(control, app_control_moh_stop, NULL, NULL);
823 }
int stasis_app_send_command_async(struct stasis_app_control *control, stasis_app_command_cb command_fn, void *data, command_data_destructor_fn data_destructor)
Asynchronous version of stasis_app_send_command().
Definition: control.c:926
int stasis_app_control_move ( struct stasis_app_control control,
const char *  app_name,
const char *  app_args 
)

Exit res_stasis and move to another Stasis application.

If the channel is no longer in res_stasis, this function does nothing.

Parameters
controlControl for res_stasis
app_nameThe name of the application to switch to
app_argsThe list of arguments to pass to the application
Returns
0 for success
-1 for error

Definition at line 473 of file control.c.

References ast_calloc, ast_free_ptr(), and stasis_app_send_command_async().

Referenced by ast_ari_channels_move().

474 {
475  struct stasis_app_control_move_data *move_data;
476  size_t size;
477 
478  size = sizeof(*move_data) + strlen(app_name) + 1;
479  if (app_args) {
480  /* Application arguments are optional */
481  size += strlen(app_args) + 1;
482  }
483 
484  if (!(move_data = ast_calloc(1, size))) {
485  return -1;
486  }
487 
488  move_data->app_name = (char *)move_data + sizeof(*move_data);
489  strcpy(move_data->app_name, app_name); /* Safe */
490 
491  if (app_args) {
492  move_data->app_args = move_data->app_name + strlen(app_name) + 1;
493  strcpy(move_data->app_args, app_args); /* Safe */
494  } else {
495  move_data->app_args = NULL;
496  }
497 
498  stasis_app_send_command_async(control, app_control_move, move_data, ast_free_ptr);
499 
500  return 0;
501 }
void ast_free_ptr(void *ptr)
free() wrapper
Definition: main/astmm.c:1739
const char * app_name(struct ast_app *app)
Definition: pbx_app.c:463
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
int stasis_app_send_command_async(struct stasis_app_control *control, stasis_app_command_cb command_fn, void *data, command_data_destructor_fn data_destructor)
Asynchronous version of stasis_app_send_command().
Definition: control.c:926
int stasis_app_control_mute ( struct stasis_app_control control,
unsigned int  direction,
enum ast_frame_type  frametype 
)

Mute the channel associated with this control.

Parameters
controlControl for res_stasis.
directionThe direction in which the audio should be muted.
frametypeThe type of stream that should be muted.
Returns
0 for success
-1 for error.

Definition at line 653 of file control.c.

References ast_calloc, ast_free_ptr(), and stasis_app_send_command_async().

Referenced by ast_ari_channels_mute().

654 {
655  struct stasis_app_control_mute_data *mute_data;
656 
657  if (!(mute_data = ast_calloc(1, sizeof(*mute_data)))) {
658  return -1;
659  }
660 
661  mute_data->direction = direction;
662  mute_data->frametype = frametype;
663 
664  stasis_app_send_command_async(control, app_control_mute, mute_data, ast_free_ptr);
665 
666  return 0;
667 }
void ast_free_ptr(void *ptr)
free() wrapper
Definition: main/astmm.c:1739
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
int stasis_app_send_command_async(struct stasis_app_control *control, stasis_app_command_cb command_fn, void *data, command_data_destructor_fn data_destructor)
Asynchronous version of stasis_app_send_command().
Definition: control.c:926
void stasis_app_control_mute_in_bridge ( struct stasis_app_control control,
int  mute 
)

Set whether audio from the channel is muted instead of passing through to the bridge.

Parameters
controlControl whose channel should have its audio muted when bridged
muteWhether audio should be muted (1) instead of passed through (0).

Definition at line 1492 of file control.c.

References stasis_app_control::bridge_features, and ast_bridge_features::mute.

Referenced by ast_ari_bridges_add_channel().

1494 {
1495  control->bridge_features->mute = mute;
1496 }
struct ast_bridge_features * bridge_features
Definition: control.c:70
void stasis_app_control_publish ( struct stasis_app_control control,
struct stasis_message message 
)

Publish a message to the control's channel's topic.

Parameters
controlControl to publish to
messageMessage to publish

Definition at line 1458 of file control.c.

References ast_channel_topic(), stasis_app_control::channel, and stasis_publish().

1460 {
1461  if (!control || !control->channel || !message) {
1462  return;
1463  }
1464  stasis_publish(ast_channel_topic(control->channel), message);
1465 }
struct ast_channel * channel
Definition: control.c:62
struct stasis_topic * ast_channel_topic(struct ast_channel *chan)
A topic which publishes the events for a particular channel.
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic's subscribers.
Definition: stasis.c:1511
int stasis_app_control_queue_control ( struct stasis_app_control control,
enum ast_control_frame_type  frame_type 
)

Queue a control frame without payload.

Parameters
controlControl to publish to.
frame_typetype of control frame.
Returns
zero on success
non-zero on failure

Definition at line 1467 of file control.c.

References ast_queue_control(), and stasis_app_control::channel.

1469 {
1470  return ast_queue_control(control->channel, frame_type);
1471 }
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
Definition: channel.c:1231
struct ast_channel * channel
Definition: control.c:62
int stasis_app_control_redirect ( struct stasis_app_control control,
const char *  endpoint 
)

Redirect a channel in res_stasis to a particular endpoint.

Parameters
controlControl for res_stasis
endpointThe endpoint transfer string where the channel should be sent to
Returns
0 for success
-1 for error

Definition at line 522 of file control.c.

References ast_free_ptr(), ast_strdup, and stasis_app_send_command_async().

Referenced by ast_ari_channels_redirect().

523 {
524  char *endpoint_data = ast_strdup(endpoint);
525 
526  if (!endpoint_data) {
527  return -1;
528  }
529 
530  stasis_app_send_command_async(control, app_control_redirect, endpoint_data, ast_free_ptr);
531 
532  return 0;
533 }
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
void ast_free_ptr(void *ptr)
free() wrapper
Definition: main/astmm.c:1739
int stasis_app_send_command_async(struct stasis_app_control *control, stasis_app_command_cb command_fn, void *data, command_data_destructor_fn data_destructor)
Asynchronous version of stasis_app_send_command().
Definition: control.c:926
void stasis_app_control_register_add_rule ( struct stasis_app_control control,
struct stasis_app_control_rule rule 
)

Registers an add channel to bridge rule.

Parameters
controlControl object
ruleThe rule to register

Definition at line 232 of file control.c.

References stasis_app_control::add_rules.

Referenced by stasis_app_control_record().

235 {
236  return app_control_register_rule(control, &control->add_rules, rule);
237 }
struct app_control_rules add_rules
Definition: control.c:78
void stasis_app_control_register_remove_rule ( struct stasis_app_control control,
struct stasis_app_control_rule rule 
)

Registers a remove channel from bridge rule.

Parameters
controlControl object
ruleThe rule to register

Definition at line 246 of file control.c.

References stasis_app_control::remove_rules.

249 {
250  return app_control_register_rule(control, &control->remove_rules, rule);
251 }
struct app_control_rules remove_rules
Definition: control.c:82
int stasis_app_control_remove_channel_from_bridge ( struct stasis_app_control control,
struct ast_bridge bridge 
)

Remove a channel from the bridge.

Parameters
controlControl whose channel should be removed from the bridge
bridgePointer to the bridge
Returns
non-zero on failure
zero on success

Definition at line 1442 of file control.c.

References ast_debug, and stasis_app_control_get_channel_id().

Referenced by ast_ari_bridges_remove_channel().

1444 {
1445  ast_debug(3, "%s: Sending channel remove_from_bridge command\n",
1447  return app_send_command_on_condition(
1448  control, app_control_remove_channel_from_bridge, bridge, NULL,
1449  app_control_can_remove_channel_from_bridge);
1450 }
#define ast_debug(level,...)
Log a DEBUG message.
const char * stasis_app_control_get_channel_id(const struct stasis_app_control *control)
Returns the uniqueid of the channel associated with this control.
Definition: control.c:1452
int stasis_app_control_ring ( struct stasis_app_control control)

Indicate ringing to the channel associated with this control.

Parameters
controlControl for res_stasis.
Returns
0 for success.
-1 for error.

Definition at line 614 of file control.c.

References stasis_app_send_command_async().

Referenced by ast_ari_channels_ring().

615 {
616  stasis_app_send_command_async(control, app_control_ring, NULL, NULL);
617 
618  return 0;
619 }
int stasis_app_send_command_async(struct stasis_app_control *control, stasis_app_command_cb command_fn, void *data, command_data_destructor_fn data_destructor)
Asynchronous version of stasis_app_send_command().
Definition: control.c:926
int stasis_app_control_ring_stop ( struct stasis_app_control control)

Stop locally generated ringing on the channel associated with this control.

Parameters
controlControl for res_stasis.
Returns
0 for success.
-1 for error.

Definition at line 629 of file control.c.

References stasis_app_send_command_async().

Referenced by ast_ari_channels_ring_stop().

630 {
631  stasis_app_send_command_async(control, app_control_ring_stop, NULL, NULL);
632 
633  return 0;
634 }
int stasis_app_send_command_async(struct stasis_app_control *control, stasis_app_command_cb command_fn, void *data, command_data_destructor_fn data_destructor)
Asynchronous version of stasis_app_send_command().
Definition: control.c:926
int stasis_app_control_set_channel_var ( struct stasis_app_control control,
const char *  variable,
const char *  value 
)

Set a variable on the channel associated with this control to value.

Parameters
controlControl for res_stasis.
variableThe name of the variable
valueThe value to set the variable to
Returns
0 for success.
-1 for error.

Definition at line 733 of file control.c.

References ast_calloc, ast_strdup, chanvar::name, stasis_app_send_command_async(), and chanvar::value.

Referenced by ast_ari_channels_set_channel_var().

734 {
735  struct chanvar *var;
736 
737  var = ast_calloc(1, sizeof(*var));
738  if (!var) {
739  return -1;
740  }
741 
742  var->name = ast_strdup(variable);
743  if (!var->name) {
744  free_chanvar(var);
745  return -1;
746  }
747 
748  /* It's kosher for value to be NULL. It means the variable is being unset */
749  if (value) {
750  var->value = ast_strdup(value);
751  if (!var->value) {
752  free_chanvar(var);
753  return -1;
754  }
755  }
756 
757  stasis_app_send_command_async(control, app_control_set_channel_var, var, free_chanvar);
758 
759  return 0;
760 }
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
char * value
Definition: control.c:711
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
structure for queuing ARI channel variable setting
Definition: control.c:707
char * name
Definition: control.c:709
int stasis_app_send_command_async(struct stasis_app_control *control, stasis_app_command_cb command_fn, void *data, command_data_destructor_fn data_destructor)
Asynchronous version of stasis_app_send_command().
Definition: control.c:926
void stasis_app_control_shutdown ( void  )

Let Stasis app internals shut down.

This is called when res_stasis is unloaded. It ensures that the Stasis app internals can free any resources they may have allocated during the time that res_stasis was loaded.

Definition at line 1702 of file control.c.

References ast_bridge_destroy(), and shutting_down.

1703 {
1704  ast_mutex_lock(&dial_bridge_lock);
1705  shutting_down = 1;
1706  if (dial_bridge) {
1708  dial_bridge = NULL;
1709  }
1710  ast_mutex_unlock(&dial_bridge_lock);
1711 }
int ast_bridge_destroy(struct ast_bridge *bridge, int cause)
Destroy a bridge.
Definition: bridge.c:944
static int shutting_down
Indicates if the Stasis app internals are being shut down.
Definition: control.c:51
static struct ast_bridge * dial_bridge
Singleton dial bridge.
Definition: control.c:980
void stasis_app_control_silence_start ( struct stasis_app_control control)

Start playing silence to a channel.

Parameters
controlControl for res_stasis.

Definition at line 854 of file control.c.

References stasis_app_send_command_async().

Referenced by ast_ari_channels_start_silence().

855 {
856  stasis_app_send_command_async(control, app_control_silence_start, NULL, NULL);
857 }
int stasis_app_send_command_async(struct stasis_app_control *control, stasis_app_command_cb command_fn, void *data, command_data_destructor_fn data_destructor)
Asynchronous version of stasis_app_send_command().
Definition: control.c:926
void stasis_app_control_silence_stop ( struct stasis_app_control control)

Stop playing silence to a channel.

Parameters
controlControl for res_stasis.

Definition at line 877 of file control.c.

References stasis_app_send_command_async().

Referenced by ast_ari_channels_stop_silence().

878 {
879  stasis_app_send_command_async(control, app_control_silence_stop, NULL, NULL);
880 }
int stasis_app_send_command_async(struct stasis_app_control *control, stasis_app_command_cb command_fn, void *data, command_data_destructor_fn data_destructor)
Asynchronous version of stasis_app_send_command().
Definition: control.c:926
void stasis_app_control_unhold ( struct stasis_app_control control)

Remove the channel associated with the control from hold.

Parameters
controlControl for res_stasis.

Definition at line 783 of file control.c.

References stasis_app_send_command_async().

Referenced by ast_ari_channels_unhold().

784 {
785  stasis_app_send_command_async(control, app_control_unhold, NULL, NULL);
786 }
int stasis_app_send_command_async(struct stasis_app_control *control, stasis_app_command_cb command_fn, void *data, command_data_destructor_fn data_destructor)
Asynchronous version of stasis_app_send_command().
Definition: control.c:926
int stasis_app_control_unmute ( struct stasis_app_control control,
unsigned int  direction,
enum ast_frame_type  frametype 
)

Unmute the channel associated with this control.

Parameters
controlControl for res_stasis.
directionThe direction in which the audio should be unmuted.
frametypeThe type of stream that should be unmuted.
Returns
0 for success
-1 for error.

Definition at line 681 of file control.c.

References ast_calloc, ast_free_ptr(), and stasis_app_send_command_async().

Referenced by ast_ari_channels_unmute().

682 {
683  struct stasis_app_control_mute_data *mute_data;
684 
685  if (!(mute_data = ast_calloc(1, sizeof(*mute_data)))) {
686  return -1;
687  }
688 
689  mute_data->direction = direction;
690  mute_data->frametype = frametype;
691 
692  stasis_app_send_command_async(control, app_control_unmute, mute_data, ast_free_ptr);
693 
694  return 0;
695 }
void ast_free_ptr(void *ptr)
free() wrapper
Definition: main/astmm.c:1739
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
int stasis_app_send_command_async(struct stasis_app_control *control, stasis_app_command_cb command_fn, void *data, command_data_destructor_fn data_destructor)
Asynchronous version of stasis_app_send_command().
Definition: control.c:926
void stasis_app_control_unregister_add_rule ( struct stasis_app_control control,
struct stasis_app_control_rule rule 
)

UnRegister an add channel to bridge rule.

Parameters
controlControl object
ruleThe rule to unregister

Definition at line 239 of file control.c.

References stasis_app_control::add_rules.

242 {
243  app_control_unregister_rule(control, &control->add_rules, rule);
244 }
struct app_control_rules add_rules
Definition: control.c:78
void stasis_app_control_unregister_remove_rule ( struct stasis_app_control control,
struct stasis_app_control_rule rule 
)

Unregisters a remove channel from bridge rule.

Parameters
controlControl object
ruleThe rule to unregister

Definition at line 253 of file control.c.

References stasis_app_control::remove_rules.

256 {
257  app_control_unregister_rule(control, &control->remove_rules, rule);
258 }
struct app_control_rules remove_rules
Definition: control.c:82
struct ast_bridge* stasis_app_get_bridge ( struct stasis_app_control control)

Gets the bridge currently associated with a control object.

Since
12
Note
If the bridge returned by this function is to be held for any length of time, its refcount should be incremented until the caller is finished with it.
Parameters
controlControl object for the channel to query.
Returns
Associated ast_bridge.
Return values
NULLif not associated with a bridge.

Definition at line 953 of file control.c.

References stasis_app_control::bridge.

Referenced by ast_ari_bridges_remove_channel(), ast_ari_bridges_set_video_source(), control_swap_channel_in_bridge(), and stasis_app_exec().

954 {
955  struct ast_bridge *ret;
956 
957  if (!control) {
958  return NULL;
959  }
960 
961  ao2_lock(control);
962  ret = control->bridge;
963  ao2_unlock(control);
964 
965  return ret;
966 }
Structure that contains information about a bridge.
Definition: bridge.h:349
struct ast_bridge * bridge
Definition: control.c:66
int stasis_app_send_command ( struct stasis_app_control control,
stasis_app_command_cb  command,
void *  data,
command_data_destructor_fn  data_destructor 
)

Invokes a command on a control's channel.

Since
12 This function dispatches the command to be executed in the context of stasis_app_exec(), so this command will block waiting for the results of the command.
Parameters
controlControl object for the channel to send the command to.
commandCommand function to execute.
dataOptional data to pass along with the control function.
data_destructorOptional function which will be called on the data in either the event of command completion or failure to schedule or complete the command
Returns
zero on success.
error code otherwise.

Definition at line 920 of file control.c.

Referenced by ast_ari_bridges_set_video_source(), and stasis_app_control_answer().

922 {
923  return app_send_command_on_condition(control, command_fn, data, data_destructor, NULL);
924 }
int stasis_app_send_command_async ( struct stasis_app_control control,
stasis_app_command_cb  command,
void *  data,
command_data_destructor_fn  data_destructor 
)

Asynchronous version of stasis_app_send_command().

Since
12 This function enqueues a command for execution, but returns immediately without waiting for the response.
Parameters
controlControl object for the channel to send the command to.
commandCommand function to execute.
dataOptional data to pass along with the control function.
data_destructorOptional function which will be called on the data in either the event of command completion or failure to schedule or complete the command
Returns
0 on success.
Non-zero on error.

Definition at line 926 of file control.c.

References ao2_ref, and stasis_app_control::is_done.

Referenced by bridge_timeout(), dial_bridge_after_cb(), stasis_app_control_add_role(), stasis_app_control_clear_roles(), stasis_app_control_continue(), stasis_app_control_dial(), stasis_app_control_dtmf(), stasis_app_control_hold(), stasis_app_control_moh_start(), stasis_app_control_moh_stop(), stasis_app_control_move(), stasis_app_control_mute(), stasis_app_control_play_uri(), stasis_app_control_record(), stasis_app_control_redirect(), stasis_app_control_ring(), stasis_app_control_ring_stop(), stasis_app_control_set_channel_var(), stasis_app_control_silence_start(), stasis_app_control_silence_stop(), stasis_app_control_unhold(), and stasis_app_control_unmute().

929 {
930  struct stasis_app_command *command;
931 
932  if (control == NULL || control->is_done) {
933  /* If exec_command fails, it calls the data_destructor. In order to
934  * provide consistent behavior, we'll also call the data_destructor
935  * on this error path. This way, callers never have to call the
936  * data_destructor themselves.
937  */
938  if (data_destructor) {
939  data_destructor(data);
940  }
941  return -1;
942  }
943 
944  command = exec_command(control, command_fn, data, data_destructor);
945  if (!command) {
946  return -1;
947  }
948  ao2_ref(command, -1);
949 
950  return 0;
951 }
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
unsigned int is_done
Definition: control.c:108

Variable Documentation

struct ast_bridge* dial_bridge
static

Singleton dial bridge.

The dial bridge is a holding bridge used to hold all outbound dialed channels that are not in any "real" ARI-created bridge. The dial bridge is invisible, meaning that it does not show up in channel snapshots, AMI or ARI output, and no events get raised for it.

This is used to keep dialed channels confined to the bridging system and unify the threading model used for dialing outbound channels.

Definition at line 980 of file control.c.

struct ast_datastore_info timeout_datastore
Initial value:
= {
.type = "ARI dial timeout",
}

Dial timeout datastore.

A datastore is used because a channel may change bridges during the course of a dial attempt. This may be because the channel changes from the dial bridge to a standard bridge, or it may move between standard bridges. In order to keep the dial timeout, we need to keep the timeout information local to the channel. That is what this datastore is for

Definition at line 1214 of file control.c.