mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-12 15:45:18 +00:00
ARI - channel recording support
This patch is the first step in adding recording support to the Asterisk REST Interface. Recordings are stored in /var/spool/recording. Since recordings may be destructive (overwriting existing files), the API rejects attempts to escape the recording directory (avoiding issues if someone attempts to record to ../../lib/sounds/greeting, for example). (closes issue ASTERISK-21594) (closes issue ASTERISK-21581) Review: https://reviewboard.asterisk.org/r/2612/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@393550 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -690,9 +690,23 @@ int ast_control_streamfile_w_cb(struct ast_channel *chan,
|
||||
/*! \brief Play a stream and wait for a digit, returning the digit that was pressed */
|
||||
int ast_play_and_wait(struct ast_channel *chan, const char *fn);
|
||||
|
||||
/*!
|
||||
* Possible actions to take if a recording already exists
|
||||
* \since 12
|
||||
*/
|
||||
enum ast_record_if_exists {
|
||||
/*! Fail the recording. */
|
||||
AST_RECORD_IF_EXISTS_FAIL,
|
||||
/*! Overwrite the existing recording. */
|
||||
AST_RECORD_IF_EXISTS_OVERWRITE,
|
||||
/*! Append to the existing recording. */
|
||||
AST_RECORD_IF_EXISTS_APPEND,
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Record a file based on input from a channel
|
||||
* This function will play "auth-thankyou" upon successful recording.
|
||||
* This function will play "auth-thankyou" upon successful recording if
|
||||
* skip_confirmation_sound is false.
|
||||
*
|
||||
* \param chan the channel being recorded
|
||||
* \param playfile Filename of sound to play before recording begins
|
||||
@@ -706,13 +720,15 @@ int ast_play_and_wait(struct ast_channel *chan, const char *fn);
|
||||
* \param path Optional filesystem path to unlock
|
||||
* \param acceptdtmf Character of DTMF to end and accept the recording
|
||||
* \param canceldtmf Character of DTMF to end and cancel the recording
|
||||
* \param skip_confirmation_sound If true, don't play auth-thankyou at end. Nice for custom recording prompts in apps.
|
||||
* \param if_exists Action to take if recording already exists.
|
||||
*
|
||||
* \retval -1 failure or hangup
|
||||
* \retval 'S' Recording ended from silence timeout
|
||||
* \retval 't' Recording ended from the message exceeding the maximum duration
|
||||
* \retval dtmfchar Recording ended via the return value's DTMF character for either cancel or accept.
|
||||
*/
|
||||
int ast_play_and_record_full(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime_sec, const char *fmt, int *duration, int *sound_duration, int silencethreshold, int maxsilence_ms, const char *path, const char *acceptdtmf, const char *canceldtmf);
|
||||
int ast_play_and_record_full(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime_sec, const char *fmt, int *duration, int *sound_duration, int silencethreshold, int maxsilence_ms, const char *path, const char *acceptdtmf, const char *canceldtmf, int skip_confirmation_sound, enum ast_record_if_exists if_exists);
|
||||
|
||||
/*!
|
||||
* \brief Record a file based on input from a channel. Use default accept and cancel DTMF.
|
||||
|
@@ -1603,6 +1603,18 @@ void ast_channel_setwhentohangup_tv(struct ast_channel *chan, struct timeval off
|
||||
*/
|
||||
int ast_answer(struct ast_channel *chan);
|
||||
|
||||
/*!
|
||||
* \brief Answer a channel, if it's not already answered.
|
||||
*
|
||||
* \param chan channel to answer
|
||||
*
|
||||
* \details See ast_answer()
|
||||
*
|
||||
* \retval 0 on success
|
||||
* \retval non-zero on failure
|
||||
*/
|
||||
int ast_auto_answer(struct ast_channel *chan);
|
||||
|
||||
/*!
|
||||
* \brief Answer a channel
|
||||
*
|
||||
|
@@ -64,8 +64,8 @@ enum ast_waitstream_fr_cb_values {
|
||||
*/
|
||||
typedef void (ast_waitstream_fr_cb)(struct ast_channel *chan, long ms, enum ast_waitstream_fr_cb_values val);
|
||||
|
||||
/*!
|
||||
* \brief Streams a file
|
||||
/*!
|
||||
* \brief Streams a file
|
||||
* \param c channel to stream the file to
|
||||
* \param filename the name of the file you wish to stream, minus the extension
|
||||
* \param preflang the preferred language you wish to have the file streamed to you in
|
||||
@@ -86,12 +86,12 @@ int ast_streamfile(struct ast_channel *c, const char *filename, const char *pref
|
||||
*/
|
||||
int ast_stream_and_wait(struct ast_channel *chan, const char *file, const char *digits);
|
||||
|
||||
/*!
|
||||
* \brief Stops a stream
|
||||
/*!
|
||||
* \brief Stops a stream
|
||||
*
|
||||
* \param c The channel you wish to stop playback on
|
||||
*
|
||||
* Stop playback of a stream
|
||||
* Stop playback of a stream
|
||||
*
|
||||
* \retval 0 always
|
||||
*
|
||||
|
@@ -23,6 +23,7 @@ extern const char *ast_config_AST_CONFIG_FILE;
|
||||
extern const char *ast_config_AST_MODULE_DIR;
|
||||
extern const char *ast_config_AST_SPOOL_DIR;
|
||||
extern const char *ast_config_AST_MONITOR_DIR;
|
||||
extern const char *ast_config_AST_RECORDING_DIR;
|
||||
extern const char *ast_config_AST_VAR_DIR;
|
||||
extern const char *ast_config_AST_DATA_DIR;
|
||||
extern const char *ast_config_AST_LOG_DIR;
|
||||
|
203
include/asterisk/stasis_app_recording.h
Normal file
203
include/asterisk/stasis_app_recording.h
Normal file
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* Asterisk -- An open source telephony toolkit.
|
||||
*
|
||||
* Copyright (C) 2013, Digium, Inc.
|
||||
*
|
||||
* David M. Lee, II <dlee@digium.com>
|
||||
*
|
||||
* See http://www.asterisk.org for more information about
|
||||
* the Asterisk project. Please do not directly contact
|
||||
* any of the maintainers of this project for assistance;
|
||||
* the project provides a web site, mailing lists and IRC
|
||||
* channels for your use.
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License Version 2. See the LICENSE file
|
||||
* at the top of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef _ASTERISK_STASIS_APP_RECORDING_H
|
||||
#define _ASTERISK_STASIS_APP_RECORDING_H
|
||||
|
||||
/*! \file
|
||||
*
|
||||
* \brief Stasis Application Recording API. See \ref res_stasis "Stasis
|
||||
* Application API" for detailed documentation.
|
||||
*
|
||||
* \author David M. Lee, II <dlee@digium.com>
|
||||
* \since 12
|
||||
*/
|
||||
|
||||
#include "asterisk/app.h"
|
||||
#include "asterisk/stasis_app.h"
|
||||
|
||||
/*! Opaque struct for handling the recording of media to a file. */
|
||||
struct stasis_app_recording;
|
||||
|
||||
/*! State of a recording operation */
|
||||
enum stasis_app_recording_state {
|
||||
/*! The recording has not started yet */
|
||||
STASIS_APP_RECORDING_STATE_QUEUED,
|
||||
/*! The media is currently recording */
|
||||
STASIS_APP_RECORDING_STATE_RECORDING,
|
||||
/*! The media is currently paused */
|
||||
STASIS_APP_RECORDING_STATE_PAUSED,
|
||||
/*! The media has stopped recording */
|
||||
STASIS_APP_RECORDING_STATE_COMPLETE,
|
||||
/*! The media has stopped playing */
|
||||
STASIS_APP_RECORDING_STATE_FAILED,
|
||||
};
|
||||
|
||||
/*! Valid operation for controlling a recording. */
|
||||
enum stasis_app_recording_media_operation {
|
||||
/*! Stop the recording operation. */
|
||||
STASIS_APP_RECORDING_STOP,
|
||||
};
|
||||
|
||||
#define STASIS_APP_RECORDING_TERMINATE_INVALID 0
|
||||
#define STASIS_APP_RECORDING_TERMINATE_NONE -1
|
||||
#define STASIS_APP_RECORDING_TERMINATE_ANY -2
|
||||
|
||||
struct stasis_app_recording_options {
|
||||
AST_DECLARE_STRING_FIELDS(
|
||||
AST_STRING_FIELD(name); /*!< name Name of the recording. */
|
||||
AST_STRING_FIELD(format); /*!< Format to be recorded (wav, gsm, etc.) */
|
||||
);
|
||||
/*! Number of seconds of silence before ending the recording. */
|
||||
int max_silence_seconds;
|
||||
/*! Maximum recording duration. 0 for no maximum. */
|
||||
int max_duration_seconds;
|
||||
/*! Which DTMF to use to terminate the recording
|
||||
* \c STASIS_APP_RECORDING_TERMINATE_NONE to terminate only on hangup
|
||||
* \c STASIS_APP_RECORDING_TERMINATE_ANY to terminate on any DTMF
|
||||
*/
|
||||
char terminate_on;
|
||||
/*! How to handle recording when a file already exists */
|
||||
enum ast_record_if_exists if_exists;
|
||||
/*! If true, a beep is played at the start of recording */
|
||||
int beep:1;
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Allocate a recording options object.
|
||||
*
|
||||
* Clean up with ao2_cleanup().
|
||||
*
|
||||
* \param name Name of the recording.
|
||||
* \param format Format to record in.
|
||||
* \return Newly allocated options object.
|
||||
* \return \c NULL on error.
|
||||
*/
|
||||
struct stasis_app_recording_options *stasis_app_recording_options_create(
|
||||
const char *name, const char *format);
|
||||
|
||||
/*!
|
||||
* \brief Parse a string into the recording termination enum.
|
||||
*
|
||||
* \param str String to parse.
|
||||
* \return DTMF value to terminate on.
|
||||
* \return \c STASIS_APP_RECORDING_TERMINATE_NONE to not terminate on DTMF.
|
||||
* \return \c STASIS_APP_RECORDING_TERMINATE_ANY to terminate on any DTMF.
|
||||
* \return \c STASIS_APP_RECORDING_TERMINATE_INVALID if input was invalid.
|
||||
*/
|
||||
char stasis_app_recording_termination_parse(const char *str);
|
||||
|
||||
/*!
|
||||
* \brief Parse a string into the if_exists enum.
|
||||
*
|
||||
* \param str String to parse.
|
||||
* \return How to handle an existing file.
|
||||
* \return -1 on error.
|
||||
*/
|
||||
enum ast_record_if_exists stasis_app_recording_if_exists_parse(
|
||||
const char *str);
|
||||
|
||||
/*!
|
||||
* \brief Record media from a channel.
|
||||
*
|
||||
* A reference to the \a options object may be kept, so it MUST NOT be modified
|
||||
* after calling this function.
|
||||
*
|
||||
* On error, \c errno is set to indicate the failure reason.
|
||||
* - \c EINVAL: Invalid input.
|
||||
* - \c EEXIST: A recording with that name is in session.
|
||||
* - \c ENOMEM: Out of memory.
|
||||
*
|
||||
* \param control Control for \c res_stasis.
|
||||
* \param options Recording options.
|
||||
* \return Recording control object.
|
||||
* \return \c NULL on error.
|
||||
*/
|
||||
struct stasis_app_recording *stasis_app_control_record(
|
||||
struct stasis_app_control *control,
|
||||
struct stasis_app_recording_options *options);
|
||||
|
||||
/*!
|
||||
* \brief Gets the current state of a recording operation.
|
||||
*
|
||||
* \param recording Recording control object.
|
||||
* \return The state of the \a recording object.
|
||||
*/
|
||||
enum stasis_app_recording_state stasis_app_recording_get_state(
|
||||
struct stasis_app_recording *recording);
|
||||
|
||||
/*!
|
||||
* \brief Gets the unique name of a recording object.
|
||||
*
|
||||
* \param recording Recording control object.
|
||||
* \return \a recording's name.
|
||||
* \return \c NULL if \a recording ic \c NULL
|
||||
*/
|
||||
const char *stasis_app_recording_get_name(
|
||||
struct stasis_app_recording *recording);
|
||||
|
||||
/*!
|
||||
* \brief Finds the recording object with the given name.
|
||||
*
|
||||
* \param name Name of the recording object to find.
|
||||
* \return Associated \ref stasis_app_recording object.
|
||||
* \return \c NULL if \a name not found.
|
||||
*/
|
||||
struct stasis_app_recording *stasis_app_recording_find_by_name(const char *name);
|
||||
|
||||
/*!
|
||||
* \brief Construct a JSON model of a recording.
|
||||
*
|
||||
* \param recording Recording to conver.
|
||||
* \return JSON model.
|
||||
* \return \c NULL on error.
|
||||
*/
|
||||
struct ast_json *stasis_app_recording_to_json(
|
||||
const struct stasis_app_recording *recording);
|
||||
|
||||
/*!
|
||||
* \brief Possible results from a recording operation.
|
||||
*/
|
||||
enum stasis_app_recording_oper_results {
|
||||
/*! Operation completed successfully. */
|
||||
STASIS_APP_RECORDING_OPER_OK,
|
||||
/*! Operation failed. */
|
||||
STASIS_APP_RECORDING_OPER_FAILED,
|
||||
/*! Operation failed b/c recording is not in session. */
|
||||
STASIS_APP_RECORDING_OPER_NOT_RECORDING,
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Controls the media for a given recording operation.
|
||||
*
|
||||
* \param recording Recording control object.
|
||||
* \param control Media control operation.
|
||||
* \return \c STASIS_APP_RECORDING_OPER_OK on success.
|
||||
* \return \ref stasis_app_recording_oper_results indicating failure.
|
||||
*/
|
||||
enum stasis_app_recording_oper_results stasis_app_recording_operation(
|
||||
struct stasis_app_recording *recording,
|
||||
enum stasis_app_recording_media_operation operation);
|
||||
|
||||
/*!
|
||||
* \brief Message type for recording updates. The data is an
|
||||
* \ref ast_channel_blob.
|
||||
*/
|
||||
struct stasis_message_type *stasis_app_recording_snapshot_type(void);
|
||||
|
||||
#endif /* _ASTERISK_STASIS_APP_RECORDING_H */
|
@@ -718,6 +718,19 @@ void ast_enable_packet_fragmentation(int sock);
|
||||
*/
|
||||
int ast_mkdir(const char *path, int mode);
|
||||
|
||||
/*!
|
||||
* \brief Recursively create directory path, but only if it resolves within
|
||||
* the given \a base_path.
|
||||
*
|
||||
* If \a base_path does not exist, it will not be created and this function
|
||||
* returns \c EPERM.
|
||||
*
|
||||
* \param path The directory path to create
|
||||
* \param mode The permissions with which to try to create the directory
|
||||
* \return 0 on success or an error code otherwise
|
||||
*/
|
||||
int ast_safe_mkdir(const char *base_path, const char *path, int mode);
|
||||
|
||||
#define ARRAY_LEN(a) (size_t) (sizeof(a) / sizeof(0[a]))
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user