Asterisk - The Open Source Telephony Project GIT-master-7e7a603
Data Structures
stasis_app_recording.h File Reference

Stasis Application Recording API. See StasisApplication API" for detailed documentation. More...

#include "asterisk/app.h"
#include "asterisk/stasis_app.h"
Include dependency graph for stasis_app_recording.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  stasis_app_recording_options
 

Functions

int stasis_app_stored_recording_copy (struct stasis_app_stored_recording *src_recording, const char *dst, struct stasis_app_stored_recording **dst_recording)
 Copy a recording. More...
 
int stasis_app_stored_recording_delete (struct stasis_app_stored_recording *recording)
 Delete a recording from disk. More...
 
struct ao2_containerstasis_app_stored_recording_find_all (void)
 Find all stored recordings on disk. More...
 
struct stasis_app_stored_recordingstasis_app_stored_recording_find_by_name (const char *name)
 Creates a stored recording object, with the given name. More...
 
const char * stasis_app_stored_recording_get_extension (struct stasis_app_stored_recording *recording)
 Returns the extension for this recording. More...
 
const char * stasis_app_stored_recording_get_file (struct stasis_app_stored_recording *recording)
 Returns the filename for this recording, for use with streamfile. More...
 
const char * stasis_app_stored_recording_get_filename (struct stasis_app_stored_recording *recording)
 Returns the full filename, with extension, for this recording. More...
 
struct ast_jsonstasis_app_stored_recording_to_json (struct stasis_app_stored_recording *recording)
 Convert stored recording info to JSON. More...
 
struct stasis_app_recordingstasis_app_control_record (struct stasis_app_control *control, struct stasis_app_recording_options *options)
 Record media from a channel. More...
 
struct stasis_app_recordingstasis_app_recording_find_by_name (const char *name)
 Finds the recording object with the given name. More...
 
const char * stasis_app_recording_get_name (struct stasis_app_recording *recording)
 Gets the unique name of a recording object. More...
 
enum stasis_app_recording_state stasis_app_recording_get_state (struct stasis_app_recording *recording)
 Gets the current state of a recording operation. More...
 
enum ast_record_if_exists stasis_app_recording_if_exists_parse (const char *str)
 Parse a string into the if_exists enum. More...
 
enum  stasis_app_recording_media_operation {
  STASIS_APP_RECORDING_CANCEL , STASIS_APP_RECORDING_STOP , STASIS_APP_RECORDING_PAUSE , STASIS_APP_RECORDING_UNPAUSE ,
  STASIS_APP_RECORDING_MUTE , STASIS_APP_RECORDING_UNMUTE , STASIS_APP_RECORDING_OPER_MAX
}
 
enum  stasis_app_recording_oper_results { STASIS_APP_RECORDING_OPER_OK , STASIS_APP_RECORDING_OPER_FAILED , STASIS_APP_RECORDING_OPER_NOT_RECORDING }
 Possible results from a recording operation. More...
 
enum stasis_app_recording_oper_results stasis_app_recording_operation (struct stasis_app_recording *recording, enum stasis_app_recording_media_operation operation)
 Controls the media for a given recording operation. More...
 
struct stasis_app_recording_optionsstasis_app_recording_options_create (const char *name, const char *format)
 Allocate a recording options object. More...
 
struct stasis_message_typestasis_app_recording_snapshot_type (void)
 Message type for recording updates. The data is an ast_channel_blob. More...
 
enum  stasis_app_recording_state {
  STASIS_APP_RECORDING_STATE_QUEUED , STASIS_APP_RECORDING_STATE_RECORDING , STASIS_APP_RECORDING_STATE_PAUSED , STASIS_APP_RECORDING_STATE_COMPLETE ,
  STASIS_APP_RECORDING_STATE_FAILED , STASIS_APP_RECORDING_STATE_CANCELED , STASIS_APP_RECORDING_STATE_MAX
}
 
#define STASIS_APP_RECORDING_TERMINATE_ANY   -2
 
#define STASIS_APP_RECORDING_TERMINATE_INVALID   0
 
#define STASIS_APP_RECORDING_TERMINATE_NONE   -1
 
char stasis_app_recording_termination_parse (const char *str)
 Parse a string into the recording termination enum. More...
 
struct ast_jsonstasis_app_recording_to_json (const struct stasis_app_recording *recording)
 Construct a JSON model of a recording. More...
 

Detailed Description

Stasis Application Recording API. See StasisApplication API" for detailed documentation.

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

Definition in file stasis_app_recording.h.

Macro Definition Documentation

◆ STASIS_APP_RECORDING_TERMINATE_ANY

#define STASIS_APP_RECORDING_TERMINATE_ANY   -2

Definition at line 174 of file stasis_app_recording.h.

◆ STASIS_APP_RECORDING_TERMINATE_INVALID

#define STASIS_APP_RECORDING_TERMINATE_INVALID   0

Definition at line 172 of file stasis_app_recording.h.

◆ STASIS_APP_RECORDING_TERMINATE_NONE

#define STASIS_APP_RECORDING_TERMINATE_NONE   -1

Definition at line 173 of file stasis_app_recording.h.

Enumeration Type Documentation

◆ stasis_app_recording_media_operation

Valid operation for controlling a recording.

Enumerator
STASIS_APP_RECORDING_CANCEL 

Stop the recording, deleting the media file(s)

STASIS_APP_RECORDING_STOP 

Stop the recording.

STASIS_APP_RECORDING_PAUSE 

Pause the recording

STASIS_APP_RECORDING_UNPAUSE 

Unpause the recording

STASIS_APP_RECORDING_MUTE 

Mute the recording (record silence)

STASIS_APP_RECORDING_UNMUTE 

Unmute the recording

STASIS_APP_RECORDING_OPER_MAX 

Sentinel

Definition at line 155 of file stasis_app_recording.h.

155 {
156 /*! Stop the recording, deleting the media file(s) */
158 /*! Stop the recording. */
160 /*! Pause the recording */
162 /*! Unpause the recording */
164 /*! Mute the recording (record silence) */
166 /*! Unmute the recording */
168 /*! Sentinel */
170};
@ STASIS_APP_RECORDING_PAUSE
@ STASIS_APP_RECORDING_UNPAUSE
@ STASIS_APP_RECORDING_UNMUTE
@ STASIS_APP_RECORDING_STOP
@ STASIS_APP_RECORDING_OPER_MAX
@ STASIS_APP_RECORDING_MUTE
@ STASIS_APP_RECORDING_CANCEL

◆ stasis_app_recording_oper_results

Possible results from a recording operation.

Enumerator
STASIS_APP_RECORDING_OPER_OK 

Operation completed successfully.

STASIS_APP_RECORDING_OPER_FAILED 

Operation failed.

STASIS_APP_RECORDING_OPER_NOT_RECORDING 

Operation failed b/c recording is not in session.

Definition at line 292 of file stasis_app_recording.h.

292 {
293 /*! Operation completed successfully. */
295 /*! Operation failed. */
297 /*! Operation failed b/c recording is not in session. */
299};
@ STASIS_APP_RECORDING_OPER_NOT_RECORDING
@ STASIS_APP_RECORDING_OPER_FAILED
@ STASIS_APP_RECORDING_OPER_OK

◆ stasis_app_recording_state

State of a recording operation

Enumerator
STASIS_APP_RECORDING_STATE_QUEUED 

The recording has not started yet

STASIS_APP_RECORDING_STATE_RECORDING 

The media is currently recording

STASIS_APP_RECORDING_STATE_PAUSED 

The media is currently paused

STASIS_APP_RECORDING_STATE_COMPLETE 

The media has stopped recording

STASIS_APP_RECORDING_STATE_FAILED 

The media has stopped recording, with error

STASIS_APP_RECORDING_STATE_CANCELED 

The media has stopped recording, discard the recording file

STASIS_APP_RECORDING_STATE_MAX 

Sentinel

Definition at line 137 of file stasis_app_recording.h.

137 {
138 /*! The recording has not started yet */
140 /*! The media is currently recording */
142 /*! The media is currently paused */
144 /*! The media has stopped recording */
146 /*! The media has stopped recording, with error */
148 /*! The media has stopped recording, discard the recording file */
150 /*! Sentinel */
152};
@ STASIS_APP_RECORDING_STATE_CANCELED
@ STASIS_APP_RECORDING_STATE_FAILED
@ STASIS_APP_RECORDING_STATE_COMPLETE
@ STASIS_APP_RECORDING_STATE_RECORDING
@ STASIS_APP_RECORDING_STATE_PAUSED
@ STASIS_APP_RECORDING_STATE_QUEUED
@ STASIS_APP_RECORDING_STATE_MAX

Function Documentation

◆ stasis_app_control_record()

struct stasis_app_recording * stasis_app_control_record ( struct stasis_app_control control,
struct stasis_app_recording_options options 
)

Record media from a channel.

A reference to the options object may be kept, so it MUST NOT be modified after calling this function.

On error, errno is set to indicate the failure reason.

  • EINVAL: Invalid input.
  • EEXIST: A recording with that name is in session.
  • ENOMEM: Out of memory.
Parameters
controlControl for res_stasis.
optionsRecording options.
Returns
Recording control object.
Return values
NULLon error.

Definition at line 370 of file res_stasis_recording.c.

373{
374 struct stasis_app_recording *recording;
375 char *last_slash;
376
377 errno = 0;
378
379 if (options == NULL ||
380 ast_strlen_zero(options->name) ||
381 ast_strlen_zero(options->format) ||
382 options->max_silence_seconds < 0 ||
383 options->max_duration_seconds < 0) {
384 errno = EINVAL;
385 return NULL;
386 }
387
388 ast_debug(3, "%s: Sending record(%s.%s) command\n",
390 options->format);
391
392 recording = ao2_alloc(sizeof(*recording), recording_dtor);
393 if (!recording) {
394 errno = ENOMEM;
395 return NULL;
396 }
397 recording->duration.total = -1;
398 recording->duration.energy_only = -1;
399
400 ast_asprintf(&recording->absolute_name, "%s/%s",
402
403 if (recording->absolute_name == NULL) {
404 errno = ENOMEM;
405 ao2_ref(recording, -1);
406 return NULL;
407 }
408
409 if ((last_slash = strrchr(recording->absolute_name, '/'))) {
410 *last_slash = '\0';
412 recording->absolute_name, 0777) != 0) {
413 /* errno set by ast_mkdir */
414 ao2_ref(recording, -1);
415 return NULL;
416 }
417 *last_slash = '/';
418 }
419
420 ao2_ref(options, +1);
421 recording->options = options;
422 ao2_ref(control, +1);
423 recording->control = control;
425
426 if ((recording->options->if_exists == AST_RECORD_IF_EXISTS_FAIL) &&
427 (ast_fileexists(recording->absolute_name, NULL, NULL))) {
428 ast_log(LOG_WARNING, "Recording file '%s' already exists and ifExists option is failure.\n",
429 recording->absolute_name);
430 errno = EEXIST;
431 ao2_ref(recording, -1);
432 return NULL;
433 }
434
435 {
436 RAII_VAR(struct stasis_app_recording *, old_recording, NULL,
438
440
441 old_recording = ao2_find(recordings, options->name,
443 if (old_recording) {
445 "Recording %s already in progress\n",
446 recording->options->name);
447 errno = EEXIST;
448 ao2_ref(recording, -1);
449 return NULL;
450 }
451 ao2_link(recordings, recording);
452 }
453
455
457
458 return recording;
459}
ast_mutex_t lock
Definition: app_sla.c:331
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:267
#define ast_log
Definition: astobj2.c:42
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532
#define OBJ_KEY
Definition: astobj2.h:1151
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1736
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
@ OBJ_NOLOCK
Assume that the ao2_container is already locked.
Definition: astobj2.h:1063
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:1129
@ AST_RECORD_IF_EXISTS_FAIL
#define ast_debug(level,...)
Log a DEBUG message.
#define LOG_WARNING
#define SCOPED_AO2LOCK(varname, obj)
scoped lock specialization for ao2 mutexes.
Definition: lock.h:604
int errno
const char * ast_config_AST_RECORDING_DIR
Definition: options.c:156
static void recording_cleanup(void *data)
static void recording_dtor(void *obj)
static int record_file(struct stasis_app_control *control, struct ast_channel *chan, void *data)
static struct stasis_app_control_rule rule_recording
static struct ao2_container * recordings
#define NULL
Definition: resample.c:96
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_register_add_rule(struct stasis_app_control *control, struct stasis_app_control_rule *rule)
Registers an add channel to bridge rule.
Definition: control.c:230
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
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
enum ast_record_if_exists if_exists
struct stasis_app_recording::@480 duration
struct stasis_app_recording_options * options
enum stasis_app_recording_state state
struct stasis_app_control * control
static struct test_options options
#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
int ast_safe_mkdir(const char *base_path, const char *path, int mode)
Recursively create directory path, but only if it resolves within the given base_path.
Definition: utils.c:2584

References stasis_app_recording::absolute_name, ao2_alloc, ao2_bump, ao2_cleanup, ao2_find, ao2_link, ao2_ref, ast_asprintf, ast_config_AST_RECORDING_DIR, ast_debug, ast_fileexists(), ast_log, AST_RECORD_IF_EXISTS_FAIL, ast_safe_mkdir(), ast_strlen_zero(), stasis_app_recording::control, stasis_app_recording::duration, stasis_app_recording::energy_only, errno, stasis_app_recording_options::if_exists, lock, LOG_WARNING, stasis_app_recording_options::name, NULL, OBJ_KEY, OBJ_NOLOCK, stasis_app_recording::options, options, RAII_VAR, record_file(), recording_cleanup(), recording_dtor(), recordings, rule_recording, SCOPED_AO2LOCK, stasis_app_control_get_channel_id(), stasis_app_control_register_add_rule(), STASIS_APP_RECORDING_STATE_QUEUED, stasis_app_send_command_async(), stasis_app_recording::state, and stasis_app_recording::total.

Referenced by ast_ari_bridges_record(), and ast_ari_channels_record().

◆ stasis_app_recording_find_by_name()

struct stasis_app_recording * stasis_app_recording_find_by_name ( const char *  name)

Finds the recording object with the given name.

Parameters
nameName of the recording object to find.
Returns
Associated stasis_app_recording object.
Return values
NULLif name not found.

Definition at line 473 of file res_stasis_recording.c.

474{
476}
static const char name[]
Definition: format_mp3.c:68

References ao2_find, name, OBJ_KEY, and recordings.

Referenced by ast_ari_recordings_get_live(), and control_recording().

◆ stasis_app_recording_get_name()

const char * stasis_app_recording_get_name ( struct stasis_app_recording recording)

Gets the unique name of a recording object.

Parameters
recordingRecording control object.
Returns
recording's name.
Return values
NULLif recording ic NULL

Definition at line 467 of file res_stasis_recording.c.

469{
470 return recording->options->name;
471}

References stasis_app_recording_options::name, and stasis_app_recording::options.

◆ stasis_app_recording_get_state()

enum stasis_app_recording_state stasis_app_recording_get_state ( struct stasis_app_recording recording)

Gets the current state of a recording operation.

Parameters
recordingRecording control object.
Returns
The state of the recording object.

Definition at line 461 of file res_stasis_recording.c.

463{
464 return recording->state;
465}

References stasis_app_recording::state.

◆ stasis_app_recording_if_exists_parse()

enum ast_record_if_exists stasis_app_recording_if_exists_parse ( const char *  str)

Parse a string into the if_exists enum.

Parameters
strString to parse.
Returns
How to handle an existing file.
-1 on error.

Definition at line 194 of file res_stasis_recording.c.

196{
197 if (ast_strlen_zero(str)) {
198 /* Default value */
200 }
201
202 if (strcasecmp(str, "fail") == 0) {
204 }
205
206 if (strcasecmp(str, "overwrite") == 0) {
208 }
209
210 if (strcasecmp(str, "append") == 0) {
212 }
213
215}
const char * str
Definition: app_jack.c:147
@ AST_RECORD_IF_EXISTS_APPEND
@ AST_RECORD_IF_EXISTS_OVERWRITE
@ AST_RECORD_IF_EXISTS_ERROR

References AST_RECORD_IF_EXISTS_APPEND, AST_RECORD_IF_EXISTS_ERROR, AST_RECORD_IF_EXISTS_FAIL, AST_RECORD_IF_EXISTS_OVERWRITE, ast_strlen_zero(), and str.

Referenced by ast_ari_bridges_record(), and ast_ari_channels_record().

◆ stasis_app_recording_operation()

enum stasis_app_recording_oper_results stasis_app_recording_operation ( struct stasis_app_recording recording,
enum stasis_app_recording_media_operation  operation 
)

Controls the media for a given recording operation.

Parameters
recordingRecording control object.
operationMedia control operation.
Return values
STASIS_APP_RECORDING_OPER_OKon success.
Returns
stasis_app_recording_oper_results indicating failure.

Definition at line 590 of file res_stasis_recording.c.

593{
595 SCOPED_AO2LOCK(lock, recording);
596
597 if ((unsigned int)recording->state >= STASIS_APP_RECORDING_STATE_MAX) {
598 ast_log(LOG_WARNING, "Invalid recording state %u\n",
599 recording->state);
600 return -1;
601 }
602
603 if ((unsigned int)operation >= STASIS_APP_RECORDING_OPER_MAX) {
604 ast_log(LOG_WARNING, "Invalid recording operation %u\n",
605 operation);
606 return -1;
607 }
608
609 cb = operations[recording->state][operation];
610
611 if (!cb) {
613 /* So we can be specific in our error message. */
615 } else {
616 /* And, really, all operations should be valid during
617 * recording */
619 "Unhandled operation during recording: %u\n",
620 operation);
622 }
623 }
624
625 return cb(recording) ?
627}
#define LOG_ERROR
int(* recording_operation_cb)(struct stasis_app_recording *recording)
recording_operation_cb operations[STASIS_APP_RECORDING_STATE_MAX][STASIS_APP_RECORDING_OPER_MAX]

References ast_log, lock, LOG_ERROR, LOG_WARNING, operations, SCOPED_AO2LOCK, STASIS_APP_RECORDING_OPER_FAILED, STASIS_APP_RECORDING_OPER_MAX, STASIS_APP_RECORDING_OPER_NOT_RECORDING, STASIS_APP_RECORDING_OPER_OK, STASIS_APP_RECORDING_STATE_MAX, STASIS_APP_RECORDING_STATE_RECORDING, and stasis_app_recording::state.

Referenced by control_recording().

◆ stasis_app_recording_options_create()

struct stasis_app_recording_options * stasis_app_recording_options_create ( const char *  name,
const char *  format 
)

Allocate a recording options object.

Clean up with ao2_cleanup().

Parameters
nameName of the recording.
formatFormat to record in.
Returns
Newly allocated options object.
Return values
NULLon error.

Definition at line 151 of file res_stasis_recording.c.

153{
156
158
159 if (!options || ast_string_field_init(options, 128)) {
160 return NULL;
161 }
163 ast_string_field_set(options, format, format);
164
165 ao2_ref(options, +1);
166 return options;
167}
static void recording_options_dtor(void *obj)
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359

References ao2_alloc, ao2_cleanup, ao2_ref, ast_string_field_init, ast_string_field_set, stasis_app_recording_options::format, name, NULL, options, RAII_VAR, and recording_options_dtor().

Referenced by ast_ari_bridges_record(), and ast_ari_channels_record().

◆ stasis_app_recording_snapshot_type()

struct stasis_message_type * stasis_app_recording_snapshot_type ( void  )

Message type for recording updates. The data is an ast_channel_blob.

Referenced by load_module(), recording_publish(), and unload_module().

◆ stasis_app_recording_termination_parse()

char stasis_app_recording_termination_parse ( const char *  str)

Parse a string into the recording termination enum.

Parameters
strString to parse.
Returns
DTMF value to terminate on.
Return values
STASIS_APP_RECORDING_TERMINATE_NONEto not terminate on DTMF.
STASIS_APP_RECORDING_TERMINATE_ANYto terminate on any DTMF.
STASIS_APP_RECORDING_TERMINATE_INVALIDif input was invalid.

Definition at line 169 of file res_stasis_recording.c.

170{
171 if (ast_strlen_zero(str)) {
173 }
174
175 if (strcasecmp(str, "none") == 0) {
177 }
178
179 if (strcasecmp(str, "any") == 0) {
181 }
182
183 if (strcasecmp(str, "#") == 0) {
184 return '#';
185 }
186
187 if (strcasecmp(str, "*") == 0) {
188 return '*';
189 }
190
192}
#define STASIS_APP_RECORDING_TERMINATE_NONE
#define STASIS_APP_RECORDING_TERMINATE_ANY
#define STASIS_APP_RECORDING_TERMINATE_INVALID

References ast_strlen_zero(), STASIS_APP_RECORDING_TERMINATE_ANY, STASIS_APP_RECORDING_TERMINATE_INVALID, STASIS_APP_RECORDING_TERMINATE_NONE, and str.

Referenced by ast_ari_bridges_record(), and ast_ari_channels_record().

◆ stasis_app_recording_to_json()

struct ast_json * stasis_app_recording_to_json ( const struct stasis_app_recording recording)

Construct a JSON model of a recording.

Parameters
recordingRecording to conver.
Returns
JSON model.
Return values
NULLon error.

Definition at line 478 of file res_stasis_recording.c.

480{
481 RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
482
483 if (recording == NULL) {
484 return NULL;
485 }
486
487 json = ast_json_pack("{s: s, s: s, s: s, s: s}",
488 "name", recording->options->name,
489 "format", recording->options->format,
490 "state", state_to_string(recording->state),
491 "target_uri", recording->options->target);
492 if (json && recording->duration.total > -1) {
493 ast_json_object_set(json, "duration",
495 }
496 if (json && recording->duration.energy_only > -1) {
497 ast_json_object_set(json, "talking_duration",
499 ast_json_object_set(json, "silence_duration",
501 }
502
503 return ast_json_ref(json);
504}
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 * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:612
struct ast_json * ast_json_integer_create(intmax_t value)
Create a JSON integer.
Definition: json.c:327
struct ast_json * ast_json_ref(struct ast_json *value)
Increase refcount on value.
Definition: json.c:67
int ast_json_object_set(struct ast_json *object, const char *key, struct ast_json *value)
Set a field in a JSON object.
Definition: json.c:414
static const char * state_to_string(enum stasis_app_recording_state state)
Abstract JSON element (object, array, string, int, ...).

References ast_json_integer_create(), ast_json_object_set(), ast_json_pack(), ast_json_ref(), ast_json_unref(), stasis_app_recording::duration, stasis_app_recording::energy_only, stasis_app_recording_options::format, stasis_app_recording_options::name, NULL, stasis_app_recording::options, RAII_VAR, stasis_app_recording::state, state_to_string(), stasis_app_recording_options::target, and stasis_app_recording::total.

Referenced by ast_ari_bridges_record(), ast_ari_channels_record(), ast_ari_recordings_get_live(), and recording_publish().

◆ stasis_app_stored_recording_copy()

int stasis_app_stored_recording_copy ( struct stasis_app_stored_recording src_recording,
const char *  dst,
struct stasis_app_stored_recording **  dst_recording 
)

Copy a recording.

Parameters
src_recordingThe recording to copy
dstThe destination of the recording to make
dst_recordingIf successful, the stored recording created as a result of the copy
Return values
0on success
Non-zeroon error

Definition at line 398 of file stored.c.

400{
401 RAII_VAR(char *, full_path, NULL, ast_free);
402 char *dst_file = ast_strdupa(dst);
403 char *format;
404 char *last_slash;
405 int res;
406
407 /* Drop the extension if specified, core will do this for us */
408 format = strrchr(dst_file, '.');
409 if (format) {
410 *format = '\0';
411 }
412
413 /* See if any intermediary directories need to be made */
414 last_slash = strrchr(dst_file, '/');
415 if (last_slash) {
416 RAII_VAR(char *, tmp_path, NULL, ast_free);
417
418 *last_slash = '\0';
419 if (ast_asprintf(&tmp_path, "%s/%s", ast_config_AST_RECORDING_DIR, dst_file) < 0) {
420 return -1;
421 }
423 tmp_path, 0777) != 0) {
424 /* errno set by ast_mkdir */
425 return -1;
426 }
427 *last_slash = '/';
428 if (ast_asprintf(&full_path, "%s/%s", ast_config_AST_RECORDING_DIR, dst_file) < 0) {
429 return -1;
430 }
431 } else {
432 /* There is no directory portion */
433 if (ast_asprintf(&full_path, "%s/%s", ast_config_AST_RECORDING_DIR, dst_file) < 0) {
434 return -1;
435 }
436 }
437
438 ast_verb(4, "Copying recording %s to %s (format %s)\n", src_recording->file,
439 full_path, src_recording->format);
440 res = ast_filecopy(src_recording->file, full_path, src_recording->format);
441 if (!res) {
442 *dst_recording = stasis_app_stored_recording_find_by_name(dst_file);
443 }
444
445 return res;
446}
#define ast_free(a)
Definition: astmm.h:180
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
int ast_filecopy(const char *oldname, const char *newname, const char *fmt)
Copies a file.
Definition: file.c:1151
#define ast_verb(level,...)
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
const char * format
Definition: stored.c:43
const ast_string_field file
Definition: stored.c:41

References ast_asprintf, ast_config_AST_RECORDING_DIR, ast_filecopy(), ast_free, ast_safe_mkdir(), ast_strdupa, ast_verb, stasis_app_stored_recording::file, stasis_app_stored_recording::format, NULL, RAII_VAR, and stasis_app_stored_recording_find_by_name().

Referenced by ast_ari_recordings_copy_stored().

◆ stasis_app_stored_recording_delete()

int stasis_app_stored_recording_delete ( struct stasis_app_stored_recording recording)

Delete a recording from disk.

Parameters
recordingRecording to delete.
Returns
0 on success.
Non-zero on error.

Definition at line 448 of file stored.c.

450{
451 /* Path was validated when the recording object was created */
452 return unlink(recording->file_with_ext);
453}
const ast_string_field file_with_ext
Definition: stored.c:41

References stasis_app_stored_recording::file_with_ext.

Referenced by ast_ari_recordings_delete_stored().

◆ stasis_app_stored_recording_find_all()

struct ao2_container * stasis_app_stored_recording_find_all ( void  )

Find all stored recordings on disk.

Returns
Container of stasis_app_stored_recording objects.
Return values
NULLon error.

Definition at line 297 of file stored.c.

298{
300 int res;
301
304 if (!recordings) {
305 return NULL;
306 }
307
310 if (res) {
311 ao2_ref(recordings, -1);
312 return NULL;
313 }
314
315 return recordings;
316}
@ AO2_ALLOC_OPT_LOCK_NOLOCK
Definition: astobj2.h:367
#define ao2_container_alloc_rbtree(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a red-black tree container.
Definition: astobj2.h:1349
@ AO2_CONTAINER_ALLOC_OPT_DUPS_REPLACE
Replace objects with duplicate keys in container.
Definition: astobj2.h:1211
int ast_file_read_dirs(const char *dir_name, ast_file_on_file on_file, void *obj, int max_depth)
Recursively iterate through files and directories up to max_depth.
Definition: file.c:1274
static struct stasis_rest_handlers recordings
REST handler for /api-docs/recordings.json.
static int recording_sort(const void *obj_left, const void *obj_right, int flags)
Definition: stored.c:225
static int handle_scan_file(const char *dir_name, const char *filename, void *obj)
Definition: stored.c:255
Generic container type.

References AO2_ALLOC_OPT_LOCK_NOLOCK, AO2_CONTAINER_ALLOC_OPT_DUPS_REPLACE, ao2_container_alloc_rbtree, ao2_ref, ast_config_AST_RECORDING_DIR, ast_file_read_dirs(), handle_scan_file(), NULL, recording_sort(), and recordings.

Referenced by ast_ari_recordings_list_stored().

◆ stasis_app_stored_recording_find_by_name()

struct stasis_app_stored_recording * stasis_app_stored_recording_find_by_name ( const char *  name)

Creates a stored recording object, with the given name.

Parameters
nameName of the recording.
Returns
New recording object.
Return values
NULLif recording is not found. errno is set to indicate why
  • ENOMEM - out of memeory
  • EACCES - file permissions (or recording is outside the config dir)
  • Any of the error codes for stat(), opendir(), readdir()

Definition at line 318 of file stored.c.

320{
321 RAII_VAR(struct stasis_app_stored_recording *, recording, NULL,
323 RAII_VAR(char *, dir, NULL, ast_free);
324 RAII_VAR(char *, file, NULL, ast_free);
325 RAII_VAR(char *, file_with_ext, NULL, ast_free);
326 int res;
327 struct stat file_stat;
328 int prefix_len = strlen(ast_config_AST_RECORDING_DIR);
329
330 errno = 0;
331
332 if (!name) {
333 errno = EINVAL;
334 return NULL;
335 }
336
337 recording = recording_alloc();
338 if (!recording) {
339 return NULL;
340 }
341
342 res = split_path(name, &dir, &file);
343 if (res != 0) {
344 return NULL;
345 }
346 ast_string_field_build(recording, file, "%s/%s", dir, file);
347
349 /* It's possible that one or more component of the recording path is
350 * a symbolic link, this would prevent dir from ever matching. */
351 char *real_basedir = realpath(ast_config_AST_RECORDING_DIR, NULL);
352
353 if (!real_basedir || !ast_begins_with(dir, real_basedir)) {
354 /* Attempt to escape the recording directory */
355 ast_log(LOG_WARNING, "Attempt to access invalid recording directory %s\n",
356 dir);
357 ast_std_free(real_basedir);
358 errno = EACCES;
359
360 return NULL;
361 }
362
363 prefix_len = strlen(real_basedir);
364 ast_std_free(real_basedir);
365 }
366
367 /* The actual name of the recording is file with the config dir
368 * prefix removed.
369 */
370 ast_string_field_set(recording, name, recording->file + prefix_len + 1);
371
372 file_with_ext = find_recording(dir, file);
373 if (!file_with_ext) {
374 return NULL;
375 }
376 ast_string_field_set(recording, file_with_ext, file_with_ext);
377 recording->format = strrchr(recording->file_with_ext, '.');
378 if (!recording->format) {
379 return NULL;
380 }
381 ++(recording->format);
382
383 res = stat(file_with_ext, &file_stat);
384 if (res != 0) {
385 return NULL;
386 }
387
388 if (!S_ISREG(file_stat.st_mode)) {
389 /* Let's not play if it's not a regular file */
390 errno = EACCES;
391 return NULL;
392 }
393
394 ao2_ref(recording, +1);
395 return recording;
396}
void ast_std_free(void *ptr)
Definition: astmm.c:1734
static struct stasis_app_stored_recording * recording_alloc(void)
Allocate a recording object.
Definition: stored.c:205
static char * find_recording(const char *dir_name, const char *file)
Finds a recording in the given directory.
Definition: stored.c:188
static int split_path(const char *path, char **dir, char **file)
Split a path into directory and file, resolving canonical directory.
Definition: stored.c:92
#define ast_string_field_build(x, field, fmt, args...)
Set a field to a complex (built) value.
Definition: stringfields.h:555
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

References ao2_cleanup, ao2_ref, ast_begins_with(), ast_config_AST_RECORDING_DIR, ast_free, ast_log, ast_std_free(), ast_string_field_build, ast_string_field_set, errno, make_ari_stubs::file, stasis_app_stored_recording::file_with_ext, find_recording(), LOG_WARNING, name, NULL, RAII_VAR, recording_alloc(), and split_path().

Referenced by ast_ari_recordings_copy_stored(), ast_ari_recordings_delete_stored(), ast_ari_recordings_get_stored(), ast_ari_recordings_get_stored_file(), play_on_channel(), and stasis_app_stored_recording_copy().

◆ stasis_app_stored_recording_get_extension()

const char * stasis_app_stored_recording_get_extension ( struct stasis_app_stored_recording recording)

Returns the extension for this recording.

Since
14.0.0
Parameters
recordingRecording to query.
Returns
The extension associated with this recording.
Return values
NULLon error

Definition at line 71 of file stored.c.

73{
74 if (!recording) {
75 return NULL;
76 }
77 return recording->format;
78}

References stasis_app_stored_recording::format, and NULL.

Referenced by ast_ari_recordings_get_stored_file().

◆ stasis_app_stored_recording_get_file()

const char * stasis_app_stored_recording_get_file ( struct stasis_app_stored_recording recording)

Returns the filename for this recording, for use with streamfile.

The returned string will be valid until the recording object is freed.

Parameters
recordingRecording to query.
Returns
Absolute path to the recording file, without the extension.
Return values
NULLon error.

Definition at line 53 of file stored.c.

55{
56 if (!recording) {
57 return NULL;
58 }
59 return recording->file;
60}

References stasis_app_stored_recording::file, and NULL.

Referenced by play_on_channel().

◆ stasis_app_stored_recording_get_filename()

const char * stasis_app_stored_recording_get_filename ( struct stasis_app_stored_recording recording)

Returns the full filename, with extension, for this recording.

Since
14.0.0
Parameters
recordingRecording to query.
Returns
Absolute path to the recording file, with the extension.
Return values
NULLon error

Definition at line 62 of file stored.c.

64{
65 if (!recording) {
66 return NULL;
67 }
68 return recording->file_with_ext;
69}

References stasis_app_stored_recording::file_with_ext, and NULL.

Referenced by ast_ari_recordings_get_stored_file().

◆ stasis_app_stored_recording_to_json()

struct ast_json * stasis_app_stored_recording_to_json ( struct stasis_app_stored_recording recording)

Convert stored recording info to JSON.

Parameters
recordingRecording to convert.
Returns
JSON representation.
Return values
NULLon error.

Definition at line 455 of file stored.c.

457{
458 if (!recording) {
459 return NULL;
460 }
461
462 return ast_json_pack("{ s: s, s: s }",
463 "name", recording->name,
464 "format", recording->format);
465}
const ast_string_field name
Definition: stored.c:41

References ast_json_pack(), stasis_app_stored_recording::format, stasis_app_stored_recording::name, and NULL.

Referenced by ast_ari_recordings_copy_stored(), ast_ari_recordings_get_stored(), and ast_ari_recordings_list_stored().