[asterisk-commits] kmoore: branch 12 r406003 - in /branches/12: res/ res/ari/ rest-api-templates...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Jan 21 08:15:35 CST 2014


Author: kmoore
Date: Tue Jan 21 08:15:21 2014
New Revision: 406003

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=406003
Log:
ARI: Support channel variables in originate

This adds back in support for specifying channel variables during an
originate without compromising the ability to specify query parameters
in the JSON body. This was accomplished by generating the body-parsing
code in a separate function instead of being integrated with the URI
query parameter parsing code such that it could be called by paths with
body parameters. This is transparent to the user of the API and
prevents manual duplication of code or data structures.

(closes issue ASTERISK-23051)
Review: https://reviewboard.asterisk.org/r/3122/
Reported by: Matt Jordan

Added:
    branches/12/rest-api-templates/body_parsing.mustache   (with props)
Modified:
    branches/12/res/ari/resource_applications.h
    branches/12/res/ari/resource_asterisk.h
    branches/12/res/ari/resource_bridges.h
    branches/12/res/ari/resource_channels.c
    branches/12/res/ari/resource_channels.h
    branches/12/res/ari/resource_device_states.h
    branches/12/res/ari/resource_mailboxes.h
    branches/12/res/ari/resource_playbacks.h
    branches/12/res/ari/resource_sounds.h
    branches/12/res/res_ari_applications.c
    branches/12/res/res_ari_asterisk.c
    branches/12/res/res_ari_bridges.c
    branches/12/res/res_ari_channels.c
    branches/12/res/res_ari_device_states.c
    branches/12/res/res_ari_mailboxes.c
    branches/12/res/res_ari_playbacks.c
    branches/12/res/res_ari_sounds.c
    branches/12/rest-api-templates/ari_resource.h.mustache
    branches/12/rest-api-templates/asterisk_processor.py
    branches/12/rest-api-templates/param_parsing.mustache
    branches/12/rest-api-templates/res_ari_resource.c.mustache
    branches/12/rest-api/api-docs/channels.json

Modified: branches/12/res/ari/resource_applications.h
URL: http://svnview.digium.com/svn/asterisk/branches/12/res/ari/resource_applications.h?view=diff&rev=406003&r1=406002&r2=406003
==============================================================================
--- branches/12/res/ari/resource_applications.h (original)
+++ branches/12/res/ari/resource_applications.h Tue Jan 21 08:15:21 2014
@@ -75,6 +75,17 @@
 	char *event_source_parse;
 };
 /*!
+ * \brief Body parsing function for /applications/{applicationName}/subscription.
+ * \param body The JSON body from which to parse parameters.
+ * \param[out] args The args structure to parse into.
+ * \retval zero on success
+ * \retval non-zero on failure
+ */
+int ast_ari_applications_subscribe_parse_body(
+	struct ast_json *body,
+	struct ast_ari_applications_subscribe_args *args);
+
+/*!
  * \brief Subscribe an application to a event source.
  *
  * Returns the state of the application after the subscriptions have changed
@@ -96,6 +107,17 @@
 	char *event_source_parse;
 };
 /*!
+ * \brief Body parsing function for /applications/{applicationName}/subscription.
+ * \param body The JSON body from which to parse parameters.
+ * \param[out] args The args structure to parse into.
+ * \retval zero on success
+ * \retval non-zero on failure
+ */
+int ast_ari_applications_unsubscribe_parse_body(
+	struct ast_json *body,
+	struct ast_ari_applications_unsubscribe_args *args);
+
+/*!
  * \brief Unsubscribe an application from an event source.
  *
  * Returns the state of the application after the subscriptions have changed

Modified: branches/12/res/ari/resource_asterisk.h
URL: http://svnview.digium.com/svn/asterisk/branches/12/res/ari/resource_asterisk.h?view=diff&rev=406003&r1=406002&r2=406003
==============================================================================
--- branches/12/res/ari/resource_asterisk.h (original)
+++ branches/12/res/ari/resource_asterisk.h Tue Jan 21 08:15:21 2014
@@ -49,6 +49,17 @@
 	char *only_parse;
 };
 /*!
+ * \brief Body parsing function for /asterisk/info.
+ * \param body The JSON body from which to parse parameters.
+ * \param[out] args The args structure to parse into.
+ * \retval zero on success
+ * \retval non-zero on failure
+ */
+int ast_ari_asterisk_get_info_parse_body(
+	struct ast_json *body,
+	struct ast_ari_asterisk_get_info_args *args);
+
+/*!
  * \brief Gets Asterisk system information.
  *
  * \param headers HTTP headers
@@ -61,6 +72,17 @@
 	/*! \brief The variable to get */
 	const char *variable;
 };
+/*!
+ * \brief Body parsing function for /asterisk/variable.
+ * \param body The JSON body from which to parse parameters.
+ * \param[out] args The args structure to parse into.
+ * \retval zero on success
+ * \retval non-zero on failure
+ */
+int ast_ari_asterisk_get_global_var_parse_body(
+	struct ast_json *body,
+	struct ast_ari_asterisk_get_global_var_args *args);
+
 /*!
  * \brief Get the value of a global variable.
  *
@@ -77,6 +99,17 @@
 	const char *value;
 };
 /*!
+ * \brief Body parsing function for /asterisk/variable.
+ * \param body The JSON body from which to parse parameters.
+ * \param[out] args The args structure to parse into.
+ * \retval zero on success
+ * \retval non-zero on failure
+ */
+int ast_ari_asterisk_set_global_var_parse_body(
+	struct ast_json *body,
+	struct ast_ari_asterisk_set_global_var_args *args);
+
+/*!
  * \brief Set the value of a global variable.
  *
  * \param headers HTTP headers

Modified: branches/12/res/ari/resource_bridges.h
URL: http://svnview.digium.com/svn/asterisk/branches/12/res/ari/resource_bridges.h?view=diff&rev=406003&r1=406002&r2=406003
==============================================================================
--- branches/12/res/ari/resource_bridges.h (original)
+++ branches/12/res/ari/resource_bridges.h Tue Jan 21 08:15:21 2014
@@ -57,6 +57,17 @@
 	/*! \brief Name to give to the bridge being created. */
 	const char *name;
 };
+/*!
+ * \brief Body parsing function for /bridges.
+ * \param body The JSON body from which to parse parameters.
+ * \param[out] args The args structure to parse into.
+ * \retval zero on success
+ * \retval non-zero on failure
+ */
+int ast_ari_bridges_create_parse_body(
+	struct ast_json *body,
+	struct ast_ari_bridges_create_args *args);
+
 /*!
  * \brief Create a new bridge.
  *
@@ -109,6 +120,17 @@
 	const char *role;
 };
 /*!
+ * \brief Body parsing function for /bridges/{bridgeId}/addChannel.
+ * \param body The JSON body from which to parse parameters.
+ * \param[out] args The args structure to parse into.
+ * \retval zero on success
+ * \retval non-zero on failure
+ */
+int ast_ari_bridges_add_channel_parse_body(
+	struct ast_json *body,
+	struct ast_ari_bridges_add_channel_args *args);
+
+/*!
  * \brief Add a channel to a bridge.
  *
  * \param headers HTTP headers
@@ -128,6 +150,17 @@
 	char *channel_parse;
 };
 /*!
+ * \brief Body parsing function for /bridges/{bridgeId}/removeChannel.
+ * \param body The JSON body from which to parse parameters.
+ * \param[out] args The args structure to parse into.
+ * \retval zero on success
+ * \retval non-zero on failure
+ */
+int ast_ari_bridges_remove_channel_parse_body(
+	struct ast_json *body,
+	struct ast_ari_bridges_remove_channel_args *args);
+
+/*!
  * \brief Remove a channel from a bridge.
  *
  * \param headers HTTP headers
@@ -142,6 +175,17 @@
 	/*! \brief Channel's id */
 	const char *moh_class;
 };
+/*!
+ * \brief Body parsing function for /bridges/{bridgeId}/moh.
+ * \param body The JSON body from which to parse parameters.
+ * \param[out] args The args structure to parse into.
+ * \retval zero on success
+ * \retval non-zero on failure
+ */
+int ast_ari_bridges_start_moh_parse_body(
+	struct ast_json *body,
+	struct ast_ari_bridges_start_moh_args *args);
+
 /*!
  * \brief Play music on hold to a bridge or change the MOH class that is playing.
  *
@@ -178,6 +222,17 @@
 	/*! \brief Number of milliseconds to skip for forward/reverse operations. */
 	int skipms;
 };
+/*!
+ * \brief Body parsing function for /bridges/{bridgeId}/play.
+ * \param body The JSON body from which to parse parameters.
+ * \param[out] args The args structure to parse into.
+ * \retval zero on success
+ * \retval non-zero on failure
+ */
+int ast_ari_bridges_play_parse_body(
+	struct ast_json *body,
+	struct ast_ari_bridges_play_args *args);
+
 /*!
  * \brief Start playback of media on a bridge.
  *
@@ -208,6 +263,17 @@
 	const char *terminate_on;
 };
 /*!
+ * \brief Body parsing function for /bridges/{bridgeId}/record.
+ * \param body The JSON body from which to parse parameters.
+ * \param[out] args The args structure to parse into.
+ * \retval zero on success
+ * \retval non-zero on failure
+ */
+int ast_ari_bridges_record_parse_body(
+	struct ast_json *body,
+	struct ast_ari_bridges_record_args *args);
+
+/*!
  * \brief Start a recording.
  *
  * This records the mixed audio from all channels participating in this bridge.

Modified: branches/12/res/ari/resource_channels.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/res/ari/resource_channels.c?view=diff&rev=406003&r1=406002&r2=406003
==============================================================================
--- branches/12/res/ari/resource_channels.c (original)
+++ branches/12/res/ari/resource_channels.c Tue Jan 21 08:15:21 2014
@@ -687,6 +687,43 @@
 	ast_ari_response_ok(response, ast_json_ref(json));
 }
 
+static int ari_channels_set_channel_var(struct ast_channel *chan,
+	const char *variable, const char *value, struct ast_ari_response *response)
+{
+	if (pbx_builtin_setvar_helper(chan, variable, value)) {
+		ast_ari_response_error(
+			response, 400, "Bad Request",
+			"Unable to set channel variable %s=%s", variable, value);
+		return -1;
+	}
+
+	return 0;
+}
+
+static int ari_channels_set_channel_vars(struct ast_channel *chan,
+	struct ast_json *variables, struct ast_ari_response *response)
+{
+	struct ast_json_iter *i;
+
+	if (!variables) {
+		/* nothing to do */
+		return 0;
+	}
+
+	for (i = ast_json_object_iter(variables); i;
+	     i = ast_json_object_iter_next(variables, i)) {
+		if (ari_channels_set_channel_var(
+			chan, ast_json_object_iter_key(i),
+			ast_json_string_get(ast_json_object_iter_value(i)),
+			response)) {
+			/* response filled in by called function */
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
 void ast_ari_channels_originate(struct ast_variable *headers,
 	struct ast_ari_channels_originate_args *args,
 	struct ast_ari_response *response)
@@ -704,12 +741,19 @@
 	char *stuff;
 	struct ast_channel *chan;
 	RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
+	struct ast_json *variable_list = NULL;
 
 	if (!cap) {
 		ast_ari_response_alloc_failed(response);
 		return;
 	}
 	ast_format_cap_add(cap, ast_format_set(&tmp_fmt, AST_FORMAT_SLINEAR, 0));
+
+	/* Parse any query parameters out of the body parameter */
+	if (args->variables) {
+		ast_ari_channels_originate_parse_body(args->variables, args);
+		variable_list = ast_json_object_get(args->variables, "variables");
+	}
 
 	if (ast_strlen_zero(args->endpoint)) {
 		ast_ari_response_error(response, 400, "Bad Request",
@@ -776,6 +820,11 @@
 		return;
 	}
 
+	if (ari_channels_set_channel_vars(chan, variable_list, response)) {
+		/* response filled in by called function */
+		return;
+	}
+
 	snapshot = ast_channel_snapshot_create(chan);
 	ast_channel_unlock(chan);
 

Modified: branches/12/res/ari/resource_channels.h
URL: http://svnview.digium.com/svn/asterisk/branches/12/res/ari/resource_channels.h?view=diff&rev=406003&r1=406002&r2=406003
==============================================================================
--- branches/12/res/ari/resource_channels.h (original)
+++ branches/12/res/ari/resource_channels.h Tue Jan 21 08:15:21 2014
@@ -68,7 +68,20 @@
 	const char *caller_id;
 	/*! \brief Timeout (in seconds) before giving up dialing, or -1 for no timeout. */
 	int timeout;
-};
+	/*! \brief The 'variables' key in the body object holds variable key/value pairs to set on the channel on creation. Other keys in the body object are interpreted as query parameters. Ex. { 'endpoint': 'SIP/Alice', 'variables': { 'CALLERID(name)': 'Alice' } } */
+	struct ast_json *variables;
+};
+/*!
+ * \brief Body parsing function for /channels.
+ * \param body The JSON body from which to parse parameters.
+ * \param[out] args The args structure to parse into.
+ * \retval zero on success
+ * \retval non-zero on failure
+ */
+int ast_ari_channels_originate_parse_body(
+	struct ast_json *body,
+	struct ast_ari_channels_originate_args *args);
+
 /*!
  * \brief Create a new channel (originate).
  *
@@ -99,6 +112,17 @@
 	/*! \brief Reason for hanging up the channel */
 	const char *reason;
 };
+/*!
+ * \brief Body parsing function for /channels/{channelId}.
+ * \param body The JSON body from which to parse parameters.
+ * \param[out] args The args structure to parse into.
+ * \retval zero on success
+ * \retval non-zero on failure
+ */
+int ast_ari_channels_hangup_parse_body(
+	struct ast_json *body,
+	struct ast_ari_channels_hangup_args *args);
+
 /*!
  * \brief Delete (i.e. hangup) a channel.
  *
@@ -118,6 +142,17 @@
 	/*! \brief The priority to continue to. */
 	int priority;
 };
+/*!
+ * \brief Body parsing function for /channels/{channelId}/continue.
+ * \param body The JSON body from which to parse parameters.
+ * \param[out] args The args structure to parse into.
+ * \retval zero on success
+ * \retval non-zero on failure
+ */
+int ast_ari_channels_continue_in_dialplan_parse_body(
+	struct ast_json *body,
+	struct ast_ari_channels_continue_in_dialplan_args *args);
+
 /*!
  * \brief Exit application; continue execution in the dialplan.
  *
@@ -181,6 +216,17 @@
 	int after;
 };
 /*!
+ * \brief Body parsing function for /channels/{channelId}/dtmf.
+ * \param body The JSON body from which to parse parameters.
+ * \param[out] args The args structure to parse into.
+ * \retval zero on success
+ * \retval non-zero on failure
+ */
+int ast_ari_channels_send_dtmf_parse_body(
+	struct ast_json *body,
+	struct ast_ari_channels_send_dtmf_args *args);
+
+/*!
  * \brief Send provided DTMF to a given channel.
  *
  * \param headers HTTP headers
@@ -196,6 +242,17 @@
 	const char *direction;
 };
 /*!
+ * \brief Body parsing function for /channels/{channelId}/mute.
+ * \param body The JSON body from which to parse parameters.
+ * \param[out] args The args structure to parse into.
+ * \retval zero on success
+ * \retval non-zero on failure
+ */
+int ast_ari_channels_mute_parse_body(
+	struct ast_json *body,
+	struct ast_ari_channels_mute_args *args);
+
+/*!
  * \brief Mute a channel.
  *
  * \param headers HTTP headers
@@ -211,6 +268,17 @@
 	const char *direction;
 };
 /*!
+ * \brief Body parsing function for /channels/{channelId}/mute.
+ * \param body The JSON body from which to parse parameters.
+ * \param[out] args The args structure to parse into.
+ * \retval zero on success
+ * \retval non-zero on failure
+ */
+int ast_ari_channels_unmute_parse_body(
+	struct ast_json *body,
+	struct ast_ari_channels_unmute_args *args);
+
+/*!
  * \brief Unmute a channel.
  *
  * \param headers HTTP headers
@@ -251,6 +319,17 @@
 	/*! \brief Music on hold class to use */
 	const char *moh_class;
 };
+/*!
+ * \brief Body parsing function for /channels/{channelId}/moh.
+ * \param body The JSON body from which to parse parameters.
+ * \param[out] args The args structure to parse into.
+ * \retval zero on success
+ * \retval non-zero on failure
+ */
+int ast_ari_channels_start_moh_parse_body(
+	struct ast_json *body,
+	struct ast_ari_channels_start_moh_args *args);
+
 /*!
  * \brief Play music on hold to a channel.
  *
@@ -315,6 +394,17 @@
 	/*! \brief Number of milliseconds to skip for forward/reverse operations. */
 	int skipms;
 };
+/*!
+ * \brief Body parsing function for /channels/{channelId}/play.
+ * \param body The JSON body from which to parse parameters.
+ * \param[out] args The args structure to parse into.
+ * \retval zero on success
+ * \retval non-zero on failure
+ */
+int ast_ari_channels_play_parse_body(
+	struct ast_json *body,
+	struct ast_ari_channels_play_args *args);
+
 /*!
  * \brief Start playback of media.
  *
@@ -345,6 +435,17 @@
 	const char *terminate_on;
 };
 /*!
+ * \brief Body parsing function for /channels/{channelId}/record.
+ * \param body The JSON body from which to parse parameters.
+ * \param[out] args The args structure to parse into.
+ * \retval zero on success
+ * \retval non-zero on failure
+ */
+int ast_ari_channels_record_parse_body(
+	struct ast_json *body,
+	struct ast_ari_channels_record_args *args);
+
+/*!
  * \brief Start a recording.
  *
  * Record audio from a channel. Note that this will not capture audio sent to the channel. The bridge itself has a record feature if that's what you want.
@@ -361,6 +462,17 @@
 	/*! \brief The channel variable or function to get */
 	const char *variable;
 };
+/*!
+ * \brief Body parsing function for /channels/{channelId}/variable.
+ * \param body The JSON body from which to parse parameters.
+ * \param[out] args The args structure to parse into.
+ * \retval zero on success
+ * \retval non-zero on failure
+ */
+int ast_ari_channels_get_channel_var_parse_body(
+	struct ast_json *body,
+	struct ast_ari_channels_get_channel_var_args *args);
+
 /*!
  * \brief Get the value of a channel variable or function.
  *
@@ -378,6 +490,17 @@
 	/*! \brief The value to set the variable to */
 	const char *value;
 };
+/*!
+ * \brief Body parsing function for /channels/{channelId}/variable.
+ * \param body The JSON body from which to parse parameters.
+ * \param[out] args The args structure to parse into.
+ * \retval zero on success
+ * \retval non-zero on failure
+ */
+int ast_ari_channels_set_channel_var_parse_body(
+	struct ast_json *body,
+	struct ast_ari_channels_set_channel_var_args *args);
+
 /*!
  * \brief Set the value of a channel variable or function.
  *
@@ -400,6 +523,17 @@
 	const char *app_args;
 };
 /*!
+ * \brief Body parsing function for /channels/{channelId}/snoop.
+ * \param body The JSON body from which to parse parameters.
+ * \param[out] args The args structure to parse into.
+ * \retval zero on success
+ * \retval non-zero on failure
+ */
+int ast_ari_channels_snoop_channel_parse_body(
+	struct ast_json *body,
+	struct ast_ari_channels_snoop_channel_args *args);
+
+/*!
  * \brief Start snooping.
  *
  * Snoop (spy/whisper) on a specific channel.

Modified: branches/12/res/ari/resource_device_states.h
URL: http://svnview.digium.com/svn/asterisk/branches/12/res/ari/resource_device_states.h?view=diff&rev=406003&r1=406002&r2=406003
==============================================================================
--- branches/12/res/ari/resource_device_states.h (original)
+++ branches/12/res/ari/resource_device_states.h Tue Jan 21 08:15:21 2014
@@ -71,6 +71,17 @@
 	const char *device_state;
 };
 /*!
+ * \brief Body parsing function for /deviceStates/{deviceName}.
+ * \param body The JSON body from which to parse parameters.
+ * \param[out] args The args structure to parse into.
+ * \retval zero on success
+ * \retval non-zero on failure
+ */
+int ast_ari_device_states_update_parse_body(
+	struct ast_json *body,
+	struct ast_ari_device_states_update_args *args);
+
+/*!
  * \brief Change the state of a device controlled by ARI. (Note - implicitly creates the device state).
  *
  * \param headers HTTP headers

Modified: branches/12/res/ari/resource_mailboxes.h
URL: http://svnview.digium.com/svn/asterisk/branches/12/res/ari/resource_mailboxes.h?view=diff&rev=406003&r1=406002&r2=406003
==============================================================================
--- branches/12/res/ari/resource_mailboxes.h (original)
+++ branches/12/res/ari/resource_mailboxes.h Tue Jan 21 08:15:21 2014
@@ -73,6 +73,17 @@
 	int new_messages;
 };
 /*!
+ * \brief Body parsing function for /mailboxes/{mailboxName}.
+ * \param body The JSON body from which to parse parameters.
+ * \param[out] args The args structure to parse into.
+ * \retval zero on success
+ * \retval non-zero on failure
+ */
+int ast_ari_mailboxes_update_parse_body(
+	struct ast_json *body,
+	struct ast_ari_mailboxes_update_args *args);
+
+/*!
  * \brief Change the state of a mailbox. (Note - implicitly creates the mailbox).
  *
  * \param headers HTTP headers

Modified: branches/12/res/ari/resource_playbacks.h
URL: http://svnview.digium.com/svn/asterisk/branches/12/res/ari/resource_playbacks.h?view=diff&rev=406003&r1=406002&r2=406003
==============================================================================
--- branches/12/res/ari/resource_playbacks.h (original)
+++ branches/12/res/ari/resource_playbacks.h Tue Jan 21 08:15:21 2014
@@ -73,6 +73,17 @@
 	const char *operation;
 };
 /*!
+ * \brief Body parsing function for /playbacks/{playbackId}/control.
+ * \param body The JSON body from which to parse parameters.
+ * \param[out] args The args structure to parse into.
+ * \retval zero on success
+ * \retval non-zero on failure
+ */
+int ast_ari_playbacks_control_parse_body(
+	struct ast_json *body,
+	struct ast_ari_playbacks_control_args *args);
+
+/*!
  * \brief Control a playback.
  *
  * \param headers HTTP headers

Modified: branches/12/res/ari/resource_sounds.h
URL: http://svnview.digium.com/svn/asterisk/branches/12/res/ari/resource_sounds.h?view=diff&rev=406003&r1=406002&r2=406003
==============================================================================
--- branches/12/res/ari/resource_sounds.h (original)
+++ branches/12/res/ari/resource_sounds.h Tue Jan 21 08:15:21 2014
@@ -47,6 +47,17 @@
 	const char *format;
 };
 /*!
+ * \brief Body parsing function for /sounds.
+ * \param body The JSON body from which to parse parameters.
+ * \param[out] args The args structure to parse into.
+ * \retval zero on success
+ * \retval non-zero on failure
+ */
+int ast_ari_sounds_list_parse_body(
+	struct ast_json *body,
+	struct ast_ari_sounds_list_args *args);
+
+/*!
  * \brief List all sounds.
  *
  * \param headers HTTP headers

Modified: branches/12/res/res_ari_applications.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/res/res_ari_applications.c?view=diff&rev=406003&r1=406002&r2=406003
==============================================================================
--- branches/12/res/res_ari_applications.c (original)
+++ branches/12/res/res_ari_applications.c Tue Jan 21 08:15:21 2014
@@ -161,6 +161,44 @@
 fin: __attribute__((unused))
 	return;
 }
+int ast_ari_applications_subscribe_parse_body(
+	struct ast_json *body,
+	struct ast_ari_applications_subscribe_args *args)
+{
+	struct ast_json *field;
+	/* Parse query parameters out of it */
+	field = ast_json_object_get(body, "eventSource");
+	if (field) {
+		/* If they were silly enough to both pass in a query param and a
+		 * JSON body, free up the query value.
+		 */
+		ast_free(args->event_source);
+		if (ast_json_typeof(field) == AST_JSON_ARRAY) {
+			/* Multiple param passed as array */
+			size_t i;
+			args->event_source_count = ast_json_array_size(field);
+			args->event_source = ast_malloc(sizeof(*args->event_source) * args->event_source_count);
+
+			if (!args->event_source) {
+				return -1;
+			}
+
+			for (i = 0; i < args->event_source_count; ++i) {
+				args->event_source[i] = ast_json_string_get(ast_json_array_get(field, i));
+			}
+		} else {
+			/* Multiple param passed as single value */
+			args->event_source_count = 1;
+			args->event_source = ast_malloc(sizeof(*args->event_source) * args->event_source_count);
+			if (!args->event_source) {
+				return -1;
+			}
+			args->event_source[0] = ast_json_string_get(field);
+		}
+	}
+	return 0;
+}
+
 /*!
  * \brief Parameter parsing callback for /applications/{applicationName}/subscription.
  * \param get_params GET parameters in the HTTP request.
@@ -176,7 +214,6 @@
 	struct ast_ari_applications_subscribe_args args = {};
 	struct ast_variable *i;
 	RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
-	struct ast_json *field;
 #if defined(AST_DEVMODE)
 	int is_valid;
 	int code;
@@ -249,37 +286,9 @@
 			goto fin;
 		}
 	}
-	/* Parse query parameters out of it */
-	field = ast_json_object_get(body, "eventSource");
-	if (field) {
-		/* If they were silly enough to both pass in a query param and a
-		 * JSON body, free up the query value.
-		 */
-		ast_free(args.event_source);
-		if (ast_json_typeof(field) == AST_JSON_ARRAY) {
-			/* Multiple param passed as array */
-			size_t i;
-			args.event_source_count = ast_json_array_size(field);
-			args.event_source = ast_malloc(sizeof(*args.event_source) * args.event_source_count);
-
-			if (!args.event_source) {
-				ast_ari_response_alloc_failed(response);
-				goto fin;
-			}
-
-			for (i = 0; i < args.event_source_count; ++i) {
-				args.event_source[i] = ast_json_string_get(ast_json_array_get(field, i));
-			}
-		} else {
-			/* Multiple param passed as single value */
-			args.event_source_count = 1;
-			args.event_source = ast_malloc(sizeof(*args.event_source) * args.event_source_count);
-			if (!args.event_source) {
-				ast_ari_response_alloc_failed(response);
-				goto fin;
-			}
-			args.event_source[0] = ast_json_string_get(field);
-		}
+	if (ast_ari_applications_subscribe_parse_body(body, &args)) {
+		ast_ari_response_alloc_failed(response);
+		goto fin;
 	}
 	ast_ari_applications_subscribe(headers, &args, response);
 #if defined(AST_DEVMODE)
@@ -318,6 +327,44 @@
 	ast_free(args.event_source);
 	return;
 }
+int ast_ari_applications_unsubscribe_parse_body(
+	struct ast_json *body,
+	struct ast_ari_applications_unsubscribe_args *args)
+{
+	struct ast_json *field;
+	/* Parse query parameters out of it */
+	field = ast_json_object_get(body, "eventSource");
+	if (field) {
+		/* If they were silly enough to both pass in a query param and a
+		 * JSON body, free up the query value.
+		 */
+		ast_free(args->event_source);
+		if (ast_json_typeof(field) == AST_JSON_ARRAY) {
+			/* Multiple param passed as array */
+			size_t i;
+			args->event_source_count = ast_json_array_size(field);
+			args->event_source = ast_malloc(sizeof(*args->event_source) * args->event_source_count);
+
+			if (!args->event_source) {
+				return -1;
+			}
+
+			for (i = 0; i < args->event_source_count; ++i) {
+				args->event_source[i] = ast_json_string_get(ast_json_array_get(field, i));
+			}
+		} else {
+			/* Multiple param passed as single value */
+			args->event_source_count = 1;
+			args->event_source = ast_malloc(sizeof(*args->event_source) * args->event_source_count);
+			if (!args->event_source) {
+				return -1;
+			}
+			args->event_source[0] = ast_json_string_get(field);
+		}
+	}
+	return 0;
+}
+
 /*!
  * \brief Parameter parsing callback for /applications/{applicationName}/subscription.
  * \param get_params GET parameters in the HTTP request.
@@ -333,7 +380,6 @@
 	struct ast_ari_applications_unsubscribe_args args = {};
 	struct ast_variable *i;
 	RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
-	struct ast_json *field;
 #if defined(AST_DEVMODE)
 	int is_valid;
 	int code;
@@ -406,37 +452,9 @@
 			goto fin;
 		}
 	}
-	/* Parse query parameters out of it */
-	field = ast_json_object_get(body, "eventSource");
-	if (field) {
-		/* If they were silly enough to both pass in a query param and a
-		 * JSON body, free up the query value.
-		 */
-		ast_free(args.event_source);
-		if (ast_json_typeof(field) == AST_JSON_ARRAY) {
-			/* Multiple param passed as array */
-			size_t i;
-			args.event_source_count = ast_json_array_size(field);
-			args.event_source = ast_malloc(sizeof(*args.event_source) * args.event_source_count);
-
-			if (!args.event_source) {
-				ast_ari_response_alloc_failed(response);
-				goto fin;
-			}
-
-			for (i = 0; i < args.event_source_count; ++i) {
-				args.event_source[i] = ast_json_string_get(ast_json_array_get(field, i));
-			}
-		} else {
-			/* Multiple param passed as single value */
-			args.event_source_count = 1;
-			args.event_source = ast_malloc(sizeof(*args.event_source) * args.event_source_count);
-			if (!args.event_source) {
-				ast_ari_response_alloc_failed(response);
-				goto fin;
-			}
-			args.event_source[0] = ast_json_string_get(field);
-		}
+	if (ast_ari_applications_unsubscribe_parse_body(body, &args)) {
+		ast_ari_response_alloc_failed(response);
+		goto fin;
 	}
 	ast_ari_applications_unsubscribe(headers, &args, response);
 #if defined(AST_DEVMODE)

Modified: branches/12/res/res_ari_asterisk.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/res/res_ari_asterisk.c?view=diff&rev=406003&r1=406002&r2=406003
==============================================================================
--- branches/12/res/res_ari_asterisk.c (original)
+++ branches/12/res/res_ari_asterisk.c Tue Jan 21 08:15:21 2014
@@ -51,6 +51,44 @@
 
 #define MAX_VALS 128
 
+int ast_ari_asterisk_get_info_parse_body(
+	struct ast_json *body,
+	struct ast_ari_asterisk_get_info_args *args)
+{
+	struct ast_json *field;
+	/* Parse query parameters out of it */
+	field = ast_json_object_get(body, "only");
+	if (field) {
+		/* If they were silly enough to both pass in a query param and a
+		 * JSON body, free up the query value.
+		 */
+		ast_free(args->only);
+		if (ast_json_typeof(field) == AST_JSON_ARRAY) {
+			/* Multiple param passed as array */
+			size_t i;
+			args->only_count = ast_json_array_size(field);
+			args->only = ast_malloc(sizeof(*args->only) * args->only_count);
+
+			if (!args->only) {
+				return -1;
+			}
+
+			for (i = 0; i < args->only_count; ++i) {
+				args->only[i] = ast_json_string_get(ast_json_array_get(field, i));
+			}
+		} else {
+			/* Multiple param passed as single value */
+			args->only_count = 1;
+			args->only = ast_malloc(sizeof(*args->only) * args->only_count);
+			if (!args->only) {
+				return -1;
+			}
+			args->only[0] = ast_json_string_get(field);
+		}
+	}
+	return 0;
+}
+
 /*!
  * \brief Parameter parsing callback for /asterisk/info.
  * \param get_params GET parameters in the HTTP request.
@@ -66,7 +104,6 @@
 	struct ast_ari_asterisk_get_info_args args = {};
 	struct ast_variable *i;
 	RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
-	struct ast_json *field;
 #if defined(AST_DEVMODE)
 	int is_valid;
 	int code;
@@ -133,37 +170,9 @@
 			goto fin;
 		}
 	}
-	/* Parse query parameters out of it */
-	field = ast_json_object_get(body, "only");
-	if (field) {
-		/* If they were silly enough to both pass in a query param and a
-		 * JSON body, free up the query value.
-		 */
-		ast_free(args.only);
-		if (ast_json_typeof(field) == AST_JSON_ARRAY) {
-			/* Multiple param passed as array */
-			size_t i;
-			args.only_count = ast_json_array_size(field);
-			args.only = ast_malloc(sizeof(*args.only) * args.only_count);
-
-			if (!args.only) {
-				ast_ari_response_alloc_failed(response);
-				goto fin;
-			}
-
-			for (i = 0; i < args.only_count; ++i) {
-				args.only[i] = ast_json_string_get(ast_json_array_get(field, i));
-			}
-		} else {
-			/* Multiple param passed as single value */
-			args.only_count = 1;
-			args.only = ast_malloc(sizeof(*args.only) * args.only_count);
-			if (!args.only) {
-				ast_ari_response_alloc_failed(response);
-				goto fin;
-			}
-			args.only[0] = ast_json_string_get(field);
-		}
+	if (ast_ari_asterisk_get_info_parse_body(body, &args)) {
+		ast_ari_response_alloc_failed(response);
+		goto fin;
 	}
 	ast_ari_asterisk_get_info(headers, &args, response);
 #if defined(AST_DEVMODE)
@@ -199,6 +208,19 @@
 	ast_free(args.only);
 	return;
 }
+int ast_ari_asterisk_get_global_var_parse_body(
+	struct ast_json *body,
+	struct ast_ari_asterisk_get_global_var_args *args)
+{
+	struct ast_json *field;
+	/* Parse query parameters out of it */
+	field = ast_json_object_get(body, "variable");
+	if (field) {
+		args->variable = ast_json_string_get(field);
+	}
+	return 0;
+}
+
 /*!
  * \brief Parameter parsing callback for /asterisk/variable.
  * \param get_params GET parameters in the HTTP request.
@@ -214,7 +236,6 @@
 	struct ast_ari_asterisk_get_global_var_args args = {};
 	struct ast_variable *i;
 	RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
-	struct ast_json *field;
 #if defined(AST_DEVMODE)
 	int is_valid;
 	int code;
@@ -241,10 +262,9 @@
 			goto fin;
 		}
 	}
-	/* Parse query parameters out of it */
-	field = ast_json_object_get(body, "variable");
-	if (field) {
-		args.variable = ast_json_string_get(field);
+	if (ast_ari_asterisk_get_global_var_parse_body(body, &args)) {
+		ast_ari_response_alloc_failed(response);
+		goto fin;
 	}
 	ast_ari_asterisk_get_global_var(headers, &args, response);
 #if defined(AST_DEVMODE)
@@ -279,6 +299,23 @@
 fin: __attribute__((unused))
 	return;
 }
+int ast_ari_asterisk_set_global_var_parse_body(
+	struct ast_json *body,
+	struct ast_ari_asterisk_set_global_var_args *args)
+{
+	struct ast_json *field;
+	/* Parse query parameters out of it */
+	field = ast_json_object_get(body, "variable");
+	if (field) {
+		args->variable = ast_json_string_get(field);
+	}
+	field = ast_json_object_get(body, "value");
+	if (field) {
+		args->value = ast_json_string_get(field);
+	}
+	return 0;
+}
+
 /*!
  * \brief Parameter parsing callback for /asterisk/variable.
  * \param get_params GET parameters in the HTTP request.
@@ -294,7 +331,6 @@
 	struct ast_ari_asterisk_set_global_var_args args = {};
 	struct ast_variable *i;
 	RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
-	struct ast_json *field;
 #if defined(AST_DEVMODE)
 	int is_valid;
 	int code;
@@ -324,14 +360,9 @@
 			goto fin;
 		}
 	}
-	/* Parse query parameters out of it */
-	field = ast_json_object_get(body, "variable");
-	if (field) {
-		args.variable = ast_json_string_get(field);
-	}
-	field = ast_json_object_get(body, "value");
-	if (field) {
-		args.value = ast_json_string_get(field);
+	if (ast_ari_asterisk_set_global_var_parse_body(body, &args)) {
+		ast_ari_response_alloc_failed(response);
+		goto fin;
 	}
 	ast_ari_asterisk_set_global_var(headers, &args, response);
 #if defined(AST_DEVMODE)

Modified: branches/12/res/res_ari_bridges.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/res/res_ari_bridges.c?view=diff&rev=406003&r1=406002&r2=406003
==============================================================================
--- branches/12/res/res_ari_bridges.c (original)
+++ branches/12/res/res_ari_bridges.c Tue Jan 21 08:15:21 2014
@@ -102,6 +102,23 @@
 fin: __attribute__((unused))
 	return;
 }
+int ast_ari_bridges_create_parse_body(
+	struct ast_json *body,
+	struct ast_ari_bridges_create_args *args)
+{
+	struct ast_json *field;
+	/* Parse query parameters out of it */
+	field = ast_json_object_get(body, "type");
+	if (field) {
+		args->type = ast_json_string_get(field);
+	}
+	field = ast_json_object_get(body, "name");
+	if (field) {
+		args->name = ast_json_string_get(field);
+	}
+	return 0;
+}
+
 /*!
  * \brief Parameter parsing callback for /bridges.
  * \param get_params GET parameters in the HTTP request.
@@ -117,7 +134,6 @@
 	struct ast_ari_bridges_create_args args = {};
 	struct ast_variable *i;
 	RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
-	struct ast_json *field;
 #if defined(AST_DEVMODE)
 	int is_valid;
 	int code;
@@ -147,14 +163,9 @@
 			goto fin;
 		}
 	}
-	/* Parse query parameters out of it */
-	field = ast_json_object_get(body, "type");
-	if (field) {
-		args.type = ast_json_string_get(field);
-	}
-	field = ast_json_object_get(body, "name");
-	if (field) {
-		args.name = ast_json_string_get(field);
+	if (ast_ari_bridges_create_parse_body(body, &args)) {
+		ast_ari_response_alloc_failed(response);
+		goto fin;
 	}
 	ast_ari_bridges_create(headers, &args, response);
 #if defined(AST_DEVMODE)
@@ -306,6 +317,48 @@
 fin: __attribute__((unused))
 	return;
 }
+int ast_ari_bridges_add_channel_parse_body(
+	struct ast_json *body,
+	struct ast_ari_bridges_add_channel_args *args)
+{
+	struct ast_json *field;
+	/* Parse query parameters out of it */
+	field = ast_json_object_get(body, "channel");
+	if (field) {
+		/* If they were silly enough to both pass in a query param and a
+		 * JSON body, free up the query value.
+		 */
+		ast_free(args->channel);
+		if (ast_json_typeof(field) == AST_JSON_ARRAY) {
+			/* Multiple param passed as array */
+			size_t i;
+			args->channel_count = ast_json_array_size(field);
+			args->channel = ast_malloc(sizeof(*args->channel) * args->channel_count);
+
+			if (!args->channel) {
+				return -1;
+			}
+
+			for (i = 0; i < args->channel_count; ++i) {
+				args->channel[i] = ast_json_string_get(ast_json_array_get(field, i));
+			}
+		} else {
+			/* Multiple param passed as single value */
+			args->channel_count = 1;
+			args->channel = ast_malloc(sizeof(*args->channel) * args->channel_count);
+			if (!args->channel) {
+				return -1;
+			}
+			args->channel[0] = ast_json_string_get(field);
+		}
+	}
+	field = ast_json_object_get(body, "role");
+	if (field) {
+		args->role = ast_json_string_get(field);
+	}
+	return 0;
+}
+
 /*!
  * \brief Parameter parsing callback for /bridges/{bridgeId}/addChannel.
  * \param get_params GET parameters in the HTTP request.
@@ -321,7 +374,6 @@
 	struct ast_ari_bridges_add_channel_args args = {};
 	struct ast_variable *i;
 	RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
-	struct ast_json *field;
 #if defined(AST_DEVMODE)
 	int is_valid;
 	int code;
@@ -397,41 +449,9 @@
 			goto fin;
 		}
 	}
-	/* Parse query parameters out of it */
-	field = ast_json_object_get(body, "channel");
-	if (field) {
-		/* If they were silly enough to both pass in a query param and a
-		 * JSON body, free up the query value.
-		 */
-		ast_free(args.channel);
-		if (ast_json_typeof(field) == AST_JSON_ARRAY) {
-			/* Multiple param passed as array */
-			size_t i;
-			args.channel_count = ast_json_array_size(field);
-			args.channel = ast_malloc(sizeof(*args.channel) * args.channel_count);
-
-			if (!args.channel) {
-				ast_ari_response_alloc_failed(response);
-				goto fin;
-			}
-
-			for (i = 0; i < args.channel_count; ++i) {
-				args.channel[i] = ast_json_string_get(ast_json_array_get(field, i));
-			}
-		} else {
-			/* Multiple param passed as single value */
-			args.channel_count = 1;
-			args.channel = ast_malloc(sizeof(*args.channel) * args.channel_count);
-			if (!args.channel) {
-				ast_ari_response_alloc_failed(response);
-				goto fin;
-			}
-			args.channel[0] = ast_json_string_get(field);
-		}
-	}
-	field = ast_json_object_get(body, "role");
-	if (field) {
-		args.role = ast_json_string_get(field);
+	if (ast_ari_bridges_add_channel_parse_body(body, &args)) {
+		ast_ari_response_alloc_failed(response);
+		goto fin;
 	}
 	ast_ari_bridges_add_channel(headers, &args, response);
 #if defined(AST_DEVMODE)
@@ -471,6 +491,44 @@
 	ast_free(args.channel);
 	return;
 }
+int ast_ari_bridges_remove_channel_parse_body(
+	struct ast_json *body,
+	struct ast_ari_bridges_remove_channel_args *args)
+{
+	struct ast_json *field;
+	/* Parse query parameters out of it */
+	field = ast_json_object_get(body, "channel");
+	if (field) {
+		/* If they were silly enough to both pass in a query param and a
+		 * JSON body, free up the query value.
+		 */
+		ast_free(args->channel);
+		if (ast_json_typeof(field) == AST_JSON_ARRAY) {
+			/* Multiple param passed as array */
+			size_t i;
+			args->channel_count = ast_json_array_size(field);
+			args->channel = ast_malloc(sizeof(*args->channel) * args->channel_count);
+
+			if (!args->channel) {
+				return -1;
+			}
+
+			for (i = 0; i < args->channel_count; ++i) {
+				args->channel[i] = ast_json_string_get(ast_json_array_get(field, i));
+			}
+		} else {
+			/* Multiple param passed as single value */
+			args->channel_count = 1;
+			args->channel = ast_malloc(sizeof(*args->channel) * args->channel_count);
+			if (!args->channel) {
+				return -1;
+			}
+			args->channel[0] = ast_json_string_get(field);
+		}
+	}
+	return 0;
+}
+
 /*!
  * \brief Parameter parsing callback for /bridges/{bridgeId}/removeChannel.
  * \param get_params GET parameters in the HTTP request.
@@ -486,7 +544,6 @@
 	struct ast_ari_bridges_remove_channel_args args = {};
 	struct ast_variable *i;

[... 1405 lines stripped ...]



More information about the asterisk-commits mailing list