28 #include "asterisk/stasis_channels.h"
111 static
void control_dtor(
void *obj)
118 ao2_cleanup(control->
app);
122 ast_cond_destroy(&control->wait_cond);
134 control = ao2_alloc(
sizeof(*control), control_dtor);
142 res = ast_cond_init(&control->wait_cond, NULL);
144 ast_log(LOG_ERROR,
"Error initializing ast_cond_t: %s\n",
170 static void app_control_register_rule(
179 static void app_control_unregister_rule(
186 AST_RWLIST_TRAVERSE_SAFE_BEGIN(list, rule, next) {
188 AST_RWLIST_REMOVE_CURRENT(next);
192 AST_RWLIST_TRAVERSE_SAFE_END;
236 return app_control_register_rule(control, &control->
add_rules, rule);
243 app_control_unregister_rule(control, &control->
add_rules, rule);
250 return app_control_register_rule(control, &control->
remove_rules, rule);
257 app_control_unregister_rule(control, &control->
remove_rules, rule);
260 static int app_control_can_add_channel_to_bridge(
263 return app_control_check_rules(control, &control->
add_rules);
266 static int app_control_can_remove_channel_from_bridge(
269 return app_control_check_rules(control, &control->
remove_rules);
290 command_fn = command_fn ? : noop_cb;
292 command = command_create(command_fn, data, data_destructor);
303 if (can_exec_fn && (retval = can_exec_fn(control))) {
305 command_complete(command, retval);
310 ast_cond_signal(&control->wait_cond);
327 return exec_command_on_condition(control, command_fn, data, data_destructor, NULL);
395 ast_assert(control->
channel != NULL);
406 control_mark_done(control);
415 if (!(continue_data =
ast_calloc(1,
sizeof(*continue_data)))) {
418 ast_copy_string(continue_data->context,
S_OR(context,
""),
sizeof(continue_data->context));
419 ast_copy_string(continue_data->extension,
S_OR(extension,
""),
sizeof(continue_data->extension));
421 continue_data->priority = priority;
423 continue_data->priority = -1;
443 ast_log(LOG_ERROR,
"Allocation failed for next app\n");
447 if (move_data->app_args) {
450 while ((token = strtok_r(move_data->app_args,
",", &move_data->app_args))) {
455 ast_log(LOG_ERROR,
"Allocation failed for next app arg\n");
462 ast_log(LOG_ERROR,
"Failed to append arg to next app args\n");
478 size =
sizeof(*move_data) + strlen(app_name) + 1;
481 size += strlen(app_args) + 1;
488 move_data->app_name = (
char *)move_data +
sizeof(*move_data);
489 strcpy(move_data->app_name, app_name);
492 move_data->app_args = move_data->app_name + strlen(app_name) + 1;
493 strcpy(move_data->app_args, app_args);
495 move_data->app_args = NULL;
506 char *endpoint = data;
509 ast_assert(control->
channel != NULL);
510 ast_assert(endpoint != NULL);
514 ast_log(LOG_NOTICE,
"Unsupported transfer requested on channel '%s'\n",
515 ast_channel_name(control->
channel));
526 if (!endpoint_data) {
538 unsigned int duration;
545 if (dtmf_data->before) {
546 usleep(dtmf_data->before * 1000);
551 if (dtmf_data->after) {
552 usleep(dtmf_data->after * 1000);
558 if (dtmf_data->before) {
562 ast_dtmf_stream(chan, NULL, dtmf_data->dtmf, dtmf_data->between, dtmf_data->duration);
564 if (dtmf_data->after) {
579 dtmf_in_bridge(chan, dtmf_data);
581 dtmf_no_bridge(chan, dtmf_data);
591 if (!(dtmf_data =
ast_calloc(1,
sizeof(*dtmf_data) + strlen(dtmf) + 1))) {
595 dtmf_data->before = before;
596 dtmf_data->between = between;
597 dtmf_data->duration = duration;
598 dtmf_data->after = after;
599 strcpy(dtmf_data->dtmf, dtmf);
638 unsigned int direction;
646 ast_channel_lock(chan);
648 ast_channel_unlock(chan);
657 if (!(mute_data =
ast_calloc(1,
sizeof(*mute_data)))) {
661 mute_data->direction = direction;
662 mute_data->frametype = frametype;
674 ast_channel_lock(chan);
676 ast_channel_unlock(chan);
685 if (!(mute_data =
ast_calloc(1,
sizeof(*mute_data)))) {
689 mute_data->direction = direction;
690 mute_data->frametype = frametype;
714 static void free_chanvar(
void *data)
719 ast_free(var->
value);
791 char *moh_class = data;
806 if (!ast_strlen_zero(moh_class)) {
841 ast_debug(3,
"%s: Starting silence generator\n",
847 "%s: Failed to start silence generator.\n",
862 ast_debug(3,
"%s: Stopping silence generator\n",
896 if (control == NULL || control->
is_done) {
902 if (data_destructor) {
903 data_destructor(data);
908 command = exec_command_on_condition(
909 control, command_fn, data, data_destructor, can_exec_fn);
914 ret = command_join(command);
923 return app_send_command_on_condition(control, command_fn, data, data_destructor, NULL);
932 if (control == NULL || control->
is_done) {
938 if (data_destructor) {
939 data_destructor(data);
944 command = exec_command(control, command_fn, data, data_destructor);
981 AST_MUTEX_DEFINE_STATIC(dial_bridge_lock);
1000 ast_mutex_lock(&dial_bridge_lock);
1007 ret_bridge =
ao2_bump(dial_bridge);
1015 ret_bridge =
ao2_bump(dial_bridge);
1018 ast_mutex_unlock(&dial_bridge_lock);
1036 ast_channel_lock(chan);
1038 ast_channel_unlock(chan);
1040 ast_debug(3,
"Channel: <%s> Reason: %d\n", ast_channel_name(control->
channel), ast_channel_hangupcause(chan));
1051 ast_debug(3,
"Channel: <%s> Reason: %d\n", ast_channel_name(control->
channel), reason);
1112 ast_channel_lock(chan);
1113 bridge_channel = ast_channel_internal_bridge_channel(chan);
1114 ast_channel_unlock(chan);
1116 if (bridge_channel != data) {
1117 ast_debug(3,
"%s: Channel is no longer in departable state\n",
1118 ast_channel_uniqueid(chan));
1122 ast_debug(3,
"%s: Channel departing bridge\n",
1123 ast_channel_uniqueid(chan));
1130 static void internal_bridge_after_cb(
struct ast_channel *chan,
void *data,
1146 ast_assert(chan == control->
channel);
1149 ast_channel_pbx_set(control->
channel, control->
pbx);
1150 control->
pbx = NULL;
1159 ast_channel_lock(chan);
1161 ast_channel_unlock(chan);
1178 ast_channel_lock(chan);
1180 ast_channel_unlock(chan);
1182 ao2_unlock(control);
1185 static void bridge_after_cb(
struct ast_channel *chan,
void *data)
1197 internal_bridge_after_cb(control->
channel, data, reason);
1215 .
type =
"ARI dial timeout",
1244 ast_channel_lock(bridge_channel->
chan);
1247 ast_channel_unlock(bridge_channel->
chan);
1254 ast_channel_unlock(bridge_channel->
chan);
1258 ast_channel_unlock(bridge_channel->
chan);
1279 struct timeval *hangup_time;
1288 hangup_time = datastore->
data;
1292 if (!bridge_channel) {
1312 if (!control || !bridge) {
1316 ast_debug(3,
"%s: Adding to bridge %s\n",
1320 ast_assert(chan != NULL);
1334 bridge_after_cb_failed, control);
1336 ast_log(LOG_ERROR,
"Error setting after-bridge callback\n");
1349 ast_assert(control->
pbx == NULL);
1350 if (!control->
pbx) {
1351 control->
pbx = ast_channel_pbx(chan);
1352 ast_channel_pbx_set(chan, NULL);
1373 ao2_unlock(control);
1385 ast_log(LOG_ERROR,
"Error adding channel to bridge\n");
1387 ast_channel_pbx_set(chan, control->
pbx);
1388 control->
pbx = NULL;
1390 ao2_unlock(control);
1392 ast_channel_lock(chan);
1394 ast_channel_unlock(chan);
1408 ast_debug(3,
"%s: Sending channel add_to_bridge command\n",
1411 return app_send_command_on_condition(
1413 app_control_can_add_channel_to_bridge);
1416 static int app_control_remove_channel_from_bridge(
1427 ast_debug(3,
"%s: Departing bridge %s\n",
1432 ast_log(LOG_WARNING,
"%s: Not in bridge %s; not removing\n",
1445 ast_debug(3,
"%s: Sending channel remove_from_bridge command\n",
1447 return app_send_command_on_condition(
1448 control, app_control_remove_channel_from_bridge, bridge, NULL,
1449 app_control_can_remove_channel_from_bridge);
1455 return ast_channel_uniqueid(control->
channel);
1461 if (!control || !control->
channel || !message) {
1510 while ((command = ao2_iterator_next(&iter))) {
1511 command_complete(command, -1);
1524 ast_assert(control->
channel == chan);
1527 while ((command = ao2_iterator_next(&iter))) {
1528 command_invoke(command, control, chan);
1547 int res = ast_cond_wait(&control->wait_cond,
1550 ast_log(LOG_ERROR,
"Error waiting on command queue\n");
1565 ast_channel_lock(chan);
1567 ast_channel_unlock(chan);
1568 if (!command_queue) {
1574 while ((command = ao2_iterator_next(&iter))) {
1575 command_invoke(command, control, chan);
1576 ao2_cleanup(command);
1581 ao2_cleanup(command_queue);
1587 return control->
app;
1591 unsigned int timeout;
1595 static struct control_dial_args *control_dial_args_alloc(
const char *dialstring,
1596 unsigned int timeout)
1600 args =
ast_malloc(
sizeof(*args) + strlen(dialstring) + 1);
1605 args->timeout = timeout;
1607 strcpy(args->dialstring, dialstring);
1612 static void control_dial_args_destroy(
void *data)
1628 struct timeval *hangup_time;
1630 hangup_time =
ast_malloc(
sizeof(
struct timeval));
1632 datastore = ast_datastore_alloc(&timeout_datastore, NULL);
1637 datastore->
data = hangup_time;
1639 ast_channel_lock(chan);
1645 ast_channel_unlock(chan);
1656 ast_channel_lock(chan);
1658 ast_channel_unlock(chan);
1664 if (args->timeout &&
set_timeout(chan, args->timeout)) {
1668 if (
ast_call(chan, args->dialstring, 0)) {
1677 ast_channel_lock(chan);
1679 ast_channel_unlock(chan);
1689 const char *dialstring,
unsigned int timeout)
1693 args = control_dial_args_alloc(dialstring, timeout);
1699 args, control_dial_args_destroy);
1704 ast_mutex_lock(&dial_bridge_lock);
1710 ast_mutex_unlock(&dial_bridge_lock);
1715 ao2_cleanup(control->
app);
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.
int ast_safe_sleep(struct ast_channel *chan, int ms)
Wait for a specified amount of time, looking for hangups.
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.
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.
char * control_next_app(struct stasis_app_control *control)
Returns the name of the application we are moving to.
Main Channel structure associated with a channel.
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.
char ** control_next_app_args(struct stasis_app_control *control)
Returns the list of arguments to pass to the application we are moving to.
unsigned int inhibit_colp
int stasis_app_control_redirect(struct stasis_app_control *control, const char *endpoint)
Redirect a channel in res_stasis to a particular endpoint.
Asterisk main include file. File version handling, generic pbx functions.
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.
const ast_string_field uniqueid
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
struct ast_bridge_features * features
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.
#define AST_LIST_HEAD(name, type)
Defines a structure to be used to hold a list of specified type.
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
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.
struct app_control_rules remove_rules
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.
Internal API for the Stasis application commands.
int stasis_app_control_dial(struct stasis_app_control *control, const char *dialstring, unsigned int timeout)
Dial a channel.
Structure that contains features information.
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
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...
static int bridge_timeout(struct ast_bridge_channel *bridge_channel, void *ignore)
Dial timeout.
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.
int(* app_command_can_exec_cb)(struct stasis_app_control *control)
int ast_softhangup(struct ast_channel *chan, int cause)
Softly hangup up a channel.
void __ao2_cleanup(void *obj)
void control_flush_queue(struct stasis_app_control *control)
Flush the control command queue.
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a list container.
int ast_call(struct ast_channel *chan, const char *addr, int timeout)
Make a call.
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Structure representing a snapshot of channel state.
void stasis_app_control_shutdown(void)
Let Stasis app internals shut down.
struct ast_bridge * stasis_app_get_bridge(struct stasis_app_control *control)
Gets the bridge currently associated with a control object.
Assume that the ao2_container is already locked.
Structure for a data store type.
ast_channel_state
ast_channel states
int ast_bridge_destroy(struct ast_bridge *bridge, int cause)
Destroy a bridge.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
ast_control_frame_type
Internal control frame subtype field values.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
void stasis_app_control_hold(struct stasis_app_control *control)
Place the channel associated with the control on hold.
struct ao2_container * command_prestart_get_container(struct ast_channel *chan)
Get the Stasis() prestart commands for a channel.
static int add_to_dial_bridge(struct stasis_app_control *control, struct ast_channel *chan)
Add a channel to the singleton dial bridge.
int ast_explicit_goto(struct ast_channel *chan, const char *context, const char *exten, int priority)
#define ao2_link_flags(container, obj, flags)
Add an object to a container.
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
#define ast_strdup(str)
A wrapper for strdup()
Structure for a data store object.
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.
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.
int ast_channel_add_bridge_role(struct ast_channel *chan, const char *role_name)
Adds a bridge role to a channel.
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.
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
int control_command_count(struct stasis_app_control *control)
Returns the count of items in a control's command queue.
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.
void ast_free_ptr(void *ptr)
free() wrapper
struct stasis_app * control_app(struct stasis_app_control *control)
Returns the pointer (non-reffed) to the app associated with this control.
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.
void ast_bridge_features_destroy(struct ast_bridge_features *features)
Destroy an allocated bridge features struct.
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
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.
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.
int control_dispatch_all(struct stasis_app_control *control, struct ast_channel *chan)
Dispatch all commands enqueued to this control.
int app_subscribe_bridge(struct stasis_app *app, struct ast_bridge *bridge)
Add a bridge subscription to an existing channel subscription.
#define AST_LIST_HEAD_DESTROY(head)
Destroys a list head structure.
int(* stasis_app_command_cb)(struct stasis_app_control *control, struct ast_channel *chan, void *data)
ast_bridge_after_cb_reason
int stasis_app_control_add_channel_to_bridge(struct stasis_app_control *control, struct ast_bridge *bridge)
Add a channel to the bridge.
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
void control_set_thread(struct stasis_app_control *control, pthread_t threadid)
set the control's thread id
void * ao2_object_get_lockaddr(void *obj)
Return the mutex lock address of an object.
static void dial_bridge_after_cb(struct ast_channel *chan, void *data)
after bridge callback for the dial bridge
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.
void stasis_app_control_silence_stop(struct stasis_app_control *control)
Stop playing silence to a channel.
static struct ast_bridge * get_dial_bridge(void)
Retrieve a reference to the dial bridge.
void control_move_cleanup(struct stasis_app_control *control)
Free any memory that was allocated for switching applications via /channels/{channelId}/move.
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
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)
struct ast_channel_snapshot * stasis_app_control_get_snapshot(const struct stasis_app_control *control)
Returns the most recent snapshot for the associated channel.
int stasis_app_channel_is_stasis_end_published(struct ast_channel *chan)
Has this channel had a StasisEnd published on it?
stasis_app_control_channel_result
Result codes used when adding/removing channels to/from bridges.
struct stasis_app_control::@497 next_app_args
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. ...
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
#define AST_MAX_EXTENSION
#define ast_channel_cleanup(c)
Cleanup a channel reference.
structure to hold extensions
Asterisk internal frame definitions.
struct ast_channel * channel
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 ...
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.
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.
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.
#define ast_malloc(len)
A wrapper for malloc()
#define AST_VECTOR_STEAL_ELEMENTS(vec)
Steal the elements from a vector and reinitialize.
#define ast_debug(level,...)
Log a DEBUG message.
#define AST_VECTOR(name, type)
Define a vector structure.
Rule to check to see if an operation is allowed.
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.
void(* command_data_destructor_fn)(void *data)
Typedef for data destructor for stasis app commands.
Core PBX routines and definitions.
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel's frame queue.
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
struct ast_bridge_features * bridge_features
static int set_timeout(struct ast_channel *chan, unsigned int timeout)
Set dial timeout on a channel to be dialed.
struct ao2_container * command_queue
ast_frame_type
Frame types.
struct ast_silence_generator * ast_channel_start_silence_generator(struct ast_channel *chan)
Starts a silence generator on the given channel.
struct stasis_topic * ast_channel_topic(struct ast_channel *chan)
A topic which publishes the events for a particular channel.
unsigned int dtmf_passthrough
int stasis_app_control_ring(struct stasis_app_control *control)
Indicate ringing to the channel associated with this control.
Structure that contains information about a bridge.
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
int stasis_app_control_bridge_features_init(struct stasis_app_control *control)
Initialize bridge features into a channel control.
static void set_interval_hook(struct ast_channel *chan)
Set a dial timeout interval hook on the channel.
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.
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.
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
int ast_bridge_depart(struct ast_channel *chan)
Depart a channel from a bridge.
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
struct stasis_app_control * control_create(struct ast_channel *channel, struct stasis_app *app)
Create a control object.
const char * app_name(struct ast_app *app)
int stasis_app_control_queue_control(struct stasis_app_control *control, enum ast_control_frame_type frame_type)
Queue a control frame without payload.
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.
int ast_channel_is_bridged(const struct ast_channel *chan)
Determine if a channel is in a bridge.
const char * stasis_app_control_get_channel_id(const struct stasis_app_control *control)
Returns the uniqueid of the channel associated with this control.
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
int stasis_app_control_ring_stop(struct stasis_app_control *control)
Stop locally generated ringing on the channel associated with this control.
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.
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic's subscribers.
#define AST_LIST_HEAD_INIT(head)
Initializes a list head structure.
#define ast_calloc(num, len)
A wrapper for calloc()
void stasis_app_control_publish(struct stasis_app_control *control, struct stasis_message *message)
Publish a message to the control's channel's topic.
#define AST_VECTOR_RESET(vec, cleanup)
Reset vector.
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.
void stasis_app_control_moh_stop(struct stasis_app_control *control)
Stop playing music on hold to a channel (does not affect hold status)
struct ast_bridge * bridge
void control_set_app(struct stasis_app_control *control, struct stasis_app *app)
Set the application the control object belongs to.
struct ast_channel * swap
void stasis_app_control_unhold(struct stasis_app_control *control)
Remove the channel associated with the control from hold.
Basic bridge subclass API.
struct ast_bridge_channel * ast_channel_get_bridge_channel(struct ast_channel *chan)
Get a reference to the channel's bridge pointer.
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.
void control_silence_stop_now(struct stasis_app_control *control)
Stop playing silence to a channel right now.
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...
void ast_channel_clear_bridge_roles(struct ast_channel *chan)
Removes all bridge roles currently on a channel.
int control_is_done(struct stasis_app_control *control)
Returns true if control_continue() has been called on this control.
struct ast_bridge_features * ast_bridge_features_new(void)
Allocate a new bridge features struct.
struct ast_frame ast_null_frame
void stasis_app_control_silence_start(struct stasis_app_control *control)
Start playing silence to a channel.
struct ast_channel * chan
Structure that contains information regarding a channel in a bridge.
After Bridge Execution API.
#define ast_channel_ref(c)
Increase channel reference count.
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...
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
structure for queuing ARI channel variable setting
int app_unsubscribe_bridge(struct stasis_app *app, struct ast_bridge *bridge)
Cancel the bridge subscription for an application.
Internal API for the Stasis application controller.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
int ast_transfer(struct ast_channel *chan, char *dest)
Transfer a channel (if supported).
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().
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.
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.
struct ast_datastore_info timeout_datastore
Dial timeout datastore.
Stasis Application API. See Stasis Application API for detailed documentation.
static int shutting_down
Indicates if the Stasis app internals are being shut down.
int ast_softhangup_nolock(struct ast_channel *chan, int cause)
Softly hangup up a channel (no channel lock)
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)
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore)
Remove a datastore from a channel.
int ast_bridge_setup_after_goto(struct ast_channel *chan)
Setup any after bridge goto location to begin execution.
static struct ast_bridge * dial_bridge
Singleton dial bridge.
int stasis_app_control_remove_channel_from_bridge(struct stasis_app_control *control, struct ast_bridge *bridge)
Remove a channel from the bridge.
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
int control_prestart_dispatch_all(struct stasis_app_control *control, struct ast_channel *chan)
Dispatch all queued prestart commands.
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.
struct ast_silence_generator * silgen
struct app_control_rules add_rules
void control_wait(struct stasis_app_control *control)
Blocks until control's command queue has a command available.
struct stasis_app_control * stasis_app_control_find_by_channel(const struct ast_channel *chan)
Returns the handler for the given channel.