[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