[asterisk-commits] dlee: branch dlee/record r389962 - in /team/dlee/record: include/asterisk/ re...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue May 28 16:27:17 CDT 2013
Author: dlee
Date: Tue May 28 16:27:14 2013
New Revision: 389962
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=389962
Log:
Append works
Modified:
team/dlee/record/include/asterisk/stasis_app_recording.h
team/dlee/record/res/res_stasis_http_bridges.c
team/dlee/record/res/res_stasis_http_channels.c
team/dlee/record/res/res_stasis_recording.c
team/dlee/record/res/stasis_http/resource_channels.c
team/dlee/record/rest-api-templates/asterisk_processor.py
team/dlee/record/rest-api/api-docs/channels.json
Modified: 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=diff&rev=389962&r1=389961&r2=389962
==============================================================================
--- team/dlee/record/include/asterisk/stasis_app_recording.h (original)
+++ team/dlee/record/include/asterisk/stasis_app_recording.h Tue May 28 16:27:14 2013
@@ -58,10 +58,10 @@
#define STASIS_APP_RECORDING_TERMINATE_ANY -2
struct stasis_app_recording_options {
- /*! \param name Name of the recording. */
- const char *name;
- /*! Format to be recorded (wav, gsm, etc.) */
- const char *format;
+ 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. */
@@ -73,9 +73,22 @@
char 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;
+ /*! 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.
@@ -91,18 +104,22 @@
/*!
* \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,
- const struct stasis_app_recording_options *options);
+ struct stasis_app_recording_options *options);
/*!
* \brief Gets the current state of a recording operation.
Modified: team/dlee/record/res/res_stasis_http_bridges.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/record/res/res_stasis_http_bridges.c?view=diff&rev=389962&r1=389961&r2=389962
==============================================================================
--- team/dlee/record/res/res_stasis_http_bridges.c (original)
+++ team/dlee/record/res/res_stasis_http_bridges.c Tue May 28 16:27:14 2013
@@ -206,10 +206,10 @@
args.max_silence_seconds = atoi(i->value);
} else
if (strcmp(i->name, "append") == 0) {
- args.append = atoi(i->value);
+ args.append = ast_true(i->value);
} else
if (strcmp(i->name, "beep") == 0) {
- args.beep = atoi(i->value);
+ args.beep = ast_true(i->value);
} else
if (strcmp(i->name, "terminateOn") == 0) {
args.terminate_on = (i->value);
Modified: team/dlee/record/res/res_stasis_http_channels.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/record/res/res_stasis_http_channels.c?view=diff&rev=389962&r1=389961&r2=389962
==============================================================================
--- team/dlee/record/res/res_stasis_http_channels.c (original)
+++ team/dlee/record/res/res_stasis_http_channels.c Tue May 28 16:27:14 2013
@@ -374,10 +374,10 @@
args.max_silence_seconds = atoi(i->value);
} else
if (strcmp(i->name, "append") == 0) {
- args.append = atoi(i->value);
+ args.append = ast_true(i->value);
} else
if (strcmp(i->name, "beep") == 0) {
- args.beep = atoi(i->value);
+ args.beep = ast_true(i->value);
} else
if (strcmp(i->name, "terminateOn") == 0) {
args.terminate_on = (i->value);
Modified: team/dlee/record/res/res_stasis_recording.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/record/res/res_stasis_recording.c?view=diff&rev=389962&r1=389961&r2=389962
==============================================================================
--- team/dlee/record/res/res_stasis_recording.c (original)
+++ team/dlee/record/res/res_stasis_recording.c Tue May 28 16:27:14 2013
@@ -47,30 +47,19 @@
static struct ao2_container *recordings;
struct stasis_app_recording {
- AST_DECLARE_STRING_FIELDS(
- AST_STRING_FIELD(name);
- AST_STRING_FIELD(format);
- );
+ /*! Recording options. */
+ struct stasis_app_recording_options *options;
/*! 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 */
- char 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->name;
+ const char *id = flags & OBJ_KEY ? obj : recording->options->name;
return ast_str_hash(id);
}
@@ -78,9 +67,9 @@
{
struct stasis_app_recording *lhs = obj;
struct stasis_app_recording *rhs = arg;
- const char *rhs_id = flags & OBJ_KEY ? arg : rhs->name;
-
- if (strcmp(lhs->name, rhs_id) == 0) {
+ const char *rhs_id = flags & OBJ_KEY ? arg : rhs->options->name;
+
+ if (strcmp(lhs->options->name, rhs_id) == 0) {
return CMP_MATCH | CMP_STOP;
} else {
return 0;
@@ -105,6 +94,31 @@
return "?";
}
+static void recording_options_dtor(void *obj)
+{
+ struct stasis_app_recording_options *options = obj;
+
+ ast_string_field_free_memory(options);
+}
+
+struct stasis_app_recording_options *stasis_app_recording_options_create(
+ const char *name, const char *format)
+{
+ RAII_VAR(struct stasis_app_recording_options *, options, NULL,
+ ao2_cleanup);
+
+ options = ao2_alloc(sizeof(*options), recording_options_dtor);
+
+ if (!options || ast_string_field_init(options, 128)) {
+ return NULL;
+ }
+ ast_string_field_set(options, name, name);
+ ast_string_field_set(options, format, format);
+
+ ao2_ref(options, +1);
+ return options;
+}
+
char stasis_app_recording_termination_parse(const char *str)
{
if (ast_strlen_zero(str)) {
@@ -164,14 +178,14 @@
char dtmf)
{
int res = 0;
- switch (recording->terminate_on) {
+ switch (recording->options->terminate_on) {
case STASIS_APP_RECORDING_TERMINATE_NONE:
break;
case STASIS_APP_RECORDING_TERMINATE_ANY:
res = 1;
break;
default:
- if (dtmf == recording->terminate_on) {
+ if (dtmf == recording->options->terminate_on) {
res = 1;
}
break;
@@ -208,13 +222,18 @@
recording_publish(recording);
ao2_unlock(recording);
- ioflags = O_CREAT|O_WRONLY|(recording->append ? O_APPEND : O_TRUNC);
-
- s = ast_writefile(recording->name,recording->format, comment, ioflags,
- check, AST_FILE_MODE);
+ ioflags = O_CREAT|O_WRONLY;
+ if (recording->options->append) {
+ ioflags |= O_APPEND;
+ } else {
+ ioflags |= O_TRUNC;
+ }
+
+ s = ast_writefile(recording->options->name,recording->options->format,
+ comment, ioflags, check, AST_FILE_MODE);
if (s == NULL) {
ast_log(LOG_WARNING, "Could not create file %s.%s\n",
- recording->name, recording->format);
+ recording->options->name, recording->options->format);
recording_fail(recording);
return NULL;
}
@@ -225,7 +244,7 @@
return NULL;
}
- if (!recording->no_beep) {
+ if (recording->options->beep) {
res = ast_play_sound(chan, "beep");
}
if (res != 0) {
@@ -233,7 +252,7 @@
return NULL;
}
- maxms = recording->max_duration_seconds * 1000;
+ maxms = recording->options->max_duration_seconds * 1000;
start = ast_tvnow();
while ((ms = ast_remaining_ms(start, maxms))) {
int terminated = 0;
@@ -305,12 +324,12 @@
{
struct stasis_app_recording *recording = obj;
- ast_string_field_free_memory(recording);
+ ao2_cleanup(recording->options);
}
struct stasis_app_recording *stasis_app_control_record(
struct stasis_app_control *control,
- const struct stasis_app_recording_options *options)
+ struct stasis_app_recording_options *options)
{
RAII_VAR(struct stasis_app_recording *, recording, NULL, ao2_cleanup);
@@ -330,19 +349,14 @@
options->format);
recording = ao2_alloc(sizeof(*recording), recording_dtor);
- if (!recording || ast_string_field_init(recording, 128)) {
+ if (!recording) {
errno = ENOMEM;
return NULL;
}
recording->control = control;
- 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_ref(options, +1);
+ recording->options = options;
recording->state = STASIS_APP_RECORDING_STATE_QUEUED;
{
@@ -356,7 +370,7 @@
if (old_recording) {
ast_log(LOG_WARNING,
"Recording %s already in progress\n",
- recording->name);
+ recording->options->name);
errno = EEXIST;
return NULL;
}
@@ -380,7 +394,7 @@
const char *stasis_app_recording_get_name(
struct stasis_app_recording *recording)
{
- return recording->name;
+ return recording->options->name;
}
struct stasis_app_recording *stasis_app_recording_find_by_name(const char *name)
@@ -406,8 +420,8 @@
}
json = ast_json_pack("{s: s, s: s, s: s}",
- "name", recording->name,
- "format", recording->format,
+ "name", recording->options->name,
+ "format", recording->options->format,
"state", state_to_string(recording->state));
return ast_json_ref(json);
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=389962&r1=389961&r2=389962
==============================================================================
--- team/dlee/record/res/stasis_http/resource_channels.c (original)
+++ team/dlee/record/res/stasis_http/resource_channels.c Tue May 28 16:27:14 2013
@@ -167,14 +167,14 @@
if (args->skipms < 0) {
stasis_http_response_error(
- response, 500, "Internal Server Error",
+ response, 400, "Bad Request",
"skipms cannot be negative");
return;
}
if (args->offsetms < 0) {
stasis_http_response_error(
- response, 500, "Internal Server Error",
+ response, 400, "Bad Request",
"offsetms cannot be negative");
return;
}
@@ -219,7 +219,8 @@
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 = {};
+ RAII_VAR(struct stasis_app_recording_options *, options, NULL,
+ ao2_cleanup);
RAII_VAR(char *, uri_encoded_name, NULL, ast_free);
size_t uri_name_maxlen;
@@ -245,26 +246,53 @@
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.append = args->append;
- options.terminate_on =
+ options = stasis_app_recording_options_create(args->name, args->format);
+ if (options == NULL) {
+ stasis_http_response_error(
+ response, 500, "Internal Server Error",
+ "Out of memory");
+ }
+ 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 == STASIS_APP_RECORDING_TERMINATE_INVALID) {
+ options->append = args->append;
+ options->beep = args->beep;
+
+ if (options->terminate_on == STASIS_APP_RECORDING_TERMINATE_INVALID) {
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");
+ recording = stasis_app_control_record(control, options);
+ if (recording == NULL) {
+ switch(errno) {
+ case EINVAL:
+ /* While the arguments are invalid, we should have
+ * caught them prior to calling record.
+ */
+ stasis_http_response_error(
+ response, 500, "Internal Server Error",
+ "Error parsing request");
+ break;
+ case EEXIST:
+ stasis_http_response_error(response, 409, "Conflict",
+ "Recording '%s' already in progress",
+ args->name);
+ break;
+ case ENOMEM:
+ stasis_http_response_error(
+ response, 500, "Internal Server Error",
+ "Out of memory");
+ break;
+ default:
+ stasis_http_response_error(
+ response, 500, "Internal Server Error",
+ "Internal Server Error");
+ break;
+ }
return;
}
Modified: team/dlee/record/rest-api-templates/asterisk_processor.py
URL: http://svnview.digium.com/svn/asterisk/team/dlee/record/rest-api-templates/asterisk_processor.py?view=diff&rev=389962&r1=389961&r2=389962
==============================================================================
--- team/dlee/record/rest-api-templates/asterisk_processor.py (original)
+++ team/dlee/record/rest-api-templates/asterisk_processor.py Tue May 28 16:27:14 2013
@@ -125,10 +125,11 @@
#: String conversion functions for string to C type.
convert_mapping = {
- 'const char *': '',
+ 'string': '',
'int': 'atoi',
'long': 'atol',
'double': 'atof',
+ 'boolean': 'ast_true',
}
def process_api(self, resource_api, context):
@@ -182,7 +183,7 @@
# Parameter names are camelcase, Asterisk convention is snake case
parameter.c_name = snakify(parameter.name)
parameter.c_data_type = self.type_mapping[parameter.data_type]
- parameter.c_convert = self.convert_mapping[parameter.c_data_type]
+ parameter.c_convert = self.convert_mapping[parameter.data_type]
# You shouldn't put a space between 'char *' and the variable
if parameter.c_data_type.endswith('*'):
parameter.c_space = ''
@@ -216,7 +217,7 @@
prop.c_name = snakify(prop.name)
if prop.type in self.type_mapping:
prop.c_type = self.type_mapping[prop.type]
- prop.c_convert = self.convert_mapping[prop.c_type]
+ prop.c_convert = self.convert_mapping[prop.type]
else:
prop.c_type = "Property type %s not mappable to a C type" % (prop.type)
prop.c_convert = "Property type %s not mappable to a C conversion" % (prop.type)
Modified: team/dlee/record/rest-api/api-docs/channels.json
URL: http://svnview.digium.com/svn/asterisk/team/dlee/record/rest-api/api-docs/channels.json?view=diff&rev=389962&r1=389961&r2=389962
==============================================================================
--- team/dlee/record/rest-api/api-docs/channels.json (original)
+++ team/dlee/record/rest-api/api-docs/channels.json Tue May 28 16:27:14 2013
@@ -487,7 +487,11 @@
"required": false,
"allowMultiple": false,
"dataType": "int",
- "defaultValue": 0
+ "defaultValue": 0,
+ "allowableValues": {
+ "valueType": "RANGE",
+ "min": 0
+ }
},
{
"name": "maxSilenceSeconds",
@@ -496,7 +500,11 @@
"required": false,
"allowMultiple": false,
"dataType": "int",
- "defaultValue": 0
+ "defaultValue": 0,
+ "allowableValues": {
+ "valueType": "RANGE",
+ "min": 0
+ }
},
{
"name": "append",
@@ -537,6 +545,10 @@
],
"errorResponses": [
{
+ "code": 400,
+ "reason": "Invalid parameters"
+ },
+ {
"code": 404,
"reason": "Channel not found"
},
@@ -546,7 +558,11 @@
},
{
"code": 409,
- "reason": "The channel is currently bridges with other channels."
+ "reason": "The channel is currently bridged with other channels."
+ },
+ {
+ "code": 409,
+ "reason": "A recording with the same name is currently in progress."
}
]
}
More information about the asterisk-commits
mailing list