Asterisk - The Open Source Telephony Project  18.5.0
Data Structures | Enumerations | Functions
resource_bridges.c File Reference

Implementation for ARI stubs. More...

#include "asterisk.h"
#include "resource_bridges.h"
#include "asterisk/stasis.h"
#include "asterisk/stasis_bridges.h"
#include "asterisk/stasis_app.h"
#include "asterisk/stasis_app_impl.h"
#include "asterisk/stasis_app_playback.h"
#include "asterisk/stasis_app_recording.h"
#include "asterisk/stasis_channels.h"
#include "asterisk/core_unreal.h"
#include "asterisk/channel.h"
#include "asterisk/bridge.h"
#include "asterisk/format_cap.h"
#include "asterisk/file.h"
#include "asterisk/musiconhold.h"
#include "asterisk/format_cache.h"
Include dependency graph for resource_bridges.c:

Go to the source code of this file.

Data Structures

struct  bridge_channel_control_thread_data
 
struct  control_list
 

Enumerations

enum  play_found_result { PLAY_FOUND_SUCCESS, PLAY_FOUND_FAILURE, PLAY_FOUND_CHANNEL_UNAVAILABLE }
 

Functions

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)
 
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 controls are found. More...
 
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 controls are found. More...
 
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_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. More...
 
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 bridges with two or fewer participants. When no explicit video source is set, talk detection will be used to determine the active video stream. More...
 
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. More...
 
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. More...
 
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. More...
 
void ast_ari_bridges_get (struct ast_variable *headers, struct ast_ari_bridges_get_args *args, struct ast_ari_response *response)
 Get bridge details. More...
 
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. More...
 
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. More...
 
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. More...
 
void ast_ari_bridges_record (struct ast_variable *headers, struct ast_ari_bridges_record_args *args, struct ast_ari_response *response)
 Start a recording. More...
 
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. More...
 
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 bridges with two or fewer participants. More...
 
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. More...
 
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. More...
 
static void * bridge_channel_control_thread (void *data)
 
static int bridge_set_video_source_cb (struct stasis_app_control *control, struct ast_channel *chan, 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 struct control_listcontrol_list_create (struct ast_ari_response *response, size_t count, const char **channels)
 
static void control_list_dtor (void *obj)
 
static struct ast_bridgefind_bridge (struct ast_ari_response *response, const char *bridge_id)
 Finds a bridge, filling the response with an error, if appropriate. More...
 
static struct stasis_app_controlfind_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. More...
 
static struct ast_channelprepare_bridge_media_channel (const char *type)
 

Detailed Description

Implementation for ARI stubs.

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

Definition in file resource_bridges.c.

Enumeration Type Documentation

◆ play_found_result

Enumerator
PLAY_FOUND_SUCCESS 
PLAY_FOUND_FAILURE 
PLAY_FOUND_CHANNEL_UNAVAILABLE 

Definition at line 503 of file resource_bridges.c.

Function Documentation

◆ ari_bridges_handle_play()

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

Definition at line 567 of file resource_bridges.c.

References ao2_cleanup, ari_bridges_play_found(), ari_bridges_play_new(), ast_assert, find_bridge(), NULL, PLAY_FOUND_CHANNEL_UNAVAILABLE, RAII_VAR, and stasis_app_bridge_playback_channel_find().

Referenced by ast_ari_bridges_play(), and ast_ari_bridges_play_with_id().

576 {
577  RAII_VAR(struct ast_bridge *, bridge, find_bridge(response, args_bridge_id), ao2_cleanup);
578  struct ast_channel *play_channel;
579 
580  ast_assert(response != NULL);
581 
582  if (!bridge) {
583  return;
584  }
585 
586  while ((play_channel = stasis_app_bridge_playback_channel_find(bridge))) {
587  /* If ari_bridges_play_found fails because the channel is unavailable for
588  * playback, The channel will be removed from the playback list soon. We
589  * can keep trying to get channels from the list until we either get one
590  * that will work or else there isn't a channel for this bridge anymore,
591  * in which case we'll revert to ari_bridges_play_new.
592  */
593  if (ari_bridges_play_found(args_media, args_media_count, args_lang,
594  args_offset_ms, args_skipms, args_playback_id, response,bridge,
595  play_channel) == PLAY_FOUND_CHANNEL_UNAVAILABLE) {
596  continue;
597  }
598  return;
599  }
600 
601  ari_bridges_play_new(args_media, args_media_count, args_lang, args_offset_ms,
602  args_skipms, args_playback_id, response, bridge);
603 }
Main Channel structure associated with a channel.
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 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)
#define ast_assert(a)
Definition: utils.h:695
#define NULL
Definition: resample.c:96
#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
Structure that contains information about a bridge.
Definition: bridge.h:357
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...
struct ast_channel * stasis_app_bridge_playback_channel_find(struct ast_bridge *bridge)
Finds an existing ARI playback channel in a bridge.
Definition: res_stasis.c:759
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ ari_bridges_play_found()

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

Performs common setup for a bridge playback operation with both new controls and when existing controls are found.

Parameters
args_mediamedias to play
args_media_countnumber of media items in media
args_langlanguage string split from arguments
args_offset_msmilliseconds offset split from arguments
args_playback_idstring to use for playback split from arguments (null valid)
responseARI response being built
bridgeBridge the playback is being peformed on
found_channelThe channel that was found controlling playback
Return values
PLAY_FOUND_SUCCESSThe operation was successful
PLAY_FOUND_FAILUREThe operation failed (terminal failure)
PLAY_FOUND_CHANNEL_UNAVAILABLEThe operation failed because the channel requested to playback with is breaking down.

Definition at line 528 of file resource_bridges.c.

References ao2_cleanup, ao2_lock, ao2_unlock, ari_bridges_play_helper(), ast_ari_response_created(), ast_free, ast_json_ref(), ast_json_unref(), bridge_channel_control_thread_data::control, NULL, PLAY_FOUND_CHANNEL_UNAVAILABLE, PLAY_FOUND_FAILURE, PLAY_FOUND_SUCCESS, RAII_VAR, stasis_app_control_find_by_channel(), and stasis_app_control_is_done().

Referenced by ari_bridges_handle_play().

537 {
538  RAII_VAR(struct ast_channel *, play_channel, found_channel, ao2_cleanup);
539  RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
540  RAII_VAR(char *, playback_url, NULL, ast_free);
541  RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
542 
543  control = stasis_app_control_find_by_channel(play_channel);
544  if (!control) {
546  }
547 
548  ao2_lock(control);
549  if (stasis_app_control_is_done(control)) {
550  /* We failed to queue the action. Bailout and return that we aren't terminal. */
551  ao2_unlock(control);
553  }
554 
555  if (ari_bridges_play_helper(args_media, args_media_count,
556  args_lang, args_offset_ms, args_skipms, args_playback_id,
557  response, bridge, control, &json, &playback_url)) {
558  ao2_unlock(control);
559  return PLAY_FOUND_FAILURE;
560  }
561  ao2_unlock(control);
562 
563  ast_ari_response_created(response, playback_url, ast_json_ref(json));
564  return PLAY_FOUND_SUCCESS;
565 }
Main Channel structure associated with a channel.
struct ast_json * ast_json_ref(struct ast_json *value)
Increase refcount on value.
Definition: json.c:67
int stasis_app_control_is_done(struct stasis_app_control *control)
Check if a control is marked as done.
Definition: res_stasis.c:1273
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
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.
Definition: res_ari.c:305
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
#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
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...
#define ao2_lock(a)
Definition: astobj2.h:718
#define ast_free(a)
Definition: astmm.h:182
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Abstract JSON element (object, array, string, int, ...).
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

◆ ari_bridges_play_helper()

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

Performs common setup for a bridge playback operation with both new controls and when existing controls are found.

Parameters
args_mediamedias to play
args_media_countnumber of media items in media
args_langlanguage string split from arguments
args_offset_msmilliseconds offset split from arguments
args_playback_idstring to use for playback split from arguments (null valid)
responseARI response being built
bridgeBridge the playback is being peformed on
controlControl being used for the playback channel
jsoncontents of the response to ARI
playback_urlstores playback URL for use with response
Return values
-1operation failed
operationwas successful

Definition at line 357 of file resource_bridges.c.

References ao2_cleanup, ast_ari_response_alloc_failed(), ast_ari_response_error(), ast_asprintf, language, NULL, RAII_VAR, S_OR, stasis_app_control_get_snapshot(), stasis_app_control_play_uri(), stasis_app_playback_get_id(), stasis_app_playback_to_json(), STASIS_PLAYBACK_TARGET_BRIDGE, and ast_bridge::uniqueid.

Referenced by ari_bridges_play_found(), and ari_bridges_play_new().

368 {
369  RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
370  RAII_VAR(struct stasis_app_playback *, playback, NULL, ao2_cleanup);
371 
372  const char *language;
373 
374  snapshot = stasis_app_control_get_snapshot(control);
375  if (!snapshot) {
377  response, 500, "Internal Error", "Failed to get control snapshot");
378  return -1;
379  }
380 
381  language = S_OR(args_lang, snapshot->base->language);
382 
383  playback = stasis_app_control_play_uri(control, args_media, args_media_count,
384  language, bridge->uniqueid, STASIS_PLAYBACK_TARGET_BRIDGE, args_skipms,
385  args_offset_ms, args_playback_id);
386 
387  if (!playback) {
389  return -1;
390  }
391 
392  if (ast_asprintf(playback_url, "/playbacks/%s",
393  stasis_app_playback_get_id(playback)) == -1) {
395  return -1;
396  }
397 
398  *json = stasis_app_playback_to_json(playback);
399  if (!*json) {
401  return -1;
402  }
403 
404  return 0;
405 }
const ast_string_field uniqueid
Definition: bridge.h:409
Structure representing a snapshot of channel state.
struct ast_json * stasis_app_playback_to_json(const struct stasis_app_playback *playback)
Convert a playback to its JSON representation.
#define NULL
Definition: resample.c:96
void ast_ari_response_alloc_failed(struct ast_ari_response *response)
Fill in response with a 500 message for allocation failures.
Definition: res_ari.c:298
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:269
const char * stasis_app_playback_get_id(struct stasis_app_playback *playback)
Gets the unique id of a playback object.
#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
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:117
struct ast_channel_snapshot * stasis_app_control_get_snapshot(const struct stasis_app_control *control)
Returns the most recent snapshot for the associated channel.
Definition: control.c:860
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.
Definition: res_ari.c:259
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
#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
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.

◆ ari_bridges_play_new()

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

Definition at line 407 of file resource_bridges.c.

References ao2_cleanup, ao2_lock, ao2_unlock, ari_bridges_play_helper(), ast_ari_response_alloc_failed(), ast_ari_response_created(), ast_ari_response_error(), AST_BRIDGE_CHANNEL_FLAG_IMMOVABLE, AST_BRIDGE_CHANNEL_FLAG_LONELY, ast_bridge_topic(), ast_channel_name(), ast_channel_topic(), ast_debug, ast_free, ast_hangup(), ast_json_ref(), ast_json_unref(), ast_malloc, ast_pthread_create_detached, ast_unreal_channel_push_to_bridge(), bridge_channel_control_thread_data::bridge_channel, bridge_channel_control_thread(), bridge_channel_control_thread_data::bridge_id, bridge_channel_control_thread_data::control, bridge_channel_control_thread_data::forward, NULL, prepare_bridge_media_channel(), RAII_VAR, stasis_app_bridge_playback_channel_add(), stasis_app_bridge_playback_channel_remove(), stasis_app_control_create(), stasis_forward_all(), stasis_forward_cancel(), and ast_bridge::uniqueid.

Referenced by ari_bridges_handle_play().

415 {
416  RAII_VAR(struct ast_channel *, play_channel, NULL, ast_hangup);
417  RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
418  RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
419  RAII_VAR(struct stasis_forward *, channel_forward, NULL, stasis_forward_cancel);
420  RAII_VAR(char *, playback_url, NULL, ast_free);
421 
422  struct stasis_topic *channel_topic;
423  struct stasis_topic *bridge_topic;
424  struct bridge_channel_control_thread_data *thread_data;
425  pthread_t threadid;
426 
427  if (!(play_channel = prepare_bridge_media_channel("Announcer"))) {
429  response, 500, "Internal Error", "Could not create playback channel");
430  return;
431  }
432  ast_debug(1, "Created announcer channel '%s'\n", ast_channel_name(play_channel));
433 
434  bridge_topic = ast_bridge_topic(bridge);
435  channel_topic = ast_channel_topic(play_channel);
436 
437  /* Forward messages from the playback channel topic to the bridge topic so that anything listening for
438  * messages on the bridge topic will receive the playback start/stop messages. Other messages that would
439  * go to this channel will be suppressed since the channel is marked as internal.
440  */
441  if (!bridge_topic || !channel_topic || !(channel_forward = stasis_forward_all(channel_topic, bridge_topic))) {
443  response, 500, "Internal Error", "Could not forward playback channel stasis messages to bridge topic");
444  return;
445  }
446 
447  if (ast_unreal_channel_push_to_bridge(play_channel, bridge,
450  response, 500, "Internal Error", "Failed to put playback channel into the bridge");
451  return;
452  }
453 
454  control = stasis_app_control_create(play_channel);
455  if (control == NULL) {
457  return;
458  }
459 
460  ao2_lock(control);
461  if (ari_bridges_play_helper(args_media, args_media_count, args_lang,
462  args_offset_ms, args_skipms, args_playback_id, response, bridge,
463  control, &json, &playback_url)) {
465  return;
466  }
468 
469  if (stasis_app_bridge_playback_channel_add(bridge, play_channel, control)) {
471  return;
472  }
473 
474  /* Give play_channel and control reference to the thread data */
475  thread_data = ast_malloc(sizeof(*thread_data) + strlen(bridge->uniqueid) + 1);
476  if (!thread_data) {
479  return;
480  }
481 
482  thread_data->bridge_channel = play_channel;
483  thread_data->control = control;
484  thread_data->forward = channel_forward;
485  /* Safe */
486  strcpy(thread_data->bridge_id, bridge->uniqueid);
487 
488  if (ast_pthread_create_detached(&threadid, NULL, bridge_channel_control_thread, thread_data)) {
491  ast_free(thread_data);
492  return;
493  }
494 
495  /* These are owned by the other thread now, so we don't want RAII_VAR disposing of them. */
496  play_channel = NULL;
497  control = NULL;
498  channel_forward = NULL;
499 
500  ast_ari_response_created(response, playback_url, ast_json_ref(json));
501 }
Main Channel structure associated with a channel.
struct ast_json * ast_json_ref(struct ast_json *value)
Increase refcount on value.
Definition: json.c:67
const ast_string_field uniqueid
Definition: bridge.h:409
#define ast_pthread_create_detached(a, b, c, d)
Definition: utils.h:563
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
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.
Definition: res_stasis.c:333
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.
Definition: res_ari.c:305
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.
Definition: res_stasis.c:743
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
void ast_ari_response_alloc_failed(struct ast_ari_response *response)
Fill in response with a 500 message for allocation failures.
Definition: res_ari.c:298
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#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
static void * bridge_channel_control_thread(void *data)
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.
Definition: core_unreal.c:928
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...
#define ao2_lock(a)
Definition: astobj2.h:718
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
struct stasis_topic * ast_channel_topic(struct ast_channel *chan)
A topic which publishes the events for a particular channel.
#define ast_free(a)
Definition: astmm.h:182
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.
Definition: res_ari.c:259
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2548
struct stasis_forward * stasis_forward_cancel(struct stasis_forward *forward)
Definition: stasis.c:1548
static struct ast_channel * prepare_bridge_media_channel(const char *type)
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.
Definition: res_stasis.c:705
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
const char * ast_channel_name(const struct ast_channel *chan)
Abstract JSON element (object, array, string, int, ...).
Forwarding information.
Definition: stasis.c:1531
struct stasis_topic * ast_bridge_topic(struct ast_bridge *bridge)
A topic which publishes the events for a particular bridge.
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.
Definition: stasis.c:1578
struct stasis_app_control * control

◆ ast_ari_bridges_add_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.

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 191 of file resource_bridges.c.

References ast_ari_bridges_add_channel_args::absorb_dtmf, ao2_cleanup, ast_ari_response_alloc_failed(), ast_ari_response_no_content(), ast_strlen_zero, ast_ari_bridges_add_channel_args::bridge_id, ast_ari_bridges_add_channel_args::channel, ast_ari_bridges_add_channel_args::channel_count, check_add_remove_channel(), control_list_create(), find_bridge(), ast_ari_bridges_add_channel_args::inhibit_connected_line_updates, ast_ari_bridges_add_channel_args::mute, NULL, RAII_VAR, ast_ari_bridges_add_channel_args::role, stasis_app_control_absorb_dtmf_in_bridge(), stasis_app_control_add_channel_to_bridge(), stasis_app_control_add_role(), stasis_app_control_bridge_features_init(), stasis_app_control_clear_roles(), stasis_app_control_inhibit_colp_in_bridge(), and stasis_app_control_mute_in_bridge().

Referenced by ast_ari_bridges_add_channel_cb().

194 {
195  RAII_VAR(struct ast_bridge *, bridge, find_bridge(response, args->bridge_id), ao2_cleanup);
196  RAII_VAR(struct control_list *, list, NULL, ao2_cleanup);
197  size_t i;
198  int has_error = 0;
199 
200  if (!bridge) {
201  /* Response filled in by find_bridge() */
202  return;
203  }
204 
205  list = control_list_create(response, args->channel_count, args->channel);
206  if (!list) {
207  /* Response filled in by control_list_create() */
208  return;
209  }
210 
211  for (i = 0; i < list->count; ++i) {
212  stasis_app_control_clear_roles(list->controls[i]);
213  if (!ast_strlen_zero(args->role)) {
214  if (stasis_app_control_add_role(list->controls[i], args->role)) {
216  return;
217  }
218  }
219 
220  /* Apply bridge features to each of the channel controls */
221  if (!stasis_app_control_bridge_features_init(list->controls[i])) {
222  stasis_app_control_absorb_dtmf_in_bridge(list->controls[i], args->absorb_dtmf);
223  stasis_app_control_mute_in_bridge(list->controls[i], args->mute);
225  }
226  }
227 
228  for (i = 0; i < list->count; ++i) {
229  if ((has_error = check_add_remove_channel(response, list->controls[i],
231  list->controls[i], bridge)))) {
232  break;
233  }
234  }
235 
236  if (!has_error) {
237  ast_ari_response_no_content(response);
238  }
239 }
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.
Definition: control.c:1464
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.
Definition: control.c:316
int stasis_app_control_bridge_features_init(struct stasis_app_control *control)
Initialize bridge features into a channel control.
Definition: control.c:1451
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 check_add_remove_channel(struct ast_ari_response *response, struct stasis_app_control *control, enum stasis_app_control_channel_result result)
#define NULL
Definition: resample.c:96
static struct control_list * control_list_create(struct ast_ari_response *response, size_t count, const char **channels)
void ast_ari_response_alloc_failed(struct ast_ari_response *response)
Fill in response with a 500 message for allocation failures.
Definition: res_ari.c:298
#define ast_strlen_zero(foo)
Definition: strings.h:52
#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
int stasis_app_control_add_channel_to_bridge(struct stasis_app_control *control, struct ast_bridge *bridge)
Add a channel to the bridge.
Definition: control.c:1383
Structure that contains information about a bridge.
Definition: bridge.h:357
void ast_ari_response_no_content(struct ast_ari_response *response)
Fill in a No Content (204) ast_ari_response.
Definition: res_ari.c:284
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.
Definition: control.c:1476
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.
Definition: control.c:338
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
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.
Definition: control.c:1470

◆ ast_ari_bridges_clear_video_source()

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 bridges with two or fewer participants. When no explicit video source is set, talk detection will be used to determine the active video stream.

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 1051 of file resource_bridges.c.

References ao2_ref, ast_ari_response_no_content(), ast_bridge_lock, ast_bridge_set_talker_src_video_mode(), ast_bridge_unlock, ast_ari_bridges_clear_video_source_args::bridge_id, and find_bridge().

Referenced by ast_ari_bridges_clear_video_source_cb().

1053 {
1054  struct ast_bridge *bridge;
1055 
1056  bridge = find_bridge(response, args->bridge_id);
1057  if (!bridge) {
1058  return;
1059  }
1060 
1061  ast_bridge_lock(bridge);
1063  ast_bridge_unlock(bridge);
1064 
1065  ao2_ref(bridge, -1);
1066  ast_ari_response_no_content(response);
1067 }
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.
#define ao2_ref(o, delta)
Definition: astobj2.h:464
Structure that contains information about a bridge.
Definition: bridge.h:357
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
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...
Definition: bridge.c:3833
void ast_ari_response_no_content(struct ast_ari_response *response)
Fill in a No Content (204) ast_ari_response.
Definition: res_ari.c:284
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480

◆ ast_ari_bridges_create()

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.

This bridge persists until it has been shut down, or Asterisk has been shut down.

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 925 of file resource_bridges.c.

References ao2_cleanup, ast_ari_response_error(), ast_ari_response_ok(), ast_bridge_lock, ast_bridge_snapshot_create(), ast_bridge_snapshot_to_json(), ast_bridge_unlock, ast_ari_bridges_create_args::bridge_id, ast_ari_bridges_create_args::name, NULL, RAII_VAR, stasis_app_bridge_create(), stasis_app_get_sanitizer(), and ast_ari_bridges_create_args::type.

Referenced by ast_ari_bridges_create_cb().

928 {
929  RAII_VAR(struct ast_bridge *, bridge, stasis_app_bridge_create(args->type, args->name, args->bridge_id), ao2_cleanup);
930  RAII_VAR(struct ast_bridge_snapshot *, snapshot, NULL, ao2_cleanup);
931 
932  if (!bridge) {
934  response, 500, "Internal Error",
935  "Unable to create bridge");
936  return;
937  }
938 
939  ast_bridge_lock(bridge);
940  snapshot = ast_bridge_snapshot_create(bridge);
941  ast_bridge_unlock(bridge);
942 
943  if (!snapshot) {
945  response, 500, "Internal Error",
946  "Unable to create snapshot for new bridge");
947  return;
948  }
949 
950  ast_ari_response_ok(response,
952 }
Structure that contains a snapshot of information about a bridge.
Definition: bridge.h:322
#define NULL
Definition: resample.c:96
#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
void ast_ari_response_ok(struct ast_ari_response *response, struct ast_json *message)
Fill in an OK (200) ast_ari_response.
Definition: res_ari.c:276
Structure that contains information about a bridge.
Definition: bridge.h:357
struct stasis_message_sanitizer * stasis_app_get_sanitizer(void)
Get the Stasis message sanitizer for app_stasis applications.
Definition: res_stasis.c:2264
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...
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
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.
Definition: res_ari.c:259
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
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 * stasis_app_bridge_create(const char *type, const char *name, const char *id)
Create a bridge of the specified type.
Definition: res_stasis.c:851

◆ ast_ari_bridges_create_with_id()

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.

This bridge persists until it has been shut down, or Asterisk has been shut down.

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 954 of file resource_bridges.c.

References ao2_cleanup, ast_ari_response_error(), ast_ari_response_ok(), ast_bridge_lock, ast_bridge_snapshot_create(), ast_bridge_snapshot_to_json(), ast_bridge_unlock, ast_strlen_zero, ast_ari_bridges_create_with_id_args::bridge_id, find_bridge(), ast_ari_bridges_create_with_id_args::name, NULL, RAII_VAR, stasis_app_bridge_create(), stasis_app_get_sanitizer(), and ast_ari_bridges_create_with_id_args::type.

Referenced by ast_ari_bridges_create_with_id_cb().

957 {
958  RAII_VAR(struct ast_bridge *, bridge, find_bridge(response, args->bridge_id), ao2_cleanup);
959  RAII_VAR(struct ast_bridge_snapshot *, snapshot, NULL, ao2_cleanup);
960 
961  if (bridge) {
962  /* update */
963  if (!ast_strlen_zero(args->name)
964  && strcmp(args->name, bridge->name)) {
966  response, 500, "Internal Error",
967  "Changing bridge name is not implemented");
968  return;
969  }
970  if (!ast_strlen_zero(args->type)) {
972  response, 500, "Internal Error",
973  "Supplying a bridge type when updating a bridge is not allowed.");
974  return;
975  }
976  ast_ari_response_ok(response,
978  return;
979  }
980 
981  bridge = stasis_app_bridge_create(args->type, args->name, args->bridge_id);
982  if (!bridge) {
984  response, 500, "Internal Error",
985  "Unable to create bridge");
986  return;
987  }
988 
989  ast_bridge_lock(bridge);
990  snapshot = ast_bridge_snapshot_create(bridge);
991  ast_bridge_unlock(bridge);
992 
993  if (!snapshot) {
995  response, 500, "Internal Error",
996  "Unable to create snapshot for new bridge");
997  return;
998  }
999 
1000  ast_ari_response_ok(response,
1002 }
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.
Structure that contains a snapshot of information about a bridge.
Definition: bridge.h:322
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#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
void ast_ari_response_ok(struct ast_ari_response *response, struct ast_json *message)
Fill in an OK (200) ast_ari_response.
Definition: res_ari.c:276
Structure that contains information about a bridge.
Definition: bridge.h:357
struct stasis_message_sanitizer * stasis_app_get_sanitizer(void)
Get the Stasis message sanitizer for app_stasis applications.
Definition: res_stasis.c:2264
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...
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
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.
Definition: res_ari.c:259
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
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 * stasis_app_bridge_create(const char *type, const char *name, const char *id)
Create a bridge of the specified type.
Definition: res_stasis.c:851

◆ ast_ari_bridges_destroy()

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.

If any channels are in this bridge, they will be removed and resume whatever they were doing beforehand.

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 872 of file resource_bridges.c.

References ao2_cleanup, ast_ari_response_no_content(), ast_ari_bridges_destroy_args::bridge_id, find_bridge(), RAII_VAR, and stasis_app_bridge_destroy().

Referenced by ast_ari_bridges_destroy_cb().

875 {
876  RAII_VAR(struct ast_bridge *, bridge, find_bridge(response, args->bridge_id), ao2_cleanup);
877  if (!bridge) {
878  return;
879  }
880 
882  ast_ari_response_no_content(response);
883 }
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.
#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
Structure that contains information about a bridge.
Definition: bridge.h:357
void stasis_app_bridge_destroy(const char *bridge_id)
Destroy the bridge.
Definition: res_stasis.c:861
void ast_ari_response_no_content(struct ast_ari_response *response)
Fill in a No Content (204) ast_ari_response.
Definition: res_ari.c:284
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ ast_ari_bridges_get()

void ast_ari_bridges_get ( struct ast_variable headers,
struct ast_ari_bridges_get_args args,
struct ast_ari_response response 
)

Get bridge details.

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 856 of file resource_bridges.c.

References ao2_cleanup, ast_ari_response_error(), ast_ari_response_ok(), ast_bridge_get_snapshot_by_uniqueid(), ast_bridge_snapshot_to_json(), ast_ari_bridges_get_args::bridge_id, RAII_VAR, and stasis_app_get_sanitizer().

Referenced by ast_ari_bridges_get_cb().

859 {
861  if (!snapshot) {
863  response, 404, "Not Found",
864  "Bridge not found");
865  return;
866  }
867 
868  ast_ari_response_ok(response,
870 }
Structure that contains a snapshot of information about a bridge.
Definition: bridge.h:322
#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
void ast_ari_response_ok(struct ast_ari_response *response, struct ast_json *message)
Fill in an OK (200) ast_ari_response.
Definition: res_ari.c:276
struct stasis_message_sanitizer * stasis_app_get_sanitizer(void)
Get the Stasis message sanitizer for app_stasis applications.
Definition: res_stasis.c:2264
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.
Definition: res_ari.c:259
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
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_by_uniqueid(const char *bridge_id)
Returns the current snapshot for the bridge.

◆ ast_ari_bridges_list()

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.

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 885 of file resource_bridges.c.

References ao2_cleanup, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_ari_response_alloc_failed(), ast_ari_response_ok(), ast_bridge_get_snapshot(), ast_bridge_snapshot_to_json(), ast_bridges(), ast_json_array_append(), ast_json_array_create(), ast_json_ref(), ast_json_unref(), bridges, NULL, RAII_VAR, and stasis_app_get_sanitizer().

Referenced by ast_ari_bridges_list_cb().

888 {
890  RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
891  struct ao2_iterator i;
892  struct ast_bridge *bridge;
893 
894  bridges = ast_bridges();
895  if (!bridges) {
897  return;
898  }
899 
900  json = ast_json_array_create();
901  if (!json) {
903  return;
904  }
905 
906  i = ao2_iterator_init(bridges, 0);
907  while ((bridge = ao2_iterator_next(&i))) {
908  struct ast_bridge_snapshot *snapshot = ast_bridge_get_snapshot(bridge);
909  /* ast_bridge_snapshot_to_json will return NULL if snapshot is NULL */
910  struct ast_json *json_bridge = ast_bridge_snapshot_to_json(snapshot, stasis_app_get_sanitizer());
911 
912  ao2_ref(bridge, -1);
913  ao2_cleanup(snapshot);
914  if (!json_bridge || ast_json_array_append(json, json_bridge)) {
917  return;
918  }
919  }
921 
922  ast_ari_response_ok(response, ast_json_ref(json));
923 }
struct ao2_container * ast_bridges(void)
Returns the global bridges container.
Definition: bridge.c:174
struct ast_json * ast_json_ref(struct ast_json *value)
Increase refcount on value.
Definition: json.c:67
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
Structure that contains a snapshot of information about a bridge.
Definition: bridge.h:322
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define NULL
Definition: resample.c:96
void ast_ari_response_alloc_failed(struct ast_ari_response *response)
Fill in response with a 500 message for allocation failures.
Definition: res_ari.c:298
struct ast_bridge_snapshot * ast_bridge_get_snapshot(struct ast_bridge *bridge)
Returns the current snapshot for the bridge.
#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
void ast_ari_response_ok(struct ast_ari_response *response, struct ast_json *message)
Fill in an OK (200) ast_ari_response.
Definition: res_ari.c:276
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_json * ast_json_array_create(void)
Create a empty JSON array.
Definition: json.c:352
int ast_json_array_append(struct ast_json *array, struct ast_json *value)
Append to an array.
Definition: json.c:368
Structure that contains information about a bridge.
Definition: bridge.h:357
struct stasis_message_sanitizer * stasis_app_get_sanitizer(void)
Get the Stasis message sanitizer for app_stasis applications.
Definition: res_stasis.c:2264
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
static struct ao2_container * bridges
Definition: bridge.c:123
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
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.
Abstract JSON element (object, array, string, int, ...).
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.

◆ ast_ari_bridges_play()

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.

The media URI may be any of a number of URI's. Currently sound:, recording:, number:, digits:, characters:, and tone: URI's are supported. This operation creates a playback resource that can be used to control the playback of media (pause, rewind, fast forward, etc.)

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 606 of file resource_bridges.c.

References ari_bridges_handle_play(), ast_ari_bridges_play_args::bridge_id, ast_ari_bridges_play_args::lang, ast_ari_bridges_play_args::media, ast_ari_bridges_play_args::media_count, ast_ari_bridges_play_args::offsetms, ast_ari_bridges_play_args::playback_id, and ast_ari_bridges_play_args::skipms.

Referenced by ast_ari_bridges_play_cb().

609 {
611  args->media,
612  args->media_count,
613  args->lang,
614  args->offsetms,
615  args->skipms,
616  args->playback_id,
617  response);
618 }
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)

◆ ast_ari_bridges_play_with_id()

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.

The media URI may be any of a number of URI's. Currently sound:, recording:, number:, digits:, characters:, and tone: URI's are supported. This operation creates a playback resource that can be used to control the playback of media (pause, rewind, fast forward, etc.)

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 620 of file resource_bridges.c.

References ari_bridges_handle_play(), ast_ari_bridges_play_with_id_args::bridge_id, ast_ari_bridges_play_with_id_args::lang, ast_ari_bridges_play_with_id_args::media, ast_ari_bridges_play_with_id_args::media_count, ast_ari_bridges_play_with_id_args::offsetms, ast_ari_bridges_play_with_id_args::playback_id, and ast_ari_bridges_play_with_id_args::skipms.

Referenced by ast_ari_bridges_play_with_id_cb().

623 {
625  args->media,
626  args->media_count,
627  args->lang,
628  args->offsetms,
629  args->skipms,
630  args->playback_id,
631  response);
632 }
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)

◆ ast_ari_bridges_record()

void ast_ari_bridges_record ( struct ast_variable headers,
struct ast_ari_bridges_record_args args,
struct ast_ari_response response 
)

Start a recording.

This records the mixed audio from all channels participating in this bridge.

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 634 of file resource_bridges.c.

References ao2_cleanup, ast_ari_response_alloc_failed(), ast_ari_response_created(), ast_ari_response_error(), ast_asprintf, ast_assert, AST_BRIDGE_CHANNEL_FLAG_IMMOVABLE, AST_BRIDGE_CHANNEL_FLAG_LONELY, ast_bridge_topic(), ast_calloc, ast_channel_topic(), ast_free, ast_get_format_for_file_ext(), ast_hangup(), ast_json_ref(), ast_json_unref(), ast_log, ast_malloc, ast_pthread_create_detached, AST_RECORD_IF_EXISTS_ERROR, ast_string_field_build, ast_unreal_channel_push_to_bridge(), ast_uri_encode(), ast_uri_http, ast_ari_bridges_record_args::beep, bridge_channel_control_thread_data::bridge_channel, bridge_channel_control_thread(), ast_ari_bridges_record_args::bridge_id, bridge_channel_control_thread_data::control, errno, find_bridge(), ast_ari_bridges_record_args::format, bridge_channel_control_thread_data::forward, ast_ari_bridges_record_args::if_exists, LOG_WARNING, ast_ari_bridges_record_args::max_duration_seconds, ast_ari_bridges_record_args::max_silence_seconds, ast_ari_bridges_record_args::name, NULL, options, prepare_bridge_media_channel(), RAII_VAR, stasis_app_control_create(), stasis_app_control_record(), stasis_app_recording_if_exists_parse(), stasis_app_recording_options_create(), STASIS_APP_RECORDING_TERMINATE_INVALID, stasis_app_recording_termination_parse(), stasis_app_recording_to_json(), stasis_forward_all(), stasis_forward_cancel(), and ast_ari_bridges_record_args::terminate_on.

Referenced by ast_ari_bridges_record_cb().

637 {
638  RAII_VAR(struct ast_bridge *, bridge, find_bridge(response, args->bridge_id), ao2_cleanup);
639  RAII_VAR(struct ast_channel *, record_channel, NULL, ast_hangup);
640  RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
641  RAII_VAR(struct stasis_app_recording *, recording, NULL, ao2_cleanup);
642  RAII_VAR(char *, recording_url, NULL, ast_free);
643  RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
645  RAII_VAR(char *, uri_encoded_name, NULL, ast_free);
646  RAII_VAR(struct stasis_forward *, channel_forward, NULL, stasis_forward_cancel);
647 
648  struct stasis_topic *channel_topic;
649  struct stasis_topic *bridge_topic;
650  size_t uri_name_maxlen;
651  struct bridge_channel_control_thread_data *thread_data;
652  pthread_t threadid;
653 
654  ast_assert(response != NULL);
655 
656  if (bridge == NULL) {
657  return;
658  }
659 
660  if (!(record_channel = prepare_bridge_media_channel("Recorder"))) {
662  response, 500, "Internal Server Error", "Failed to create recording channel");
663  return;
664  }
665 
666  bridge_topic = ast_bridge_topic(bridge);
667  channel_topic = ast_channel_topic(record_channel);
668 
669  /* Forward messages from the recording channel topic to the bridge topic so that anything listening for
670  * messages on the bridge topic will receive the recording start/stop messages. Other messages that would
671  * go to this channel will be suppressed since the channel is marked as internal.
672  */
673  if (!bridge_topic || !channel_topic || !(channel_forward = stasis_forward_all(channel_topic, bridge_topic))) {
675  response, 500, "Internal Error", "Could not forward record channel stasis messages to bridge topic");
676  return;
677  }
678 
679  if (ast_unreal_channel_push_to_bridge(record_channel, bridge,
682  response, 500, "Internal Error", "Failed to put recording channel into the bridge");
683  return;
684  }
685 
686  control = stasis_app_control_create(record_channel);
687  if (control == NULL) {
689  return;
690  }
691 
693  if (options == NULL) {
695  return;
696  }
697 
698  ast_string_field_build(options, target, "bridge:%s", args->bridge_id);
699  options->max_silence_seconds = args->max_silence_seconds;
700  options->max_duration_seconds = args->max_duration_seconds;
701  options->terminate_on =
703  options->if_exists =
705  options->beep = args->beep;
706 
707  if (options->terminate_on == STASIS_APP_RECORDING_TERMINATE_INVALID) {
709  response, 400, "Bad Request",
710  "terminateOn invalid");
711  return;
712  }
713 
714  if (options->if_exists == AST_RECORD_IF_EXISTS_ERROR) {
716  response, 400, "Bad Request",
717  "ifExists invalid");
718  return;
719  }
720 
721  if (!ast_get_format_for_file_ext(options->format)) {
723  response, 422, "Unprocessable Entity",
724  "specified format is unknown on this system");
725  return;
726  }
727 
729  if (recording == NULL) {
730  switch(errno) {
731  case EINVAL:
732  /* While the arguments are invalid, we should have
733  * caught them prior to calling record.
734  */
736  response, 500, "Internal Server Error",
737  "Error parsing request");
738  break;
739  case EEXIST:
740  ast_ari_response_error(response, 409, "Conflict",
741  "Recording '%s' already exists and can not be overwritten",
742  args->name);
743  break;
744  case ENOMEM:
746  break;
747  case EPERM:
749  response, 400, "Bad Request",
750  "Recording name invalid");
751  break;
752  default:
754  "Unrecognized recording error: %s\n",
755  strerror(errno));
757  response, 500, "Internal Server Error",
758  "Internal Server Error");
759  break;
760  }
761  return;
762  }
763 
764  uri_name_maxlen = strlen(args->name) * 3;
765  uri_encoded_name = ast_malloc(uri_name_maxlen);
766  if (!uri_encoded_name) {
768  return;
769  }
770  ast_uri_encode(args->name, uri_encoded_name, uri_name_maxlen, ast_uri_http);
771 
772  if (ast_asprintf(&recording_url, "/recordings/live/%s",
773  uri_encoded_name) == -1) {
774  recording_url = NULL;
776  return;
777  }
778 
779  json = stasis_app_recording_to_json(recording);
780  if (!json) {
782  return;
783  }
784 
785  thread_data = ast_calloc(1, sizeof(*thread_data));
786  if (!thread_data) {
788  return;
789  }
790 
791  thread_data->bridge_channel = record_channel;
792  thread_data->control = control;
793  thread_data->forward = channel_forward;
794 
795  if (ast_pthread_create_detached(&threadid, NULL, bridge_channel_control_thread, thread_data)) {
797  ast_free(thread_data);
798  return;
799  }
800 
801  /* These are owned by the other thread now, so we don't want RAII_VAR disposing of them. */
802  record_channel = NULL;
803  control = NULL;
804  channel_forward = NULL;
805 
806  ast_ari_response_created(response, recording_url, ast_json_ref(json));
807 }
Main Channel structure associated with a channel.
struct ast_json * ast_json_ref(struct ast_json *value)
Increase refcount on value.
Definition: json.c:67
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.
#define ast_pthread_create_detached(a, b, c, d)
Definition: utils.h:563
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
struct stasis_app_control * stasis_app_control_create(struct ast_channel *chan)
Creates a control handler for a channel that isn&#39;t in a stasis app.
Definition: res_stasis.c:333
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.
Definition: res_ari.c:305
#define LOG_WARNING
Definition: logger.h:274
char * ast_uri_encode(const char *string, char *outbuf, int buflen, struct ast_flags spec)
Turn text string to URI-encoded XX version.
Definition: main/utils.c:577
#define ast_assert(a)
Definition: utils.h:695
char stasis_app_recording_termination_parse(const char *str)
Parse a string into the recording termination enum.
#define NULL
Definition: resample.c:96
void ast_ari_response_alloc_failed(struct ast_ari_response *response)
Fill in response with a 500 message for allocation failures.
Definition: res_ari.c:298
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:269
struct ast_json * stasis_app_recording_to_json(const struct stasis_app_recording *recording)
Construct a JSON model of a recording.
#define ast_log
Definition: astobj2.c:42
#define STASIS_APP_RECORDING_TERMINATE_INVALID
#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
static void * bridge_channel_control_thread(void *data)
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.
Definition: core_unreal.c:928
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
struct stasis_topic * ast_channel_topic(struct ast_channel *chan)
A topic which publishes the events for a particular channel.
Structure that contains information about a bridge.
Definition: bridge.h:357
enum ast_record_if_exists stasis_app_recording_if_exists_parse(const char *str)
Parse a string into the if_exists enum.
int errno
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
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.
Definition: res_ari.c:259
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2548
struct stasis_app_recording_options * stasis_app_recording_options_create(const char *name, const char *format)
Allocate a recording options object.
struct stasis_forward * stasis_forward_cancel(struct stasis_forward *forward)
Definition: stasis.c:1548
struct ast_format * ast_get_format_for_file_ext(const char *file_ext)
Get the ast_format associated with the given file extension.
Definition: file.c:1938
#define ast_string_field_build(x, field, fmt, args...)
Set a field to a complex (built) value.
Definition: stringfields.h:550
static struct ast_channel * prepare_bridge_media_channel(const char *type)
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Abstract JSON element (object, array, string, int, ...).
Forwarding information.
Definition: stasis.c:1531
const struct ast_flags ast_uri_http
Definition: main/utils.c:573
static struct test_options options
struct stasis_topic * ast_bridge_topic(struct ast_bridge *bridge)
A topic which publishes the events for a particular bridge.
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.
Definition: stasis.c:1578
struct stasis_app_control * control
struct stasis_app_recording * stasis_app_control_record(struct stasis_app_control *control, struct stasis_app_recording_options *options)
Record media from a channel.

◆ ast_ari_bridges_remove_channel()

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.

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 241 of file resource_bridges.c.

References ao2_cleanup, ast_ari_response_error(), ast_ari_response_no_content(), ast_log, ast_ari_bridges_remove_channel_args::bridge_id, ast_ari_bridges_remove_channel_args::channel, ast_ari_bridges_remove_channel_args::channel_count, control_list_create(), find_bridge(), LOG_WARNING, NULL, RAII_VAR, stasis_app_control_remove_channel_from_bridge(), and stasis_app_get_bridge().

Referenced by ast_ari_bridges_remove_channel_cb().

244 {
245  RAII_VAR(struct ast_bridge *, bridge, find_bridge(response, args->bridge_id), ao2_cleanup);
246  RAII_VAR(struct control_list *, list, NULL, ao2_cleanup);
247  size_t i;
248 
249  if (!bridge) {
250  /* Response filled in by find_bridge() */
251  return;
252  }
253 
254  list = control_list_create(response, args->channel_count, args->channel);
255  if (!list) {
256  /* Response filled in by control_list_create() */
257  return;
258  }
259 
260  /* Make sure all of the channels are in this bridge */
261  for (i = 0; i < list->count; ++i) {
262  if (stasis_app_get_bridge(list->controls[i]) != bridge) {
263  ast_log(LOG_WARNING, "Channel %s not in bridge %s\n",
264  args->channel[i], args->bridge_id);
265  ast_ari_response_error(response, 422,
266  "Unprocessable Entity",
267  "Channel not in this bridge");
268  return;
269  }
270  }
271 
272  /* Now actually remove it */
273  for (i = 0; i < list->count; ++i) {
275  bridge);
276  }
277 
278  ast_ari_response_no_content(response);
279 }
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
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.
#define LOG_WARNING
Definition: logger.h:274
int stasis_app_control_remove_channel_from_bridge(struct stasis_app_control *control, struct ast_bridge *bridge)
Remove a channel from the bridge.
Definition: control.c:1420
#define NULL
Definition: resample.c:96
static struct control_list * control_list_create(struct ast_ari_response *response, size_t count, const char **channels)
#define ast_log
Definition: astobj2.c:42
#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
Structure that contains information about a bridge.
Definition: bridge.h:357
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.
Definition: res_ari.c:259
void ast_ari_response_no_content(struct ast_ari_response *response)
Fill in a No Content (204) ast_ari_response.
Definition: res_ari.c:284
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ ast_ari_bridges_set_video_source()

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 bridges with two or fewer participants.

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 1016 of file resource_bridges.c.

References __ao2_cleanup(), ao2_bump, ao2_ref, ast_ari_response_error(), ast_ari_response_no_content(), ast_ari_bridges_set_video_source_args::bridge_id, bridge_set_video_source_cb(), ast_ari_bridges_set_video_source_args::channel_id, find_bridge(), find_channel_control(), stasis_app_get_bridge(), and stasis_app_send_command().

Referenced by ast_ari_bridges_set_video_source_cb().

1018 {
1019  struct ast_bridge *bridge;
1020  struct stasis_app_control *control;
1021 
1022  bridge = find_bridge(response, args->bridge_id);
1023  if (!bridge) {
1024  return;
1025  }
1026 
1027  control = find_channel_control(response, args->channel_id);
1028  if (!control) {
1029  ao2_ref(bridge, -1);
1030  return;
1031  }
1032 
1033  if (stasis_app_get_bridge(control) != bridge) {
1034  ast_ari_response_error(response, 422,
1035  "Unprocessable Entity",
1036  "Channel not in this bridge");
1037  ao2_ref(bridge, -1);
1038  ao2_ref(control, -1);
1039  return;
1040  }
1041 
1043  ao2_bump(bridge), __ao2_cleanup);
1044 
1045  ao2_ref(bridge, -1);
1046  ao2_ref(control, -1);
1047 
1048  ast_ari_response_no_content(response);
1049 }
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
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.
void __ao2_cleanup(void *obj)
Definition: astobj2.c:674
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&#39;s channel.
Definition: control.c:898
static int bridge_set_video_source_cb(struct stasis_app_control *control, struct ast_channel *chan, void *data)
#define ao2_bump(obj)
Definition: astobj2.h:491
#define ao2_ref(o, delta)
Definition: astobj2.h:464
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.
Structure that contains information about a bridge.
Definition: bridge.h:357
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.
Definition: res_ari.c:259
void ast_ari_response_no_content(struct ast_ari_response *response)
Fill in a No Content (204) ast_ari_response.
Definition: res_ari.c:284

◆ ast_ari_bridges_start_moh()

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.

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 809 of file resource_bridges.c.

References ao2_cleanup, ast_ari_response_alloc_failed(), ast_ari_response_no_content(), ast_channel_cleanup, ast_moh_start(), ast_ari_bridges_start_moh_args::bridge_id, find_bridge(), ast_ari_bridges_start_moh_args::moh_class, NULL, RAII_VAR, and stasis_app_bridge_moh_channel().

Referenced by ast_ari_bridges_start_moh_cb().

812 {
813  RAII_VAR(struct ast_bridge *, bridge, find_bridge(response, args->bridge_id), ao2_cleanup);
814  struct ast_channel *moh_channel;
815  const char *moh_class = args->moh_class;
816 
817  if (!bridge) {
818  /* The response is provided by find_bridge() */
819  return;
820  }
821 
822  moh_channel = stasis_app_bridge_moh_channel(bridge);
823  if (!moh_channel) {
825  return;
826  }
827 
828  ast_moh_start(moh_channel, moh_class, NULL);
829  ast_channel_cleanup(moh_channel);
830 
831  ast_ari_response_no_content(response);
832 
833 }
Main Channel structure associated with a channel.
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.
#define NULL
Definition: resample.c:96
void ast_ari_response_alloc_failed(struct ast_ari_response *response)
Fill in response with a 500 message for allocation failures.
Definition: res_ari.c:298
#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_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:2992
Structure that contains information about a bridge.
Definition: bridge.h:357
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
struct ast_bridge * bridge
Definition: control.c:64
void ast_ari_response_no_content(struct ast_ari_response *response)
Fill in a No Content (204) ast_ari_response.
Definition: res_ari.c:284
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
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.
Definition: res_stasis.c:629

◆ ast_ari_bridges_stop_moh()

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.

This will only stop music on hold being played via POST bridges/{bridgeId}/moh.

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 835 of file resource_bridges.c.

References ao2_cleanup, ast_ari_response_error(), ast_ari_response_no_content(), ast_ari_bridges_stop_moh_args::bridge_id, find_bridge(), RAII_VAR, and stasis_app_bridge_moh_stop().

Referenced by ast_ari_bridges_stop_moh_cb().

838 {
839  RAII_VAR(struct ast_bridge *, bridge, find_bridge(response, args->bridge_id), ao2_cleanup);
840 
841  if (!bridge) {
842  /* the response is provided by find_bridge() */
843  return;
844  }
845 
846  if (stasis_app_bridge_moh_stop(bridge)) {
848  response, 409, "Conflict",
849  "Bridge isn't playing music");
850  return;
851  }
852 
853  ast_ari_response_no_content(response);
854 }
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.
#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
Structure that contains information about a bridge.
Definition: bridge.h:357
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.
Definition: res_stasis.c:649
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.
Definition: res_ari.c:259
void ast_ari_response_no_content(struct ast_ari_response *response)
Fill in a No Content (204) ast_ari_response.
Definition: res_ari.c:284
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ bridge_channel_control_thread()

static void* bridge_channel_control_thread ( void *  data)
static

Definition at line 288 of file resource_bridges.c.

References ao2_cleanup, ast_callid_threadassoc_add(), ast_channel_callid(), ast_free, ast_hangup(), ast_strdupa, bridge_channel_control_thread_data::bridge_channel, bridge_channel_control_thread_data::bridge_id, bridge_channel_control_thread_data::control, bridge_channel_control_thread_data::forward, NULL, stasis_app_bridge_playback_channel_remove(), stasis_app_control_execute_until_exhausted(), stasis_app_control_flush_queue(), and stasis_forward_cancel().

Referenced by ari_bridges_play_new(), and ast_ari_bridges_record().

289 {
290  struct bridge_channel_control_thread_data *thread_data = data;
291  struct ast_channel *bridge_channel = thread_data->bridge_channel;
292  struct stasis_app_control *control = thread_data->control;
293  struct stasis_forward *forward = thread_data->forward;
294  ast_callid callid = ast_channel_callid(bridge_channel);
295  char *bridge_id = ast_strdupa(thread_data->bridge_id);
296 
297  if (callid) {
299  }
300 
301  ast_free(thread_data);
302  thread_data = NULL;
303 
304  stasis_app_control_execute_until_exhausted(bridge_channel, control);
306 
307  stasis_app_bridge_playback_channel_remove(bridge_id, control);
308  stasis_forward_cancel(forward);
309  ao2_cleanup(control);
310  ast_hangup(bridge_channel);
311  return NULL;
312 }
Main Channel structure associated with a channel.
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.
Definition: res_stasis.c:743
unsigned int ast_callid
Definition: logger.h:87
#define NULL
Definition: resample.c:96
int ast_callid_threadassoc_add(ast_callid callid)
Adds a known callid to thread storage of the calling thread.
Definition: logger.c:1984
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
void stasis_app_control_flush_queue(struct stasis_app_control *control)
Flush the control command queue.
Definition: res_stasis.c:1278
#define ast_free(a)
Definition: astmm.h:182
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2548
struct stasis_forward * stasis_forward_cancel(struct stasis_forward *forward)
Definition: stasis.c:1548
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.
Definition: res_stasis.c:1250
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Forwarding information.
Definition: stasis.c:1531
struct stasis_app_control * control
ast_callid ast_channel_callid(const struct ast_channel *chan)

◆ bridge_set_video_source_cb()

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

Definition at line 1004 of file resource_bridges.c.

References ast_bridge_lock, ast_bridge_set_single_src_video_mode(), and ast_bridge_unlock.

Referenced by ast_ari_bridges_set_video_source().

1006 {
1007  struct ast_bridge *bridge = data;
1008 
1009  ast_bridge_lock(bridge);
1011  ast_bridge_unlock(bridge);
1012 
1013  return 0;
1014 }
Structure that contains information about a bridge.
Definition: bridge.h:357
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
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.
Definition: bridge.c:3816
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480

◆ check_add_remove_channel()

static int check_add_remove_channel ( struct ast_ari_response response,
struct stasis_app_control control,
enum stasis_app_control_channel_result  result 
)
static

Definition at line 175 of file resource_bridges.c.

References ast_ari_response_error(), STASIS_APP_CHANNEL_OKAY, STASIS_APP_CHANNEL_RECORDING, and stasis_app_control_get_channel_id().

Referenced by ast_ari_bridges_add_channel().

178 {
179  switch (result) {
182  response, 409, "Conflict", "Channel %s currently recording",
184  return -1;
186  return 0;
187  }
188  return 0;
189 }
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_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.
Definition: res_ari.c:259
static PGresult * result
Definition: cel_pgsql.c:88

◆ control_list_create()

static struct control_list* control_list_create ( struct ast_ari_response response,
size_t  count,
const char **  channels 
)
static

Definition at line 138 of file resource_bridges.c.

References ao2_alloc, ao2_cleanup, ao2_ref, ast_ari_response_alloc_failed(), ast_ari_response_error(), ast_strlen_zero, control_list_dtor(), control_list::count, find_channel_control(), NULL, and RAII_VAR.

Referenced by ast_ari_bridges_add_channel(), and ast_ari_bridges_remove_channel().

138  {
139  RAII_VAR(struct control_list *, list, NULL, ao2_cleanup);
140  size_t i;
141 
142  if (count == 0 || !channels) {
143  ast_ari_response_error(response, 400, "Bad Request", "Missing parameter channel");
144  return NULL;
145  }
146 
147  list = ao2_alloc(sizeof(*list) + count * sizeof(list->controls[0]), control_list_dtor);
148  if (!list) {
150  return NULL;
151  }
152 
153  for (i = 0; i < count; ++i) {
154  if (ast_strlen_zero(channels[i])) {
155  continue;
156  }
157  list->controls[list->count] =
158  find_channel_control(response, channels[i]);
159  if (!list->controls[list->count]) {
160  /* response filled in by find_channel_control() */
161  return NULL;
162  }
163  ++list->count;
164  }
165 
166  if (list->count == 0) {
167  ast_ari_response_error(response, 400, "Bad Request", "Missing parameter channel");
168  return NULL;
169  }
170 
171  ao2_ref(list, +1);
172  return list;
173 }
static void control_list_dtor(void *obj)
#define NULL
Definition: resample.c:96
void ast_ari_response_alloc_failed(struct ast_ari_response *response)
Fill in response with a 500 message for allocation failures.
Definition: res_ari.c:298
#define ast_strlen_zero(foo)
Definition: strings.h:52
#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 ao2_ref(o, delta)
Definition: astobj2.h:464
static struct channel_usage channels
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.
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
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.
Definition: res_ari.c:259
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ control_list_dtor()

static void control_list_dtor ( void *  obj)
static

Definition at line 128 of file resource_bridges.c.

References ao2_cleanup, control_list::controls, control_list::count, and NULL.

Referenced by control_list_create().

128  {
129  struct control_list *list = obj;
130  size_t i;
131 
132  for (i = 0; i < list->count; ++i) {
133  ao2_cleanup(list->controls[i]);
134  list->controls[i] = NULL;
135  }
136 }
#define NULL
Definition: resample.c:96
struct stasis_app_control * controls[]
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ find_bridge()

static struct ast_bridge* find_bridge ( struct ast_ari_response response,
const char *  bridge_id 
)
static

Finds a bridge, filling the response with an error, if appropriate.

Parameters
[out]responseResponse to fill with an error if control is not found.
bridge_idID of the bridge to lookup.
Returns
Bridget.
NULL if bridge does not exist.

Definition at line 57 of file resource_bridges.c.

References ao2_cleanup, ao2_ref, ast_ari_response_error(), ast_assert, ast_bridge_get_snapshot_by_uniqueid(), NULL, RAII_VAR, and stasis_app_bridge_find_by_id().

Referenced by ari_bridges_handle_play(), ast_ari_bridges_add_channel(), ast_ari_bridges_clear_video_source(), ast_ari_bridges_create_with_id(), ast_ari_bridges_destroy(), ast_ari_bridges_record(), ast_ari_bridges_remove_channel(), ast_ari_bridges_set_video_source(), ast_ari_bridges_start_moh(), and ast_ari_bridges_stop_moh().

60 {
61  RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
62 
63  ast_assert(response != NULL);
64 
65  bridge = stasis_app_bridge_find_by_id(bridge_id);
66  if (bridge == NULL) {
67  RAII_VAR(struct ast_bridge_snapshot *, snapshot,
69  if (!snapshot) {
70  ast_ari_response_error(response, 404, "Not found",
71  "Bridge not found");
72  return NULL;
73  }
74 
75  ast_ari_response_error(response, 409, "Conflict",
76  "Bridge not in Stasis application");
77  return NULL;
78  }
79 
80  ao2_ref(bridge, +1);
81  return bridge;
82 }
Structure that contains a snapshot of information about a bridge.
Definition: bridge.h:322
#define ast_assert(a)
Definition: utils.h:695
#define NULL
Definition: resample.c:96
#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 ao2_ref(o, delta)
Definition: astobj2.h:464
Structure that contains information about a bridge.
Definition: bridge.h:357
struct ast_bridge * stasis_app_bridge_find_by_id(const char *bridge_id)
Returns the bridge with the given id.
Definition: res_stasis.c:774
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.
Definition: res_ari.c:259
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct ast_bridge_snapshot * ast_bridge_get_snapshot_by_uniqueid(const char *bridge_id)
Returns the current snapshot for the bridge.

◆ find_channel_control()

static struct stasis_app_control* find_channel_control ( struct ast_ari_response response,
const char *  channel_id 
)
static

Finds the control object for a channel, filling the response with an error, if appropriate.

Parameters
[out]responseResponse to fill with an error if control is not found.
channel_idID of the channel to lookup.
Returns
Channel control object.
NULL if control object does not exist.

Definition at line 92 of file resource_bridges.c.

References ao2_cleanup, ao2_ref, ast_ari_response_error(), ast_assert, ast_channel_snapshot_get_latest(), ast_log, LOG_DEBUG, NULL, RAII_VAR, and stasis_app_control_find_by_channel_id().

Referenced by ast_ari_bridges_set_video_source(), and control_list_create().

95 {
96  RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
97 
98  ast_assert(response != NULL);
99 
100  control = stasis_app_control_find_by_channel_id(channel_id);
101  if (control == NULL) {
102  /* Distinguish between 400 and 422 errors */
103  RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL,
104  ao2_cleanup);
105  snapshot = ast_channel_snapshot_get_latest(channel_id);
106  if (snapshot == NULL) {
107  ast_log(LOG_DEBUG, "Couldn't find '%s'\n", channel_id);
108  ast_ari_response_error(response, 400, "Bad Request",
109  "Channel not found");
110  return NULL;
111  }
112 
113  ast_log(LOG_DEBUG, "Found non-stasis '%s'\n", channel_id);
114  ast_ari_response_error(response, 422, "Unprocessable Entity",
115  "Channel not in Stasis application");
116  return NULL;
117  }
118 
119  ao2_ref(control, +1);
120  return control;
121 }
Structure representing a snapshot of channel state.
#define ast_assert(a)
Definition: utils.h:695
#define NULL
Definition: resample.c:96
#define LOG_DEBUG
Definition: logger.h:241
#define ast_log
Definition: astobj2.c:42
#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 ao2_ref(o, delta)
Definition: astobj2.h:464
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.
Definition: res_ari.c:259
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.
Definition: res_stasis.c:349
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...
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ prepare_bridge_media_channel()

static struct ast_channel* prepare_bridge_media_channel ( const char *  type)
static

Definition at line 314 of file resource_bridges.c.

References ao2_cleanup, ast_channel_cleanup, ast_format_cap_alloc, ast_format_cap_append, AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_slin, ast_request(), NULL, RAII_VAR, and stasis_app_channel_unreal_set_internal().

Referenced by ari_bridges_play_new(), and ast_ari_bridges_record().

315 {
316  RAII_VAR(struct ast_format_cap *, cap, NULL, ao2_cleanup);
317  struct ast_channel *chan;
318 
320  if (!cap) {
321  return NULL;
322  }
323 
325 
326  chan = ast_request(type, cap, NULL, NULL, "ARI", NULL);
327  if (!chan) {
328  return NULL;
329  }
330 
332  ast_channel_cleanup(chan);
333  return NULL;
334  }
335  return chan;
336 }
static const char type[]
Definition: chan_ooh323.c:109
Main Channel structure associated with a channel.
#define NULL
Definition: resample.c:96
int stasis_app_channel_unreal_set_internal(struct ast_channel *chan)
Mark this unreal channel and it&#39;s other half as being internal to Stasis.
Definition: res_stasis.c:2288
struct ast_channel * ast_request(const char *type, struct ast_format_cap *request_cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *addr, int *cause)
Requests a channel.
Definition: channel.c:6444
#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_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:2992
#define ast_format_cap_append(cap, format, framing)
Definition: format_cap.h:103
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
Definition: format_cache.c:41