Asterisk - The Open Source Telephony Project GIT-master-7e7a603
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_operation_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, int hangup, 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_operation_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.

◆ DIGITS_URI_SCHEME

#define DIGITS_URI_SCHEME   "digits:"

Definition at line 60 of file res_stasis_playback.c.

◆ NUMBER_URI_SCHEME

#define NUMBER_URI_SCHEME   "number:"

Definition at line 59 of file res_stasis_playback.c.

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

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

◆ RECORDING_URI_SCHEME

#define RECORDING_URI_SCHEME   "recording:"

Definition at line 58 of file res_stasis_playback.c.

◆ SOUND_URI_SCHEME

#define SOUND_URI_SCHEME   "sound:"

Definition at line 57 of file res_stasis_playback.c.

◆ TONE_URI_SCHEME

#define TONE_URI_SCHEME   "tone:"

Definition at line 62 of file res_stasis_playback.c.

Typedef Documentation

◆ playback_operation_cb

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

Definition at line 601 of file res_stasis_playback.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 791 of file res_stasis_playback.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 791 of file res_stasis_playback.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 791 of file res_stasis_playback.c.

◆ load_module()

static int load_module ( void  )
static

Definition at line 760 of file res_stasis_playback.c.

761{
762 int r;
763
765 if (r != 0) {
767 }
768
771 if (!playbacks) {
774 }
776}
@ AO2_ALLOC_OPT_LOCK_MUTEX
Definition: astobj2.h:363
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
Definition: astobj2.h:1303
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
static struct ao2_container * playbacks
static int playback_cmp(void *obj, void *arg, int flags)
static int playback_hash(const void *obj, int flags)
#define PLAYBACK_BUCKETS
#define NULL
Definition: resample.c:96
#define STASIS_MESSAGE_TYPE_CLEANUP(name)
Boiler-plate messaging macro for cleaning up message types.
Definition: stasis.h:1515
#define STASIS_MESSAGE_TYPE_INIT(name)
Boiler-plate messaging macro for initializing message types.
Definition: stasis.h:1493
struct stasis_message_type * stasis_app_playback_snapshot_type(void)
Message type for playback updates. The data is an ast_channel_blob.

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(), playbacks, stasis_app_playback_snapshot_type(), STASIS_MESSAGE_TYPE_CLEANUP, and STASIS_MESSAGE_TYPE_INIT.

◆ play_on_channel()

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

Definition at line 293 of file res_stasis_playback.c.

295{
296 int res;
297 int hangup;
298 long offsetms;
299 size_t index;
300
301 /* Even though these local variables look fairly pointless, they avoid
302 * having a bunch of NULL's passed directly into
303 * ast_control_streamfile() */
304 const char *fwd = NULL;
305 const char *rev = NULL;
306 const char *stop = NULL;
307 const char *pause = NULL;
308 const char *restart = NULL;
309
310 ast_assert(playback != NULL);
311
312 if (ast_channel_state(chan) != AST_STATE_UP) {
314 }
315
316 offsetms = playback->offsetms;
317
318 for (index = 0; index < AST_VECTOR_SIZE(&playback->medias); index++) {
319 playback->media_index = index;
320
321 /* Set the current media to play */
322 ast_string_field_set(playback, media, AST_VECTOR_GET(&playback->medias, playback->media_index));
323
324 res = playback_first_update(playback, ast_channel_uniqueid(chan));
325 if (res != 0) {
326 return;
327 }
328
329 if (ast_begins_with(playback->media, SOUND_URI_SCHEME)) {
330 playback->controllable = 1;
331
332 /* Play sound */
333 res = ast_control_streamfile_lang(chan, playback->media + strlen(SOUND_URI_SCHEME),
334 fwd, rev, stop, pause, restart, playback->skipms, playback->language,
335 &offsetms);
336 } else if (ast_begins_with(playback->media, RECORDING_URI_SCHEME)) {
337 /* Play recording */
338 RAII_VAR(struct stasis_app_stored_recording *, recording, NULL,
340 const char *relname =
341 playback->media + strlen(RECORDING_URI_SCHEME);
342 recording = stasis_app_stored_recording_find_by_name(relname);
343
344 if (!recording) {
345 ast_log(LOG_ERROR, "Attempted to play recording '%s' on channel '%s' but recording does not exist",
346 relname, ast_channel_name(chan));
347 continue;
348 }
349
350 playback->controllable = 1;
351
353 stasis_app_stored_recording_get_file(recording), fwd, rev, stop, pause,
354 restart, playback->skipms, playback->language, &offsetms);
355 } else if (ast_begins_with(playback->media, NUMBER_URI_SCHEME)) {
356 int number;
357
358 if (sscanf(playback->media + strlen(NUMBER_URI_SCHEME), "%30d", &number) != 1) {
359 ast_log(LOG_ERROR, "Attempted to play number '%s' on channel '%s' but number is invalid",
360 playback->media + strlen(NUMBER_URI_SCHEME), ast_channel_name(chan));
361 continue;
362 }
363
364 res = ast_say_number(chan, number, stop, playback->language, NULL);
365 } else if (ast_begins_with(playback->media, DIGITS_URI_SCHEME)) {
366 res = ast_say_digit_str(chan, playback->media + strlen(DIGITS_URI_SCHEME),
367 stop, playback->language);
368 } else if (ast_begins_with(playback->media, CHARACTERS_URI_SCHEME)) {
369 res = ast_say_character_str(chan, playback->media + strlen(CHARACTERS_URI_SCHEME),
370 stop, playback->language, AST_SAY_CASE_NONE);
371 } else if (ast_begins_with(playback->media, TONE_URI_SCHEME)) {
372 playback->controllable = 1;
373 res = ast_control_tone(chan, playback->media + strlen(TONE_URI_SCHEME));
374 } else {
375 /* Play URL */
376 ast_log(LOG_ERROR, "Attempted to play URI '%s' on channel '%s' but scheme is unsupported\n",
377 playback->media, ast_channel_name(chan));
378 continue;
379 }
380
381 hangup = ast_check_hangup(chan);
382
383 playback_final_update(playback, offsetms, res, hangup,
385
386 if (hangup) {
387 ast_log(LOG_DEBUG, "Channel: %s already hangup, stop playback\n", ast_channel_name(chan));
388 break;
389 }
390
391 if (res == AST_CONTROL_STREAM_STOP) {
392 break;
393 }
394
395 /* Reset offset for any subsequent media */
396 offsetms = 0;
397 }
398 return;
399}
unsigned int stop
Definition: app_sla.c:336
#define ast_log
Definition: astobj2.c:42
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
static int hangup(void *data)
Definition: chan_pjsip.c:2516
const char * ast_channel_name(const struct ast_channel *chan)
const char * ast_channel_uniqueid(const struct ast_channel *chan)
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:445
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4277
ast_channel_state
ast_channel states
Definition: channelstate.h:35
@ AST_STATE_UP
Definition: channelstate.h:42
int ast_control_tone(struct ast_channel *chan, const char *tone)
Controls playback of a tone.
Definition: main/app.c:1545
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:1473
@ AST_CONTROL_PROGRESS
@ AST_CONTROL_STREAM_STOP
#define LOG_DEBUG
#define LOG_ERROR
#define NUMBER_URI_SCHEME
static int playback_first_update(struct stasis_app_playback *playback, const char *uniqueid)
#define RECORDING_URI_SCHEME
static void playback_final_update(struct stasis_app_playback *playback, long playedms, int res, int hangup, const char *uniqueid)
#define CHARACTERS_URI_SCHEME
#define TONE_URI_SCHEME
#define DIGITS_URI_SCHEME
#define SOUND_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:8271
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:8235
@ AST_SAY_CASE_NONE
Definition: say.h:182
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:8259
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
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:318
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521
static int force_inline attribute_pure ast_begins_with(const char *str, const char *prefix)
Checks whether a string begins with another.
Definition: strings.h:97
Number structure.
Definition: app_followme.c:154
const ast_string_field language
const ast_string_field media
struct stasis_app_playback::@479 medias
#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
#define ast_assert(a)
Definition: utils.h:739
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:609
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:680

References ao2_cleanup, ast_assert, ast_begins_with(), ast_channel_name(), ast_channel_uniqueid(), ast_check_hangup(), 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, stasis_app_playback::controllable, DIGITS_URI_SCHEME, hangup(), stasis_app_playback::language, LOG_DEBUG, LOG_ERROR, stasis_app_playback::media, stasis_app_playback::media_index, stasis_app_playback::medias, NULL, NUMBER_URI_SCHEME, stasis_app_playback::offsetms, playback_final_update(), playback_first_update(), RAII_VAR, RECORDING_URI_SCHEME, stasis_app_playback::skipms, 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().

◆ 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 407 of file res_stasis_playback.c.

409{
410 RAII_VAR(struct stasis_app_playback *, playback, NULL, ao2_cleanup);
411
412 playback = stasis_app_playback_find_by_id(playback_id);
413 if (!playback) {
414 ast_log(LOG_ERROR, "Couldn't find playback %s\n",
415 playback_id);
416 return;
417 }
418
419 play_on_channel(playback, bridge_channel->chan);
420}
struct stasis_app_playback * stasis_app_playback_find_by_id(const char *id)
Finds the playback object with the given id.
static void play_on_channel(struct stasis_app_playback *playback, struct ast_channel *chan)
struct ast_channel * chan

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

◆ play_uri()

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

Definition at line 435 of file res_stasis_playback.c.

437{
438 struct stasis_app_playback *playback = data;
439 struct ast_bridge *bridge;
440
441 if (!control) {
442 return -1;
443 }
444
445 bridge = stasis_app_get_bridge(control);
446 if (bridge) {
447 struct ast_bridge_channel *bridge_chan;
448
449 /* Queue up playback on the bridge */
451 bridge_chan = ao2_bump(bridge_find_channel(bridge, chan));
453 if (bridge_chan) {
455 bridge_chan,
457 playback->id,
458 NULL); /* moh_class */
459 }
460 ao2_cleanup(bridge_chan);
461 } else {
462 play_on_channel(playback, chan);
463 }
464
465 return 0;
466}
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:481
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:470
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.
struct ast_bridge_channel * bridge_find_channel(struct ast_bridge *bridge, struct ast_channel *chan)
Definition: bridge.c:1429
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 * stasis_app_get_bridge(struct stasis_app_control *control)
Gets the bridge currently associated with a control object.
Definition: control.c:951
Structure that contains information regarding a channel in a bridge.
struct ast_bridge * bridge
Bridge this channel is participating in.
Structure that contains information about a bridge.
Definition: bridge.h:349
const ast_string_field id

References ao2_bump, ao2_cleanup, ast_bridge_channel_queue_playfile_sync(), ast_bridge_lock, ast_bridge_unlock, ast_bridge_channel::bridge, bridge_find_channel(), ast_bridge_channel::chan, 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().

◆ playback_cancel()

static int playback_cancel ( struct stasis_app_playback playback)
static

Definition at line 608 of file res_stasis_playback.c.

609{
610 SCOPED_AO2LOCK(lock, playback);
612 return 0;
613}
ast_mutex_t lock
Definition: app_sla.c:331
#define SCOPED_AO2LOCK(varname, obj)
scoped lock specialization for ao2 mutexes.
Definition: lock.h:604
@ STASIS_PLAYBACK_STATE_CANCELED
enum stasis_app_playback_state state

References lock, SCOPED_AO2LOCK, STASIS_PLAYBACK_STATE_CANCELED, and stasis_app_playback::state.

◆ playback_cmp()

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

Definition at line 183 of file res_stasis_playback.c.

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

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

Referenced by load_module().

◆ playback_create()

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

Definition at line 142 of file res_stasis_playback.c.

144{
145 RAII_VAR(struct stasis_app_playback *, playback, NULL, ao2_cleanup);
146 char uuid[AST_UUID_STR_LEN];
147
148 if (!control) {
149 return NULL;
150 }
151
152 playback = ao2_alloc(sizeof(*playback), playback_dtor);
153 if (!playback || ast_string_field_init(playback, 128)) {
154 return NULL;
155 }
156
157 if (AST_VECTOR_INIT(&playback->medias, 8)) {
158 ao2_ref(playback, -1);
159 return NULL;
160 }
161
162 if (!ast_strlen_zero(id)) {
163 ast_string_field_set(playback, id, id);
164 } else {
165 ast_uuid_generate_str(uuid, sizeof(uuid));
166 ast_string_field_set(playback, id, uuid);
167 }
168
169 ao2_ref(control, +1);
170 playback->control = control;
171
172 ao2_ref(playback, +1);
173 return playback;
174}
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
static void playback_dtor(void *obj)
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
#define AST_UUID_STR_LEN
Definition: uuid.h:27
char * ast_uuid_generate_str(char *buf, size_t size)
Generate a UUID string.
Definition: uuid.c:141
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113

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, stasis_app_playback::control, NULL, playback_dtor(), and RAII_VAR.

Referenced by stasis_app_control_play_uri().

◆ playback_dtor()

static void playback_dtor ( void *  obj)
static

Definition at line 126 of file res_stasis_playback.c.

127{
128 struct stasis_app_playback *playback = obj;
129 int i;
130
131 for (i = 0; i < AST_VECTOR_SIZE(&playback->medias); i++) {
132 char *media = AST_VECTOR_GET(&playback->medias, i);
133
135 }
136 AST_VECTOR_FREE(&playback->medias);
137
138 ao2_cleanup(playback->control);
140}
#define ast_free(a)
Definition: astmm.h:180
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:374
struct stasis_app_control * control
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition: vector.h:174

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

Referenced by playback_create().

◆ playback_final_update()

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

Definition at line 263 of file res_stasis_playback.c.

265{
266 SCOPED_AO2LOCK(lock, playback);
267
268 playback->playedms = playedms;
269 if (res == 0) {
270 if (playback->media_index == AST_VECTOR_SIZE(&playback->medias) - 1 || hangup ) {
272 } else {
274 }
275 } else {
276 if (playback->state == STASIS_PLAYBACK_STATE_STOPPED) {
277 ast_log(LOG_NOTICE, "%s: Playback stopped for %s\n",
278 uniqueid, playback->media);
279 } else {
280 ast_log(LOG_WARNING, "%s: Playback failed for %s\n",
281 uniqueid, playback->media);
282 if (playback->media_index == AST_VECTOR_SIZE(&playback->medias) - 1 || hangup ) {
284 } else {
286 }
287 }
288 }
289
290 playback_publish(playback);
291}
#define LOG_NOTICE
#define LOG_WARNING
static void playback_publish(struct stasis_app_playback *playback)
@ STASIS_PLAYBACK_STATE_STOPPED
@ STASIS_PLAYBACK_STATE_FAILED
@ STASIS_PLAYBACK_STATE_COMPLETE
@ STASIS_PLAYBACK_STATE_CONTINUING

References ast_log, AST_VECTOR_SIZE, hangup(), lock, LOG_NOTICE, LOG_WARNING, stasis_app_playback::media, stasis_app_playback::media_index, stasis_app_playback::medias, playback_publish(), stasis_app_playback::playedms, SCOPED_AO2LOCK, STASIS_PLAYBACK_STATE_COMPLETE, STASIS_PLAYBACK_STATE_CONTINUING, STASIS_PLAYBACK_STATE_FAILED, STASIS_PLAYBACK_STATE_STOPPED, and stasis_app_playback::state.

Referenced by play_on_channel().

◆ playback_first_update()

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

Definition at line 244 of file res_stasis_playback.c.

246{
247 int res;
248 SCOPED_AO2LOCK(lock, playback);
249
250 if (playback->state == STASIS_PLAYBACK_STATE_CANCELED) {
251 ast_log(LOG_NOTICE, "%s: Playback canceled for %s\n",
252 uniqueid, playback->media);
253 res = -1;
254 } else {
255 res = 0;
257 }
258
259 playback_publish(playback);
260 return res;
261}
@ STASIS_PLAYBACK_STATE_PLAYING

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

Referenced by play_on_channel().

◆ playback_forward()

static int playback_forward ( struct stasis_app_playback playback)
static

Definition at line 682 of file res_stasis_playback.c.

683{
684 SCOPED_AO2LOCK(lock, playback);
685
686 if (!playback->controllable) {
687 return -1;
688 }
689
692}
@ AST_CONTROL_STREAM_FORWARD
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:1465

References AST_CONTROL_STREAM_FORWARD, stasis_app_playback::control, stasis_app_playback::controllable, lock, SCOPED_AO2LOCK, and stasis_app_control_queue_control().

◆ playback_hash()

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

Definition at line 176 of file res_stasis_playback.c.

177{
178 const struct stasis_app_playback *playback = obj;
179 const char *id = flags & OBJ_KEY ? obj : playback->id;
180 return ast_str_hash(id);
181}
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
Definition: strings.h:1259

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

Referenced by load_module().

◆ playback_noop()

static int playback_noop ( struct stasis_app_playback playback)
static

Definition at line 603 of file res_stasis_playback.c.

604{
605 return 0;
606}

◆ playback_pause()

static int playback_pause ( struct stasis_app_playback playback)
static

◆ playback_publish()

static void playback_publish ( struct stasis_app_playback playback)
static

Definition at line 222 of file res_stasis_playback.c.

223{
224 RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
226
227 ast_assert(playback != NULL);
228
229 json = stasis_app_playback_to_json(playback);
230 if (json == NULL) {
231 return;
232 }
233
237 if (message == NULL) {
238 return;
239 }
240
242}
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.
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
struct ast_json * stasis_app_playback_to_json(const struct stasis_app_playback *playback)
Convert a playback to its JSON representation.
const char * stasis_app_control_get_channel_id(const struct stasis_app_control *control)
Returns the uniqueid of the channel associated with this control.
Definition: control.c:1450
void stasis_app_control_publish(struct stasis_app_control *control, struct stasis_message *message)
Publish a message to the control's channel's topic.
Definition: control.c:1456
Abstract JSON element (object, array, string, int, ...).

References ao2_cleanup, ast_assert, ast_channel_blob_create_from_cache(), ast_json_unref(), stasis_app_playback::control, 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().

◆ playback_restart()

static int playback_restart ( struct stasis_app_playback playback)
static

Definition at line 628 of file res_stasis_playback.c.

629{
630 SCOPED_AO2LOCK(lock, playback);
631
632 if (!playback->controllable) {
633 return -1;
634 }
635
638}
@ AST_CONTROL_STREAM_RESTART

References AST_CONTROL_STREAM_RESTART, stasis_app_playback::control, stasis_app_playback::controllable, lock, SCOPED_AO2LOCK, and stasis_app_control_queue_control().

◆ playback_reverse()

static int playback_reverse ( struct stasis_app_playback playback)
static

Definition at line 670 of file res_stasis_playback.c.

671{
672 SCOPED_AO2LOCK(lock, playback);
673
674 if (!playback->controllable) {
675 return -1;
676 }
677
680}
@ AST_CONTROL_STREAM_REVERSE

References AST_CONTROL_STREAM_REVERSE, stasis_app_playback::control, stasis_app_playback::controllable, lock, SCOPED_AO2LOCK, and stasis_app_control_queue_control().

◆ playback_stop()

static int playback_stop ( struct stasis_app_playback playback)
static

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

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 if (!strcmp(state, "failed")) {
111 type = "PlaybackFinished";
112 } else {
113 return NULL;
114 }
115
116 return ast_json_pack("{s: s, s: o?, s: O}",
117 "type", type,
119 "playback", blob);
120}
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:612
struct ast_json * ast_json_timeval(const struct timeval tv, const char *zone)
Construct a timeval as JSON.
Definition: json.c:670
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
Definition: json.c:283
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
Definition: json.c:407
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
const struct timeval * stasis_message_timestamp(const struct stasis_message *msg)
Get the time when a message was created.
Blob of data associated with a channel.
struct ast_json * blob

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

◆ playback_unpause()

static int playback_unpause ( struct stasis_app_playback playback)
static

◆ 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 426 of file res_stasis_playback.c.

427{
428 struct stasis_app_playback *playback = data;
429
430 ao2_unlink_flags(playbacks, playback,
432 ao2_ref(playback, -1);
433}
#define OBJ_POINTER
Definition: astobj2.h:1150
#define ao2_unlink_flags(container, obj, flags)
Remove an object from a container.
Definition: astobj2.h:1600
@ OBJ_NODATA
Definition: astobj2.h:1044
@ OBJ_UNLINK
Definition: astobj2.h:1039

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

Referenced by stasis_app_control_play_uri().

◆ 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 468 of file res_stasis_playback.c.

472{
473 const char *type = NULL;
474 switch (target_type) {
476 type = "channel";
477 break;
479 type = "bridge";
480 break;
481 }
482
483 ast_assert(type != NULL);
484
485 ast_string_field_build(playback, target, "%s:%s", type, target_id);
486}
@ STASIS_PLAYBACK_TARGET_BRIDGE
@ STASIS_PLAYBACK_TARGET_CHANNEL
#define ast_string_field_build(x, field, fmt, args...)
Set a field to a complex (built) value.
Definition: stringfields.h:555

References ast_assert, ast_string_field_build, NULL, STASIS_PLAYBACK_TARGET_BRIDGE, STASIS_PLAYBACK_TARGET_CHANNEL, and type.

Referenced by stasis_app_control_play_uri().

◆ 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.
Return values
NULLon error.

Definition at line 488 of file res_stasis_playback.c.

493{
494 struct stasis_app_playback *playback;
495 size_t i;
496
497 if (skipms < 0 || offsetms < 0 || media_count == 0) {
498 return NULL;
499 }
500
501 playback = playback_create(control, id);
502 if (!playback) {
503 return NULL;
504 }
505
506 for (i = 0; i < media_count; i++) {
507 char *media_uri;
508
509 if (ast_strlen_zero(media[i])) {
510 ast_log(LOG_ERROR, "Attempted to play media on channel '%s' but no media URI was provided.\n",
512 ao2_ref(playback, -1);
513 return NULL;
514 }
515
516 media_uri = ast_malloc(strlen(media[i]) + 1);
517 if (!media_uri) {
518 ao2_ref(playback, -1);
519 return NULL;
520 }
521
522 ast_debug(3, "%s: Sending play(%s) command\n",
524
525 /* safe */
526 strcpy(media_uri, media[i]);
527 if (AST_VECTOR_APPEND(&playback->medias, media_uri)) {
528 ao2_ref(playback, -1);
529 ast_free(media_uri);
530 return NULL;
531 }
532 }
533
534 if (skipms == 0) {
536 }
537
538 ast_string_field_set(playback, media, AST_VECTOR_GET(&playback->medias, 0));
540 set_target_uri(playback, target_type, target_id);
541 playback->skipms = skipms;
542 playback->offsetms = offsetms;
543 ao2_link(playbacks, playback);
544
546 playback_publish(playback);
547
549
550 return playback;
551}
static int skipms
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532
static char language[MAX_LANGUAGE]
Definition: chan_iax2.c:324
#define ast_debug(level,...)
Log a DEBUG message.
#define PLAYBACK_DEFAULT_SKIPMS
static struct stasis_app_playback * playback_create(struct stasis_app_control *control, const char *id)
static int play_uri(struct stasis_app_control *control, struct ast_channel *chan, void *data)
static void set_target_uri(struct stasis_app_playback *playback, enum stasis_app_playback_target_type target_type, const char *target_id)
static void remove_from_playbacks(void *data)
RAII_VAR function to remove a playback from the global list when leaving scope.
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:924
@ STASIS_PLAYBACK_STATE_QUEUED
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256

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, stasis_app_playback::control, language, LOG_ERROR, stasis_app_playback::media, stasis_app_playback::medias, NULL, stasis_app_playback::offsetms, play_uri(), playback_create(), PLAYBACK_DEFAULT_SKIPMS, playback_publish(), playbacks, remove_from_playbacks(), set_target_uri(), skipms, stasis_app_playback::skipms, stasis_app_control_get_channel_id(), stasis_app_send_command_async(), STASIS_PLAYBACK_STATE_QUEUED, and stasis_app_playback::state.

Referenced by ari_bridges_play_helper(), and ari_channels_handle_play().

◆ 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.
Return values
NULLif id not found.

Definition at line 567 of file res_stasis_playback.c.

568{
569 return ao2_find(playbacks, id, OBJ_KEY);
570}
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1736

References ao2_find, OBJ_KEY, and playbacks.

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

◆ 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.
Return values
NULLif playback ic NULL

Definition at line 560 of file res_stasis_playback.c.

562{
563 /* id is immutable; no lock needed */
564 return control->id;
565}

References stasis_app_playback::control.

Referenced by ari_bridges_play_helper(), and ari_channels_handle_play().

◆ 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 553 of file res_stasis_playback.c.

555{
556 SCOPED_AO2LOCK(lock, control);
557 return control->state;
558}

References stasis_app_playback::control, lock, and SCOPED_AO2LOCK.

◆ 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.
operationMedia control operation.
Return values
STASIS_PLAYBACK_OPER_OKon success.
Returns
stasis_playback_oper_results indicating failure.

Definition at line 726 of file res_stasis_playback.c.

729{
731 SCOPED_AO2LOCK(lock, playback);
732
733 ast_assert((unsigned int)playback->state < STASIS_PLAYBACK_STATE_MAX);
734
735 if (operation >= STASIS_PLAYBACK_MEDIA_OP_MAX) {
736 ast_log(LOG_ERROR, "Invalid playback operation %u\n", operation);
737 return -1;
738 }
739
740 cb = operations[playback->state][operation];
741
742 if (!cb) {
743 if (playback->state != STASIS_PLAYBACK_STATE_PLAYING) {
744 /* So we can be specific in our error message. */
746 } else {
747 /* And, really, all operations should be valid during
748 * playback */
750 "Unhandled operation during playback: %u\n",
751 operation);
753 }
754 }
755
756 return cb(playback) ?
758}
int(* playback_operation_cb)(struct stasis_app_playback *playback)
playback_operation_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....
@ STASIS_PLAYBACK_OPER_NOT_PLAYING
@ STASIS_PLAYBACK_OPER_FAILED
@ STASIS_PLAYBACK_OPER_OK
@ STASIS_PLAYBACK_STATE_MAX
@ STASIS_PLAYBACK_MEDIA_OP_MAX

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, STASIS_PLAYBACK_STATE_PLAYING, and stasis_app_playback::state.

Referenced by ast_ari_playbacks_control(), and ast_ari_playbacks_stop().

◆ 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
NULLon error
Returns
A JSON object on success

Definition at line 572 of file res_stasis_playback.c.

574{
575 RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
576
577 if (playback == NULL) {
578 return NULL;
579 }
580
581 if (playback->media_index == AST_VECTOR_SIZE(&playback->medias) - 1) {
582 json = ast_json_pack("{s: s, s: s, s: s, s: s, s: s}",
583 "id", playback->id,
584 "media_uri", playback->media,
585 "target_uri", playback->target,
586 "language", playback->language,
587 "state", state_to_string(playback->state));
588 } else {
589 json = ast_json_pack("{s: s, s: s, s: s, s: s, s: s, s: s}",
590 "id", playback->id,
591 "media_uri", playback->media,
592 "next_media_uri", AST_VECTOR_GET(&playback->medias, playback->media_index + 1),
593 "target_uri", playback->target,
594 "language", playback->language,
595 "state", state_to_string(playback->state));
596 }
597
598 return ast_json_ref(json);
599}
struct ast_json * ast_json_ref(struct ast_json *value)
Increase refcount on value.
Definition: json.c:67
static const char * state_to_string(enum stasis_app_playback_state state)
const ast_string_field target

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, stasis_app_playback::media_index, stasis_app_playback::medias, NULL, RAII_VAR, stasis_app_playback::state, 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().

◆ STASIS_MESSAGE_TYPE_DEFN()

STASIS_MESSAGE_TYPE_DEFN ( stasis_app_playback_snapshot_type  ,
to_json = playback_to_json 
)

◆ state_to_string()

static const char * state_to_string ( enum stasis_app_playback_state  state)
static

Definition at line 196 of file res_stasis_playback.c.

197{
198 switch (state) {
200 return "queued";
202 return "playing";
204 return "paused";
206 return "continuing";
208 return "failed";
212 /* It doesn't really matter how we got here, but all of these
213 * states really just mean 'done' */
214 return "done";
216 break;
217 }
218
219 return "?";
220}

References STASIS_PLAYBACK_STATE_CANCELED, STASIS_PLAYBACK_STATE_COMPLETE, STASIS_PLAYBACK_STATE_CONTINUING, STASIS_PLAYBACK_STATE_FAILED, 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().

◆ unload_module()

static int unload_module ( void  )
static

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 791 of file res_stasis_playback.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 791 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 698 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.

Referenced by load_module(), remove_from_playbacks(), stasis_app_control_play_uri(), stasis_app_playback_find_by_id(), and unload_module().