Asterisk - The Open Source Telephony Project  21.4.1
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"

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.

Function Documentation

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_skipms
args_playback_idstring to use for playback split from arguments (null valid)
responseARI response being built
bridgeBridge the playback is being performed 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 538 of file resource_bridges.c.

References ari_bridges_play_helper(), ast_ari_response_created(), ast_json_ref(), ast_json_unref(), RAII_VAR, stasis_app_control_find_by_channel(), and stasis_app_control_is_done().

547 {
548  RAII_VAR(struct ast_channel *, play_channel, found_channel, ao2_cleanup);
549  RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
550  RAII_VAR(char *, playback_url, NULL, ast_free);
551  RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
552 
553  control = stasis_app_control_find_by_channel(play_channel);
554  if (!control) {
555  return PLAY_FOUND_CHANNEL_UNAVAILABLE;
556  }
557 
558  ao2_lock(control);
559  if (stasis_app_control_is_done(control)) {
560  /* We failed to queue the action. Bailout and return that we aren't terminal. */
561  ao2_unlock(control);
562  return PLAY_FOUND_CHANNEL_UNAVAILABLE;
563  }
564 
565  if (ari_bridges_play_helper(args_media, args_media_count,
566  args_lang, args_offset_ms, args_skipms, args_playback_id,
567  response, bridge, control, &json, &playback_url)) {
568  ao2_unlock(control);
569  return PLAY_FOUND_FAILURE;
570  }
571  ao2_unlock(control);
572 
573  ast_ari_response_created(response, playback_url, ast_json_ref(json));
574  return PLAY_FOUND_SUCCESS;
575 }
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:1276
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
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...
Abstract JSON element (object, array, string, int, ...).
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
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
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_skipms
args_playback_idstring to use for playback split from arguments (null valid)
responseARI response being built
bridgeBridge the playback is being performed 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
Returns
operation was successful

Definition at line 358 of file resource_bridges.c.

References ast_ari_response_alloc_failed(), ast_ari_response_error(), ast_asprintf, ast_channel_snapshot::base, ast_channel::language, ast_channel_snapshot_base::language, RAII_VAR, S_OR, ast_channel::snapshot, 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().

369 {
370  RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
371  RAII_VAR(struct stasis_app_playback *, playback, NULL, ao2_cleanup);
372 
373  const char *language;
374 
375  snapshot = stasis_app_control_get_snapshot(control);
376  if (!snapshot) {
378  response, 500, "Internal Error", "Failed to get control snapshot");
379  return -1;
380  }
381 
382  language = S_OR(args_lang, snapshot->base->language);
383 
384  playback = stasis_app_control_play_uri(control, args_media, args_media_count,
385  language, bridge->uniqueid, STASIS_PLAYBACK_TARGET_BRIDGE, args_skipms,
386  args_offset_ms, args_playback_id);
387 
388  if (!playback) {
390  return -1;
391  }
392 
393  if (ast_asprintf(playback_url, "/playbacks/%s",
394  stasis_app_playback_get_id(playback)) == -1) {
396  return -1;
397  }
398 
399  *json = stasis_app_playback_to_json(playback);
400  if (!*json) {
402  return -1;
403  }
404 
405  return 0;
406 }
const ast_string_field uniqueid
Definition: bridge.h:401
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.
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:267
const char * stasis_app_playback_get_id(struct stasis_app_playback *playback)
Gets the unique id of a playback object.
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:882
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 S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:80
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.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
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, ast_ari_response_alloc_failed(), ast_ari_response_no_content(), ast_ari_bridges_add_channel_args::bridge_id, ast_ari_bridges_add_channel_args::channel, ast_ari_bridges_add_channel_args::channel_count, find_bridge(), ast_ari_bridges_add_channel_args::inhibit_connected_line_updates, ast_ari_bridges_add_channel_args::mute, 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:1486
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:338
int stasis_app_control_bridge_features_init(struct stasis_app_control *control)
Initialize bridge features into a channel control.
Definition: control.c:1473
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 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
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:1405
Structure that contains information about a bridge.
Definition: bridge.h:349
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:1498
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:360
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
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:1492
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 1072 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().

1074 {
1075  struct ast_bridge *bridge;
1076 
1077  bridge = find_bridge(response, args->bridge_id);
1078  if (!bridge) {
1079  return;
1080  }
1081 
1082  ast_bridge_lock(bridge);
1084  ast_bridge_unlock(bridge);
1085 
1086  ao2_ref(bridge, -1);
1087  ast_ari_response_no_content(response);
1088 }
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)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
Structure that contains information about a bridge.
Definition: bridge.h:349
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:481
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:3766
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:470
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 946 of file resource_bridges.c.

References 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, RAII_VAR, stasis_app_bridge_create(), stasis_app_get_sanitizer(), and ast_ari_bridges_create_args::type.

Referenced by ast_ari_bridges_create_cb().

949 {
950  RAII_VAR(struct ast_bridge *, bridge, stasis_app_bridge_create(args->type, args->name, args->bridge_id), ao2_cleanup);
951  RAII_VAR(struct ast_bridge_snapshot *, snapshot, NULL, ao2_cleanup);
952 
953  if (!bridge) {
955  response, 500, "Internal Error",
956  "Unable to create bridge");
957  return;
958  }
959 
960  ast_bridge_lock(bridge);
961  snapshot = ast_bridge_snapshot_create(bridge);
962  ast_bridge_unlock(bridge);
963 
964  if (!snapshot) {
966  response, 500, "Internal Error",
967  "Unable to create snapshot for new bridge");
968  return;
969  }
970 
971  ast_ari_response_ok(response,
973 }
Structure that contains a snapshot of information about a bridge.
Definition: bridge.h:314
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:349
struct stasis_message_sanitizer * stasis_app_get_sanitizer(void)
Get the Stasis message sanitizer for app_stasis applications.
Definition: res_stasis.c:2271
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:481
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 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_lock(bridge)
Lock the bridge.
Definition: bridge.h:470
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.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
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:854
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 975 of file resource_bridges.c.

References 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_with_id_args::bridge_id, find_bridge(), ast_ari_bridges_create_with_id_args::name, ast_bridge::name, 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().

978 {
979  RAII_VAR(struct ast_bridge *, bridge, find_bridge(response, args->bridge_id), ao2_cleanup);
980  RAII_VAR(struct ast_bridge_snapshot *, snapshot, NULL, ao2_cleanup);
981 
982  if (bridge) {
983  /* update */
984  if (!ast_strlen_zero(args->name)
985  && strcmp(args->name, bridge->name)) {
987  response, 500, "Internal Error",
988  "Changing bridge name is not implemented");
989  return;
990  }
991  if (!ast_strlen_zero(args->type)) {
993  response, 500, "Internal Error",
994  "Supplying a bridge type when updating a bridge is not allowed.");
995  return;
996  }
997  ast_ari_response_ok(response,
999  return;
1000  }
1001 
1002  bridge = stasis_app_bridge_create(args->type, args->name, args->bridge_id);
1003  if (!bridge) {
1005  response, 500, "Internal Error",
1006  "Unable to create bridge");
1007  return;
1008  }
1009 
1010  ast_bridge_lock(bridge);
1011  snapshot = ast_bridge_snapshot_create(bridge);
1012  ast_bridge_unlock(bridge);
1013 
1014  if (!snapshot) {
1016  response, 500, "Internal Error",
1017  "Unable to create snapshot for new bridge");
1018  return;
1019  }
1020 
1021  ast_ari_response_ok(response,
1023 }
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:314
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:349
struct stasis_message_sanitizer * stasis_app_get_sanitizer(void)
Get the Stasis message sanitizer for app_stasis applications.
Definition: res_stasis.c:2271
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:481
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 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_lock(bridge)
Lock the bridge.
Definition: bridge.h:470
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.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
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:854
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 882 of file resource_bridges.c.

References 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().

885 {
886  RAII_VAR(struct ast_bridge *, bridge, find_bridge(response, args->bridge_id), ao2_cleanup);
887  if (!bridge) {
888  return;
889  }
890 
892  ast_ari_response_no_content(response);
893 }
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 information about a bridge.
Definition: bridge.h:349
void stasis_app_bridge_destroy(const char *bridge_id)
Destroy the bridge.
Definition: res_stasis.c:864
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 RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
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 866 of file resource_bridges.c.

References 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, ast_channel::snapshot, and stasis_app_get_sanitizer().

Referenced by ast_ari_bridges_get_cb().

869 {
870  RAII_VAR(struct ast_bridge_snapshot *, snapshot, ast_bridge_get_snapshot_by_uniqueid(args->bridge_id), ao2_cleanup);
871  if (!snapshot) {
873  response, 404, "Not Found",
874  "Bridge not found");
875  return;
876  }
877 
878  ast_ari_response_ok(response,
880 }
struct ast_bridge_snapshot * ast_bridge_get_snapshot_by_uniqueid(const char *uniqueid)
Returns the current snapshot for the bridge.
Structure that contains a snapshot of information about a bridge.
Definition: bridge.h:314
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:2271
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 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.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
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 895 of file resource_bridges.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_ref, ast_ari_response_alloc_failed(), ast_ari_response_ok(), AST_BRIDGE_FLAG_INVISIBLE, 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, ast_bridge::feature_flags, RAII_VAR, and stasis_app_get_sanitizer().

Referenced by ast_ari_bridges_list_cb().

898 {
899  RAII_VAR(struct ao2_container *, bridges, NULL, ao2_cleanup);
900  RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
901  struct ao2_iterator i;
902  struct ast_bridge *bridge;
903 
904  bridges = ast_bridges();
905  if (!bridges) {
907  return;
908  }
909 
910  json = ast_json_array_create();
911  if (!json) {
913  return;
914  }
915 
916  i = ao2_iterator_init(bridges, 0);
917  while ((bridge = ao2_iterator_next(&i))) {
918  struct ast_bridge_snapshot *snapshot;
919  struct ast_json *json_bridge = NULL;
920 
921  /* Invisible bridges don't get shown externally and have no snapshot */
922  if (ast_test_flag(&bridge->feature_flags, AST_BRIDGE_FLAG_INVISIBLE)) {
923  ao2_ref(bridge, -1);
924  continue;
925  }
926 
927  snapshot = ast_bridge_get_snapshot(bridge);
928  if (snapshot) {
929  json_bridge = ast_bridge_snapshot_to_json(snapshot, stasis_app_get_sanitizer());
930  ao2_ref(snapshot, -1);
931  }
932 
933  ao2_ref(bridge, -1);
934 
935  if (!json_bridge || ast_json_array_append(json, json_bridge)) {
938  return;
939  }
940  }
942 
943  ast_ari_response_ok(response, ast_json_ref(json));
944 }
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
struct ast_flags feature_flags
Definition: bridge.h:369
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:314
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
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 ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
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 ast_json * ast_json_array_create(void)
Create a empty JSON array.
Definition: json.c:362
int ast_json_array_append(struct ast_json *array, struct ast_json *value)
Append to an array.
Definition: json.c:378
struct ast_bridge_snapshot * ast_bridge_get_snapshot(struct ast_bridge *bridge)
Returns the current snapshot for the bridge.
Structure that contains information about a bridge.
Definition: bridge.h:349
struct stasis_message_sanitizer * stasis_app_get_sanitizer(void)
Get the Stasis message sanitizer for app_stasis applications.
Definition: res_stasis.c:2271
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:1821
Abstract JSON element (object, array, string, int, ...).
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.
Generic container type.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
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 616 of file resource_bridges.c.

References 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().

619 {
620  ari_bridges_handle_play(args->bridge_id,
621  args->media,
622  args->media_count,
623  args->lang,
624  args->offsetms,
625  args->skipms,
626  args->playback_id,
627  response);
628 }
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 630 of file resource_bridges.c.

References 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().

633 {
634  ari_bridges_handle_play(args->bridge_id,
635  args->media,
636  args->media_count,
637  args->lang,
638  args->offsetms,
639  args->skipms,
640  args->playback_id,
641  response);
642 }
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 644 of file resource_bridges.c.

References ast_ari_response_alloc_failed(), ast_ari_response_created(), ast_ari_response_error(), ast_asprintf, AST_BRIDGE_CHANNEL_FLAG_IMMOVABLE, AST_BRIDGE_CHANNEL_FLAG_LONELY, ast_bridge_topic(), ast_calloc, ast_channel_topic(), ast_get_format_for_file_ext(), ast_hangup(), ast_json_ref(), ast_json_unref(), ast_malloc, AST_RECORD_IF_EXISTS_ERROR, ast_string_field_build, ast_unreal_channel_push_to_bridge(), ast_uri_encode(), ast_ari_bridges_record_args::beep, ast_ari_bridges_record_args::bridge_id, ast_channel::channel_forward, find_bridge(), ast_ari_bridges_record_args::format, ast_ari_bridges_record_args::if_exists, ast_ari_bridges_record_args::max_duration_seconds, ast_ari_bridges_record_args::max_silence_seconds, ast_ari_bridges_record_args::name, RAII_VAR, stasis_app_control_create(), stasis_app_control_record(), stasis_app_recording_if_exists_parse(), stasis_app_recording_options_create(), stasis_app_recording_termination_parse(), stasis_app_recording_to_json(), stasis_forward_all(), and ast_ari_bridges_record_args::terminate_on.

Referenced by ast_ari_bridges_record_cb().

647 {
648  RAII_VAR(struct ast_bridge *, bridge, find_bridge(response, args->bridge_id), ao2_cleanup);
649  RAII_VAR(struct ast_channel *, record_channel, NULL, ast_hangup);
650  RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
651  RAII_VAR(struct stasis_app_recording *, recording, NULL, ao2_cleanup);
652  RAII_VAR(char *, recording_url, NULL, ast_free);
653  RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
654  RAII_VAR(struct stasis_app_recording_options *, options, NULL, ao2_cleanup);
655  RAII_VAR(char *, uri_encoded_name, NULL, ast_free);
656  RAII_VAR(struct stasis_forward *, channel_forward, NULL, stasis_forward_cancel);
657 
658  struct stasis_topic *channel_topic;
659  struct stasis_topic *bridge_topic;
660  size_t uri_name_maxlen;
661  struct bridge_channel_control_thread_data *thread_data;
662  pthread_t threadid;
663 
664  ast_assert(response != NULL);
665 
666  if (bridge == NULL) {
667  return;
668  }
669 
670  if (!(record_channel = prepare_bridge_media_channel("Recorder"))) {
672  response, 500, "Internal Server Error", "Failed to create recording channel");
673  return;
674  }
675 
676  bridge_topic = ast_bridge_topic(bridge);
677  channel_topic = ast_channel_topic(record_channel);
678 
679  /* Forward messages from the recording channel topic to the bridge topic so that anything listening for
680  * messages on the bridge topic will receive the recording start/stop messages. Other messages that would
681  * go to this channel will be suppressed since the channel is marked as internal.
682  */
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");
686  return;
687  }
688 
689  if (ast_unreal_channel_push_to_bridge(record_channel, bridge,
692  response, 500, "Internal Error", "Failed to put recording channel into the bridge");
693  return;
694  }
695 
696  control = stasis_app_control_create(record_channel);
697  if (control == NULL) {
699  return;
700  }
701 
702  options = stasis_app_recording_options_create(args->name, args->format);
703  if (options == NULL) {
705  return;
706  }
707 
708  ast_string_field_build(options, target, "bridge:%s", args->bridge_id);
709  options->max_silence_seconds = args->max_silence_seconds;
710  options->max_duration_seconds = args->max_duration_seconds;
711  options->terminate_on =
713  options->if_exists =
715  options->beep = args->beep;
716 
717  if (options->terminate_on == STASIS_APP_RECORDING_TERMINATE_INVALID) {
719  response, 400, "Bad Request",
720  "terminateOn invalid");
721  return;
722  }
723 
724  if (options->if_exists == AST_RECORD_IF_EXISTS_ERROR) {
726  response, 400, "Bad Request",
727  "ifExists invalid");
728  return;
729  }
730 
731  if (!ast_get_format_for_file_ext(options->format)) {
733  response, 422, "Unprocessable Entity",
734  "specified format is unknown on this system");
735  return;
736  }
737 
738  recording = stasis_app_control_record(control, options);
739  if (recording == NULL) {
740  switch(errno) {
741  case EINVAL:
742  /* While the arguments are invalid, we should have
743  * caught them prior to calling record.
744  */
746  response, 500, "Internal Server Error",
747  "Error parsing request");
748  break;
749  case EEXIST:
750  ast_ari_response_error(response, 409, "Conflict",
751  "Recording '%s' already exists and can not be overwritten",
752  args->name);
753  break;
754  case ENOMEM:
756  break;
757  case EPERM:
759  response, 400, "Bad Request",
760  "Recording name invalid");
761  break;
762  default:
763  ast_log(LOG_WARNING,
764  "Unrecognized recording error: %s\n",
765  strerror(errno));
767  response, 500, "Internal Server Error",
768  "Internal Server Error");
769  break;
770  }
771  return;
772  }
773 
774  uri_name_maxlen = strlen(args->name) * 3;
775  uri_encoded_name = ast_malloc(uri_name_maxlen);
776  if (!uri_encoded_name) {
778  return;
779  }
780  ast_uri_encode(args->name, uri_encoded_name, uri_name_maxlen, ast_uri_http);
781 
782  if (ast_asprintf(&recording_url, "/recordings/live/%s",
783  uri_encoded_name) == -1) {
784  recording_url = NULL;
786  return;
787  }
788 
789  json = stasis_app_recording_to_json(recording);
790  if (!json) {
792  return;
793  }
794 
795  thread_data = ast_calloc(1, sizeof(*thread_data));
796  if (!thread_data) {
798  return;
799  }
800 
801  thread_data->bridge_channel = record_channel;
802  thread_data->control = control;
803  thread_data->forward = channel_forward;
804 
805  if (ast_pthread_create_detached(&threadid, NULL, bridge_channel_control_thread, thread_data)) {
807  ast_free(thread_data);
808  return;
809  }
810 
811  /* These are owned by the other thread now, so we don't want RAII_VAR disposing of them. */
812  record_channel = NULL;
813  control = NULL;
814  channel_forward = NULL;
815 
816  ast_ari_response_created(response, recording_url, ast_json_ref(json));
817 }
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.
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
char * ast_uri_encode(const char *string, char *outbuf, int buflen, struct ast_flags spec)
Turn text string to URI-encoded XX version.
Definition: utils.c:723
char stasis_app_recording_termination_parse(const char *str)
Parse a string into the recording termination enum.
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:267
struct ast_json * stasis_app_recording_to_json(const struct stasis_app_recording *recording)
Construct a JSON model of a recording.
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:191
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:349
enum ast_record_if_exists stasis_app_recording_if_exists_parse(const char *str)
Parse a string into the if_exists enum.
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
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:2541
struct stasis_app_recording_options * stasis_app_recording_options_create(const char *name, const char *format)
Allocate a recording options object.
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:2006
#define ast_string_field_build(x, field, fmt, args...)
Set a field to a complex (built) value.
Definition: stringfields.h:555
struct stasis_topic * ast_bridge_topic(struct ast_bridge *bridge)
A topic which publishes the events for a particular bridge.
Abstract JSON element (object, array, string, int, ...).
Forwarding information.
Definition: stasis.c:1531
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
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
struct stasis_app_recording * stasis_app_control_record(struct stasis_app_control *control, struct stasis_app_recording_options *options)
Record media from a 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 ast_ari_response_error(), ast_ari_response_no_content(), ast_ari_bridges_remove_channel_args::bridge_id, ast_ari_bridges_remove_channel_args::channel, ast_ari_bridges_remove_channel_args::channel_count, find_bridge(), 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:953
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.
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:1442
Structure that contains information about a bridge.
Definition: bridge.h:349
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 RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
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 1037 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, 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().

1039 {
1040  struct ast_bridge *bridge;
1041  struct stasis_app_control *control;
1042 
1043  bridge = find_bridge(response, args->bridge_id);
1044  if (!bridge) {
1045  return;
1046  }
1047 
1048  control = find_channel_control(response, args->channel_id);
1049  if (!control) {
1050  ao2_ref(bridge, -1);
1051  return;
1052  }
1053 
1054  if (stasis_app_get_bridge(control) != bridge) {
1055  ast_ari_response_error(response, 422,
1056  "Unprocessable Entity",
1057  "Channel not in this bridge");
1058  ao2_ref(bridge, -1);
1059  ao2_ref(control, -1);
1060  return;
1061  }
1062 
1063  stasis_app_send_command(control, bridge_set_video_source_cb,
1064  ao2_bump(bridge), __ao2_cleanup);
1065 
1066  ao2_ref(bridge, -1);
1067  ao2_ref(control, -1);
1068 
1069  ast_ari_response_no_content(response);
1070 }
struct ast_bridge * stasis_app_get_bridge(struct stasis_app_control *control)
Gets the bridge currently associated with a control object.
Definition: control.c:953
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:677
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.
Definition: control.c:920
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
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:349
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
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 819 of file resource_bridges.c.

References 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, RAII_VAR, and stasis_app_bridge_moh_channel().

Referenced by ast_ari_bridges_start_moh_cb().

822 {
823  RAII_VAR(struct ast_bridge *, bridge, find_bridge(response, args->bridge_id), ao2_cleanup);
824  struct ast_channel *moh_channel;
825  const char *moh_class = args->moh_class;
826 
827  if (!bridge) {
828  /* The response is provided by find_bridge() */
829  return;
830  }
831 
832  moh_channel = stasis_app_bridge_moh_channel(bridge);
833  if (!moh_channel) {
835  return;
836  }
837 
838  ast_moh_start(moh_channel, moh_class, NULL);
839  ast_channel_cleanup(moh_channel);
840 
841  ast_ari_response_no_content(response);
842 
843 }
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.
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_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:2969
Structure that contains information about a bridge.
Definition: bridge.h:349
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:7766
struct ast_bridge * bridge
struct ast_bridge * bridge
Definition: control.c:66
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 RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
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
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 845 of file resource_bridges.c.

References 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().

848 {
849  RAII_VAR(struct ast_bridge *, bridge, find_bridge(response, args->bridge_id), ao2_cleanup);
850 
851  if (!bridge) {
852  /* the response is provided by find_bridge() */
853  return;
854  }
855 
858  response, 409, "Conflict",
859  "Bridge isn't playing music");
860  return;
861  }
862 
863  ast_ari_response_no_content(response);
864 }
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 information about a bridge.
Definition: bridge.h:349
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
struct ast_bridge * bridge
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 RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
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.
Return values
NULLif bridge does not exist.

Definition at line 57 of file resource_bridges.c.

References ao2_ref, ast_ari_response_error(), ast_bridge_get_snapshot_by_uniqueid(), RAII_VAR, and stasis_app_bridge_find_by_id().

Referenced by 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 
66  if (bridge == NULL) {
68  ast_bridge_get_snapshot_by_uniqueid(bridge_id), ao2_cleanup);
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 }
struct ast_bridge_snapshot * ast_bridge_get_snapshot_by_uniqueid(const char *uniqueid)
Returns the current snapshot for the bridge.
Structure that contains a snapshot of information about a bridge.
Definition: bridge.h:314
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
Structure that contains information about a bridge.
Definition: bridge.h:349
struct ast_bridge * stasis_app_bridge_find_by_id(const char *bridge_id)
Returns the bridge with the given id.
Definition: res_stasis.c:774
struct ast_bridge * bridge
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 RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
struct ast_channel_snapshot * snapshot
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.
Return values
NULLif control object does not exist.

Definition at line 92 of file resource_bridges.c.

References ao2_ref, ast_ari_response_error(), ast_channel_snapshot_get_latest(), RAII_VAR, and stasis_app_control_find_by_channel_id().

Referenced by ast_ari_bridges_set_video_source().

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);
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 ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
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 RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
struct ast_channel_snapshot * snapshot