Asterisk - The Open Source Telephony Project  18.5.0
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 dependency graph for control.c:

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_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. More...
 
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

◆ app_command_can_exec_cb

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 265 of file control.c.

Function Documentation

◆ add_to_dial_bridge()

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 1041 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(), dial_bridge_after_cb_failed(), get_dial_bridge(), and NULL.

Referenced by app_control_dial(), and depart_channel().

1042 {
1043  struct ast_bridge *bridge;
1044 
1045  bridge = get_dial_bridge();
1046  if (!bridge) {
1047  return -1;
1048  }
1049 
1050  control->bridge = bridge;
1053  control->bridge = NULL;
1054  ao2_ref(bridge, -1);
1055  return -1;
1056  }
1057 
1058  ao2_ref(bridge, -1);
1059 
1060  return 0;
1061 }
static void dial_bridge_after_cb_failed(enum ast_bridge_after_cb_reason reason, void *data)
Definition: control.c:1025
#define NULL
Definition: resample.c:96
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:259
static void dial_bridge_after_cb(struct ast_channel *chan, void *data)
after bridge callback for the dial bridge
Definition: control.c:1009
static struct ast_bridge * get_dial_bridge(void)
Retrieve a reference to the dial bridge.
Definition: control.c:974
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:1924
#define ao2_ref(o, delta)
Definition: astobj2.h:464
Structure that contains information about a bridge.
Definition: bridge.h:357
struct ast_bridge * bridge
Definition: control.c:64

◆ app_control_add_role()

static int app_control_add_role ( struct stasis_app_control control,
struct ast_channel chan,
void *  data 
)
static

Definition at line 308 of file control.c.

References ast_channel_add_bridge_role(), and stasis_app_command::data.

Referenced by stasis_app_control_add_role().

310 {
311  char *role = data;
312 
313  return ast_channel_add_bridge_role(chan, role);
314 }
int ast_channel_add_bridge_role(struct ast_channel *chan, const char *role_name)
Adds a bridge role to a channel.
Definition: bridge_roles.c:317

◆ app_control_can_add_channel_to_bridge()

static int app_control_can_add_channel_to_bridge ( struct stasis_app_control control)
static

Definition at line 245 of file control.c.

References stasis_app_control::add_rules, and app_control_check_rules().

Referenced by stasis_app_control_add_channel_to_bridge().

247 {
248  return app_control_check_rules(control, &control->add_rules);
249 }
static enum stasis_app_control_channel_result app_control_check_rules(const struct stasis_app_control *control, struct app_control_rules *list)
Definition: control.c:203
struct app_control_rules add_rules
Definition: control.c:76

◆ app_control_can_remove_channel_from_bridge()

static int app_control_can_remove_channel_from_bridge ( struct stasis_app_control control)
static

Definition at line 251 of file control.c.

References app_control_check_rules(), and stasis_app_control::remove_rules.

Referenced by stasis_app_control_remove_channel_from_bridge().

253 {
254  return app_control_check_rules(control, &control->remove_rules);
255 }
struct app_control_rules remove_rules
Definition: control.c:80
static enum stasis_app_control_channel_result app_control_check_rules(const struct stasis_app_control *control, struct app_control_rules *list)
Definition: control.c:203

◆ app_control_check_rules()

static enum stasis_app_control_channel_result app_control_check_rules ( const struct stasis_app_control control,
struct app_control_rules list 
)
static

Definition at line 203 of file control.c.

References AST_LIST_TRAVERSE, stasis_app_control_rule::check_rule, and stasis_app_control_rule::next.

Referenced by app_control_can_add_channel_to_bridge(), and app_control_can_remove_channel_from_bridge().

206 {
207  int res = 0;
209  AST_LIST_TRAVERSE(list, rule, next) {
210  if ((res = rule->check_rule(control))) {
211  return res;
212  }
213  }
214  return res;
215 }
enum stasis_app_control_channel_result(* check_rule)(const struct stasis_app_control *control)
Checks to see if an operation is allowed on the control.
Definition: stasis_app.h:352
Rule to check to see if an operation is allowed.
Definition: stasis_app.h:345
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
struct stasis_app_control_rule * next
Definition: stasis_app.h:355

◆ app_control_clear_roles()

static int app_control_clear_roles ( struct stasis_app_control control,
struct ast_channel chan,
void *  data 
)
static

Definition at line 330 of file control.c.

References ast_channel_clear_bridge_roles().

Referenced by stasis_app_control_clear_roles().

332 {
334 
335  return 0;
336 }
void ast_channel_clear_bridge_roles(struct ast_channel *chan)
Removes all bridge roles currently on a channel.
Definition: bridge_roles.c:360

◆ app_control_continue()

static int app_control_continue ( struct stasis_app_control control,
struct ast_channel chan,
void *  data 
)
static

Definition at line 368 of file control.c.

References ast_assert, ast_bridge_depart(), ast_explicit_goto(), stasis_app_control::channel, stasis_app_control_continue_data::context, control_mark_done(), stasis_app_control_continue_data::extension, NULL, stasis_app_control_continue_data::priority, and stasis_app_get_bridge().

Referenced by stasis_app_control_continue().

370 {
371  struct stasis_app_control_continue_data *continue_data = data;
372 
373  ast_assert(control->channel != NULL);
374 
375  /* If we're in a Stasis bridge, depart it before going back to the
376  * dialplan */
377  if (stasis_app_get_bridge(control)) {
378  ast_bridge_depart(control->channel);
379  }
380 
381  /* Called from stasis_app_exec thread; no lock needed */
382  ast_explicit_goto(control->channel, continue_data->context, continue_data->extension, continue_data->priority);
383 
384  control_mark_done(control);
385 
386  return 0;
387 }
void control_mark_done(struct stasis_app_control *control)
Definition: control.c:354
struct ast_bridge * stasis_app_get_bridge(struct stasis_app_control *control)
Gets the bridge currently associated with a control object.
Definition: control.c:931
int ast_explicit_goto(struct ast_channel *chan, const char *context, const char *exten, int priority)
Definition: pbx.c:6987
#define ast_assert(a)
Definition: utils.h:695
#define NULL
Definition: resample.c:96
struct ast_channel * channel
Definition: control.c:60
char context[AST_MAX_CONTEXT]
Definition: control.c:363
char extension[AST_MAX_EXTENSION]
Definition: control.c:364
int ast_bridge_depart(struct ast_channel *chan)
Depart a channel from a bridge.
Definition: bridge.c:1952

◆ app_control_dial()

static int app_control_dial ( struct stasis_app_control control,
struct ast_channel chan,
void *  data 
)
static

Definition at line 1628 of file control.c.

References add_to_dial_bridge(), args, ast_bridge_setup_after_goto(), ast_call(), ast_channel_is_bridged(), ast_channel_lock, ast_channel_publish_dial(), ast_channel_unlock, AST_SOFTHANGUP_ASYNCGOTO, AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), control_dial_args::dialstring, NULL, set_timeout(), and control_dial_args::timeout.

Referenced by stasis_app_control_dial().

1630 {
1631  struct control_dial_args *args = data;
1632  int bridged;
1633 
1634  ast_channel_lock(chan);
1635  bridged = ast_channel_is_bridged(chan);
1636  ast_channel_unlock(chan);
1637 
1638  if (!bridged && add_to_dial_bridge(control, chan)) {
1639  return -1;
1640  }
1641 
1642  if (args->timeout && set_timeout(chan, args->timeout)) {
1643  return -1;
1644  }
1645 
1646  if (ast_call(chan, args->dialstring, 0)) {
1647  /* If call fails normally this channel would then just be normally hung up and destroyed.
1648  * In this case though the channel is being handled by the ARI control thread and dial
1649  * bridge which needs to be notified that the channel should be hung up. To do this we
1650  * queue a soft hangup which will cause each to wake up, see that the channel has been
1651  * hung up, and then destroy it.
1652  */
1653  int hangup_flag;
1655  ast_channel_lock(chan);
1656  ast_softhangup_nolock(chan, hangup_flag);
1657  ast_channel_unlock(chan);
1658  return -1;
1659  }
1660 
1662 
1663  return 0;
1664 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
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...
int ast_call(struct ast_channel *chan, const char *addr, int timeout)
Make a call.
Definition: channel.c:6553
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:1041
const char * args
#define NULL
Definition: resample.c:96
char dialstring[0]
Definition: control.c:1570
unsigned int timeout
Definition: control.c:1569
static int set_timeout(struct ast_channel *chan, unsigned int timeout)
Set dial timeout on a channel to be dialed.
Definition: control.c:1603
int ast_softhangup_nolock(struct ast_channel *chan, int reason)
Softly hangup up a channel (no channel lock)
Definition: channel.c:2463
int ast_channel_is_bridged(const struct ast_channel *chan)
Determine if a channel is in a bridge.
Definition: channel.c:10746
#define ast_channel_unlock(chan)
Definition: channel.h:2946
int ast_bridge_setup_after_goto(struct ast_channel *chan)
Setup any after bridge goto location to begin execution.
Definition: bridge_after.c:447

◆ app_control_dtmf()

static int app_control_dtmf ( struct stasis_app_control control,
struct ast_channel chan,
void *  data 
)
static

Definition at line 547 of file control.c.

References AST_CONTROL_PROGRESS, ast_indicate(), AST_STATE_UP, dtmf_in_bridge(), dtmf_no_bridge(), and stasis_app_get_bridge().

Referenced by stasis_app_control_dtmf().

549 {
550  struct stasis_app_control_dtmf_data *dtmf_data = data;
551 
552  if (ast_channel_state(chan) != AST_STATE_UP) {
554  }
555 
556  if (stasis_app_get_bridge(control)) {
557  dtmf_in_bridge(chan, dtmf_data);
558  } else {
559  dtmf_no_bridge(chan, dtmf_data);
560  }
561 
562  return 0;
563 }
static void dtmf_no_bridge(struct ast_channel *chan, struct stasis_app_control_dtmf_data *dtmf_data)
Definition: control.c:534
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4322
struct ast_bridge * stasis_app_get_bridge(struct stasis_app_control *control)
Gets the bridge currently associated with a control object.
Definition: control.c:931
ast_channel_state
ast_channel states
Definition: channelstate.h:35
static void dtmf_in_bridge(struct ast_channel *chan, struct stasis_app_control_dtmf_data *dtmf_data)
Definition: control.c:521

◆ app_control_hold()

static int app_control_hold ( struct stasis_app_control control,
struct ast_channel chan,
void *  data 
)
static

Definition at line 740 of file control.c.

References AST_CONTROL_HOLD, ast_indicate(), and stasis_app_control::channel.

Referenced by stasis_app_control_hold().

742 {
744 
745  return 0;
746 }
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4322
struct ast_channel * channel
Definition: control.c:60

◆ app_control_moh_start()

static int app_control_moh_start ( struct stasis_app_control control,
struct ast_channel chan,
void *  data 
)
static

Definition at line 766 of file control.c.

References AST_CONTROL_PROGRESS, ast_indicate(), ast_moh_start(), AST_STATE_UP, and NULL.

Referenced by stasis_app_control_moh_start().

768 {
769  char *moh_class = data;
770 
771  if (ast_channel_state(chan) != AST_STATE_UP) {
773  }
774 
775  ast_moh_start(chan, moh_class, NULL);
776 
777  return 0;
778 }
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4322
ast_channel_state
ast_channel states
Definition: channelstate.h:35
#define NULL
Definition: resample.c:96
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:7866

◆ app_control_moh_stop()

static int app_control_moh_stop ( struct stasis_app_control control,
struct ast_channel chan,
void *  data 
)
static

Definition at line 791 of file control.c.

References ast_moh_stop().

Referenced by stasis_app_control_moh_stop().

793 {
794  ast_moh_stop(chan);
795  return 0;
796 }
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:7876

◆ app_control_move()

static int app_control_move ( struct stasis_app_control control,
struct ast_channel chan,
void *  data 
)
static

Definition at line 414 of file control.c.

References stasis_app_control_move_data::app_args, stasis_app_control_move_data::app_name, ast_free, ast_log, ast_strdup, AST_VECTOR_APPEND, control_move_cleanup(), LOG_ERROR, and stasis_app_control::next_app.

Referenced by stasis_app_control_move().

416 {
417  struct stasis_app_control_move_data *move_data = data;
418 
419  control->next_app = ast_strdup(move_data->app_name);
420  if (!control->next_app) {
421  ast_log(LOG_ERROR, "Allocation failed for next app\n");
422  return -1;
423  }
424 
425  if (move_data->app_args) {
426  char *token;
427 
428  while ((token = strtok_r(move_data->app_args, ",", &move_data->app_args))) {
429  int res;
430  char *arg;
431 
432  if (!(arg = ast_strdup(token))) {
433  ast_log(LOG_ERROR, "Allocation failed for next app arg\n");
434  control_move_cleanup(control);
435  return -1;
436  }
437 
438  res = AST_VECTOR_APPEND(&control->next_app_args, arg);
439  if (res) {
440  ast_log(LOG_ERROR, "Failed to append arg to next app args\n");
441  ast_free(arg);
442  control_move_cleanup(control);
443  return -1;
444  }
445  }
446  }
447 
448  return 0;
449 }
char * next_app
Definition: control.c:94
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define ast_log
Definition: astobj2.c:42
void control_move_cleanup(struct stasis_app_control *control)
Free any memory that was allocated for switching applications via /channels/{channelId}/move.
Definition: control.c:1702
#define LOG_ERROR
Definition: logger.h:285
#define ast_free(a)
Definition: astmm.h:182

◆ app_control_mute()

static int app_control_mute ( struct stasis_app_control control,
struct ast_channel chan,
void *  data 
)
static

Definition at line 619 of file control.c.

References ast_channel_lock, ast_channel_suppress(), ast_channel_unlock, stasis_app_control::channel, stasis_app_control_mute_data::direction, and stasis_app_control_mute_data::frametype.

Referenced by stasis_app_control_mute().

621 {
622  struct stasis_app_control_mute_data *mute_data = data;
623 
624  ast_channel_lock(chan);
625  ast_channel_suppress(control->channel, mute_data->direction, mute_data->frametype);
626  ast_channel_unlock(chan);
627 
628  return 0;
629 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
int ast_channel_suppress(struct ast_channel *chan, unsigned int direction, enum ast_frame_type frametype)
Suppress passing of a frame type on a channel.
Definition: channel.c:10978
struct ast_channel * channel
Definition: control.c:60
enum ast_frame_type frametype
Definition: control.c:615
#define ast_channel_unlock(chan)
Definition: channel.h:2946

◆ app_control_redirect()

static int app_control_redirect ( struct stasis_app_control control,
struct ast_channel chan,
void *  data 
)
static

Definition at line 481 of file control.c.

References ast_assert, ast_channel_name(), ast_log, ast_transfer(), stasis_app_control::channel, LOG_NOTICE, and NULL.

Referenced by stasis_app_control_redirect().

483 {
484  char *endpoint = data;
485  int res;
486 
487  ast_assert(control->channel != NULL);
488  ast_assert(endpoint != NULL);
489 
490  res = ast_transfer(control->channel, endpoint);
491  if (!res) {
492  ast_log(LOG_NOTICE, "Unsupported transfer requested on channel '%s'\n",
493  ast_channel_name(control->channel));
494  return 0;
495  }
496 
497  return 0;
498 }
#define ast_assert(a)
Definition: utils.h:695
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
struct ast_channel * channel
Definition: control.c:60
#define LOG_NOTICE
Definition: logger.h:263
const char * ast_channel_name(const struct ast_channel *chan)
int ast_transfer(struct ast_channel *chan, char *dest)
Transfer a channel (if supported).
Definition: channel.c:6577

◆ app_control_register_rule()

static void app_control_register_rule ( struct stasis_app_control control,
struct app_control_rules list,
struct stasis_app_control_rule obj 
)
static

Definition at line 162 of file control.c.

References ao2_lock, ao2_unlock, AST_LIST_INSERT_TAIL, and stasis_app_control::command_queue.

Referenced by stasis_app_control_register_add_rule(), and stasis_app_control_register_remove_rule().

165 {
166  ao2_lock(control->command_queue);
167  AST_LIST_INSERT_TAIL(list, obj, next);
168  ao2_unlock(control->command_queue);
169 }
#define ao2_unlock(a)
Definition: astobj2.h:730
#define ao2_lock(a)
Definition: astobj2.h:718
struct ao2_container * command_queue
Definition: control.c:54
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730

◆ app_control_remove_channel_from_bridge()

static int app_control_remove_channel_from_bridge ( struct stasis_app_control control,
struct ast_channel chan,
void *  data 
)
static

Definition at line 1394 of file control.c.

References ast_debug, ast_log, stasis_app_control::bridge, depart_channel(), LOG_WARNING, stasis_app_control_get_channel_id(), stasis_app_get_bridge(), and ast_bridge::uniqueid.

Referenced by stasis_app_control_remove_channel_from_bridge().

1397 {
1398  struct ast_bridge *bridge = data;
1399 
1400  if (!control) {
1401  return -1;
1402  }
1403 
1404  /* We should only depart from our own bridge */
1405  ast_debug(3, "%s: Departing bridge %s\n",
1407  bridge->uniqueid);
1408 
1409  if (bridge != stasis_app_get_bridge(control)) {
1410  ast_log(LOG_WARNING, "%s: Not in bridge %s; not removing\n",
1412  bridge->uniqueid);
1413  return -1;
1414  }
1415 
1416  depart_channel(control, chan);
1417  return 0;
1418 }
const ast_string_field uniqueid
Definition: bridge.h:409
#define LOG_WARNING
Definition: logger.h:274
struct ast_bridge * stasis_app_get_bridge(struct stasis_app_control *control)
Gets the bridge currently associated with a control object.
Definition: control.c:931
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
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.
Definition: control.c:1069
Structure that contains information about a bridge.
Definition: bridge.h:357
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:1430

◆ app_control_ring()

static int app_control_ring ( struct stasis_app_control control,
struct ast_channel chan,
void *  data 
)
static

Definition at line 584 of file control.c.

References AST_CONTROL_RINGING, ast_indicate(), and stasis_app_control::channel.

Referenced by stasis_app_control_ring().

586 {
588 
589  return 0;
590 }
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4322
struct ast_channel * channel
Definition: control.c:60

◆ app_control_ring_stop()

static int app_control_ring_stop ( struct stasis_app_control control,
struct ast_channel chan,
void *  data 
)
static

Definition at line 599 of file control.c.

References ast_indicate(), and stasis_app_control::channel.

Referenced by stasis_app_control_ring_stop().

601 {
602  ast_indicate(control->channel, -1);
603 
604  return 0;
605 }
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4322
struct ast_channel * channel
Definition: control.c:60

◆ app_control_set_channel_var()

static int app_control_set_channel_var ( struct stasis_app_control control,
struct ast_channel chan,
void *  data 
)
static

Definition at line 701 of file control.c.

References stasis_app_control::channel, chanvar::name, pbx_builtin_setvar_helper(), chanvar::value, and var.

Referenced by stasis_app_control_set_channel_var().

703 {
704  struct chanvar *var = data;
705 
706  pbx_builtin_setvar_helper(control->channel, var->name, var->value);
707 
708  return 0;
709 }
#define var
Definition: ast_expr2f.c:614
char * value
Definition: control.c:689
struct ast_channel * channel
Definition: control.c:60
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...
structure for queuing ARI channel variable setting
Definition: control.c:685
char * name
Definition: control.c:687

◆ app_control_silence_start()

static int app_control_silence_start ( struct stasis_app_control control,
struct ast_channel chan,
void *  data 
)
static

Definition at line 803 of file control.c.

References ast_channel_start_silence_generator(), ast_channel_stop_silence_generator(), AST_CONTROL_PROGRESS, ast_debug, ast_indicate(), ast_log, AST_STATE_UP, stasis_app_control::channel, LOG_WARNING, stasis_app_control::silgen, and stasis_app_control_get_channel_id().

Referenced by stasis_app_control_silence_start().

805 {
806  if (ast_channel_state(chan) != AST_STATE_UP) {
808  }
809 
810  if (control->silgen) {
811  /* We have a silence generator, but it may have been implicitly
812  * disabled by media actions (music on hold, playing media,
813  * etc.) Just stop it and restart a new one.
814  */
816  control->channel, control->silgen);
817  }
818 
819  ast_debug(3, "%s: Starting silence generator\n",
822 
823  if (!control->silgen) {
825  "%s: Failed to start silence generator.\n",
827  }
828 
829  return 0;
830 }
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4322
#define LOG_WARNING
Definition: logger.h:274
ast_channel_state
ast_channel states
Definition: channelstate.h:35
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
struct ast_channel * channel
Definition: control.c:60
struct ast_silence_generator * ast_channel_start_silence_generator(struct ast_channel *chan)
Starts a silence generator on the given channel.
Definition: channel.c:8266
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:1430
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:8312
struct ast_silence_generator * silgen
Definition: control.c:84

◆ app_control_silence_stop()

static int app_control_silence_stop ( struct stasis_app_control control,
struct ast_channel chan,
void *  data 
)
static

Definition at line 848 of file control.c.

References control_silence_stop_now().

Referenced by stasis_app_control_silence_stop().

850 {
851  control_silence_stop_now(control);
852  return 0;
853 }
void control_silence_stop_now(struct stasis_app_control *control)
Stop playing silence to a channel right now.
Definition: control.c:837

◆ app_control_unhold()

static int app_control_unhold ( struct stasis_app_control control,
struct ast_channel chan,
void *  data 
)
static

Definition at line 753 of file control.c.

References AST_CONTROL_UNHOLD, ast_indicate(), and stasis_app_control::channel.

Referenced by stasis_app_control_unhold().

755 {
757 
758  return 0;
759 }
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4322
struct ast_channel * channel
Definition: control.c:60

◆ app_control_unmute()

static int app_control_unmute ( struct stasis_app_control control,
struct ast_channel chan,
void *  data 
)
static

Definition at line 647 of file control.c.

References ast_channel_lock, ast_channel_unlock, ast_channel_unsuppress(), stasis_app_control::channel, stasis_app_control_mute_data::direction, and stasis_app_control_mute_data::frametype.

Referenced by stasis_app_control_unmute().

649 {
650  struct stasis_app_control_mute_data *mute_data = data;
651 
652  ast_channel_lock(chan);
653  ast_channel_unsuppress(control->channel, mute_data->direction, mute_data->frametype);
654  ast_channel_unlock(chan);
655 
656  return 0;
657 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
struct ast_channel * channel
Definition: control.c:60
enum ast_frame_type frametype
Definition: control.c:615
#define ast_channel_unlock(chan)
Definition: channel.h:2946
int ast_channel_unsuppress(struct ast_channel *chan, unsigned int direction, enum ast_frame_type frametype)
Stop suppressing of a frame type on a channel.
Definition: channel.c:11040

◆ app_control_unregister_rule()

static void app_control_unregister_rule ( struct stasis_app_control control,
struct app_control_rules list,
struct stasis_app_control_rule obj 
)
static

Definition at line 171 of file control.c.

References ao2_lock, ao2_unlock, AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, stasis_app_control::command_queue, and stasis_app_control_rule::next.

Referenced by stasis_app_control_unregister_add_rule(), and stasis_app_control_unregister_remove_rule().

174 {
176 
177  ao2_lock(control->command_queue);
178  AST_RWLIST_TRAVERSE_SAFE_BEGIN(list, rule, next) {
179  if (rule == obj) {
181  break;
182  }
183  }
185  ao2_unlock(control->command_queue);
186 }
#define ao2_unlock(a)
Definition: astobj2.h:730
#define ao2_lock(a)
Definition: astobj2.h:718
#define AST_RWLIST_REMOVE_CURRENT
Definition: linkedlists.h:569
Rule to check to see if an operation is allowed.
Definition: stasis_app.h:345
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:544
struct ao2_container * command_queue
Definition: control.c:54
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:616
struct stasis_app_control_rule * next
Definition: stasis_app.h:355

◆ app_send_command_on_condition()

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

Definition at line 866 of file control.c.

References ao2_ref, command_join(), stasis_app_command::data_destructor, exec_command_on_condition(), and NULL.

Referenced by stasis_app_control_add_channel_to_bridge(), stasis_app_control_remove_channel_from_bridge(), and stasis_app_send_command().

870 {
871  int ret;
872  struct stasis_app_command *command;
873 
874  if (control == NULL || control->is_done) {
875  /* If exec_command_on_condition fails, it calls the data_destructor.
876  * In order to provide consistent behavior, we'll also call the data_destructor
877  * on this error path. This way, callers never have to call the
878  * data_destructor themselves.
879  */
880  if (data_destructor) {
882  }
883  return -1;
884  }
885 
886  command = exec_command_on_condition(
887  control, command_fn, data, data_destructor, can_exec_fn);
888  if (!command) {
889  return -1;
890  }
891 
892  ret = command_join(command);
893  ao2_ref(command, -1);
894 
895  return ret;
896 }
#define NULL
Definition: resample.c:96
command_data_destructor_fn data_destructor
Definition: command.c:38
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static struct stasis_app_command * exec_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)
Definition: control.c:267
int command_join(struct stasis_app_command *command)
Definition: command.c:86

◆ bridge_after_cb()

static void bridge_after_cb ( struct ast_channel chan,
void *  data 
)
static

Definition at line 1163 of file control.c.

References AST_BRIDGE_AFTER_CB_REASON_DEPART, stasis_app_control::channel, and internal_bridge_after_cb().

Referenced by control_swap_channel_in_bridge().

1164 {
1165  struct stasis_app_control *control = data;
1166 
1168 }
struct ast_channel * channel
Definition: control.c:60
static void internal_bridge_after_cb(struct ast_channel *chan, void *data, enum ast_bridge_after_cb_reason reason)
Definition: control.c:1108

◆ bridge_after_cb_failed()

static void bridge_after_cb_failed ( enum ast_bridge_after_cb_reason  reason,
void *  data 
)
static

Definition at line 1170 of file control.c.

References ast_bridge_after_cb_reason_string(), ast_debug, stasis_app_control::channel, and internal_bridge_after_cb().

Referenced by control_swap_channel_in_bridge().

1172 {
1173  struct stasis_app_control *control = data;
1174 
1175  internal_bridge_after_cb(control->channel, data, reason);
1176 
1177  ast_debug(3, " reason: %s\n",
1179 }
const char * ast_bridge_after_cb_reason_string(enum ast_bridge_after_cb_reason reason)
Get a string representation of an after bridge callback reason.
Definition: bridge_after.c:296
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
struct ast_channel * channel
Definition: control.c:60
static void internal_bridge_after_cb(struct ast_channel *chan, void *data, enum ast_bridge_after_cb_reason reason)
Definition: control.c:1108

◆ bridge_channel_depart()

static int bridge_channel_depart ( struct stasis_app_control control,
struct ast_channel chan,
void *  data 
)
static

Definition at line 1085 of file control.c.

References ast_channel_internal_bridge_channel(), ast_channel_lock, ast_channel_uniqueid(), ast_channel_unlock, ast_debug, and depart_channel().

Referenced by dial_bridge_after_cb(), get_dial_bridge(), and internal_bridge_after_cb().

1087 {
1088  struct ast_bridge_channel *bridge_channel;
1089 
1090  ast_channel_lock(chan);
1091  bridge_channel = ast_channel_internal_bridge_channel(chan);
1092  ast_channel_unlock(chan);
1093 
1094  if (bridge_channel != data) {
1095  ast_debug(3, "%s: Channel is no longer in departable state\n",
1096  ast_channel_uniqueid(chan));
1097  return -1;
1098  }
1099 
1100  ast_debug(3, "%s: Channel departing bridge\n",
1101  ast_channel_uniqueid(chan));
1102 
1103  depart_channel(control, chan);
1104 
1105  return 0;
1106 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
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.
Definition: control.c:1069
struct ast_bridge_channel * ast_channel_internal_bridge_channel(const struct ast_channel *chan)
const char * ast_channel_uniqueid(const struct ast_channel *chan)
#define ast_channel_unlock(chan)
Definition: channel.h:2946
Structure that contains information regarding a channel in a bridge.

◆ bridge_timeout()

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 1215 of file control.c.

References ao2_cleanup, ast_channel_datastore_find(), ast_channel_datastore_remove(), ast_channel_lock, ast_channel_unlock, ast_datastore_free(), AST_STATE_UP, ast_bridge_channel::chan, hangup_channel(), NULL, RAII_VAR, stasis_app_control_find_by_channel(), and stasis_app_send_command_async().

Referenced by set_interval_hook().

1216 {
1217  struct ast_datastore *datastore;
1218  RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
1219 
1220  control = stasis_app_control_find_by_channel(bridge_channel->chan);
1221 
1222  ast_channel_lock(bridge_channel->chan);
1223  if (ast_channel_state(bridge_channel->chan) != AST_STATE_UP) {
1224  /* Don't bother removing the datastore because it will happen when the channel is hung up */
1225  ast_channel_unlock(bridge_channel->chan);
1227  return -1;
1228  }
1229 
1230  datastore = ast_channel_datastore_find(bridge_channel->chan, &timeout_datastore, NULL);
1231  if (!datastore) {
1232  ast_channel_unlock(bridge_channel->chan);
1233  return -1;
1234  }
1235  ast_channel_datastore_remove(bridge_channel->chan, datastore);
1236  ast_channel_unlock(bridge_channel->chan);
1237  ast_datastore_free(datastore);
1238 
1239  return -1;
1240 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
ast_channel_state
ast_channel states
Definition: channelstate.h:35
static int hangup_channel(struct stasis_app_control *control, struct ast_channel *chan, void *data)
Definition: control.c:1196
Structure for a data store object.
Definition: datastore.h:68
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:2404
#define NULL
Definition: resample.c:96
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
#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:911
#define ast_channel_unlock(chan)
Definition: channel.h:2946
struct ast_channel * chan
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
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:904
struct ast_datastore_info timeout_datastore
Dial timeout datastore.
Definition: control.c:1192
int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore)
Remove a datastore from a channel.
Definition: channel.c:2399
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

◆ control_add_channel_to_bridge()

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 1378 of file control.c.

References control_swap_channel_in_bridge(), and NULL.

Referenced by stasis_app_control_add_channel_to_bridge().

1379 {
1380  return control_swap_channel_in_bridge(control, data, chan, NULL);
1381 }
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:1284
#define NULL
Definition: resample.c:96
void * data
Definition: datastore.h:70

◆ control_app()

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 1563 of file control.c.

References stasis_app_control::app.

Referenced by bridge_stasis_moving(), bridge_stasis_push_peek(), channel_replaced_cb(), channel_stolen_cb(), and stasis_app_exec().

1564 {
1565  return control->app;
1566 }
struct stasis_app * app
Definition: control.c:90

◆ control_command_count()

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
Return values
numberof commands in the command que

Definition at line 343 of file control.c.

References ao2_container_count(), and stasis_app_control::command_queue.

Referenced by stasis_app_control_execute_until_exhausted().

344 {
345  return ao2_container_count(control->command_queue);
346 }
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
struct ao2_container * command_queue
Definition: control.c:54

◆ control_create()

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.
NULL on error.

Definition at line 123 of file control.c.

References stasis_app_control::add_rules, ao2_alloc, AO2_ALLOC_OPT_LOCK_MUTEX, ao2_bump, ao2_container_alloc_list, ao2_ref, stasis_app_control::app, ast_channel_ref, ast_cond_init, AST_LIST_HEAD_INIT, ast_log, AST_VECTOR_INIT, stasis_app_control::channel, stasis_app_control::command_queue, control_dtor(), errno, LOG_ERROR, stasis_app_control::next_app, NULL, stasis_app_control::remove_rules, and stasis_app_control::wait_cond.

Referenced by stasis_app_control_create(), and stasis_app_exec().

124 {
125  struct stasis_app_control *control;
126  int res;
127 
128  control = ao2_alloc(sizeof(*control), control_dtor);
129  if (!control) {
130  return NULL;
131  }
132 
133  AST_LIST_HEAD_INIT(&control->add_rules);
134  AST_LIST_HEAD_INIT(&control->remove_rules);
135 
136  res = ast_cond_init(&control->wait_cond, NULL);
137  if (res != 0) {
138  ast_log(LOG_ERROR, "Error initializing ast_cond_t: %s\n",
139  strerror(errno));
140  ao2_ref(control, -1);
141  return NULL;
142  }
143 
144  control->app = ao2_bump(app);
145 
146  ast_channel_ref(channel);
147  control->channel = channel;
148 
151  if (!control->command_queue) {
152  ao2_ref(control, -1);
153  return NULL;
154  }
155 
156  control->next_app = NULL;
157  AST_VECTOR_INIT(&control->next_app_args, 0);
158 
159  return control;
160 }
ast_cond_t wait_cond
Definition: control.c:52
char * next_app
Definition: control.c:94
struct app_control_rules remove_rules
Definition: control.c:80
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Definition: astobj2.h:1335
#define ast_cond_init(cond, attr)
Definition: lock.h:199
#define NULL
Definition: resample.c:96
struct stasis_app * app
Definition: control.c:90
#define ao2_bump(obj)
Definition: astobj2.h:491
#define ast_log
Definition: astobj2.c:42
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_channel * channel
Definition: control.c:60
struct ao2_container * command_queue
Definition: control.c:54
#define LOG_ERROR
Definition: logger.h:285
int errno
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
#define AST_LIST_HEAD_INIT(head)
Initializes a list head structure.
Definition: linkedlists.h:625
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2970
static void control_dtor(void *obj)
Definition: control.c:105
struct app_control_rules add_rules
Definition: control.c:76

◆ control_dial_args_alloc()

static struct control_dial_args* control_dial_args_alloc ( const char *  dialstring,
unsigned int  timeout 
)
static

Definition at line 1573 of file control.c.

References args, ast_malloc, control_dial_args::dialstring, NULL, timeout, and control_dial_args::timeout.

Referenced by stasis_app_control_dial().

1575 {
1576  struct control_dial_args *args;
1577 
1578  args = ast_malloc(sizeof(*args) + strlen(dialstring) + 1);
1579  if (!args) {
1580  return NULL;
1581  }
1582 
1583  args->timeout = timeout;
1584  /* Safe */
1585  strcpy(args->dialstring, dialstring);
1586 
1587  return args;
1588 }
static int timeout
Definition: cdr_mysql.c:86
const char * args
#define NULL
Definition: resample.c:96
char dialstring[0]
Definition: control.c:1570
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
unsigned int timeout
Definition: control.c:1569

◆ control_dial_args_destroy()

static void control_dial_args_destroy ( void *  data)
static

Definition at line 1590 of file control.c.

References args, and ast_free.

Referenced by stasis_app_control_dial().

1591 {
1592  struct control_dial_args *args = data;
1593 
1594  ast_free(args);
1595 }
const char * args
#define ast_free(a)
Definition: astmm.h:182

◆ control_dispatch_all()

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 1495 of file control.c.

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

Referenced by stasis_app_control_execute_until_exhausted(), and stasis_app_exec().

1497 {
1498  int count = 0;
1499  struct ao2_iterator iter;
1500  struct stasis_app_command *command;
1501 
1502  ast_assert(control->channel == chan);
1503 
1505  while ((command = ao2_iterator_next(&iter))) {
1506  command_invoke(command, control, chan);
1507  ao2_ref(command, -1);
1508  ++count;
1509  }
1510  ao2_iterator_destroy(&iter);
1511 
1512  return count;
1513 }
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ast_assert(a)
Definition: utils.h:695
void command_invoke(struct stasis_app_command *command, struct stasis_app_control *control, struct ast_channel *chan)
Definition: command.c:101
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_channel * channel
Definition: control.c:60
struct ao2_container * command_queue
Definition: control.c:54
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.

◆ control_dtor()

static void control_dtor ( void *  obj)
static

Definition at line 105 of file control.c.

References stasis_app_control::add_rules, ao2_cleanup, stasis_app_control::app, ast_bridge_features_destroy(), ast_channel_cleanup, ast_cond_destroy, AST_LIST_HEAD_DESTROY, stasis_app_control::bridge_features, stasis_app_control::channel, stasis_app_control::command_queue, control_move_cleanup(), stasis_app_control::remove_rules, and stasis_app_control::wait_cond.

Referenced by control_create().

106 {
107  struct stasis_app_control *control = obj;
108 
109  ao2_cleanup(control->command_queue);
110 
111  ast_channel_cleanup(control->channel);
112  ao2_cleanup(control->app);
113 
114  control_move_cleanup(control);
115 
116  ast_cond_destroy(&control->wait_cond);
117  AST_LIST_HEAD_DESTROY(&control->add_rules);
120 
121 }
ast_cond_t wait_cond
Definition: control.c:52
struct app_control_rules remove_rules
Definition: control.c:80
void ast_bridge_features_destroy(struct ast_bridge_features *features)
Destroy an allocated bridge features struct.
Definition: bridge.c:3741
struct stasis_app * app
Definition: control.c:90
#define AST_LIST_HEAD_DESTROY(head)
Destroys a list head structure.
Definition: linkedlists.h:652
void control_move_cleanup(struct stasis_app_control *control)
Free any memory that was allocated for switching applications via /channels/{channelId}/move.
Definition: control.c:1702
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:2992
struct ast_channel * channel
Definition: control.c:60
struct ast_bridge_features * bridge_features
Definition: control.c:68
struct ao2_container * command_queue
Definition: control.c:54
#define ast_cond_destroy(cond)
Definition: lock.h:200
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct app_control_rules add_rules
Definition: control.c:76

◆ control_flush_queue()

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.
Returns
Nothing

Definition at line 1482 of file control.c.

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

Referenced by stasis_app_control_flush_queue(), and stasis_app_exec().

1483 {
1484  struct ao2_iterator iter;
1485  struct stasis_app_command *command;
1486 
1488  while ((command = ao2_iterator_next(&iter))) {
1489  command_complete(command, -1);
1490  ao2_ref(command, -1);
1491  }
1492  ao2_iterator_destroy(&iter);
1493 }
void command_complete(struct stasis_app_command *command, int retval)
Definition: command.c:77
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ao2_container * command_queue
Definition: control.c:54
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.

◆ control_is_done()

int control_is_done ( struct stasis_app_control control)

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

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

Definition at line 348 of file control.c.

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

349 {
350  /* Called from stasis_app_exec thread; no lock needed */
351  return control->is_done;
352 }

◆ control_mark_done()

void control_mark_done ( struct stasis_app_control control)

Definition at line 354 of file control.c.

References ao2_lock, ao2_unlock, and stasis_app_control::command_queue.

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

355 {
356  /* Locking necessary to sync with other threads adding commands to the queue. */
357  ao2_lock(control->command_queue);
358  control->is_done = 1;
359  ao2_unlock(control->command_queue);
360 }
#define ao2_unlock(a)
Definition: astobj2.h:730
#define ao2_lock(a)
Definition: astobj2.h:718
struct ao2_container * command_queue
Definition: control.c:54

◆ control_move_cleanup()

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 1702 of file control.c.

References ast_free, ast_free_ptr(), AST_VECTOR_RESET, stasis_app_control::next_app, and NULL.

Referenced by app_control_move(), control_dtor(), and stasis_app_exec().

1703 {
1704  ast_free(control->next_app);
1705  control->next_app = NULL;
1706 
1707  AST_VECTOR_RESET(&control->next_app_args, ast_free_ptr);
1708 }
char * next_app
Definition: control.c:94
#define NULL
Definition: resample.c:96
void ast_free_ptr(void *ptr)
free() wrapper
Definition: astmm.c:1771
#define ast_free(a)
Definition: astmm.h:182
#define AST_VECTOR_RESET(vec, cleanup)
Reset vector.
Definition: vector.h:627

◆ control_next_app()

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 1697 of file control.c.

References stasis_app_control::next_app.

Referenced by stasis_app_exec().

1698 {
1699  return control->next_app;
1700 }
char * next_app
Definition: control.c:94

◆ control_next_app_args()

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 1710 of file control.c.

References AST_VECTOR_STEAL_ELEMENTS.

Referenced by stasis_app_exec().

1711 {
1712  return AST_VECTOR_STEAL_ELEMENTS(&control->next_app_args);
1713 }
#define AST_VECTOR_STEAL_ELEMENTS(vec)
Steal the elements from a vector and reinitialize.
Definition: vector.h:140

◆ control_next_app_args_size()

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 1715 of file control.c.

References AST_VECTOR_SIZE.

Referenced by stasis_app_exec().

1716 {
1717  return AST_VECTOR_SIZE(&control->next_app_args);
1718 }
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611

◆ control_prestart_dispatch_all()

int control_prestart_dispatch_all ( struct stasis_app_control control,
struct ast_channel chan 
)

Dispatch all queued prestart commands.

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

Definition at line 1535 of file control.c.

References ao2_cleanup, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, AO2_ITERATOR_UNLINK, ast_channel_lock, ast_channel_unlock, command_invoke(), command_prestart_get_container(), and stasis_app_control::command_queue.

Referenced by stasis_app_exec().

1537 {
1538  struct ao2_container *command_queue;
1539  int count = 0;
1540  struct ao2_iterator iter;
1541  struct stasis_app_command *command;
1542 
1543  ast_channel_lock(chan);
1544  command_queue = command_prestart_get_container(chan);
1545  ast_channel_unlock(chan);
1546  if (!command_queue) {
1547  return 0;
1548  }
1549 
1550  iter = ao2_iterator_init(command_queue, AO2_ITERATOR_UNLINK);
1551 
1552  while ((command = ao2_iterator_next(&iter))) {
1553  command_invoke(command, control, chan);
1554  ao2_cleanup(command);
1555  ++count;
1556  }
1557 
1558  ao2_iterator_destroy(&iter);
1559  ao2_cleanup(command_queue);
1560  return count;
1561 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
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
void command_invoke(struct stasis_app_command *command, struct stasis_app_control *control, struct ast_channel *chan)
Definition: command.c:101
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
#define ast_channel_unlock(chan)
Definition: channel.h:2946
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
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.

◆ control_set_app()

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 1691 of file control.c.

References ao2_bump, ao2_cleanup, and stasis_app_control::app.

Referenced by stasis_app_exec().

1692 {
1693  ao2_cleanup(control->app);
1694  control->app = ao2_bump(app);
1695 }
struct stasis_app * app
Definition: control.c:90
#define ao2_bump(obj)
Definition: astobj2.h:491
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ control_silence_stop_now()

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 837 of file control.c.

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

Referenced by app_control_silence_stop(), and stasis_app_exec().

838 {
839  if (control->silgen) {
840  ast_debug(3, "%s: Stopping silence generator\n",
843  control->channel, control->silgen);
844  control->silgen = NULL;
845  }
846 }
#define NULL
Definition: resample.c:96
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
struct ast_channel * channel
Definition: control.c:60
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:1430
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:8312
struct ast_silence_generator * silgen
Definition: control.c:84

◆ control_swap_channel_in_bridge()

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 1284 of file control.c.

References ao2_lock, ao2_unlock, stasis_app_control::app, app_subscribe_bridge(), ast_assert, ast_bridge_depart(), ast_bridge_impart(), AST_BRIDGE_IMPART_CHAN_DEPARTABLE, AST_BRIDGE_IMPART_INHIBIT_JOIN_COLP, ast_bridge_set_after_callback(), ast_channel_lock, ast_channel_pbx(), ast_channel_pbx_set(), ast_channel_unlock, ast_debug, ast_log, stasis_app_control::bridge, bridge_after_cb(), bridge_after_cb_failed(), stasis_app_control::bridge_features, ast_bridge_features::inhibit_colp, LOG_ERROR, NULL, 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(), and defer_bridge_add().

1285 {
1286  int res;
1287  struct ast_bridge_features *features;
1289 
1290  if (!control || !bridge) {
1291  return -1;
1292  }
1293 
1294  ast_debug(3, "%s: Adding to bridge %s\n",
1296  bridge->uniqueid);
1297 
1298  ast_assert(chan != NULL);
1299 
1300  /* Depart whatever Stasis bridge we're currently in. */
1301  if (stasis_app_get_bridge(control)) {
1302  /* Note that it looks like there's a race condition here, since
1303  * we don't have control locked. But this happens from the
1304  * control callback thread, so there won't be any other
1305  * concurrent attempts to bridge.
1306  */
1307  ast_bridge_depart(chan);
1308  }
1309 
1310 
1312  bridge_after_cb_failed, control);
1313  if (res != 0) {
1314  ast_log(LOG_ERROR, "Error setting after-bridge callback\n");
1315  return -1;
1316  }
1317 
1318  ao2_lock(control);
1319 
1320  /* Ensure the controlling application is subscribed early enough
1321  * to receive the ChannelEnteredBridge message. This works in concert
1322  * with the subscription handled in the Stasis application execution
1323  * loop */
1324  app_subscribe_bridge(control->app, bridge);
1325 
1326  /* Save off the channel's PBX */
1327  ast_assert(control->pbx == NULL);
1328  if (!control->pbx) {
1329  control->pbx = ast_channel_pbx(chan);
1330  ast_channel_pbx_set(chan, NULL);
1331  }
1332 
1333  /* Pull bridge features from the control */
1334  features = control->bridge_features;
1335  control->bridge_features = NULL;
1336  if (features && features->inhibit_colp) {
1338  }
1339 
1340  ast_assert(stasis_app_get_bridge(control) == NULL);
1341  /* We need to set control->bridge here since bridge_after_cb may be run
1342  * before ast_bridge_impart returns. bridge_after_cb gets a reason
1343  * code so it can tell if the bridge is actually valid or not.
1344  */
1345  control->bridge = bridge;
1346 
1347  /* We can't be holding the control lock while impart is running
1348  * or we could create a deadlock with bridge_after_cb which also
1349  * tries to lock control.
1350  */
1351  ao2_unlock(control);
1352  res = ast_bridge_impart(bridge,
1353  chan,
1354  swap,
1355  features, /* features */
1356  flags);
1357  if (res != 0) {
1358  /* ast_bridge_impart failed before it could spawn the depart
1359  * thread. The callbacks aren't called in this case.
1360  * The impart could still fail even if ast_bridge_impart returned
1361  * ok but that's handled by bridge_after_cb.
1362  */
1363  ast_log(LOG_ERROR, "Error adding channel to bridge\n");
1364  ao2_lock(control);
1365  ast_channel_pbx_set(chan, control->pbx);
1366  control->pbx = NULL;
1367  control->bridge = NULL;
1368  ao2_unlock(control);
1369  } else {
1370  ast_channel_lock(chan);
1371  set_interval_hook(chan);
1372  ast_channel_unlock(chan);
1373  }
1374 
1375  return res;
1376 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
unsigned int inhibit_colp
const ast_string_field uniqueid
Definition: bridge.h:409
Structure that contains features information.
static void bridge_after_cb(struct ast_channel *chan, void *data)
Definition: control.c:1163
struct ast_bridge * stasis_app_get_bridge(struct stasis_app_control *control)
Gets the bridge currently associated with a control object.
Definition: control.c:931
#define ast_assert(a)
Definition: utils.h:695
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
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:259
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:90
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
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:1924
struct ast_pbx * ast_channel_pbx(const struct ast_channel *chan)
#define ao2_lock(a)
Definition: astobj2.h:718
struct ast_bridge_features * bridge_features
Definition: control.c:68
#define LOG_ERROR
Definition: logger.h:285
static void set_interval_hook(struct ast_channel *chan)
Set a dial timeout interval hook on the channel.
Definition: control.c:1254
int ast_bridge_depart(struct ast_channel *chan)
Depart a channel from a bridge.
Definition: bridge.c:1952
static void bridge_after_cb_failed(enum ast_bridge_after_cb_reason reason, void *data)
Definition: control.c:1170
struct ast_pbx * pbx
Definition: control.c:72
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:1430
#define ast_channel_unlock(chan)
Definition: channel.h:2946
struct ast_bridge * bridge
Definition: control.c:64
void ast_channel_pbx_set(struct ast_channel *chan, struct ast_pbx *value)

◆ control_wait()

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 1515 of file control.c.

References ao2_container_count(), ao2_lock, ao2_object_get_lockaddr(), ao2_unlock, ast_assert, ast_cond_wait, ast_log, stasis_app_control::command_queue, LOG_ERROR, NULL, and stasis_app_control::wait_cond.

Referenced by stasis_app_exec().

1516 {
1517  if (!control) {
1518  return;
1519  }
1520 
1521  ast_assert(control->command_queue != NULL);
1522 
1523  ao2_lock(control->command_queue);
1524  while (ao2_container_count(control->command_queue) == 0) {
1525  int res = ast_cond_wait(&control->wait_cond,
1527  if (res < 0) {
1528  ast_log(LOG_ERROR, "Error waiting on command queue\n");
1529  break;
1530  }
1531  }
1532  ao2_unlock(control->command_queue);
1533 }
ast_cond_t wait_cond
Definition: control.c:52
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
#define ast_cond_wait(cond, mutex)
Definition: lock.h:203
#define ast_assert(a)
Definition: utils.h:695
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
void * ao2_object_get_lockaddr(void *obj)
Return the mutex lock address of an object.
Definition: astobj2.c:476
#define ast_log
Definition: astobj2.c:42
#define ao2_lock(a)
Definition: astobj2.h:718
struct ao2_container * command_queue
Definition: control.c:54
#define LOG_ERROR
Definition: logger.h:285

◆ depart_channel()

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 1069 of file control.c.

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

Referenced by app_control_remove_channel_from_bridge(), and bridge_channel_depart().

1070 {
1071  ast_bridge_depart(chan);
1072 
1073  /* Channels which have a PBX are not ones that have been created and dialed from ARI. They
1074  * have externally come in from the dialplan, and thus should not be placed into the dial
1075  * bridge. Only channels which are created and dialed in ARI should go into the dial bridge.
1076  */
1077  if (!ast_check_hangup(chan) && ast_channel_state(chan) != AST_STATE_UP && !ast_channel_pbx(chan)) {
1078  /* Channel is still being dialed, so put it back in the dialing bridge */
1079  add_to_dial_bridge(control, chan);
1080  }
1081 
1082  return 0;
1083 }
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:1041
struct ast_pbx * ast_channel_pbx(const struct ast_channel *chan)
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:1952

◆ dial_bridge_after_cb()

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 1009 of file control.c.

References __ao2_cleanup(), ast_channel_get_bridge_channel(), ast_channel_hangupcause(), ast_channel_lock, ast_channel_name(), ast_channel_unlock, ast_debug, stasis_app_control::bridge, bridge_channel_depart(), stasis_app_control::channel, NULL, and stasis_app_send_command_async().

Referenced by add_to_dial_bridge(), and dial_bridge_after_cb_failed().

1010 {
1011  struct stasis_app_control *control = data;
1012  struct ast_bridge_channel *bridge_channel;
1013 
1014  ast_channel_lock(chan);
1015  bridge_channel = ast_channel_get_bridge_channel(chan);
1016  ast_channel_unlock(chan);
1017 
1018  ast_debug(3, "Channel: <%s> Reason: %d\n", ast_channel_name(control->channel), ast_channel_hangupcause(chan));
1019 
1021 
1022  control->bridge = NULL;
1023 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
void __ao2_cleanup(void *obj)
Definition: astobj2.c:674
#define NULL
Definition: resample.c:96
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
struct ast_channel * channel
Definition: control.c:60
static int bridge_channel_depart(struct stasis_app_control *control, struct ast_channel *chan, void *data)
Definition: control.c:1085
#define ast_channel_unlock(chan)
Definition: channel.h:2946
struct ast_bridge * bridge
Definition: control.c:64
struct ast_bridge_channel * ast_channel_get_bridge_channel(struct ast_channel *chan)
Get a reference to the channel&#39;s bridge pointer.
Definition: channel.c:10783
Structure that contains information regarding a channel in a bridge.
int ast_channel_hangupcause(const struct ast_channel *chan)
const char * ast_channel_name(const 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:904

◆ dial_bridge_after_cb_failed()

static void dial_bridge_after_cb_failed ( enum ast_bridge_after_cb_reason  reason,
void *  data 
)
static

Definition at line 1025 of file control.c.

References ast_channel_name(), ast_debug, stasis_app_control::channel, and dial_bridge_after_cb().

Referenced by add_to_dial_bridge().

1026 {
1027  struct stasis_app_control *control = data;
1028 
1029  ast_debug(3, "Channel: <%s> Reason: %d\n", ast_channel_name(control->channel), reason);
1030  dial_bridge_after_cb(control->channel, data);
1031 }
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static void dial_bridge_after_cb(struct ast_channel *chan, void *data)
after bridge callback for the dial bridge
Definition: control.c:1009
struct ast_channel * channel
Definition: control.c:60
const char * ast_channel_name(const struct ast_channel *chan)

◆ dtmf_in_bridge()

static void dtmf_in_bridge ( struct ast_channel chan,
struct stasis_app_control_dtmf_data dtmf_data 
)
static

Definition at line 521 of file control.c.

References stasis_app_control_dtmf_data::after, ast_dtmf_stream_external(), stasis_app_control_dtmf_data::before, stasis_app_control_dtmf_data::between, stasis_app_control_dtmf_data::dtmf, and stasis_app_control_dtmf_data::duration.

Referenced by app_control_dtmf().

522 {
523  if (dtmf_data->before) {
524  usleep(dtmf_data->before * 1000);
525  }
526 
527  ast_dtmf_stream_external(chan, dtmf_data->dtmf, dtmf_data->between, dtmf_data->duration);
528 
529  if (dtmf_data->after) {
530  usleep(dtmf_data->after * 1000);
531  }
532 }
void ast_dtmf_stream_external(struct ast_channel *chan, const char *digits, int between, unsigned int duration)
Send a string of DTMF digits to a channel from an external thread.
Definition: main/app.c:996

◆ dtmf_no_bridge()

static void dtmf_no_bridge ( struct ast_channel chan,
struct stasis_app_control_dtmf_data dtmf_data 
)
static

Definition at line 534 of file control.c.

References stasis_app_control_dtmf_data::after, ast_dtmf_stream(), ast_safe_sleep(), stasis_app_control_dtmf_data::before, stasis_app_control_dtmf_data::between, stasis_app_control_dtmf_data::dtmf, stasis_app_control_dtmf_data::duration, and NULL.

Referenced by app_control_dtmf().

535 {
536  if (dtmf_data->before) {
537  ast_safe_sleep(chan, dtmf_data->before);
538  }
539 
540  ast_dtmf_stream(chan, NULL, dtmf_data->dtmf, dtmf_data->between, dtmf_data->duration);
541 
542  if (dtmf_data->after) {
543  ast_safe_sleep(chan, dtmf_data->after);
544  }
545 }
int ast_dtmf_stream(struct ast_channel *chan, struct ast_channel *peer, const char *digits, int between, unsigned int duration)
Send a string of DTMF digits to a channel.
Definition: main/app.c:981
int ast_safe_sleep(struct ast_channel *chan, int ms)
Wait for a specified amount of time, looking for hangups.
Definition: channel.c:1574
#define NULL
Definition: resample.c:96

◆ exec_command()

static struct stasis_app_command* exec_command ( struct stasis_app_control control,
stasis_app_command_cb  command_fn,
void *  data,
command_data_destructor_fn  data_destructor 
)
static

Definition at line 301 of file control.c.

References exec_command_on_condition(), and NULL.

Referenced by stasis_app_send_command_async().

304 {
305  return exec_command_on_condition(control, command_fn, data, data_destructor, NULL);
306 }
#define NULL
Definition: resample.c:96
static struct stasis_app_command * exec_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)
Definition: control.c:267

◆ exec_command_on_condition()

static struct stasis_app_command* exec_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

Definition at line 267 of file control.c.

References ao2_link_flags, ao2_lock, ao2_ref, ao2_unlock, ast_cond_signal, command_complete(), command_create(), stasis_app_control::command_queue, noop_cb(), NULL, OBJ_NOLOCK, retval, and stasis_app_control::wait_cond.

Referenced by app_send_command_on_condition(), and exec_command().

271 {
272  int retval;
273  struct stasis_app_command *command;
274 
275  command_fn = command_fn ? : noop_cb;
276 
277  command = command_create(command_fn, data, data_destructor);
278  if (!command) {
279  return NULL;
280  }
281 
282  ao2_lock(control->command_queue);
283  if (control->is_done) {
284  ao2_unlock(control->command_queue);
285  ao2_ref(command, -1);
286  return NULL;
287  }
288  if (can_exec_fn && (retval = can_exec_fn(control))) {
289  ao2_unlock(control->command_queue);
290  command_complete(command, retval);
291  return command;
292  }
293 
294  ao2_link_flags(control->command_queue, command, OBJ_NOLOCK);
295  ast_cond_signal(&control->wait_cond);
296  ao2_unlock(control->command_queue);
297 
298  return command;
299 }
ast_cond_t wait_cond
Definition: control.c:52
static int noop_cb(struct stasis_app_control *control, struct ast_channel *chan, void *data)
Definition: control.c:257
void command_complete(struct stasis_app_command *command, int retval)
Definition: command.c:77
Assume that the ao2_container is already locked.
Definition: astobj2.h:1067
#define ao2_link_flags(container, obj, flags)
Definition: astobj2.h:1572
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
command_data_destructor_fn data_destructor
Definition: command.c:38
#define ast_cond_signal(cond)
Definition: lock.h:201
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
struct ao2_container * command_queue
Definition: control.c:54
struct stasis_app_command * command_create(stasis_app_command_cb callback, void *data, command_data_destructor_fn data_destructor)
Definition: command.c:55
static ENTRY retval
Definition: hsearch.c:50

◆ free_chanvar()

static void free_chanvar ( void *  data)
static

Definition at line 692 of file control.c.

References ast_free, chanvar::name, chanvar::value, and var.

Referenced by stasis_app_control_set_channel_var().

693 {
694  struct chanvar *var = data;
695 
696  ast_free(var->name);
697  ast_free(var->value);
698  ast_free(var);
699 }
#define var
Definition: ast_expr2f.c:614
char * value
Definition: control.c:689
#define ast_free(a)
Definition: astmm.h:182
structure for queuing ARI channel variable setting
Definition: control.c:685
char * name
Definition: control.c:687

◆ get_dial_bridge()

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 974 of file control.c.

References ao2_bump, ast_mutex_lock, ast_mutex_unlock, bridge_channel_depart(), dial_bridge_lock, end, NULL, shutting_down, and stasis_app_bridge_create_invisible().

Referenced by add_to_dial_bridge().

975 {
976  struct ast_bridge *ret_bridge = NULL;
977 
979 
980  if (shutting_down) {
981  goto end;
982  }
983 
984  if (dial_bridge) {
985  ret_bridge = ao2_bump(dial_bridge);
986  goto end;
987  }
988 
989  dial_bridge = stasis_app_bridge_create_invisible("holding", "dial_bridge", NULL);
990  if (!dial_bridge) {
991  goto end;
992  }
993  ret_bridge = ao2_bump(dial_bridge);
994 
995 end:
997  return ret_bridge;
998 }
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:856
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
char * end
Definition: eagi_proxy.c:73
static ast_mutex_t dial_bridge_lock
Definition: control.c:959
#define ao2_bump(obj)
Definition: astobj2.h:491
Structure that contains information about a bridge.
Definition: bridge.h:357
static int shutting_down
Indicates if the Stasis app internals are being shut down.
Definition: control.c:49
static struct ast_bridge * dial_bridge
Singleton dial bridge.
Definition: control.c:958
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ hangup_channel()

static int hangup_channel ( struct stasis_app_control control,
struct ast_channel chan,
void *  data 
)
static

Definition at line 1196 of file control.c.

References ast_softhangup(), and AST_SOFTHANGUP_EXPLICIT.

Referenced by bridge_timeout().

1198 {
1200  return 0;
1201 }
int ast_softhangup(struct ast_channel *chan, int reason)
Softly hangup up a channel.
Definition: channel.c:2476

◆ internal_bridge_after_cb()

static void internal_bridge_after_cb ( struct ast_channel chan,
void *  data,
enum ast_bridge_after_cb_reason  reason 
)
static

Definition at line 1108 of file control.c.

References __ao2_cleanup(), ao2_lock, ao2_unlock, stasis_app_control::app, app_unsubscribe_bridge(), ast_assert, AST_BRIDGE_AFTER_CB_REASON_IMPART_FAILED, ast_bridge_after_cb_reason_string(), ast_bridge_setup_after_goto(), ast_channel_get_bridge_channel(), ast_channel_lock, ast_channel_pbx_set(), ast_channel_uniqueid(), ast_channel_unlock, ast_debug, AST_SOFTHANGUP_ASYNCGOTO, AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), stasis_app_control::bridge, bridge_channel_depart(), stasis_app_control::channel, NULL, stasis_app_control::pbx, stasis_app_channel_is_stasis_end_published(), stasis_app_send_command_async(), and ast_bridge::uniqueid.

Referenced by bridge_after_cb(), and bridge_after_cb_failed().

1110 {
1111  struct stasis_app_control *control = data;
1112  struct ast_bridge_channel *bridge_channel;
1113 
1114  ao2_lock(control);
1115  ast_debug(3, "%s, %s: %s\n",
1116  ast_channel_uniqueid(chan), control->bridge ? control->bridge->uniqueid : "unknown",
1118 
1120  /* The impart actually failed so control->bridge isn't valid. */
1121  control->bridge = NULL;
1122  }
1123 
1124  ast_assert(chan == control->channel);
1125 
1126  /* Restore the channel's PBX */
1127  ast_channel_pbx_set(control->channel, control->pbx);
1128  control->pbx = NULL;
1129 
1130  if (control->bridge) {
1131  app_unsubscribe_bridge(control->app, control->bridge);
1132 
1133  /* No longer in the bridge */
1134  control->bridge = NULL;
1135 
1136  /* Get the bridge channel so we don't depart from the wrong bridge */
1137  ast_channel_lock(chan);
1138  bridge_channel = ast_channel_get_bridge_channel(chan);
1139  ast_channel_unlock(chan);
1140 
1141  /* Depart this channel from the bridge using the command queue if possible */
1143  }
1144 
1146  /* The channel has had a StasisEnd published on it, but until now had remained in
1147  * the bridging system. This means that the channel moved from a Stasis bridge to a
1148  * non-Stasis bridge and is now exiting the bridging system. Because of this, the
1149  * channel needs to exit the Stasis application and go to wherever the non-Stasis
1150  * bridge has directed it to go. If the non-Stasis bridge has not set up an after
1151  * bridge destination, then the channel should be hung up.
1152  */
1153  int hangup_flag;
1154 
1156  ast_channel_lock(chan);
1157  ast_softhangup_nolock(chan, hangup_flag);
1158  ast_channel_unlock(chan);
1159  }
1160  ao2_unlock(control);
1161 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
const ast_string_field uniqueid
Definition: bridge.h:409
const char * ast_bridge_after_cb_reason_string(enum ast_bridge_after_cb_reason reason)
Get a string representation of an after bridge callback reason.
Definition: bridge_after.c:296
void __ao2_cleanup(void *obj)
Definition: astobj2.c:674
#define ast_assert(a)
Definition: utils.h:695
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
struct stasis_app * app
Definition: control.c:90
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
int stasis_app_channel_is_stasis_end_published(struct ast_channel *chan)
Has this channel had a StasisEnd published on it?
Definition: res_stasis.c:1299
struct ast_channel * channel
Definition: control.c:60
#define ao2_lock(a)
Definition: astobj2.h:718
static int bridge_channel_depart(struct stasis_app_control *control, struct ast_channel *chan, void *data)
Definition: control.c:1085
const char * ast_channel_uniqueid(const struct ast_channel *chan)
struct ast_pbx * pbx
Definition: control.c:72
int ast_softhangup_nolock(struct ast_channel *chan, int reason)
Softly hangup up a channel (no channel lock)
Definition: channel.c:2463
#define ast_channel_unlock(chan)
Definition: channel.h:2946
struct ast_bridge * bridge
Definition: control.c:64
void ast_channel_pbx_set(struct ast_channel *chan, struct ast_pbx *value)
struct ast_bridge_channel * ast_channel_get_bridge_channel(struct ast_channel *chan)
Get a reference to the channel&#39;s bridge pointer.
Definition: channel.c:10783
Structure that contains information regarding a channel in a bridge.
int app_unsubscribe_bridge(struct stasis_app *app, struct ast_bridge *bridge)
Cancel the bridge subscription for an application.
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:904
int ast_bridge_setup_after_goto(struct ast_channel *chan)
Setup any after bridge goto location to begin execution.
Definition: bridge_after.c:447

◆ noop_cb()

static int noop_cb ( struct stasis_app_control control,
struct ast_channel chan,
void *  data 
)
static

Definition at line 257 of file control.c.

Referenced by exec_command_on_condition().

259 {
260  return 0;
261 }

◆ set_interval_hook()

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 1254 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, ast_bridge_channel::features, and NULL.

Referenced by control_swap_channel_in_bridge(), and set_timeout().

1255 {
1256  struct ast_datastore *datastore;
1257  struct timeval *hangup_time;
1258  int64_t ms;
1259  struct ast_bridge_channel *bridge_channel;
1260 
1261  datastore = ast_channel_datastore_find(chan, &timeout_datastore, NULL);
1262  if (!datastore) {
1263  return;
1264  }
1265 
1266  hangup_time = datastore->data;
1267 
1268  ms = ast_tvdiff_ms(*hangup_time, ast_tvnow());
1269  bridge_channel = ast_channel_get_bridge_channel(chan);
1270  if (!bridge_channel) {
1271  return;
1272  }
1273 
1274  if (ast_bridge_interval_hook(bridge_channel->features, 0, ms > 0 ? ms : 1,
1275  bridge_timeout, NULL, NULL, 0)) {
1276  ao2_ref(bridge_channel, -1);
1277  return;
1278  }
1279 
1280  ast_queue_frame(bridge_channel->chan, &ast_null_frame);
1281  ao2_ref(bridge_channel, -1);
1282 }
struct ast_bridge_features * features
static int bridge_timeout(struct ast_bridge_channel *bridge_channel, void *ignore)
Dial timeout.
Definition: control.c:1215
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:98
Structure for a data store object.
Definition: datastore.h:68
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:2404
#define NULL
Definition: resample.c:96
#define ao2_ref(o, delta)
Definition: astobj2.h:464
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:3382
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel&#39;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&#39;s bridge pointer.
Definition: channel.c:10783
struct ast_frame ast_null_frame
Definition: main/frame.c:79
void * data
Definition: datastore.h:70
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:1192

◆ set_timeout()

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 1603 of file control.c.

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

Referenced by app_control_dial().

1604 {
1605  struct ast_datastore *datastore;
1606  struct timeval *hangup_time;
1607 
1608  hangup_time = ast_malloc(sizeof(struct timeval));
1609 
1611  if (!datastore) {
1612  return -1;
1613  }
1614  *hangup_time = ast_tvadd(ast_tvnow(), ast_samp2tv(timeout, 1));
1615  datastore->data = hangup_time;
1616 
1617  ast_channel_lock(chan);
1618  ast_channel_datastore_add(chan, datastore);
1619 
1620  if (ast_channel_is_bridged(chan)) {
1621  set_interval_hook(chan);
1622  }
1623  ast_channel_unlock(chan);
1624 
1625  return 0;
1626 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
static int timeout
Definition: cdr_mysql.c:86
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
Structure for a data store object.
Definition: datastore.h:68
#define NULL
Definition: resample.c:96
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:238
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
static void set_interval_hook(struct ast_channel *chan)
Set a dial timeout interval hook on the channel.
Definition: control.c:1254
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: extconf.c:2283
int ast_channel_is_bridged(const struct ast_channel *chan)
Determine if a channel is in a bridge.
Definition: channel.c:10746
#define ast_channel_unlock(chan)
Definition: channel.h:2946
void * data
Definition: datastore.h:70
#define ast_datastore_alloc(info, uid)
Definition: datastore.h:89
struct ast_datastore_info timeout_datastore
Dial timeout datastore.
Definition: control.c:1192
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2390

◆ stasis_app_control_absorb_dtmf_in_bridge()

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 1464 of file control.c.

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

Referenced by ast_ari_bridges_add_channel().

1466 {
1467  control->bridge_features->dtmf_passthrough = !absorb;
1468 }
struct ast_bridge_features * bridge_features
Definition: control.c:68
unsigned int dtmf_passthrough

◆ stasis_app_control_add_channel_to_bridge()

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 1383 of file control.c.

References app_control_can_add_channel_to_bridge(), app_send_command_on_condition(), ast_debug, control_add_channel_to_bridge(), NULL, and stasis_app_control_get_channel_id().

Referenced by ast_ari_bridges_add_channel().

1385 {
1386  ast_debug(3, "%s: Sending channel add_to_bridge command\n",
1388 
1390  control, control_add_channel_to_bridge, bridge, NULL,
1392 }
#define NULL
Definition: resample.c:96
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:1378
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static int app_control_can_add_channel_to_bridge(struct stasis_app_control *control)
Definition: control.c:245
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)
Definition: control.c:866
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:1430

◆ stasis_app_control_add_role()

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 316 of file control.c.

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

Referenced by ast_ari_bridges_add_channel().

317 {
318  char *role_dup;
319 
320  role_dup = ast_strdup(role);
321  if (!role_dup) {
322  return -1;
323  }
324 
326 
327  return 0;
328 }
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
void ast_free_ptr(void *ptr)
free() wrapper
Definition: astmm.c:1771
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:904
static int app_control_add_role(struct stasis_app_control *control, struct ast_channel *chan, void *data)
Definition: control.c:308

◆ stasis_app_control_bridge_features_init()

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 1451 of file control.c.

References ast_bridge_features_new(), and stasis_app_control::bridge_features.

Referenced by ast_ari_bridges_add_channel().

1453 {
1454  struct ast_bridge_features *features;
1455 
1456  features = ast_bridge_features_new();
1457  if (!features) {
1458  return 1;
1459  }
1460  control->bridge_features = features;
1461  return 0;
1462 }
Structure that contains features information.
struct ast_bridge_features * bridge_features
Definition: control.c:68
struct ast_bridge_features * ast_bridge_features_new(void)
Allocate a new bridge features struct.
Definition: bridge.c:3750

◆ stasis_app_control_clear_roles()

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 338 of file control.c.

References app_control_clear_roles(), NULL, and stasis_app_send_command_async().

Referenced by ast_ari_bridges_add_channel().

339 {
341 }
#define NULL
Definition: resample.c:96
static int app_control_clear_roles(struct stasis_app_control *control, struct ast_channel *chan, void *data)
Definition: control.c:330
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:904

◆ stasis_app_control_continue()

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 389 of file control.c.

References app_control_continue(), ast_calloc, ast_copy_string(), ast_free_ptr(), stasis_app_control_continue_data::context, stasis_app_control_continue_data::extension, priority, stasis_app_control_continue_data::priority, S_OR, and stasis_app_send_command_async().

Referenced by ast_ari_channels_continue_in_dialplan().

390 {
391  struct stasis_app_control_continue_data *continue_data;
392 
393  if (!(continue_data = ast_calloc(1, sizeof(*continue_data)))) {
394  return -1;
395  }
396  ast_copy_string(continue_data->context, S_OR(context, ""), sizeof(continue_data->context));
397  ast_copy_string(continue_data->extension, S_OR(extension, ""), sizeof(continue_data->extension));
398  if (priority > 0) {
399  continue_data->priority = priority;
400  } else {
401  continue_data->priority = -1;
402  }
403 
405 
406  return 0;
407 }
static int priority
void ast_free_ptr(void *ptr)
free() wrapper
Definition: astmm.c:1771
structure to hold extensions
char context[AST_MAX_CONTEXT]
Definition: control.c:363
char extension[AST_MAX_EXTENSION]
Definition: control.c:364
static int app_control_continue(struct stasis_app_control *control, struct ast_channel *chan, void *data)
Definition: control.c:368
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
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:904
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116

◆ stasis_app_control_dial()

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 1666 of file control.c.

References app_control_dial(), args, control_dial_args_alloc(), control_dial_args_destroy(), and stasis_app_send_command_async().

Referenced by ast_ari_channels_dial().

1668 {
1669  struct control_dial_args *args;
1670 
1672  if (!args) {
1673  return -1;
1674  }
1675 
1678 }
static int timeout
Definition: cdr_mysql.c:86
static struct control_dial_args * control_dial_args_alloc(const char *dialstring, unsigned int timeout)
Definition: control.c:1573
const char * args
char dialstring[0]
Definition: control.c:1570
static void control_dial_args_destroy(void *data)
Definition: control.c:1590
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:904
static int app_control_dial(struct stasis_app_control *control, struct ast_channel *chan, void *data)
Definition: control.c:1628

◆ stasis_app_control_dtmf()

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 565 of file control.c.

References stasis_app_control_dtmf_data::after, app_control_dtmf(), ast_calloc, ast_free_ptr(), stasis_app_control_dtmf_data::before, stasis_app_control_dtmf_data::between, stasis_app_control_dtmf_data::dtmf, stasis_app_control_dtmf_data::duration, and stasis_app_send_command_async().

Referenced by ast_ari_channels_send_dtmf().

566 {
567  struct stasis_app_control_dtmf_data *dtmf_data;
568 
569  if (!(dtmf_data = ast_calloc(1, sizeof(*dtmf_data) + strlen(dtmf) + 1))) {
570  return -1;
571  }
572 
573  dtmf_data->before = before;
574  dtmf_data->between = between;
575  dtmf_data->duration = duration;
576  dtmf_data->after = after;
577  strcpy(dtmf_data->dtmf, dtmf);
578 
580 
581  return 0;
582 }
void ast_free_ptr(void *ptr)
free() wrapper
Definition: astmm.c:1771
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
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:904
static int app_control_dtmf(struct stasis_app_control *control, struct ast_channel *chan, void *data)
Definition: control.c:547

◆ stasis_app_control_get_channel_id()

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.
NULL if control is NULL.

Definition at line 1430 of file control.c.

References ast_channel_uniqueid(), and stasis_app_control::channel.

Referenced by app_control_answer(), app_control_remove_channel_from_bridge(), app_control_silence_start(), check_add_remove_channel(), control_compare(), control_hash(), control_silence_stop_now(), control_swap_channel_in_bridge(), masq_match_cb(), playback_publish(), recording_publish(), 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().

1432 {
1433  return ast_channel_uniqueid(control->channel);
1434 }
struct ast_channel * channel
Definition: control.c:60
const char * ast_channel_uniqueid(const struct ast_channel *chan)

◆ stasis_app_control_get_snapshot()

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.
NULL if channel isn't in cache.

Definition at line 860 of file control.c.

References ast_channel_snapshot_get_latest(), and stasis_app_control_get_channel_id().

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

862 {
864 }
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:1430
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...

◆ stasis_app_control_hold()

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 748 of file control.c.

References app_control_hold(), NULL, and stasis_app_send_command_async().

Referenced by ast_ari_channels_hold().

749 {
751 }
#define NULL
Definition: resample.c:96
static int app_control_hold(struct stasis_app_control *control, struct ast_channel *chan, void *data)
Definition: control.c:740
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:904

◆ stasis_app_control_inhibit_colp_in_bridge()

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
muteWhether COLP frames should be generated (0) or not (1).

Definition at line 1476 of file control.c.

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

Referenced by ast_ari_bridges_add_channel().

1478 {
1479  control->bridge_features->inhibit_colp = inhibit_colp;
1480 }
unsigned int inhibit_colp
struct ast_bridge_features * bridge_features
Definition: control.c:68

◆ stasis_app_control_moh_start()

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 780 of file control.c.

References app_control_moh_start(), ast_free_ptr(), ast_strdup, ast_strlen_zero, NULL, and stasis_app_send_command_async().

Referenced by ast_ari_channels_start_moh().

781 {
782  char *data = NULL;
783 
784  if (!ast_strlen_zero(moh_class)) {
785  data = ast_strdup(moh_class);
786  }
787 
789 }
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
void ast_free_ptr(void *ptr)
free() wrapper
Definition: astmm.c:1771
#define ast_strlen_zero(foo)
Definition: strings.h:52
static int app_control_moh_start(struct stasis_app_control *control, struct ast_channel *chan, void *data)
Definition: control.c:766
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:904

◆ stasis_app_control_moh_stop()

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 798 of file control.c.

References app_control_moh_stop(), NULL, and stasis_app_send_command_async().

Referenced by ast_ari_channels_stop_moh().

799 {
801 }
#define NULL
Definition: resample.c:96
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:904
static int app_control_moh_stop(struct stasis_app_control *control, struct ast_channel *chan, void *data)
Definition: control.c:791

◆ stasis_app_control_move()

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 451 of file control.c.

References stasis_app_control_move_data::app_args, app_control_move(), stasis_app_control_move_data::app_name, ast_calloc, ast_free_ptr(), NULL, and stasis_app_send_command_async().

Referenced by ast_ari_channels_move().

452 {
453  struct stasis_app_control_move_data *move_data;
454  size_t size;
455 
456  size = sizeof(*move_data) + strlen(app_name) + 1;
457  if (app_args) {
458  /* Application arguments are optional */
459  size += strlen(app_args) + 1;
460  }
461 
462  if (!(move_data = ast_calloc(1, size))) {
463  return -1;
464  }
465 
466  move_data->app_name = (char *)move_data + sizeof(*move_data);
467  strcpy(move_data->app_name, app_name); /* Safe */
468 
469  if (app_args) {
470  move_data->app_args = move_data->app_name + strlen(app_name) + 1;
471  strcpy(move_data->app_args, app_args); /* Safe */
472  } else {
473  move_data->app_args = NULL;
474  }
475 
477 
478  return 0;
479 }
#define NULL
Definition: resample.c:96
void ast_free_ptr(void *ptr)
free() wrapper
Definition: astmm.c:1771
static int app_control_move(struct stasis_app_control *control, struct ast_channel *chan, void *data)
Definition: control.c:414
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:204
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:904

◆ stasis_app_control_mute()

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 631 of file control.c.

References app_control_mute(), ast_calloc, ast_free_ptr(), stasis_app_control_mute_data::direction, stasis_app_control_mute_data::frametype, and stasis_app_send_command_async().

Referenced by ast_ari_channels_mute().

632 {
633  struct stasis_app_control_mute_data *mute_data;
634 
635  if (!(mute_data = ast_calloc(1, sizeof(*mute_data)))) {
636  return -1;
637  }
638 
639  mute_data->direction = direction;
640  mute_data->frametype = frametype;
641 
643 
644  return 0;
645 }
void ast_free_ptr(void *ptr)
free() wrapper
Definition: astmm.c:1771
enum ast_frame_type frametype
Definition: control.c:615
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
static int app_control_mute(struct stasis_app_control *control, struct ast_channel *chan, void *data)
Definition: control.c: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:904
direction

◆ stasis_app_control_mute_in_bridge()

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 1470 of file control.c.

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

Referenced by ast_ari_bridges_add_channel().

1472 {
1473  control->bridge_features->mute = mute;
1474 }
static int mute
Definition: chan_alsa.c:144
struct ast_bridge_features * bridge_features
Definition: control.c:68

◆ stasis_app_control_publish()

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 1436 of file control.c.

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

Referenced by playback_publish(), and recording_publish().

1438 {
1439  if (!control || !control->channel || !message) {
1440  return;
1441  }
1442  stasis_publish(ast_channel_topic(control->channel), message);
1443 }
struct ast_channel * channel
Definition: control.c:60
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&#39;s subscribers.
Definition: stasis.c:1511

◆ stasis_app_control_queue_control()

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 1445 of file control.c.

References ast_queue_control(), and stasis_app_control::channel.

Referenced by playback_forward(), playback_pause(), playback_restart(), playback_reverse(), playback_stop(), playback_unpause(), recording_cancel(), recording_mute(), recording_pause(), recording_stop(), recording_unmute(), and recording_unpause().

1447 {
1448  return ast_queue_control(control->channel, frame_type);
1449 }
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:60
frame_type
Definition: codec_builtin.c:44

◆ stasis_app_control_redirect()

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 500 of file control.c.

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

Referenced by ast_ari_channels_redirect().

501 {
502  char *endpoint_data = ast_strdup(endpoint);
503 
504  if (!endpoint_data) {
505  return -1;
506  }
507 
509 
510  return 0;
511 }
static int app_control_redirect(struct stasis_app_control *control, struct ast_channel *chan, void *data)
Definition: control.c:481
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
void ast_free_ptr(void *ptr)
free() wrapper
Definition: astmm.c:1771
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:904

◆ stasis_app_control_register_add_rule()

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 217 of file control.c.

References stasis_app_control::add_rules, and app_control_register_rule().

Referenced by stasis_app_control_record().

220 {
221  return app_control_register_rule(control, &control->add_rules, rule);
222 }
static void app_control_register_rule(struct stasis_app_control *control, struct app_control_rules *list, struct stasis_app_control_rule *obj)
Definition: control.c:162
struct app_control_rules add_rules
Definition: control.c:76

◆ stasis_app_control_register_remove_rule()

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 231 of file control.c.

References app_control_register_rule(), and stasis_app_control::remove_rules.

234 {
235  return app_control_register_rule(control, &control->remove_rules, rule);
236 }
struct app_control_rules remove_rules
Definition: control.c:80
static void app_control_register_rule(struct stasis_app_control *control, struct app_control_rules *list, struct stasis_app_control_rule *obj)
Definition: control.c:162

◆ stasis_app_control_remove_channel_from_bridge()

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 1420 of file control.c.

References app_control_can_remove_channel_from_bridge(), app_control_remove_channel_from_bridge(), app_send_command_on_condition(), ast_debug, NULL, and stasis_app_control_get_channel_id().

Referenced by ast_ari_bridges_remove_channel().

1422 {
1423  ast_debug(3, "%s: Sending channel remove_from_bridge command\n",
1426  control, app_control_remove_channel_from_bridge, bridge, NULL,
1428 }
static int app_control_can_remove_channel_from_bridge(struct stasis_app_control *control)
Definition: control.c:251
#define NULL
Definition: resample.c:96
static int app_control_remove_channel_from_bridge(struct stasis_app_control *control, struct ast_channel *chan, void *data)
Definition: control.c:1394
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
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)
Definition: control.c:866
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:1430

◆ stasis_app_control_ring()

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 592 of file control.c.

References app_control_ring(), NULL, and stasis_app_send_command_async().

Referenced by ast_ari_channels_ring().

593 {
595 
596  return 0;
597 }
#define NULL
Definition: resample.c:96
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:904
static int app_control_ring(struct stasis_app_control *control, struct ast_channel *chan, void *data)
Definition: control.c:584

◆ stasis_app_control_ring_stop()

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 607 of file control.c.

References app_control_ring_stop(), NULL, and stasis_app_send_command_async().

Referenced by ast_ari_channels_ring_stop().

608 {
610 
611  return 0;
612 }
#define NULL
Definition: resample.c:96
static int app_control_ring_stop(struct stasis_app_control *control, struct ast_channel *chan, void *data)
Definition: control.c:599
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:904

◆ stasis_app_control_set_channel_var()

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 711 of file control.c.

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

Referenced by ast_ari_channels_set_channel_var().

712 {
713  struct chanvar *var;
714 
715  var = ast_calloc(1, sizeof(*var));
716  if (!var) {
717  return -1;
718  }
719 
720  var->name = ast_strdup(variable);
721  if (!var->name) {
722  free_chanvar(var);
723  return -1;
724  }
725 
726  /* It's kosher for value to be NULL. It means the variable is being unset */
727  if (value) {
728  var->value = ast_strdup(value);
729  if (!var->value) {
730  free_chanvar(var);
731  return -1;
732  }
733  }
734 
736 
737  return 0;
738 }
#define var
Definition: ast_expr2f.c:614
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
int value
Definition: syslog.c:37
char * value
Definition: control.c:689
static int app_control_set_channel_var(struct stasis_app_control *control, struct ast_channel *chan, void *data)
Definition: control.c:701
static void free_chanvar(void *data)
Definition: control.c:692
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
structure for queuing ARI channel variable setting
Definition: control.c:685
char * name
Definition: control.c:687
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:904

◆ stasis_app_control_shutdown()

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 1680 of file control.c.

References ast_bridge_destroy(), ast_mutex_lock, ast_mutex_unlock, dial_bridge_lock, NULL, and shutting_down.

Referenced by unload_module().

1681 {
1683  shutting_down = 1;
1684  if (dial_bridge) {
1686  dial_bridge = NULL;
1687  }
1689 }
int ast_bridge_destroy(struct ast_bridge *bridge, int cause)
Destroy a bridge.
Definition: bridge.c:970
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
static ast_mutex_t dial_bridge_lock
Definition: control.c:959
static int shutting_down
Indicates if the Stasis app internals are being shut down.
Definition: control.c:49
static struct ast_bridge * dial_bridge
Singleton dial bridge.
Definition: control.c:958
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ stasis_app_control_silence_start()

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 832 of file control.c.

References app_control_silence_start(), NULL, and stasis_app_send_command_async().

Referenced by ast_ari_channels_start_silence().

833 {
835 }
#define NULL
Definition: resample.c:96
static int app_control_silence_start(struct stasis_app_control *control, struct ast_channel *chan, void *data)
Definition: control.c:803
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:904

◆ stasis_app_control_silence_stop()

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 855 of file control.c.

References app_control_silence_stop(), NULL, and stasis_app_send_command_async().

Referenced by ast_ari_channels_stop_silence().

856 {
858 }
#define NULL
Definition: resample.c:96
static int app_control_silence_stop(struct stasis_app_control *control, struct ast_channel *chan, void *data)
Definition: control.c:848
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:904

◆ stasis_app_control_unhold()

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 761 of file control.c.

References app_control_unhold(), NULL, and stasis_app_send_command_async().

Referenced by ast_ari_channels_unhold().

762 {
764 }
static int app_control_unhold(struct stasis_app_control *control, struct ast_channel *chan, void *data)
Definition: control.c:753
#define NULL
Definition: resample.c:96
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:904

◆ stasis_app_control_unmute()

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 659 of file control.c.

References app_control_unmute(), ast_calloc, ast_free_ptr(), stasis_app_control_mute_data::direction, stasis_app_control_mute_data::frametype, and stasis_app_send_command_async().

Referenced by ast_ari_channels_unmute().

660 {
661  struct stasis_app_control_mute_data *mute_data;
662 
663  if (!(mute_data = ast_calloc(1, sizeof(*mute_data)))) {
664  return -1;
665  }
666 
667  mute_data->direction = direction;
668  mute_data->frametype = frametype;
669 
671 
672  return 0;
673 }
void ast_free_ptr(void *ptr)
free() wrapper
Definition: astmm.c:1771
static int app_control_unmute(struct stasis_app_control *control, struct ast_channel *chan, void *data)
Definition: control.c:647
enum ast_frame_type frametype
Definition: control.c:615
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
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:904
direction

◆ stasis_app_control_unregister_add_rule()

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 224 of file control.c.

References stasis_app_control::add_rules, and app_control_unregister_rule().

Referenced by record_file(), and recording_fail().

227 {
228  app_control_unregister_rule(control, &control->add_rules, rule);
229 }
static void app_control_unregister_rule(struct stasis_app_control *control, struct app_control_rules *list, struct stasis_app_control_rule *obj)
Definition: control.c:171
struct app_control_rules add_rules
Definition: control.c:76

◆ stasis_app_control_unregister_remove_rule()

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 238 of file control.c.

References app_control_unregister_rule(), and stasis_app_control::remove_rules.

241 {
242  app_control_unregister_rule(control, &control->remove_rules, rule);
243 }
struct app_control_rules remove_rules
Definition: control.c:80
static void app_control_unregister_rule(struct stasis_app_control *control, struct app_control_rules *list, struct stasis_app_control_rule *obj)
Definition: control.c:171

◆ stasis_app_get_bridge()

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.
NULL if not associated with a bridge.

Definition at line 931 of file control.c.

References ao2_lock, ao2_unlock, stasis_app_control::bridge, and NULL.

Referenced by app_control_continue(), app_control_dtmf(), app_control_remove_channel_from_bridge(), ast_ari_bridges_remove_channel(), ast_ari_bridges_set_video_source(), control_swap_channel_in_bridge(), play_uri(), record_file(), and stasis_app_exec().

932 {
933  struct ast_bridge *ret;
934 
935  if (!control) {
936  return NULL;
937  }
938 
939  ao2_lock(control);
940  ret = control->bridge;
941  ao2_unlock(control);
942 
943  return ret;
944 }
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
#define ao2_lock(a)
Definition: astobj2.h:718
Structure that contains information about a bridge.
Definition: bridge.h:357
struct ast_bridge * bridge
Definition: control.c:64

◆ stasis_app_send_command()

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 898 of file control.c.

References app_send_command_on_condition(), and NULL.

Referenced by ast_ari_bridges_set_video_source(), and stasis_app_control_answer().

900 {
901  return app_send_command_on_condition(control, command_fn, data, data_destructor, NULL);
902 }
#define NULL
Definition: resample.c:96
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)
Definition: control.c:866

◆ stasis_app_send_command_async()

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 904 of file control.c.

References ao2_ref, stasis_app_command::data_destructor, exec_command(), and NULL.

Referenced by bridge_timeout(), dial_bridge_after_cb(), internal_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().

907 {
908  struct stasis_app_command *command;
909 
910  if (control == NULL || control->is_done) {
911  /* If exec_command fails, it calls the data_destructor. In order to
912  * provide consistent behavior, we'll also call the data_destructor
913  * on this error path. This way, callers never have to call the
914  * data_destructor themselves.
915  */
916  if (data_destructor) {
918  }
919  return -1;
920  }
921 
922  command = exec_command(control, command_fn, data, data_destructor);
923  if (!command) {
924  return -1;
925  }
926  ao2_ref(command, -1);
927 
928  return 0;
929 }
static struct stasis_app_command * exec_command(struct stasis_app_control *control, stasis_app_command_cb command_fn, void *data, command_data_destructor_fn data_destructor)
Definition: control.c:301
#define NULL
Definition: resample.c:96
command_data_destructor_fn data_destructor
Definition: command.c:38
#define ao2_ref(o, delta)
Definition: astobj2.h:464

Variable Documentation

◆ dial_bridge

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 958 of file control.c.

◆ dial_bridge_lock

ast_mutex_t dial_bridge_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
static

Definition at line 959 of file control.c.

Referenced by get_dial_bridge(), and stasis_app_control_shutdown().

◆ shutting_down

int shutting_down
static

Indicates if the Stasis app internals are being shut down.

Definition at line 49 of file control.c.

Referenced by get_dial_bridge(), and stasis_app_control_shutdown().

◆ timeout_datastore

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 1192 of file control.c.