59 const char *bridge_id)
76 "Bridge not in Stasis application");
94 const char *channel_id)
101 if (control ==
NULL) {
106 if (snapshot ==
NULL) {
109 "Channel not found");
115 "Channel not in Stasis application");
132 for (i = 0; i < list->
count; ++i) {
153 for (i = 0; i <
count; ++i) {
157 list->controls[list->count] =
159 if (!list->controls[list->count]) {
166 if (list->count == 0) {
182 response, 409,
"Conflict",
"Channel %s currently recording",
211 for (i = 0; i < list->count; ++i) {
228 for (i = 0; i < list->count; ++i) {
231 list->controls[i], bridge)))) {
261 for (i = 0; i < list->count; ++i) {
266 "Unprocessable Entity",
267 "Channel not in this bridge");
273 for (i = 0; i < list->count; ++i) {
359 size_t args_media_count,
360 const char *args_lang,
363 const char *args_playback_id,
378 response, 500,
"Internal Error",
"Failed to get control snapshot");
386 args_offset_ms, args_playback_id);
409 size_t args_media_count,
410 const char *args_lang,
413 const char *args_playback_id,
436 response, 500,
"Internal Error",
"Could not create playback channel");
448 if (!bridge_topic || !channel_topic || !(channel_forward =
stasis_forward_all(channel_topic, bridge_topic))) {
450 response, 500,
"Internal Error",
"Could not forward playback channel stasis messages to bridge topic");
457 response, 500,
"Internal Error",
"Failed to put playback channel into the bridge");
462 if (control ==
NULL) {
469 args_offset_ms, args_skipms, args_playback_id, response, bridge,
470 control, &json, &playback_url)) {
492 thread_data->
control = control;
493 thread_data->
forward = channel_forward;
507 channel_forward =
NULL;
539 size_t args_media_count,
540 const char *args_lang,
543 const char *args_playback_id,
566 args_lang, args_offset_ms, args_skipms, args_playback_id,
567 response, bridge, control, &json, &playback_url)) {
578 const char *args_bridge_id,
579 const char **args_media,
580 size_t args_media_count,
581 const char *args_lang,
584 const char *args_playback_id,
604 args_offset_ms, args_skipms, args_playback_id, response,
bridge,
612 args_skipms, args_playback_id, response,
bridge);
660 size_t uri_name_maxlen;
666 if (bridge ==
NULL) {
672 response, 500,
"Internal Server Error",
"Failed to create recording channel");
683 if (!bridge_topic || !channel_topic || !(channel_forward =
stasis_forward_all(channel_topic, bridge_topic))) {
685 response, 500,
"Internal Error",
"Could not forward record channel stasis messages to bridge topic");
692 response, 500,
"Internal Error",
"Failed to put recording channel into the bridge");
709 options->max_silence_seconds =
args->max_silence_seconds;
710 options->max_duration_seconds =
args->max_duration_seconds;
719 response, 400,
"Bad Request",
720 "terminateOn invalid");
726 response, 400,
"Bad Request",
733 response, 422,
"Unprocessable Entity",
734 "specified format is unknown on this system");
739 if (recording ==
NULL) {
746 response, 500,
"Internal Server Error",
747 "Error parsing request");
751 "Recording '%s' already exists and can not be overwritten",
759 response, 400,
"Bad Request",
760 "Recording name invalid");
764 "Unrecognized recording error: %s\n",
767 response, 500,
"Internal Server Error",
768 "Internal Server Error");
774 uri_name_maxlen = strlen(
args->name) * 3;
775 uri_encoded_name =
ast_malloc(uri_name_maxlen);
776 if (!uri_encoded_name) {
783 uri_encoded_name) == -1) {
784 recording_url =
NULL;
795 thread_data =
ast_calloc(1,
sizeof(*thread_data));
803 thread_data->
forward = channel_forward;
812 record_channel =
NULL;
814 channel_forward =
NULL;
825 const char *moh_class =
args->moh_class;
858 response, 409,
"Conflict",
859 "Bridge isn't playing music");
873 response, 404,
"Not Found",
955 response, 500,
"Internal Error",
956 "Unable to create bridge");
966 response, 500,
"Internal Error",
967 "Unable to create snapshot for new bridge");
985 && strcmp(
args->name, bridge->name)) {
987 response, 500,
"Internal Error",
988 "Changing bridge name is not implemented");
993 response, 500,
"Internal Error",
994 "Supplying a bridge type when updating a bridge is not allowed.");
1005 response, 500,
"Internal Error",
1006 "Unable to create bridge");
1016 response, 500,
"Internal Error",
1017 "Unable to create snapshot for new bridge");
1056 "Unprocessable Entity",
1057 "Channel not in this bridge");
void ast_ari_response_created(struct ast_ari_response *response, const char *url, struct ast_json *message)
Fill in a Created (201) ast_ari_response.
void ast_ari_response_error(struct ast_ari_response *response, int response_code, const char *response_text, const char *message_fmt,...)
Fill in an error ast_ari_response.
void ast_ari_response_ok(struct ast_ari_response *response, struct ast_json *message)
Fill in an OK (200) ast_ari_response.
void ast_ari_response_alloc_failed(struct ast_ari_response *response)
Fill in response with a 500 message for allocation failures.
void ast_ari_response_no_content(struct ast_ari_response *response)
Fill in a No Content (204) ast_ari_response.
Asterisk main include file. File version handling, generic pbx functions.
#define ast_strdupa(s)
duplicate a string in memory from the stack
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
#define ast_calloc(num, len)
A wrapper for calloc()
#define ast_malloc(len)
A wrapper for malloc()
#define ao2_iterator_next(iter)
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
void __ao2_cleanup(void *obj)
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_alloc(data_size, destructor_fn)
static struct ao2_container * bridges
struct ao2_container * ast_bridges(void)
Returns the global bridges container.
void ast_bridge_set_talker_src_video_mode(struct ast_bridge *bridge)
Set the bridge to pick the strongest talker supporting video as the single source video feed.
#define ast_bridge_unlock(bridge)
Unlock the bridge.
void ast_bridge_set_single_src_video_mode(struct ast_bridge *bridge, struct ast_channel *video_src_chan)
Set a bridge to feed a single video source to all participants.
#define ast_bridge_lock(bridge)
Lock the bridge.
int ast_bridge_queue_everyone_else(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
Queue the given frame to everyone else.
@ AST_BRIDGE_FLAG_INVISIBLE
@ AST_BRIDGE_CHANNEL_FLAG_IMMOVABLE
@ AST_BRIDGE_CHANNEL_FLAG_LONELY
static char language[MAX_LANGUAGE]
General Asterisk PBX channel definitions.
const char * ast_channel_name(const struct ast_channel *chan)
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
struct stasis_topic * ast_channel_topic(struct ast_channel *chan)
A topic which publishes the events for a particular channel.
ast_callid ast_channel_callid(const struct ast_channel *chan)
#define ast_channel_cleanup(c)
Cleanup a channel reference.
struct ast_channel * ast_request(const char *type, struct ast_format_cap *request_cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *addr, int *cause)
Requests a channel.
static struct channel_usage channels
Unreal channel derivative framework.
int ast_unreal_channel_push_to_bridge(struct ast_channel *ast, struct ast_bridge *bridge, unsigned int flags)
Push the semi2 unreal channel into a bridge from either member of the unreal pair.
Generic File Format Support. Should be included by clients of the file handling routines....
struct ast_format * ast_get_format_for_file_ext(const char *file_ext)
Get the ast_format associated with the given file extension.
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,...
@ AST_RECORD_IF_EXISTS_ERROR
#define ast_debug(level,...)
Log a DEBUG message.
int ast_callid_threadassoc_add(ast_callid callid)
Adds a known callid to thread storage of the calling thread.
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
int ast_json_array_append(struct ast_json *array, struct ast_json *value)
Append to an array.
struct ast_json * ast_json_array_create(void)
Create a empty JSON array.
struct ast_json * ast_json_ref(struct ast_json *value)
Increase refcount on value.
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
void ast_ari_bridges_add_channel(struct ast_variable *headers, struct ast_ari_bridges_add_channel_args *args, struct ast_ari_response *response)
Add a channel to a bridge.
void ast_ari_bridges_clear_video_source(struct ast_variable *headers, struct ast_ari_bridges_clear_video_source_args *args, struct ast_ari_response *response)
Removes any explicit video source in a multi-party mixing bridge. This operation has no effect on bri...
void ast_ari_bridges_get(struct ast_variable *headers, struct ast_ari_bridges_get_args *args, struct ast_ari_response *response)
Get bridge details.
static struct stasis_app_control * find_channel_control(struct ast_ari_response *response, const char *channel_id)
Finds the control object for a channel, filling the response with an error, if appropriate.
void ast_ari_bridges_play_with_id(struct ast_variable *headers, struct ast_ari_bridges_play_with_id_args *args, struct ast_ari_response *response)
Start playback of media on a bridge.
static struct control_list * control_list_create(struct ast_ari_response *response, size_t count, const char **channels)
void ast_ari_bridges_play(struct ast_variable *headers, struct ast_ari_bridges_play_args *args, struct ast_ari_response *response)
Start playback of media on a bridge.
static void control_list_dtor(void *obj)
static struct ast_bridge * find_bridge(struct ast_ari_response *response, const char *bridge_id)
Finds a bridge, filling the response with an error, if appropriate.
static int bridge_set_video_source_cb(struct stasis_app_control *control, struct ast_channel *chan, void *data)
void ast_ari_bridges_destroy(struct ast_variable *headers, struct ast_ari_bridges_destroy_args *args, struct ast_ari_response *response)
Shut down a bridge.
@ PLAY_FOUND_CHANNEL_UNAVAILABLE
void ast_ari_bridges_remove_channel(struct ast_variable *headers, struct ast_ari_bridges_remove_channel_args *args, struct ast_ari_response *response)
Remove a channel from a bridge.
void ast_ari_bridges_create(struct ast_variable *headers, struct ast_ari_bridges_create_args *args, struct ast_ari_response *response)
Create a new bridge.
void ast_ari_bridges_create_with_id(struct ast_variable *headers, struct ast_ari_bridges_create_with_id_args *args, struct ast_ari_response *response)
Create a new bridge or updates an existing one.
static int ari_bridges_play_helper(const char **args_media, size_t args_media_count, const char *args_lang, int args_offset_ms, int args_skipms, const char *args_playback_id, struct ast_ari_response *response, struct ast_bridge *bridge, struct stasis_app_control *control, struct ast_json **json, char **playback_url)
Performs common setup for a bridge playback operation with both new controls and when existing contro...
static void * bridge_channel_control_thread(void *data)
static int check_add_remove_channel(struct ast_ari_response *response, struct stasis_app_control *control, enum stasis_app_control_channel_result result)
static void ari_bridges_play_new(const char **args_media, size_t args_media_count, const char *args_lang, int args_offset_ms, int args_skipms, const char *args_playback_id, struct ast_ari_response *response, struct ast_bridge *bridge)
void ast_ari_bridges_set_video_source(struct ast_variable *headers, struct ast_ari_bridges_set_video_source_args *args, struct ast_ari_response *response)
Set a channel as the video source in a multi-party mixing bridge. This operation has no effect on bri...
static enum play_found_result ari_bridges_play_found(const char **args_media, size_t args_media_count, const char *args_lang, int args_offset_ms, int args_skipms, const char *args_playback_id, struct ast_ari_response *response, struct ast_bridge *bridge, struct ast_channel *found_channel)
Performs common setup for a bridge playback operation with both new controls and when existing contro...
void ast_ari_bridges_record(struct ast_variable *headers, struct ast_ari_bridges_record_args *args, struct ast_ari_response *response)
Start a recording.
void ast_ari_bridges_start_moh(struct ast_variable *headers, struct ast_ari_bridges_start_moh_args *args, struct ast_ari_response *response)
Play music on hold to a bridge or change the MOH class that is playing.
static void ari_bridges_handle_play(const char *args_bridge_id, const char **args_media, size_t args_media_count, const char *args_lang, int args_offset_ms, int args_skipms, const char *args_playback_id, struct ast_ari_response *response)
void ast_ari_bridges_stop_moh(struct ast_variable *headers, struct ast_ari_bridges_stop_moh_args *args, struct ast_ari_response *response)
Stop playing music on hold to a bridge.
void ast_ari_bridges_list(struct ast_variable *headers, struct ast_ari_bridges_list_args *args, struct ast_ari_response *response)
List all active bridges in Asterisk.
static struct ast_channel * prepare_bridge_media_channel(const char *type)
Generated file - declares stubs to be implemented in res/ari/resource_bridges.c.
Stasis Message Bus API. See Stasis Message Bus API for detailed documentation.
struct stasis_forward * stasis_forward_cancel(struct stasis_forward *forward)
struct stasis_forward * stasis_forward_all(struct stasis_topic *from_topic, struct stasis_topic *to_topic)
Create a subscription which forwards all messages from one topic to another.
Stasis Application API. See Stasis Application API for detailed documentation.
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.
void stasis_app_bridge_playback_channel_remove(char *bridge_id, struct stasis_app_control *control)
remove channel from list of ARI playback channels for bridges.
struct stasis_message_sanitizer * stasis_app_get_sanitizer(void)
Get the Stasis message sanitizer for app_stasis applications.
const char * stasis_app_control_get_channel_id(const struct stasis_app_control *control)
Returns the uniqueid of the channel associated with this control.
int stasis_app_control_add_channel_to_bridge(struct stasis_app_control *control, struct ast_bridge *bridge)
Add a channel to the bridge.
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.
void stasis_app_bridge_destroy(const char *bridge_id)
Destroy the bridge.
struct ast_bridge * stasis_app_bridge_find_by_id(const char *bridge_id)
Returns the bridge with the given id.
struct ast_bridge * stasis_app_bridge_create(const char *type, const char *name, const char *id)
Create a bridge of the specified type.
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.
void stasis_app_control_execute_until_exhausted(struct ast_channel *chan, struct stasis_app_control *control)
Act on a stasis app control queue until it is empty.
struct ast_channel * stasis_app_bridge_moh_channel(struct ast_bridge *bridge)
Finds or creates an announcer channel in a bridge that can play music on hold.
void stasis_app_control_flush_queue(struct stasis_app_control *control)
Flush the control command queue.
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.
int stasis_app_channel_unreal_set_internal(struct ast_channel *chan)
Mark this unreal channel and it's other half as being internal to Stasis.
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.
int stasis_app_control_remove_channel_from_bridge(struct stasis_app_control *control, struct ast_bridge *bridge)
Remove a channel from the bridge.
struct ast_bridge * stasis_app_get_bridge(struct stasis_app_control *control)
Gets the bridge currently associated with a control object.
int stasis_app_control_bridge_features_init(struct stasis_app_control *control)
Initialize bridge features into a channel control.
int stasis_app_bridge_playback_channel_add(struct ast_bridge *bridge, struct ast_channel *chan, struct stasis_app_control *control)
Adds a channel to the list of ARI playback channels for bridges.
struct stasis_app_control * stasis_app_control_find_by_channel_id(const char *channel_id)
Returns the handler for the channel with the given id.
struct ast_channel * stasis_app_bridge_playback_channel_find(struct ast_bridge *bridge)
Finds an existing ARI playback channel in a bridge.
int stasis_app_control_is_done(struct stasis_app_control *control)
Check if a control is marked as done.
struct ast_channel_snapshot * stasis_app_control_get_snapshot(const struct stasis_app_control *control)
Returns the most recent snapshot for the associated channel.
stasis_app_control_channel_result
Result codes used when adding/removing channels to/from bridges.
@ STASIS_APP_CHANNEL_RECORDING
@ STASIS_APP_CHANNEL_OKAY
struct stasis_app_control * stasis_app_control_find_by_channel(const struct ast_channel *chan)
Returns the handler for the given channel.
struct stasis_app_control * stasis_app_control_create(struct ast_channel *chan)
Creates a control handler for a channel that isn't in a stasis app.
int stasis_app_bridge_moh_stop(struct ast_bridge *bridge)
Breaks down MOH channels playing on the bridge created by stasis_app_bridge_moh_channel.
Backend API for implementing components of res_stasis.
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.
Stasis Application Playback API. See StasisApplication API" for detailed documentation.
@ STASIS_PLAYBACK_TARGET_BRIDGE
struct stasis_app_playback * stasis_app_control_play_uri(struct stasis_app_control *control, const char **media, size_t media_count, const char *language, const char *target_id, enum stasis_app_playback_target_type target_type, int skipms, long offsetms, const char *id)
Play a file to the control's channel.
struct ast_json * stasis_app_playback_to_json(const struct stasis_app_playback *playback)
Convert a playback to its JSON representation.
const char * stasis_app_playback_get_id(struct stasis_app_playback *playback)
Gets the unique id of a playback object.
Stasis Application Recording API. See StasisApplication API" for detailed documentation.
struct stasis_app_recording_options * stasis_app_recording_options_create(const char *name, const char *format)
Allocate a recording options object.
struct ast_json * stasis_app_recording_to_json(const struct stasis_app_recording *recording)
Construct a JSON model of a recording.
struct stasis_app_recording * stasis_app_control_record(struct stasis_app_control *control, struct stasis_app_recording_options *options)
Record media from a channel.
enum ast_record_if_exists stasis_app_recording_if_exists_parse(const char *str)
Parse a string into the if_exists enum.
#define STASIS_APP_RECORDING_TERMINATE_INVALID
char stasis_app_recording_termination_parse(const char *str)
Parse a string into the recording termination enum.
struct ast_json * ast_bridge_snapshot_to_json(const struct ast_bridge_snapshot *snapshot, const struct stasis_message_sanitizer *sanitize)
Build a JSON object from a ast_bridge_snapshot.
struct ast_bridge_snapshot * ast_bridge_get_snapshot(struct ast_bridge *bridge)
Returns the current snapshot for the bridge.
struct ast_bridge_snapshot * ast_bridge_get_snapshot_by_uniqueid(const char *bridge_id)
Returns the current snapshot for the bridge.
struct ast_bridge_snapshot * ast_bridge_snapshot_create(struct ast_bridge *bridge)
Generate a snapshot of the bridge state. This is an ao2 object, so ao2_cleanup() to deallocate.
struct stasis_topic * ast_bridge_topic(struct ast_bridge *bridge)
A topic which publishes the events for a particular bridge.
#define ast_string_field_build(x, field, fmt, args...)
Set a field to a complex (built) value.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Structure that contains a snapshot of information about a bridge.
Structure that contains information about a bridge.
const ast_string_field uniqueid
struct ast_flags feature_flags
const ast_string_field language
Structure representing a snapshot of channel state.
struct ast_channel_snapshot_base * base
Main Channel structure associated with a channel.
struct ast_bridge_channel * bridge_channel
struct ast_channel_snapshot * snapshot
struct ast_bridge * bridge
struct stasis_forward * channel_forward
Data structure associated with a single frame of data.
enum ast_frame_type frametype
Abstract JSON element (object, array, string, int, ...).
Structure for variables, used for configurations and for channel variables.
struct ast_channel * bridge_channel
struct stasis_app_control * control
struct stasis_forward * forward
struct stasis_app_control * controls[]
struct ast_bridge * bridge
#define ast_test_flag(p, flag)
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
char * ast_uri_encode(const char *string, char *outbuf, int buflen, struct ast_flags spec)
Turn text string to URI-encoded XX version.
const struct ast_flags ast_uri_http
#define ast_pthread_create_detached(a, b, c, d)