Asterisk - The Open Source Telephony Project  18.5.0
Data Structures | Macros | Typedefs | Functions | Variables
res_stasis_playback.c File Reference

res_stasis playback support. More...

#include "asterisk.h"
#include "asterisk/app.h"
#include "asterisk/astobj2.h"
#include "asterisk/bridge.h"
#include "asterisk/bridge_internal.h"
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/paths.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/stringfields.h"
#include "asterisk/uuid.h"
#include "asterisk/say.h"
#include "asterisk/indications.h"
Include dependency graph for res_stasis_playback.c:

Go to the source code of this file.

Data Structures

struct  stasis_app_playback
 

Macros

#define CHARACTERS_URI_SCHEME   "characters:"
 
#define DIGITS_URI_SCHEME   "digits:"
 
#define NUMBER_URI_SCHEME   "number:"
 
#define PLAYBACK_BUCKETS   127
 
#define PLAYBACK_DEFAULT_SKIPMS   3000
 
#define RECORDING_URI_SCHEME   "recording:"
 
#define SOUND_URI_SCHEME   "sound:"
 
#define TONE_URI_SCHEME   "tone:"
 

Typedefs

typedef int(* playback_opreation_cb) (struct stasis_app_playback *playback)
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static int load_module (void)
 
static void play_on_channel (struct stasis_app_playback *playback, struct ast_channel *chan)
 
static void play_on_channel_in_bridge (struct ast_bridge_channel *bridge_channel, const char *playback_id)
 Special case code to play while a channel is in a bridge. More...
 
static int play_uri (struct stasis_app_control *control, struct ast_channel *chan, void *data)
 
static int playback_cancel (struct stasis_app_playback *playback)
 
static int playback_cmp (void *obj, void *arg, int flags)
 
static struct stasis_app_playbackplayback_create (struct stasis_app_control *control, const char *id)
 
static void playback_dtor (void *obj)
 
static void playback_final_update (struct stasis_app_playback *playback, long playedms, int res, const char *uniqueid)
 
static int playback_first_update (struct stasis_app_playback *playback, const char *uniqueid)
 
static int playback_forward (struct stasis_app_playback *playback)
 
static int playback_hash (const void *obj, int flags)
 
static int playback_noop (struct stasis_app_playback *playback)
 
static int playback_pause (struct stasis_app_playback *playback)
 
static void playback_publish (struct stasis_app_playback *playback)
 
static int playback_restart (struct stasis_app_playback *playback)
 
static int playback_reverse (struct stasis_app_playback *playback)
 
static int playback_stop (struct stasis_app_playback *playback)
 
static struct ast_jsonplayback_to_json (struct stasis_message *message, const struct stasis_message_sanitizer *sanitize)
 
static int playback_unpause (struct stasis_app_playback *playback)
 
static void remove_from_playbacks (void *data)
 RAII_VAR function to remove a playback from the global list when leaving scope. More...
 
static void set_target_uri (struct stasis_app_playback *playback, enum stasis_app_playback_target_type target_type, const char *target_id)
 
struct stasis_app_playbackstasis_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. More...
 
struct stasis_app_playbackstasis_app_playback_find_by_id (const char *id)
 Finds the playback object with the given id. More...
 
const char * stasis_app_playback_get_id (struct stasis_app_playback *control)
 Gets the unique id of a playback object. More...
 
enum stasis_app_playback_state stasis_app_playback_get_state (struct stasis_app_playback *control)
 Gets the current state of a playback operation. More...
 
enum stasis_playback_oper_results stasis_app_playback_operation (struct stasis_app_playback *playback, enum stasis_app_playback_media_operation operation)
 Controls the media for a given playback operation. More...
 
struct ast_jsonstasis_app_playback_to_json (const struct stasis_app_playback *playback)
 Convert a playback to its JSON representation. More...
 
 STASIS_MESSAGE_TYPE_DEFN (stasis_app_playback_snapshot_type,.to_json=playback_to_json,)
 
static const char * state_to_string (enum stasis_app_playback_state state)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS , .description = "Stasis application playback support" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .requires = "res_stasis,res_stasis_recording" }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
playback_opreation_cb operations [STASIS_PLAYBACK_STATE_MAX][STASIS_PLAYBACK_MEDIA_OP_MAX]
 A sparse array detailing how commands should be handled in the various playback states. Unset entries imply invalid operations. More...
 
static struct ao2_containerplaybacks
 

Detailed Description

res_stasis playback support.

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

Definition in file res_stasis_playback.c.

Macro Definition Documentation

◆ CHARACTERS_URI_SCHEME

#define CHARACTERS_URI_SCHEME   "characters:"

Definition at line 61 of file res_stasis_playback.c.

Referenced by play_on_channel().

◆ DIGITS_URI_SCHEME

#define DIGITS_URI_SCHEME   "digits:"

Definition at line 60 of file res_stasis_playback.c.

Referenced by play_on_channel().

◆ NUMBER_URI_SCHEME

#define NUMBER_URI_SCHEME   "number:"

Definition at line 59 of file res_stasis_playback.c.

Referenced by play_on_channel().

◆ PLAYBACK_BUCKETS

#define PLAYBACK_BUCKETS   127

Number of hash buckets for playback container. Keep it prime!

Definition at line 52 of file res_stasis_playback.c.

Referenced by load_module().

◆ PLAYBACK_DEFAULT_SKIPMS

#define PLAYBACK_DEFAULT_SKIPMS   3000

Default number of milliseconds of media to skip

Definition at line 55 of file res_stasis_playback.c.

Referenced by stasis_app_control_play_uri().

◆ RECORDING_URI_SCHEME

#define RECORDING_URI_SCHEME   "recording:"

Definition at line 58 of file res_stasis_playback.c.

Referenced by play_on_channel().

◆ SOUND_URI_SCHEME

#define SOUND_URI_SCHEME   "sound:"

Definition at line 57 of file res_stasis_playback.c.

Referenced by play_on_channel().

◆ TONE_URI_SCHEME

#define TONE_URI_SCHEME   "tone:"

Definition at line 62 of file res_stasis_playback.c.

Referenced by play_on_channel().

Typedef Documentation

◆ playback_opreation_cb

typedef int(* playback_opreation_cb) (struct stasis_app_playback *playback)

Definition at line 584 of file res_stasis_playback.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 773 of file res_stasis_playback.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 773 of file res_stasis_playback.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 773 of file res_stasis_playback.c.

◆ load_module()

static int load_module ( void  )
static

Definition at line 742 of file res_stasis_playback.c.

References AO2_ALLOC_OPT_LOCK_MUTEX, ao2_container_alloc_hash, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, NULL, PLAYBACK_BUCKETS, playback_cmp(), playback_hash(), stasis_app_playback_snapshot_type(), STASIS_MESSAGE_TYPE_CLEANUP, and STASIS_MESSAGE_TYPE_INIT.

Referenced by unload_module().

743 {
744  int r;
745 
747  if (r != 0) {
749  }
750 
753  if (!playbacks) {
756  }
758 }
static int playback_cmp(void *obj, void *arg, int flags)
#define STASIS_MESSAGE_TYPE_INIT(name)
Boiler-plate messaging macro for initializing message types.
Definition: stasis.h:1501
static struct ao2_container * playbacks
#define STASIS_MESSAGE_TYPE_CLEANUP(name)
Boiler-plate messaging macro for cleaning up message types.
Definition: stasis.h:1523
#define PLAYBACK_BUCKETS
#define NULL
Definition: resample.c:96
struct stasis_message_type * stasis_app_playback_snapshot_type(void)
Message type for playback updates. The data is an ast_channel_blob.
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Definition: astobj2.h:1310
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
static int playback_hash(const void *obj, int flags)

◆ play_on_channel()

static void play_on_channel ( struct stasis_app_playback playback,
struct ast_channel chan 
)
static

Definition at line 285 of file res_stasis_playback.c.

References ao2_cleanup, ast_assert, ast_begins_with(), ast_channel_name(), ast_channel_uniqueid(), AST_CONTROL_PROGRESS, AST_CONTROL_STREAM_STOP, ast_control_streamfile_lang(), ast_control_tone(), ast_indicate(), ast_log, AST_SAY_CASE_NONE, ast_say_character_str(), ast_say_digit_str(), ast_say_number(), AST_STATE_UP, ast_string_field_set, AST_VECTOR_GET, AST_VECTOR_SIZE, CHARACTERS_URI_SCHEME, DIGITS_URI_SCHEME, stasis_app_playback::language, LOG_ERROR, stasis_app_playback::media, NULL, NUMBER_URI_SCHEME, playback_final_update(), playback_first_update(), RAII_VAR, RECORDING_URI_SCHEME, SOUND_URI_SCHEME, stasis_app_stored_recording_find_by_name(), stasis_app_stored_recording_get_file(), stop, and TONE_URI_SCHEME.

Referenced by play_on_channel_in_bridge(), and play_uri().

287 {
288  int res;
289  long offsetms;
290  size_t index;
291 
292  /* Even though these local variables look fairly pointless, they avoid
293  * having a bunch of NULL's passed directly into
294  * ast_control_streamfile() */
295  const char *fwd = NULL;
296  const char *rev = NULL;
297  const char *stop = NULL;
298  const char *pause = NULL;
299  const char *restart = NULL;
300 
301  ast_assert(playback != NULL);
302 
303  if (ast_channel_state(chan) != AST_STATE_UP) {
305  }
306 
307  offsetms = playback->offsetms;
308 
309  for (index = 0; index < AST_VECTOR_SIZE(&playback->medias); index++) {
310  playback->media_index = index;
311 
312  /* Set the current media to play */
313  ast_string_field_set(playback, media, AST_VECTOR_GET(&playback->medias, playback->media_index));
314 
315  res = playback_first_update(playback, ast_channel_uniqueid(chan));
316  if (res != 0) {
317  return;
318  }
319 
320  if (ast_begins_with(playback->media, SOUND_URI_SCHEME)) {
321  playback->controllable = 1;
322 
323  /* Play sound */
324  res = ast_control_streamfile_lang(chan, playback->media + strlen(SOUND_URI_SCHEME),
325  fwd, rev, stop, pause, restart, playback->skipms, playback->language,
326  &offsetms);
327  } else if (ast_begins_with(playback->media, RECORDING_URI_SCHEME)) {
328  /* Play recording */
329  RAII_VAR(struct stasis_app_stored_recording *, recording, NULL,
330  ao2_cleanup);
331  const char *relname =
332  playback->media + strlen(RECORDING_URI_SCHEME);
333  recording = stasis_app_stored_recording_find_by_name(relname);
334 
335  if (!recording) {
336  ast_log(LOG_ERROR, "Attempted to play recording '%s' on channel '%s' but recording does not exist",
337  relname, ast_channel_name(chan));
338  continue;
339  }
340 
341  playback->controllable = 1;
342 
343  res = ast_control_streamfile_lang(chan,
344  stasis_app_stored_recording_get_file(recording), fwd, rev, stop, pause,
345  restart, playback->skipms, playback->language, &offsetms);
346  } else if (ast_begins_with(playback->media, NUMBER_URI_SCHEME)) {
347  int number;
348 
349  if (sscanf(playback->media + strlen(NUMBER_URI_SCHEME), "%30d", &number) != 1) {
350  ast_log(LOG_ERROR, "Attempted to play number '%s' on channel '%s' but number is invalid",
351  playback->media + strlen(NUMBER_URI_SCHEME), ast_channel_name(chan));
352  continue;
353  }
354 
355  res = ast_say_number(chan, number, stop, playback->language, NULL);
356  } else if (ast_begins_with(playback->media, DIGITS_URI_SCHEME)) {
357  res = ast_say_digit_str(chan, playback->media + strlen(DIGITS_URI_SCHEME),
358  stop, playback->language);
359  } else if (ast_begins_with(playback->media, CHARACTERS_URI_SCHEME)) {
360  res = ast_say_character_str(chan, playback->media + strlen(CHARACTERS_URI_SCHEME),
361  stop, playback->language, AST_SAY_CASE_NONE);
362  } else if (ast_begins_with(playback->media, TONE_URI_SCHEME)) {
363  playback->controllable = 1;
364  res = ast_control_tone(chan, playback->media + strlen(TONE_URI_SCHEME));
365  } else {
366  /* Play URL */
367  ast_log(LOG_ERROR, "Attempted to play URI '%s' on channel '%s' but scheme is unsupported\n",
368  playback->media, ast_channel_name(chan));
369  continue;
370  }
371 
372  playback_final_update(playback, offsetms, res,
373  ast_channel_uniqueid(chan));
374  if (res == AST_CONTROL_STREAM_STOP) {
375  break;
376  }
377 
378  /* Reset offset for any subsequent media */
379  offsetms = 0;
380  }
381  return;
382 }
int ast_control_streamfile_lang(struct ast_channel *chan, const char *file, const char *fwd, const char *rev, const char *stop, const char *suspend, const char *restart, int skipms, const char *lang, long *offsetms)
Version of ast_control_streamfile() which allows the language of the media file to be specified...
Definition: main/app.c:1327
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4322
const char * stasis_app_stored_recording_get_file(struct stasis_app_stored_recording *recording)
Returns the filename for this recording, for use with streamfile.
Definition: stored.c:53
int ast_say_digit_str(struct ast_channel *chan, const char *num, const char *ints, const char *lang)
says digits of a string
Definition: channel.c:8355
int ast_control_tone(struct ast_channel *chan, const char *tone)
Controls playback of a tone.
Definition: main/app.c:1399
ast_channel_state
ast_channel states
Definition: channelstate.h:35
unsigned int stop
Definition: app_meetme.c:1096
#define ast_assert(a)
Definition: utils.h:695
#define NULL
Definition: resample.c:96
Number structure.
Definition: app_followme.c:154
static int playback_first_update(struct stasis_app_playback *playback, const char *uniqueid)
const ast_string_field media
#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 DIGITS_URI_SCHEME
int ast_say_character_str(struct ast_channel *chan, const char *num, const char *ints, const char *lang, enum ast_say_case_sensitivity sensitivity)
function to pronounce character and phonetic strings
Definition: channel.c:8367
#define CHARACTERS_URI_SCHEME
const char * ast_channel_uniqueid(const struct ast_channel *chan)
#define LOG_ERROR
Definition: logger.h:285
#define NUMBER_URI_SCHEME
#define RECORDING_URI_SCHEME
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
#define TONE_URI_SCHEME
const char * ast_channel_name(const struct ast_channel *chan)
struct stasis_app_stored_recording * stasis_app_stored_recording_find_by_name(const char *name)
Creates a stored recording object, with the given name.
Definition: stored.c:310
static int force_inline attribute_pure ast_begins_with(const char *str, const char *prefix)
Definition: strings.h:94
#define SOUND_URI_SCHEME
static void playback_final_update(struct stasis_app_playback *playback, long playedms, int res, const char *uniqueid)
const ast_string_field language
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ play_on_channel_in_bridge()

static void play_on_channel_in_bridge ( struct ast_bridge_channel bridge_channel,
const char *  playback_id 
)
static

Special case code to play while a channel is in a bridge.

Parameters
bridge_channelThe channel's bridge_channel.
playback_idId of the playback to start.

Definition at line 390 of file res_stasis_playback.c.

References ao2_cleanup, ast_log, ast_bridge_channel::chan, LOG_ERROR, NULL, play_on_channel(), RAII_VAR, and stasis_app_playback_find_by_id().

Referenced by play_uri().

392 {
393  RAII_VAR(struct stasis_app_playback *, playback, NULL, ao2_cleanup);
394 
395  playback = stasis_app_playback_find_by_id(playback_id);
396  if (!playback) {
397  ast_log(LOG_ERROR, "Couldn't find playback %s\n",
398  playback_id);
399  return;
400  }
401 
402  play_on_channel(playback, bridge_channel->chan);
403 }
#define NULL
Definition: resample.c:96
#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
struct stasis_app_playback * stasis_app_playback_find_by_id(const char *id)
Finds the playback object with the given id.
#define LOG_ERROR
Definition: logger.h:285
static void play_on_channel(struct stasis_app_playback *playback, struct ast_channel *chan)
struct ast_channel * chan
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ play_uri()

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

Definition at line 418 of file res_stasis_playback.c.

References ao2_bump, ao2_cleanup, ast_bridge_channel_queue_playfile_sync(), ast_bridge_lock, ast_bridge_unlock, bridge_find_channel(), stasis_app_playback::id, NULL, play_on_channel(), play_on_channel_in_bridge(), and stasis_app_get_bridge().

Referenced by stasis_app_control_play_uri().

420 {
421  struct stasis_app_playback *playback = data;
422  struct ast_bridge *bridge;
423 
424  if (!control) {
425  return -1;
426  }
427 
428  bridge = stasis_app_get_bridge(control);
429  if (bridge) {
430  struct ast_bridge_channel *bridge_chan;
431 
432  /* Queue up playback on the bridge */
433  ast_bridge_lock(bridge);
434  bridge_chan = ao2_bump(bridge_find_channel(bridge, chan));
435  ast_bridge_unlock(bridge);
436  if (bridge_chan) {
438  bridge_chan,
440  playback->id,
441  NULL); /* moh_class */
442  }
443  ao2_cleanup(bridge_chan);
444  } else {
445  play_on_channel(playback, chan);
446  }
447 
448  return 0;
449 }
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 void play_on_channel_in_bridge(struct ast_bridge_channel *bridge_channel, const char *playback_id)
Special case code to play while a channel is in a bridge.
struct ast_bridge_channel * bridge_find_channel(struct ast_bridge *bridge, struct ast_channel *chan)
Definition: bridge.c:1469
#define NULL
Definition: resample.c:96
const ast_string_field id
#define ao2_bump(obj)
Definition: astobj2.h:491
Structure that contains information about a bridge.
Definition: bridge.h:357
static void play_on_channel(struct stasis_app_playback *playback, struct ast_channel *chan)
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480
Structure that contains information regarding a channel in a bridge.
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
int ast_bridge_channel_queue_playfile_sync(struct ast_bridge_channel *bridge_channel, ast_bridge_custom_play_fn custom_play, const char *playfile, const char *moh_class)
Synchronously queue a bridge action play file frame onto the bridge channel.

◆ playback_cancel()

static int playback_cancel ( struct stasis_app_playback playback)
static

Definition at line 591 of file res_stasis_playback.c.

References lock, SCOPED_AO2LOCK, and STASIS_PLAYBACK_STATE_CANCELED.

592 {
593  SCOPED_AO2LOCK(lock, playback);
594  playback->state = STASIS_PLAYBACK_STATE_CANCELED;
595  return 0;
596 }
ast_mutex_t lock
Definition: app_meetme.c:1091
#define SCOPED_AO2LOCK(varname, obj)
scoped lock specialization for ao2 mutexes.
Definition: lock.h:602

◆ playback_cmp()

static int playback_cmp ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 181 of file res_stasis_playback.c.

References CMP_MATCH, CMP_STOP, stasis_app_playback::id, and OBJ_KEY.

Referenced by load_module().

182 {
183  struct stasis_app_playback *lhs = obj;
184  struct stasis_app_playback *rhs = arg;
185  const char *rhs_id = flags & OBJ_KEY ? arg : rhs->id;
186 
187  if (strcmp(lhs->id, rhs_id) == 0) {
188  return CMP_MATCH | CMP_STOP;
189  } else {
190  return 0;
191  }
192 }
#define OBJ_KEY
Definition: astobj2.h:1155
const ast_string_field id

◆ playback_create()

static struct stasis_app_playback* playback_create ( struct stasis_app_control control,
const char *  id 
)
static

Definition at line 140 of file res_stasis_playback.c.

References ao2_alloc, ao2_cleanup, ao2_ref, ast_string_field_init, ast_string_field_set, ast_strlen_zero, ast_uuid_generate_str(), AST_UUID_STR_LEN, AST_VECTOR_INIT, NULL, playback_dtor(), and RAII_VAR.

Referenced by stasis_app_control_play_uri().

142 {
143  RAII_VAR(struct stasis_app_playback *, playback, NULL, ao2_cleanup);
144  char uuid[AST_UUID_STR_LEN];
145 
146  if (!control) {
147  return NULL;
148  }
149 
150  playback = ao2_alloc(sizeof(*playback), playback_dtor);
151  if (!playback || ast_string_field_init(playback, 128)) {
152  return NULL;
153  }
154 
155  if (AST_VECTOR_INIT(&playback->medias, 8)) {
156  ao2_ref(playback, -1);
157  return NULL;
158  }
159 
160  if (!ast_strlen_zero(id)) {
161  ast_string_field_set(playback, id, id);
162  } else {
163  ast_uuid_generate_str(uuid, sizeof(uuid));
164  ast_string_field_set(playback, id, uuid);
165  }
166 
167  ao2_ref(control, +1);
168  playback->control = control;
169 
170  ao2_ref(playback, +1);
171  return playback;
172 }
#define AST_UUID_STR_LEN
Definition: uuid.h:27
static void playback_dtor(void *obj)
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113
#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_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:353
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
char * ast_uuid_generate_str(char *buf, size_t size)
Generate a UUID string.
Definition: uuid.c:143
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ playback_dtor()

static void playback_dtor ( void *  obj)
static

Definition at line 124 of file res_stasis_playback.c.

References ao2_cleanup, ast_free, ast_string_field_free_memory, AST_VECTOR_FREE, AST_VECTOR_GET, AST_VECTOR_SIZE, and stasis_app_playback::media.

Referenced by playback_create().

125 {
126  struct stasis_app_playback *playback = obj;
127  int i;
128 
129  for (i = 0; i < AST_VECTOR_SIZE(&playback->medias); i++) {
130  char *media = AST_VECTOR_GET(&playback->medias, i);
131 
132  ast_free(media);
133  }
134  AST_VECTOR_FREE(&playback->medias);
135 
136  ao2_cleanup(playback->control);
138 }
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition: vector.h:174
const ast_string_field media
#define ast_free(a)
Definition: astmm.h:182
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:368
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611

◆ playback_final_update()

static void playback_final_update ( struct stasis_app_playback playback,
long  playedms,
int  res,
const char *  uniqueid 
)
static

Definition at line 259 of file res_stasis_playback.c.

References ast_log, AST_VECTOR_SIZE, lock, LOG_NOTICE, LOG_WARNING, stasis_app_playback::media, playback_publish(), SCOPED_AO2LOCK, STASIS_PLAYBACK_STATE_COMPLETE, STASIS_PLAYBACK_STATE_CONTINUING, and STASIS_PLAYBACK_STATE_STOPPED.

Referenced by play_on_channel().

261 {
262  SCOPED_AO2LOCK(lock, playback);
263 
264  playback->playedms = playedms;
265  if (res == 0) {
266  if (playback->media_index == AST_VECTOR_SIZE(&playback->medias) - 1) {
267  playback->state = STASIS_PLAYBACK_STATE_COMPLETE;
268  } else {
269  playback->state = STASIS_PLAYBACK_STATE_CONTINUING;
270  }
271  } else {
272  if (playback->state == STASIS_PLAYBACK_STATE_STOPPED) {
273  ast_log(LOG_NOTICE, "%s: Playback stopped for %s\n",
274  uniqueid, playback->media);
275  } else {
276  ast_log(LOG_WARNING, "%s: Playback failed for %s\n",
277  uniqueid, playback->media);
278  playback->state = STASIS_PLAYBACK_STATE_STOPPED;
279  }
280  }
281 
282  playback_publish(playback);
283 }
#define LOG_WARNING
Definition: logger.h:274
const ast_string_field media
#define ast_log
Definition: astobj2.c:42
ast_mutex_t lock
Definition: app_meetme.c:1091
#define LOG_NOTICE
Definition: logger.h:263
#define SCOPED_AO2LOCK(varname, obj)
scoped lock specialization for ao2 mutexes.
Definition: lock.h:602
static void playback_publish(struct stasis_app_playback *playback)
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611

◆ playback_first_update()

static int playback_first_update ( struct stasis_app_playback playback,
const char *  uniqueid 
)
static

Definition at line 240 of file res_stasis_playback.c.

References ast_log, lock, LOG_NOTICE, stasis_app_playback::media, playback_publish(), SCOPED_AO2LOCK, STASIS_PLAYBACK_STATE_CANCELED, and STASIS_PLAYBACK_STATE_PLAYING.

Referenced by play_on_channel().

242 {
243  int res;
244  SCOPED_AO2LOCK(lock, playback);
245 
246  if (playback->state == STASIS_PLAYBACK_STATE_CANCELED) {
247  ast_log(LOG_NOTICE, "%s: Playback canceled for %s\n",
248  uniqueid, playback->media);
249  res = -1;
250  } else {
251  res = 0;
252  playback->state = STASIS_PLAYBACK_STATE_PLAYING;
253  }
254 
255  playback_publish(playback);
256  return res;
257 }
const ast_string_field media
#define ast_log
Definition: astobj2.c:42
ast_mutex_t lock
Definition: app_meetme.c:1091
#define LOG_NOTICE
Definition: logger.h:263
#define SCOPED_AO2LOCK(varname, obj)
scoped lock specialization for ao2 mutexes.
Definition: lock.h:602
static void playback_publish(struct stasis_app_playback *playback)

◆ playback_forward()

static int playback_forward ( struct stasis_app_playback playback)
static

Definition at line 665 of file res_stasis_playback.c.

References AST_CONTROL_STREAM_FORWARD, lock, SCOPED_AO2LOCK, and stasis_app_control_queue_control().

666 {
667  SCOPED_AO2LOCK(lock, playback);
668 
669  if (!playback->controllable) {
670  return -1;
671  }
672 
673  return stasis_app_control_queue_control(playback->control,
675 }
ast_mutex_t lock
Definition: app_meetme.c:1091
#define SCOPED_AO2LOCK(varname, obj)
scoped lock specialization for ao2 mutexes.
Definition: lock.h:602
int stasis_app_control_queue_control(struct stasis_app_control *control, enum ast_control_frame_type frame_type)
Queue a control frame without payload.
Definition: control.c:1445

◆ playback_hash()

static int playback_hash ( const void *  obj,
int  flags 
)
static

Definition at line 174 of file res_stasis_playback.c.

References ast_str_hash(), stasis_app_playback::id, and OBJ_KEY.

Referenced by load_module().

175 {
176  const struct stasis_app_playback *playback = obj;
177  const char *id = flags & OBJ_KEY ? obj : playback->id;
178  return ast_str_hash(id);
179 }
#define OBJ_KEY
Definition: astobj2.h:1155
const ast_string_field id
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
Definition: strings.h:1206

◆ playback_noop()

static int playback_noop ( struct stasis_app_playback playback)
static

Definition at line 586 of file res_stasis_playback.c.

587 {
588  return 0;
589 }

◆ playback_pause()

static int playback_pause ( struct stasis_app_playback playback)
static

Definition at line 623 of file res_stasis_playback.c.

References AST_CONTROL_STREAM_SUSPEND, lock, playback_publish(), SCOPED_AO2LOCK, stasis_app_control_queue_control(), and STASIS_PLAYBACK_STATE_PAUSED.

624 {
625  SCOPED_AO2LOCK(lock, playback);
626 
627  if (!playback->controllable) {
628  return -1;
629  }
630 
631  playback->state = STASIS_PLAYBACK_STATE_PAUSED;
632  playback_publish(playback);
633 
634  return stasis_app_control_queue_control(playback->control,
636 }
ast_mutex_t lock
Definition: app_meetme.c:1091
#define SCOPED_AO2LOCK(varname, obj)
scoped lock specialization for ao2 mutexes.
Definition: lock.h:602
int stasis_app_control_queue_control(struct stasis_app_control *control, enum ast_control_frame_type frame_type)
Queue a control frame without payload.
Definition: control.c:1445
static void playback_publish(struct stasis_app_playback *playback)

◆ playback_publish()

static void playback_publish ( struct stasis_app_playback playback)
static

Definition at line 218 of file res_stasis_playback.c.

References ao2_cleanup, ast_assert, ast_channel_blob_create_from_cache(), ast_json_unref(), NULL, RAII_VAR, stasis_app_control_get_channel_id(), stasis_app_control_publish(), stasis_app_playback_snapshot_type(), and stasis_app_playback_to_json().

Referenced by playback_final_update(), playback_first_update(), playback_pause(), playback_unpause(), and stasis_app_control_play_uri().

219 {
220  RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
222 
223  ast_assert(playback != NULL);
224 
225  json = stasis_app_playback_to_json(playback);
226  if (json == NULL) {
227  return;
228  }
229 
231  stasis_app_control_get_channel_id(playback->control),
233  if (message == NULL) {
234  return;
235  }
236 
237  stasis_app_control_publish(playback->control, message);
238 }
void stasis_app_control_publish(struct stasis_app_control *control, struct stasis_message *message)
Publish a message to the control&#39;s channel&#39;s topic.
Definition: control.c:1436
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
#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
struct stasis_message_type * stasis_app_playback_snapshot_type(void)
Message type for playback updates. The data is an ast_channel_blob.
const char * stasis_app_control_get_channel_id(const struct stasis_app_control *control)
Returns the uniqueid of the channel associated with this control.
Definition: control.c:1430
struct stasis_message * ast_channel_blob_create_from_cache(const char *uniqueid, struct stasis_message_type *type, struct ast_json *blob)
Create a ast_channel_blob message, pulling channel state from the cache.
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Abstract JSON element (object, array, string, int, ...).
struct ast_json * stasis_app_playback_to_json(const struct stasis_app_playback *playback)
Convert a playback to its JSON representation.

◆ playback_restart()

static int playback_restart ( struct stasis_app_playback playback)
static

Definition at line 611 of file res_stasis_playback.c.

References AST_CONTROL_STREAM_RESTART, lock, SCOPED_AO2LOCK, and stasis_app_control_queue_control().

612 {
613  SCOPED_AO2LOCK(lock, playback);
614 
615  if (!playback->controllable) {
616  return -1;
617  }
618 
619  return stasis_app_control_queue_control(playback->control,
621 }
ast_mutex_t lock
Definition: app_meetme.c:1091
#define SCOPED_AO2LOCK(varname, obj)
scoped lock specialization for ao2 mutexes.
Definition: lock.h:602
int stasis_app_control_queue_control(struct stasis_app_control *control, enum ast_control_frame_type frame_type)
Queue a control frame without payload.
Definition: control.c:1445

◆ playback_reverse()

static int playback_reverse ( struct stasis_app_playback playback)
static

Definition at line 653 of file res_stasis_playback.c.

References AST_CONTROL_STREAM_REVERSE, lock, SCOPED_AO2LOCK, and stasis_app_control_queue_control().

654 {
655  SCOPED_AO2LOCK(lock, playback);
656 
657  if (!playback->controllable) {
658  return -1;
659  }
660 
661  return stasis_app_control_queue_control(playback->control,
663 }
ast_mutex_t lock
Definition: app_meetme.c:1091
#define SCOPED_AO2LOCK(varname, obj)
scoped lock specialization for ao2 mutexes.
Definition: lock.h:602
int stasis_app_control_queue_control(struct stasis_app_control *control, enum ast_control_frame_type frame_type)
Queue a control frame without payload.
Definition: control.c:1445

◆ playback_stop()

static int playback_stop ( struct stasis_app_playback playback)
static

Definition at line 598 of file res_stasis_playback.c.

References AST_CONTROL_STREAM_STOP, lock, SCOPED_AO2LOCK, stasis_app_control_queue_control(), and STASIS_PLAYBACK_STATE_STOPPED.

599 {
600  SCOPED_AO2LOCK(lock, playback);
601 
602  if (!playback->controllable) {
603  return -1;
604  }
605 
606  playback->state = STASIS_PLAYBACK_STATE_STOPPED;
607  return stasis_app_control_queue_control(playback->control,
609 }
ast_mutex_t lock
Definition: app_meetme.c:1091
#define SCOPED_AO2LOCK(varname, obj)
scoped lock specialization for ao2 mutexes.
Definition: lock.h:602
int stasis_app_control_queue_control(struct stasis_app_control *control, enum ast_control_frame_type frame_type)
Queue a control frame without payload.
Definition: control.c:1445

◆ playback_to_json()

static struct ast_json* playback_to_json ( struct stasis_message message,
const struct stasis_message_sanitizer sanitize 
)
static

Definition at line 95 of file res_stasis_playback.c.

References ast_json_object_get(), ast_json_pack(), ast_json_string_get(), ast_json_timeval(), ast_channel_blob::blob, NULL, stasis_app_playback_snapshot_type(), stasis_message_data(), stasis_message_timestamp(), STASIS_MESSAGE_TYPE_DEFN(), and type.

97 {
98  struct ast_channel_blob *channel_blob = stasis_message_data(message);
99  struct ast_json *blob = channel_blob->blob;
100  const char *state =
102  const char *type;
103 
104  if (!strcmp(state, "playing")) {
105  type = "PlaybackStarted";
106  } else if (!strcmp(state, "continuing")) {
107  type = "PlaybackContinuing";
108  } else if (!strcmp(state, "done")) {
109  type = "PlaybackFinished";
110  } else {
111  return NULL;
112  }
113 
114  return ast_json_pack("{s: s, s: o?, s: O}",
115  "type", type,
116  "timestamp", ast_json_timeval(*stasis_message_timestamp(message), NULL),
117  "playback", blob);
118 }
static const char type[]
Definition: chan_ooh323.c:109
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
struct ast_json * blob
#define NULL
Definition: resample.c:96
Blob of data associated with a channel.
const struct timeval * stasis_message_timestamp(const struct stasis_message *msg)
Get the time when a message was created.
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
Definition: json.c:273
struct ast_json * ast_json_timeval(const struct timeval tv, const char *zone)
Construct a timeval as JSON.
Definition: json.c:649
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
Definition: json.c:397
Abstract JSON element (object, array, string, int, ...).

◆ playback_unpause()

static int playback_unpause ( struct stasis_app_playback playback)
static

Definition at line 638 of file res_stasis_playback.c.

References AST_CONTROL_STREAM_SUSPEND, lock, playback_publish(), SCOPED_AO2LOCK, stasis_app_control_queue_control(), and STASIS_PLAYBACK_STATE_PLAYING.

639 {
640  SCOPED_AO2LOCK(lock, playback);
641 
642  if (!playback->controllable) {
643  return -1;
644  }
645 
646  playback->state = STASIS_PLAYBACK_STATE_PLAYING;
647  playback_publish(playback);
648 
649  return stasis_app_control_queue_control(playback->control,
651 }
ast_mutex_t lock
Definition: app_meetme.c:1091
#define SCOPED_AO2LOCK(varname, obj)
scoped lock specialization for ao2 mutexes.
Definition: lock.h:602
int stasis_app_control_queue_control(struct stasis_app_control *control, enum ast_control_frame_type frame_type)
Queue a control frame without payload.
Definition: control.c:1445
static void playback_publish(struct stasis_app_playback *playback)

◆ remove_from_playbacks()

static void remove_from_playbacks ( void *  data)
static

RAII_VAR function to remove a playback from the global list when leaving scope.

Definition at line 409 of file res_stasis_playback.c.

References ao2_ref, ao2_unlink_flags, OBJ_NODATA, OBJ_POINTER, and OBJ_UNLINK.

Referenced by stasis_app_control_play_uri().

410 {
411  struct stasis_app_playback *playback = data;
412 
413  ao2_unlink_flags(playbacks, playback,
415  ao2_ref(playback, -1);
416 }
#define OBJ_POINTER
Definition: astobj2.h:1154
static struct ao2_container * playbacks
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_unlink_flags(container, obj, flags)
Definition: astobj2.h:1622

◆ set_target_uri()

static void set_target_uri ( struct stasis_app_playback playback,
enum stasis_app_playback_target_type  target_type,
const char *  target_id 
)
static

Definition at line 451 of file res_stasis_playback.c.

References ast_assert, ast_string_field_build, NULL, STASIS_PLAYBACK_TARGET_BRIDGE, STASIS_PLAYBACK_TARGET_CHANNEL, stasis_app_playback::target, and type.

Referenced by stasis_app_control_play_uri().

455 {
456  const char *type = NULL;
457  switch (target_type) {
459  type = "channel";
460  break;
462  type = "bridge";
463  break;
464  }
465 
466  ast_assert(type != NULL);
467 
468  ast_string_field_build(playback, target, "%s:%s", type, target_id);
469 }
static const char type[]
Definition: chan_ooh323.c:109
#define ast_assert(a)
Definition: utils.h:695
#define NULL
Definition: resample.c:96
const ast_string_field target
#define ast_string_field_build(x, field, fmt, args...)
Set a field to a complex (built) value.
Definition: stringfields.h:550

◆ stasis_app_control_play_uri()

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.

Note that the file isn't the full path to the file. Asterisk's internal playback mechanism will automagically select the best format based on the available codecs for the channel.

Parameters
controlControl for res_stasis.
mediaArray of const char * media files to play.
media_countThe number of media files in media.
languageSelects the file based on language.
target_idID of the target bridge or channel.
target_typeWhat the target type is
skipmsNumber of milliseconds to skip for forward/reverse operations.
offsetmsNumber of milliseconds to skip before playing.
idID to assign the new playback or NULL for default.
Returns
Playback control object.
NULL on error.

Definition at line 471 of file res_stasis_playback.c.

References ao2_bump, ao2_link, ao2_ref, ast_debug, ast_free, ast_log, ast_malloc, ast_string_field_set, ast_strlen_zero, AST_VECTOR_APPEND, AST_VECTOR_GET, LOG_ERROR, NULL, play_uri(), playback_create(), PLAYBACK_DEFAULT_SKIPMS, playback_publish(), remove_from_playbacks(), set_target_uri(), skipms, stasis_app_control_get_channel_id(), stasis_app_send_command_async(), and STASIS_PLAYBACK_STATE_QUEUED.

Referenced by ari_bridges_play_helper(), and ari_channels_handle_play().

476 {
477  struct stasis_app_playback *playback;
478  size_t i;
479 
480  if (skipms < 0 || offsetms < 0 || media_count == 0) {
481  return NULL;
482  }
483 
484  playback = playback_create(control, id);
485  if (!playback) {
486  return NULL;
487  }
488 
489  for (i = 0; i < media_count; i++) {
490  char *media_uri;
491 
492  if (ast_strlen_zero(media[i])) {
493  ast_log(LOG_ERROR, "Attempted to play media on channel '%s' but no media URI was provided.\n",
495  ao2_ref(playback, -1);
496  return NULL;
497  }
498 
499  media_uri = ast_malloc(strlen(media[i]) + 1);
500  if (!media_uri) {
501  ao2_ref(playback, -1);
502  return NULL;
503  }
504 
505  ast_debug(3, "%s: Sending play(%s) command\n",
507 
508  /* safe */
509  strcpy(media_uri, media[i]);
510  if (AST_VECTOR_APPEND(&playback->medias, media_uri)) {
511  ao2_ref(playback, -1);
512  ast_free(media_uri);
513  return NULL;
514  }
515  }
516 
517  if (skipms == 0) {
519  }
520 
521  ast_string_field_set(playback, media, AST_VECTOR_GET(&playback->medias, 0));
523  set_target_uri(playback, target_type, target_id);
524  playback->skipms = skipms;
525  playback->offsetms = offsetms;
526  ao2_link(playbacks, playback);
527 
528  playback->state = STASIS_PLAYBACK_STATE_QUEUED;
529  playback_publish(playback);
530 
532 
533  return playback;
534 }
static void set_target_uri(struct stasis_app_playback *playback, enum stasis_app_playback_target_type target_type, const char *target_id)
static struct ao2_container * playbacks
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256
#define NULL
Definition: resample.c:96
#define PLAYBACK_DEFAULT_SKIPMS
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ao2_bump(obj)
Definition: astobj2.h:491
const ast_string_field media
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:117
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
int stasis_app_send_command_async(struct stasis_app_control *control, stasis_app_command_cb command, void *data, command_data_destructor_fn data_destructor)
Asynchronous version of stasis_app_send_command().
Definition: control.c:904
static int skipms
static void remove_from_playbacks(void *data)
RAII_VAR function to remove a playback from the global list when leaving scope.
#define LOG_ERROR
Definition: logger.h:285
const char * stasis_app_control_get_channel_id(const struct stasis_app_control *control)
Returns the uniqueid of the channel associated with this control.
Definition: control.c:1430
#define ast_free(a)
Definition: astmm.h:182
static int play_uri(struct stasis_app_control *control, struct ast_channel *chan, void *data)
static struct stasis_app_playback * playback_create(struct stasis_app_control *control, const char *id)
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
static void playback_publish(struct stasis_app_playback *playback)
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514
#define ao2_link(container, obj)
Definition: astobj2.h:1549

◆ stasis_app_playback_find_by_id()

struct stasis_app_playback* stasis_app_playback_find_by_id ( const char *  id)

Finds the playback object with the given id.

Parameters
idId of the playback object to find.
Returns
Associated stasis_app_playback object.
NULL if id not found.

Definition at line 550 of file res_stasis_playback.c.

References ao2_find, and OBJ_KEY.

Referenced by ast_ari_playbacks_control(), ast_ari_playbacks_get(), ast_ari_playbacks_stop(), and play_on_channel_in_bridge().

551 {
552  return ao2_find(playbacks, id, OBJ_KEY);
553 }
#define OBJ_KEY
Definition: astobj2.h:1155
static struct ao2_container * playbacks
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756

◆ stasis_app_playback_get_id()

const char* stasis_app_playback_get_id ( struct stasis_app_playback playback)

Gets the unique id of a playback object.

Parameters
playbackPlayback control object.
Returns
playback's id.
NULL if playback ic NULL

Definition at line 543 of file res_stasis_playback.c.

References stasis_app_playback::id.

Referenced by ari_bridges_play_helper(), and ari_channels_handle_play().

545 {
546  /* id is immutable; no lock needed */
547  return control->id;
548 }
const ast_string_field id

◆ stasis_app_playback_get_state()

enum stasis_app_playback_state stasis_app_playback_get_state ( struct stasis_app_playback playback)

Gets the current state of a playback operation.

Parameters
playbackPlayback control object.
Returns
The state of the playback object.

Definition at line 536 of file res_stasis_playback.c.

References lock, and SCOPED_AO2LOCK.

538 {
539  SCOPED_AO2LOCK(lock, control);
540  return control->state;
541 }
ast_mutex_t lock
Definition: app_meetme.c:1091
#define SCOPED_AO2LOCK(varname, obj)
scoped lock specialization for ao2 mutexes.
Definition: lock.h:602

◆ stasis_app_playback_operation()

enum stasis_playback_oper_results stasis_app_playback_operation ( struct stasis_app_playback playback,
enum stasis_app_playback_media_operation  operation 
)

Controls the media for a given playback operation.

Parameters
playbackPlayback control object.
controlMedia control operation.
Returns
STASIS_PLAYBACK_OPER_OK on success.
stasis_playback_oper_results indicating failure.

Definition at line 708 of file res_stasis_playback.c.

References ast_assert, ast_log, lock, LOG_ERROR, operations, SCOPED_AO2LOCK, STASIS_PLAYBACK_MEDIA_OP_MAX, STASIS_PLAYBACK_OPER_FAILED, STASIS_PLAYBACK_OPER_NOT_PLAYING, STASIS_PLAYBACK_OPER_OK, STASIS_PLAYBACK_STATE_MAX, and STASIS_PLAYBACK_STATE_PLAYING.

Referenced by ast_ari_playbacks_control(), and ast_ari_playbacks_stop().

711 {
713  SCOPED_AO2LOCK(lock, playback);
714 
715  ast_assert((unsigned int)playback->state < STASIS_PLAYBACK_STATE_MAX);
716 
717  if (operation >= STASIS_PLAYBACK_MEDIA_OP_MAX) {
718  ast_log(LOG_ERROR, "Invalid playback operation %u\n", operation);
719  return -1;
720  }
721 
722  cb = operations[playback->state][operation];
723 
724  if (!cb) {
725  if (playback->state != STASIS_PLAYBACK_STATE_PLAYING) {
726  /* So we can be specific in our error message. */
728  } else {
729  /* And, really, all operations should be valid during
730  * playback */
732  "Unhandled operation during playback: %u\n",
733  operation);
735  }
736  }
737 
738  return cb(playback) ?
740 }
#define ast_assert(a)
Definition: utils.h:695
#define ast_log
Definition: astobj2.c:42
ast_mutex_t lock
Definition: app_meetme.c:1091
playback_opreation_cb operations[STASIS_PLAYBACK_STATE_MAX][STASIS_PLAYBACK_MEDIA_OP_MAX]
A sparse array detailing how commands should be handled in the various playback states. Unset entries imply invalid operations.
#define LOG_ERROR
Definition: logger.h:285
int(* playback_opreation_cb)(struct stasis_app_playback *playback)
#define SCOPED_AO2LOCK(varname, obj)
scoped lock specialization for ao2 mutexes.
Definition: lock.h:602

◆ stasis_app_playback_to_json()

struct ast_json* stasis_app_playback_to_json ( const struct stasis_app_playback playback)

Convert a playback to its JSON representation.

Parameters
playbackThe playback object to convert to JSON
Return values

Definition at line 555 of file res_stasis_playback.c.

References ast_json_pack(), ast_json_ref(), ast_json_unref(), AST_VECTOR_GET, AST_VECTOR_SIZE, stasis_app_playback::id, stasis_app_playback::language, stasis_app_playback::media, NULL, RAII_VAR, state_to_string(), and stasis_app_playback::target.

Referenced by ari_bridges_play_helper(), ari_channels_handle_play(), ast_ari_playbacks_get(), and playback_publish().

557 {
558  RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
559 
560  if (playback == NULL) {
561  return NULL;
562  }
563 
564  if (playback->media_index == AST_VECTOR_SIZE(&playback->medias) - 1) {
565  json = ast_json_pack("{s: s, s: s, s: s, s: s, s: s}",
566  "id", playback->id,
567  "media_uri", playback->media,
568  "target_uri", playback->target,
569  "language", playback->language,
570  "state", state_to_string(playback->state));
571  } else {
572  json = ast_json_pack("{s: s, s: s, s: s, s: s, s: s, s: s}",
573  "id", playback->id,
574  "media_uri", playback->media,
575  "next_media_uri", AST_VECTOR_GET(&playback->medias, playback->media_index + 1),
576  "target_uri", playback->target,
577  "language", playback->language,
578  "state", state_to_string(playback->state));
579  }
580 
581  return ast_json_ref(json);
582 }
struct ast_json * ast_json_ref(struct ast_json *value)
Increase refcount on value.
Definition: json.c:67
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
#define NULL
Definition: resample.c:96
const ast_string_field target
const ast_string_field id
const ast_string_field media
static const char * state_to_string(enum stasis_app_playback_state state)
#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_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
Abstract JSON element (object, array, string, int, ...).
const ast_string_field language
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611

◆ STASIS_MESSAGE_TYPE_DEFN()

STASIS_MESSAGE_TYPE_DEFN ( stasis_app_playback_snapshot_type  ,
to_json = playback_to_json 
)

Referenced by playback_to_json().

◆ state_to_string()

static const char* state_to_string ( enum stasis_app_playback_state  state)
static

Definition at line 194 of file res_stasis_playback.c.

References STASIS_PLAYBACK_STATE_CANCELED, STASIS_PLAYBACK_STATE_COMPLETE, STASIS_PLAYBACK_STATE_CONTINUING, STASIS_PLAYBACK_STATE_MAX, STASIS_PLAYBACK_STATE_PAUSED, STASIS_PLAYBACK_STATE_PLAYING, STASIS_PLAYBACK_STATE_QUEUED, and STASIS_PLAYBACK_STATE_STOPPED.

Referenced by stasis_app_playback_to_json().

195 {
196  switch (state) {
198  return "queued";
200  return "playing";
202  return "paused";
204  return "continuing";
208  /* It doesn't really matter how we got here, but all of these
209  * states really just mean 'done' */
210  return "done";
212  break;
213  }
214 
215  return "?";
216 }

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 760 of file res_stasis_playback.c.

References ao2_cleanup, AST_MODFLAG_GLOBAL_SYMBOLS, AST_MODULE_INFO(), AST_MODULE_SUPPORT_CORE, ASTERISK_GPL_KEY, load_module(), NULL, stasis_app_playback_snapshot_type(), and STASIS_MESSAGE_TYPE_CLEANUP.

761 {
763  playbacks = NULL;
765  return 0;
766 }
static struct ao2_container * playbacks
#define STASIS_MESSAGE_TYPE_CLEANUP(name)
Boiler-plate messaging macro for cleaning up message types.
Definition: stasis.h:1523
#define NULL
Definition: resample.c:96
struct stasis_message_type * stasis_app_playback_snapshot_type(void)
Message type for playback updates. The data is an ast_channel_blob.
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS , .description = "Stasis application playback support" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .requires = "res_stasis,res_stasis_recording" }
static

Definition at line 773 of file res_stasis_playback.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 773 of file res_stasis_playback.c.

◆ operations

A sparse array detailing how commands should be handled in the various playback states. Unset entries imply invalid operations.

Definition at line 681 of file res_stasis_playback.c.

Referenced by stasis_app_playback_operation().

◆ playbacks

struct ao2_container* playbacks
static

Container of all current playbacks

Definition at line 65 of file res_stasis_playback.c.