[asterisk-commits] dlee: branch dlee/record r389615 - in /team/dlee/record: include/asterisk/ re...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Thu May 23 15:34:14 CDT 2013
Author: dlee
Date: Thu May 23 15:34:11 2013
New Revision: 389615
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=389615
Log:
Recording initial work
Added:
team/dlee/record/include/asterisk/stasis_app_recording.h (with props)
team/dlee/record/res/res_stasis_recording.c (with props)
team/dlee/record/res/res_stasis_recording.exports.in (with props)
Modified:
team/dlee/record/include/asterisk/channel.h
team/dlee/record/include/asterisk/file.h
team/dlee/record/include/asterisk/stasis_http.h
team/dlee/record/res/res_stasis_http.c
team/dlee/record/res/res_stasis_playback.c
team/dlee/record/res/stasis_http/resource_channels.c
Modified: team/dlee/record/include/asterisk/channel.h
URL: http://svnview.digium.com/svn/asterisk/team/dlee/record/include/asterisk/channel.h?view=diff&rev=389615&r1=389614&r2=389615
==============================================================================
--- team/dlee/record/include/asterisk/channel.h (original)
+++ team/dlee/record/include/asterisk/channel.h Thu May 23 15:34:11 2013
@@ -1560,6 +1560,24 @@
* \retval non-zero on failure
*/
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
+ */
+static inline int ast_auto_answer(struct ast_channel *chan)
+{
+ if (ast_channel_state(chan) == AST_STATE_UP) {
+ /* Already answered */
+ return 0;
+ }
+ return ast_answer(chan);}
/*!
* \brief Answer a channel
Modified: team/dlee/record/include/asterisk/file.h
URL: http://svnview.digium.com/svn/asterisk/team/dlee/record/include/asterisk/file.h?view=diff&rev=389615&r1=389614&r2=389615
==============================================================================
--- team/dlee/record/include/asterisk/file.h (original)
+++ team/dlee/record/include/asterisk/file.h Thu May 23 15:34:11 2013
@@ -64,8 +64,8 @@
*/
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
@@ -75,6 +75,27 @@
* \retval -1 on failure.
*/
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang);
+
+/*!
+ * \brief Plays a sound to the channel, in the channel's default language.
+ *
+ * This will stop any existing streams on the channel.
+
+ * \param c channel to stream the file to
+ * \param filename the name of the file you wish to stream, minus the extension
+ * \retval 0 on success.
+ * \retval -1 on failure.
+ */
+static int ast_play_sound(struct ast_channel *c, const char *filename)
+{
+ int res;
+ res = ast_streamfile(chan, "beep", ast_channel_language(chan));
+ if (res == 0) {
+ res = ast_waitstream(chan, "");
+ }
+ ast_stopstream(chan);
+ return res;
+}
/*!
* \brief stream file until digit
@@ -86,12 +107,12 @@
*/
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
*
Added: team/dlee/record/include/asterisk/stasis_app_recording.h
URL: http://svnview.digium.com/svn/asterisk/team/dlee/record/include/asterisk/stasis_app_recording.h?view=auto&rev=389615
==============================================================================
--- team/dlee/record/include/asterisk/stasis_app_recording.h (added)
+++ team/dlee/record/include/asterisk/stasis_app_recording.h Thu May 23 15:34:11 2013
@@ -1,0 +1,159 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * David M. Lee, II <dlee at 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 at digium.com>
+ * \since 12
+ */
+
+#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,
+ /*! Enum end sentinel. */
+ STASIS_APP_RECORDING_STATE_MAX,
+};
+
+/*! Valid operation for controlling a recording. */
+enum stasis_app_recording_media_operation {
+ /*! Stop the recording operation. */
+ STASIS_APP_RECORDING_STOP,
+ /*! Enum end sentinel. */
+ STASIS_APP_RECORDING_MEDIA_OP_MAX,
+};
+
+enum stasis_app_recording_termination {
+ STASIS_APP_RECORDING_TERMINATE_NONE,
+ STASIS_APP_RECORDING_TERMINATE_HASH,
+ STASIS_APP_RECORDING_TERMINATE_STAR,
+ STASIS_APP_RECORDING_TERMINATE_ANY,
+};
+
+struct stasis_app_recording_options {
+ /*! \param name Name of the recording. */
+ const char *name;
+ /*! Format to be recorded (wav, gsm, etc.) */
+ const char *format;
+ /*! 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 */
+ enum stasis_app_recording_termination terminate_on;
+ /*! If true, file is appended to instead of overwriting. */
+ int append:1;
+ /*! If true, no beep is played at the start of recording */
+ int no_beep:1;
+};
+
+/*!
+ * \brief Parse a string into the recording termination enum.
+ *
+ * \param str String to parse.
+ * \return Parsed value.
+ * \return -1 on error.
+ */
+enum stasis_app_recording_termination stasis_app_recording_termination_parse(const char *str);
+
+/*!
+ * \brief Record media from a channel.
+ *
+ * \param control Control for \c res_stasis.
+ * \return Recording control object.
+ * \return \c NULL on error.
+ */
+struct stasis_app_recording *stasis_app_control_record(
+ struct stasis_app_control *control,
+ const 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 id of a recording object.
+ *
+ * \param recording Recording control object.
+ * \return \a recording's id.
+ * \return \c NULL if \a recording ic \c NULL
+ */
+const char *stasis_app_recording_get_id(
+ struct stasis_app_recording *recording);
+
+/*!
+ * \brief Finds the recording object with the given id.
+ *
+ * \param id Id of the recording object to find.
+ * \return Associated \ref stasis_app_recording object.
+ * \return \c NULL if \a id not found.
+ */
+struct stasis_app_recording *stasis_app_recording_find_by_id(const char *id);
+
+struct ast_json *stasis_app_recording_to_json(
+ const struct stasis_app_recording *recording);
+
+enum stasis_app_recording_oper_results {
+ STASIS_APP_RECORDING_OPER_OK,
+ STASIS_APP_RECORDING_OPER_FAILED,
+ 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 */
Propchange: team/dlee/record/include/asterisk/stasis_app_recording.h
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/dlee/record/include/asterisk/stasis_app_recording.h
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Propchange: team/dlee/record/include/asterisk/stasis_app_recording.h
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: team/dlee/record/include/asterisk/stasis_http.h
URL: http://svnview.digium.com/svn/asterisk/team/dlee/record/include/asterisk/stasis_http.h?view=diff&rev=389615&r1=389614&r2=389615
==============================================================================
--- team/dlee/record/include/asterisk/stasis_http.h (original)
+++ team/dlee/record/include/asterisk/stasis_http.h Thu May 23 15:34:11 2013
@@ -166,7 +166,7 @@
* \brief Fill in a <tt>Created</tt> (201) \a stasis_http_response.
*/
void stasis_http_response_created(struct stasis_http_response *response,
- const char *url);
+ const char *url, struct ast_json *message);
/*!
* \brief Fill in \a response with a 500 message for allocation failures.
Modified: team/dlee/record/res/res_stasis_http.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/record/res/res_stasis_http.c?view=diff&rev=389615&r1=389614&r2=389615
==============================================================================
--- team/dlee/record/res/res_stasis_http.c (original)
+++ team/dlee/record/res/res_stasis_http.c Thu May 23 15:34:11 2013
@@ -331,9 +331,9 @@
}
void stasis_http_response_created(struct stasis_http_response *response,
- const char *url)
-{
- response->message = ast_json_null();
+ const char *url, struct ast_json *message)
+{
+ response->message = message;
response->response_code = 201;
response->response_text = "Created";
ast_str_append(&response->headers, 0, "Location: %s\r\n", url);
Modified: team/dlee/record/res/res_stasis_playback.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/record/res/res_stasis_playback.c?view=diff&rev=389615&r1=389614&r2=389615
==============================================================================
--- team/dlee/record/res/res_stasis_playback.c (original)
+++ team/dlee/record/res/res_stasis_playback.c Thu May 23 15:34:11 2013
@@ -266,7 +266,7 @@
stasis_app_control_get_channel_id(control), uri);
playback = ao2_alloc(sizeof(*playback), playback_dtor);
- if (!playback || ast_string_field_init(playback, 128) ){
+ if (!playback || ast_string_field_init(playback, 128)) {
return NULL;
}
@@ -329,7 +329,6 @@
if (playback == NULL) {
return NULL;
}
-
json = ast_json_pack("{s: s, s: s, s: s, s: s}",
"id", playback->id,
Added: team/dlee/record/res/res_stasis_recording.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/record/res/res_stasis_recording.c?view=auto&rev=389615
==============================================================================
--- team/dlee/record/res/res_stasis_recording.c (added)
+++ team/dlee/record/res/res_stasis_recording.c Thu May 23 15:34:11 2013
@@ -1,0 +1,346 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * David M. Lee, II <dlee at 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.
+ */
+
+/*! \file
+ *
+ * \brief res_stasis recording support.
+ *
+ * \author David M. Lee, II <dlee at digium.com>
+ */
+
+/*** MODULEINFO
+ <depend type="module">res_stasis</depend>
+ <support_level>core</support_level>
+ ***/
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#include "asterisk/file.h"
+#include "asterisk/module.h"
+#include "asterisk/stasis_app_impl.h"
+#include "asterisk/stasis_app_recording.h"
+#include "asterisk/stasis_channels.h"
+#include "asterisk/uuid.h"
+
+/*! Number of hash buckets for recording container. Keep it prime! */
+#define RECORDING_BUCKETS 127
+
+STASIS_MESSAGE_TYPE_DEFN(stasis_app_recording_snapshot_type);
+
+/*! Container of all current recordings */
+static struct ao2_container *recordings;
+
+struct stasis_app_recording {
+ AST_DECLARE_STRING_FIELDS(
+ AST_STRING_FIELD(id); /*!< Recording unique id */
+ AST_STRING_FIELD(name);
+ AST_STRING_FIELD(format);
+ );
+ /*! Control object for the channel we're playing back to */
+ struct stasis_app_control *control;
+ /*! Current state of the recording. */
+ enum stasis_app_recording_state state;
+ /*! 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 */
+ enum stasis_app_recording_termination terminate_on;
+ /*! If true, file is appended to instead of overwriting. */
+ int append:1;
+ /*! If true, no beep is played at the start of recording */
+ int no_beep:1;
+};
+
+static int recording_hash(const void *obj, int flags)
+{
+ const struct stasis_app_recording *recording = obj;
+ const char *id = flags & OBJ_KEY ? obj : recording->id;
+ return ast_str_hash(id);
+}
+
+static int recording_cmp(void *obj, void *arg, int flags)
+{
+ struct stasis_app_recording *lhs = obj;
+ struct stasis_app_recording *rhs = arg;
+ const char *rhs_id = flags & OBJ_KEY ? arg : rhs->id;
+
+ if (strcmp(lhs->id, rhs_id) == 0) {
+ return CMP_MATCH | CMP_STOP;
+ } else {
+ return 0;
+ }
+}
+
+enum stasis_app_recording_termination stasis_app_recording_termination_parse(const char *str)
+{
+ if (ast_strlen_zero(str)) {
+ return STASIS_APP_RECORDING_TERMINATE_NONE;
+ }
+
+ if (strcmp(str, "none")) {
+ return STASIS_APP_RECORDING_TERMINATE_NONE;
+ }
+
+ if (strcmp(str, "#") == 0) {
+ return STASIS_APP_RECORDING_TERMINATE_HASH;
+ }
+
+ if (strcmp(str, "*") == 0) {
+ return STASIS_APP_RECORDING_TERMINATE_STAR;
+ }
+
+ if (strcmp(str, "any") == 0) {
+ return STASIS_APP_RECORDING_TERMINATE_ANY;
+ }
+
+ return -1;
+}
+
+static void recording_publish(struct stasis_app_recording *recording)
+{
+ RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
+ RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
+ RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
+
+ ast_assert(recording != NULL);
+
+ json = stasis_app_recording_to_json(recording);
+ if (json == NULL) {
+ return;
+ }
+
+ message = ast_channel_blob_create_from_cache(
+ stasis_app_control_get_channel_id(recording->control),
+ stasis_app_recording_snapshot_type(), json);
+ if (message == NULL) {
+ return;
+ }
+
+ stasis_app_control_publish(recording->control, message);
+}
+
+static void recording_fail(struct stasis_app_recording *recording)
+{
+ SCOPED_AO2LOCK(lock, recording);
+ recording->state = STASIS_APP_RECORDING_STATE_FAILED;
+ recording_publish(recording);
+}
+
+static void *record_file(struct stasis_app_control *control,
+ struct ast_channel *chan, void *data)
+{
+ struct stasis_app_recording *recording = data;
+ int res;
+ long maxms;
+
+ ao2_lock(recording);
+ recording->state = STASIS_APP_RECORDING_STATE_RECORDING;
+ recording_publish(recording);
+ ao2_unlock(recording);
+
+ res = ast_auto_answer(chan);
+ if (res != 0) {
+ recording_fail(recording);
+ return NULL;
+ }
+
+ if (!recording->no_beep) {
+ res = ast_play_sound(chan, "beep");
+ }
+ if (res != 0) {
+ recording_fail(recording);
+ return NULL;
+ }
+
+ maxms = control->max_duration_seconds * 1000;
+ start = ast_tvnow();
+ while ((ms = ast_remaining_ms(start, maxms))) {
+ RAII_VAR(struct ast_frame *, f, NULL, ast_frame_dtor);
+
+ res = ast_waitfor(chan, ms);
+ if (res < 0) {
+ break;
+ }
+
+ if (maxduration > 0 && res == 0) {
+ break;
+ }
+
+ f = ast_read(chan);
+ if (!f) {
+ break;
+ }
+
+ switch (f->frametype) {
+ case AST_FRAME_VOICE:
+ res = ast_writestream(s, f);
+ break;
+ case AST_FRAME_VIDEO:
+ res = ast_writestream(s, f);
+ break;
+ case AST_FRAME_DTMF:
+
+ break;
+ }
+ }
+
+ ao2_lock(recording);
+ recording->state = STASIS_APP_RECORDING_STATE_COMPLETE;
+ recording_publish(recording);
+ ao2_unlock(recording);
+ return NULL;
+}
+
+static void recording_dtor(void *obj)
+{
+ struct stasis_app_recording *recording = obj;
+
+ ast_string_field_free_memory(recording);
+}
+
+struct stasis_app_recording *stasis_app_control_record(
+ struct stasis_app_control *control,
+ const struct stasis_app_recording_options *options)
+{
+ RAII_VAR(struct stasis_app_recording *, recording, NULL, ao2_cleanup);
+ char id[AST_UUID_STR_LEN];
+
+ if (options == NULL ||
+ ast_strlen_zero(options->name) ||
+ ast_strlen_zero(options->format) ||
+ options->max_silence_seconds < 0 ||
+ options->max_duration_seconds < 0 ||
+ options->terminate_on < 0) {
+ return NULL;
+ }
+
+ ast_debug(3, "%s: Sending record(%s.%s) command\n",
+ stasis_app_control_get_channel_id(control), options->name,
+ options->format);
+
+ recording = ao2_alloc(sizeof(*recording), recording_dtor);
+ if (!recording || ast_string_field_init(recording, 128)) {
+ return NULL;
+ }
+
+ ast_uuid_generate_str(id, sizeof(id));
+ recording->control = control;
+ ast_string_field_set(recording, id, id);
+ ast_string_field_set(recording, name, options->name);
+ ast_string_field_set(recording, format, options->format);
+ recording->max_silence_seconds = options->max_silence_seconds;
+ recording->max_duration_seconds = options->max_duration_seconds;
+ recording->terminate_on = options->terminate_on;
+ recording->append = options->append;
+ recording->no_beep = options->no_beep;
+ ao2_link(recordings, recording);
+
+ recording->state = STASIS_APP_RECORDING_STATE_QUEUED;
+
+ /* A ref is kept in the recordings container; no need to bump */
+ stasis_app_send_command_async(control, record_file, recording);
+
+ /* Although this should be bumped for the caller */
+ ao2_ref(recording, +1);
+ return recording;
+}
+
+enum stasis_app_recording_state stasis_app_recording_get_state(
+ struct stasis_app_recording *recording)
+{
+ return recording->state;
+}
+
+const char *stasis_app_recording_get_id(
+ struct stasis_app_recording *recording)
+{
+ return recording->id;
+}
+
+struct stasis_app_recording *stasis_app_recording_find_by_id(const char *id)
+{
+ RAII_VAR(struct stasis_app_recording *, recording, NULL, ao2_cleanup);
+
+ recording = ao2_find(recordings, id, OBJ_KEY);
+ if (recording == NULL) {
+ return NULL;
+ }
+
+ ao2_ref(recording, +1);
+ return recording;
+}
+
+struct ast_json *stasis_app_recording_to_json(
+ const struct stasis_app_recording *recording)
+{
+ RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
+
+ if (recording == NULL) {
+ return NULL;
+ }
+
+ json = ast_json_pack("{s: s, s: s, s: s, s: s}",
+ "id", recording->id,
+ "name", recording->name,
+ "format", recording->format,
+ "state", recording->state);
+
+ return ast_json_ref(json);
+}
+
+enum stasis_app_recording_oper_results stasis_app_recording_operation(
+ struct stasis_app_recording *recording,
+ enum stasis_app_recording_media_operation operation)
+{
+ ast_assert(0); // TODO
+ return STASIS_APP_RECORDING_OPER_FAILED;
+}
+
+static int load_module(void)
+{
+ int r;
+
+ r = STASIS_MESSAGE_TYPE_INIT(stasis_app_recording_snapshot_type);
+ if (r != 0) {
+ return AST_MODULE_LOAD_FAILURE;
+ }
+
+ recordings = ao2_container_alloc(RECORDING_BUCKETS, recording_hash,
+ recording_cmp);
+ if (!recordings) {
+ return AST_MODULE_LOAD_FAILURE;
+ }
+ return AST_MODULE_LOAD_SUCCESS;
+}
+
+static int unload_module(void)
+{
+ ao2_cleanup(recordings);
+ recordings = NULL;
+ STASIS_MESSAGE_TYPE_CLEANUP(stasis_app_recording_snapshot_type);
+ return 0;
+}
+
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS,
+ "Stasis application recording support",
+ .load = load_module,
+ .unload = unload_module,
+ .nonoptreq = "res_stasis");
Propchange: team/dlee/record/res/res_stasis_recording.c
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/dlee/record/res/res_stasis_recording.c
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Propchange: team/dlee/record/res/res_stasis_recording.c
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: team/dlee/record/res/res_stasis_recording.exports.in
URL: http://svnview.digium.com/svn/asterisk/team/dlee/record/res/res_stasis_recording.exports.in?view=auto&rev=389615
==============================================================================
--- team/dlee/record/res/res_stasis_recording.exports.in (added)
+++ team/dlee/record/res/res_stasis_recording.exports.in Thu May 23 15:34:11 2013
@@ -1,0 +1,6 @@
+{
+ global:
+ LINKER_SYMBOL_PREFIXstasis_app_*;
+ local:
+ *;
+};
Propchange: team/dlee/record/res/res_stasis_recording.exports.in
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/dlee/record/res/res_stasis_recording.exports.in
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Propchange: team/dlee/record/res/res_stasis_recording.exports.in
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: team/dlee/record/res/stasis_http/resource_channels.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/record/res/stasis_http/resource_channels.c?view=diff&rev=389615&r1=389614&r2=389615
==============================================================================
--- team/dlee/record/res/stasis_http/resource_channels.c (original)
+++ team/dlee/record/res/stasis_http/resource_channels.c Thu May 23 15:34:11 2013
@@ -1,4 +1,4 @@
-/* -*- C -*-
+/*
* Asterisk -- An open source telephony toolkit.
*
* Copyright (C) 2012 - 2013, Digium, Inc.
@@ -35,6 +35,7 @@
#include "asterisk/file.h"
#include "asterisk/stasis_app.h"
#include "asterisk/stasis_app_playback.h"
+#include "asterisk/stasis_app_recording.h"
#include "asterisk/stasis_channels.h"
#include "resource_channels.h"
@@ -145,6 +146,7 @@
RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
RAII_VAR(struct stasis_app_playback *, playback, NULL, ao2_cleanup);
RAII_VAR(char *, playback_url, NULL, ast_free);
+ RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
const char *language;
ast_assert(response != NULL);
@@ -197,12 +199,84 @@
return;
}
- stasis_http_response_created(response, playback_url);
-}
-void stasis_http_record_channel(struct ast_variable *headers, struct ast_record_channel_args *args, struct stasis_http_response *response)
-{
- ast_log(LOG_ERROR, "TODO: stasis_http_record_channel\n");
-}
+ json = stasis_app_playback_to_json(playback);
+ if (!json) {
+ stasis_http_response_error(
+ response, 500, "Internal Server Error",
+ "Out of memory");
+ return;
+ }
+
+ stasis_http_response_created(response, playback_url, json);
+}
+
+void stasis_http_record_channel(struct ast_variable *headers,
+ struct ast_record_channel_args *args,
+ struct stasis_http_response *response)
+{
+ RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
+ RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
+ RAII_VAR(struct stasis_app_recording *, recording, NULL, ao2_cleanup);
+ RAII_VAR(char *, recording_url, NULL, ast_free);
+ RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
+ struct stasis_app_recording_options options = {};
+
+ ast_assert(response != NULL);
+
+ if (args->max_duration_seconds < 0) {
+ stasis_http_response_error(
+ response, 400, "Bad Request",
+ "max_duration_seconds cannot be negative");
+ return;
+ }
+
+ if (args->max_silence_seconds < 0) {
+ stasis_http_response_error(
+ response, 400, "Bad Request",
+ "max_silence_seconds cannot be negative");
+ return;
+ }
+
+ control = find_control(response, args->channel_id);
+ if (control == NULL) {
+ /* Response filled in by find_control */
+ return;
+ }
+
+ options.name = args->name;
+ options.format = args->format;
+ options.max_silence_seconds = args->max_silence_seconds;
+ options.max_duration_seconds = args->max_duration_seconds;
+ options.terminate_on =
+ stasis_app_recording_termination_parse(args->terminate_on);
+
+ if (options.terminate_on == -1) {
+ stasis_http_response_error(
+ response, 400, "Bad Request",
+ "terminateOn invalid");
+ return;
+ }
+
+ recording = stasis_app_control_record(control, &options);
+ if (!recording) {
+ stasis_http_response_error(
+ response, 500, "Internal Server Error",
+ "Failed to start recording");
+ return;
+ }
+
+ ast_asprintf(&recording_url, "/recording/%s",
+ stasis_app_recording_get_id(recording));
+ if (!recording_url) {
+ stasis_http_response_error(
+ response, 500, "Internal Server Error",
+ "Out of memory");
+ return;
+ }
+
+ stasis_http_response_created(response, recording_url, json);
+}
+
void stasis_http_get_channel(struct ast_variable *headers,
struct ast_get_channel_args *args,
struct stasis_http_response *response)
More information about the asterisk-commits
mailing list