[asterisk-commits] kharwell: branch 12 r403134 - in /branches/12: include/asterisk/ main/ res/ r...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Sat Nov 23 11:38:32 CST 2013


Author: kharwell
Date: Sat Nov 23 11:38:29 2013
New Revision: 403134

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=403134
Log:
ARI: Implement device state API

Created a data model and implemented functionality for an ARI device state
resource.  The following operations have been added that allow a user to
manipulate an ARI controlled device:

Create/Change the state of an ARI controlled device
PUT    /deviceStates/{deviceName}&{deviceState}

Retrieve all ARI controlled devices
GET    /deviceStates

Retrieve the current state of a device
GET    /deviceStates/{deviceName}

Destroy a device-state controlled by ARI
DELETE /deviceStates/{deviceName}

The ARI controlled device must begin with 'Stasis:'.  An example controlled
device name would be Stasis:Example.  A 'DeviceStateChanged' event has also
been added so that an application can subscribe and receive device change
events.  Any device state, ARI controlled or not, can be subscribed to.

While adding the event, the underlying subscription control mechanism was
refactored so that all current and future resource subscriptions would be
the same.  Each event resource must now register itself in order to be able
to properly handle [un]subscribes.

(issue ASTERISK-22838)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/3025/

Added:
    branches/12/include/asterisk/stasis_app_device_state.h   (with props)
    branches/12/res/ari/resource_device_states.c   (with props)
    branches/12/res/ari/resource_device_states.h   (with props)
    branches/12/res/res_ari_device_states.c   (with props)
    branches/12/res/res_stasis_device_state.c   (with props)
    branches/12/res/res_stasis_device_state.exports.in   (with props)
    branches/12/rest-api/api-docs/deviceStates.json   (with props)
Modified:
    branches/12/include/asterisk/devicestate.h
    branches/12/include/asterisk/stasis_app.h
    branches/12/main/devicestate.c
    branches/12/res/ari.make
    branches/12/res/ari/ari_model_validators.c
    branches/12/res/ari/ari_model_validators.h
    branches/12/res/ari/resource_applications.h
    branches/12/res/res_stasis.c
    branches/12/res/stasis/app.c
    branches/12/res/stasis/app.h
    branches/12/rest-api-templates/ari.make.mustache
    branches/12/rest-api/api-docs/applications.json
    branches/12/rest-api/api-docs/events.json
    branches/12/rest-api/resources.json

Modified: branches/12/include/asterisk/devicestate.h
URL: http://svnview.digium.com/svn/asterisk/branches/12/include/asterisk/devicestate.h?view=diff&rev=403134&r1=403133&r2=403134
==============================================================================
--- branches/12/include/asterisk/devicestate.h (original)
+++ branches/12/include/asterisk/devicestate.h Sat Nov 23 11:38:29 2013
@@ -325,6 +325,15 @@
 struct stasis_message_type *ast_device_state_message_type(void);
 
 /*!
+ * \brief Clear the device from the stasis cache.
+ * \param The device to clear
+ * \retval 0 if successful
+ * \retval -1 nothing to clear
+ * \since 12
+ */
+int ast_device_state_clear_cache(const char *device);
+
+/*!
  * \brief Initialize the device state core
  * \retval 0 Success
  * \retval -1 Failure

Modified: branches/12/include/asterisk/stasis_app.h
URL: http://svnview.digium.com/svn/asterisk/branches/12/include/asterisk/stasis_app.h?view=diff&rev=403134&r1=403133&r2=403134
==============================================================================
--- branches/12/include/asterisk/stasis_app.h (original)
+++ branches/12/include/asterisk/stasis_app.h Sat Nov 23 11:38:29 2013
@@ -111,6 +111,18 @@
  */
 int stasis_app_send(const char *app_name, struct ast_json *message);
 
+/*! \brief Forward declare app */
+struct stasis_app;
+
+/*!
+ * \brief Retrieve an application's name
+ *
+ * \param app An application
+ *
+ * \return The name of the application.
+ */
+const char *stasis_app_name(const struct stasis_app *app);
+
 /*!
  * \brief Return the JSON representation of a Stasis application.
  *
@@ -120,6 +132,102 @@
  * \return \c NULL on error.
  */
 struct ast_json *stasis_app_to_json(const char *app_name);
+
+/*!
+ * \brief Event source information and callbacks.
+ */
+struct stasis_app_event_source {
+	/*! \brief The scheme to match against on [un]subscribes */
+	const char *scheme;
+
+	/*!
+	 * \brief Find an event source data object by the given id/name.
+	 *
+	 * \param app Application
+	 * \param id A unique identifier to search on
+	 *
+	 * \return The data object associated with the id/name.
+	 */
+	void *(*find)(const struct stasis_app *app, const char *id);
+
+	/*!
+	 * \brief Subscribe an application to an event source.
+	 *
+	 * \param app Application
+	 * \param obj an event source data object
+	 *
+	 * \return 0 on success, failure code otherwise
+	 */
+	int (*subscribe)(struct stasis_app *app, void *obj);
+
+	/*!
+	 * \brief Cancel the subscription an app has to an event source.
+	 *
+	 * \param app Application
+	 * \param id a previously subscribed object id
+	 *
+	 * \return 0 on success, failure code otherwise
+	 */
+	int (*unsubscribe)(struct stasis_app *app, const char *id);
+
+	/*!
+	 * \brief Find an event source by the given id/name.
+	 *
+	 * \param app Application
+	 * \param id A unique identifier to check
+	 *
+	 * \return true if id is subscribed, false otherwise.
+	 */
+	int (*is_subscribed)(struct stasis_app *app, const char *id);
+
+	/*!
+	 * \brief Convert event source data to json
+	 *
+	 * \param app Application
+	 * \param id json object to fill
+	 */
+	void (*to_json)(const struct stasis_app *app, struct ast_json *json);
+
+	/*! Next item in the list */
+	AST_LIST_ENTRY(stasis_app_event_source) next;
+};
+
+/*!
+ * \brief Register an application event source.
+ *
+ * \param obj the event source to register
+ */
+void stasis_app_register_event_source(struct stasis_app_event_source *obj);
+
+/*!
+ * \brief Register core event sources.
+ */
+void stasis_app_register_event_sources(void);
+
+/*!
+ * \brief Checks to see if the given object is a core event source
+ *
+ * \note core event sources are currently only endpoint, bridge, and channel.
+ *
+ * \param obj event source object to check
+ *
+ * \return non-zero if core event source, otherwise 0 (false)
+
+ */
+int stasis_app_is_core_event_source(struct stasis_app_event_source *obj);
+
+/*!
+ * \brief Unregister an application event source.
+ *
+ * \param obj the event source to unregister
+ */
+void stasis_app_unregister_event_source(struct stasis_app_event_source *obj);
+
+/*!
+ * \brief Unregister core event sources.
+ */
+void stasis_app_unregister_event_sources(void);
+
 
 /*! \brief Return code for stasis_app_[un]subscribe */
 enum stasis_app_subscribe_res {

Added: branches/12/include/asterisk/stasis_app_device_state.h
URL: http://svnview.digium.com/svn/asterisk/branches/12/include/asterisk/stasis_app_device_state.h?view=auto&rev=403134
==============================================================================
--- branches/12/include/asterisk/stasis_app_device_state.h (added)
+++ branches/12/include/asterisk/stasis_app_device_state.h Sat Nov 23 11:38:29 2013
@@ -1,0 +1,95 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * Kevin Harwell <kharwell 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_DEVICE_STATE_H
+#define _ASTERISK_STASIS_APP_DEVICE_STATE_H
+
+/*! \file
+ *
+ * \brief Stasis Application Device State API. See \ref res_stasis "Stasis
+ * Application API" for detailed documentation.
+ *
+ * \author Kevin Harwell <kharwell at digium.com>
+ * \since 12
+ */
+
+#include "asterisk/app.h"
+#include "asterisk/stasis_app.h"
+
+/*! @{ */
+
+/*!
+ * \brief Convert device state to json.
+ *
+ * \param name the name of the device
+ * \param state the device state
+ * \return JSON representation.
+ * \return \c NULL on error.
+ */
+struct ast_json *stasis_app_device_state_to_json(
+	const char *name, enum ast_device_state state);
+
+/*!
+ * \brief Convert device states to json array.
+ *
+ * \return JSON representation.
+ * \return \c NULL on error.
+ */
+struct ast_json *stasis_app_device_states_to_json(void);
+
+/*! Stasis device state application result codes */
+enum stasis_device_state_result {
+	/*! Application controlled device state is okay */
+	STASIS_DEVICE_STATE_OK,
+	/*! The device name is not application controlled */
+	STASIS_DEVICE_STATE_NOT_CONTROLLED,
+	/*! The application controlled device name is missing */
+	STASIS_DEVICE_STATE_MISSING,
+	/*! The application controlled device is unknown */
+	STASIS_DEVICE_STATE_UNKNOWN,
+	/*! The application controlled device has subscribers */
+	STASIS_DEVICE_STATE_SUBSCRIBERS
+};
+
+/*!
+ * \brief Changes the state of a device controlled by ARI.
+ *
+ * \note The controlled device must be prefixed with 'Stasis:'.
+ * \note Implicitly creates the device state.
+ *
+ * \param name the name of the ARI controlled device
+ * \param value a valid device state value
+ *
+ * \return a stasis device state application result.
+ */
+enum stasis_device_state_result stasis_app_device_state_update(
+	const char *name, const char *value);
+
+/*!
+ * \brief Delete a device controlled by ARI.
+ *
+ * \param name the name of the ARI controlled device
+ *
+ * \returna stasis device state application result.
+ */
+enum stasis_device_state_result stasis_app_device_state_delete(
+	const char *name);
+
+/*! @} */
+
+#endif /* _ASTERISK_STASIS_APP_DEVICE_STATE_H */

Propchange: branches/12/include/asterisk/stasis_app_device_state.h
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: branches/12/include/asterisk/stasis_app_device_state.h
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Rev URL

Propchange: branches/12/include/asterisk/stasis_app_device_state.h
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: branches/12/main/devicestate.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/main/devicestate.c?view=diff&rev=403134&r1=403133&r2=403134
==============================================================================
--- branches/12/main/devicestate.c (original)
+++ branches/12/main/devicestate.c Sat Nov 23 11:38:29 2013
@@ -734,6 +734,22 @@
 	return stasis_topic_pool_get_topic(device_state_topic_pool, device);
 }
 
+int ast_device_state_clear_cache(const char *device)
+{
+	RAII_VAR(struct stasis_message *, cached_msg, NULL, ao2_cleanup);
+	RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
+
+	if (!(cached_msg = stasis_cache_get(ast_device_state_cache(),
+					    ast_device_state_message_type(), device))) {
+		/* nothing to clear */
+		return -1;
+	}
+
+	msg = stasis_cache_clear_create(cached_msg);
+	stasis_publish(ast_device_state_topic(device), msg);
+	return 0;
+}
+
 int ast_publish_device_state_full(
 			const char *device,
 			enum ast_device_state state,

Modified: branches/12/res/ari.make
URL: http://svnview.digium.com/svn/asterisk/branches/12/res/ari.make?view=diff&rev=403134&r1=403133&r2=403134
==============================================================================
--- branches/12/res/ari.make (original)
+++ branches/12/res/ari.make Sat Nov 23 11:38:29 2013
@@ -45,6 +45,10 @@
 
 ari/resource_playbacks.o: _ASTCFLAGS+=$(call MOD_ASTCFLAGS,res_ari_playbacks)
 
+res_ari_device_states.so: ari/resource_device_states.o
+
+ari/resource_device_states.o: _ASTCFLAGS+=$(call MOD_ASTCFLAGS,res_ari_device_states)
+
 res_ari_events.so: ari/resource_events.o
 
 ari/resource_events.o: _ASTCFLAGS+=$(call MOD_ASTCFLAGS,res_ari_events)

Modified: branches/12/res/ari/ari_model_validators.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/res/ari/ari_model_validators.c?view=diff&rev=403134&r1=403133&r2=403134
==============================================================================
--- branches/12/res/ari/ari_model_validators.c (original)
+++ branches/12/res/ari/ari_model_validators.c Sat Nov 23 11:38:29 2013
@@ -1333,6 +1333,60 @@
 	return ast_ari_validate_playback;
 }
 
+int ast_ari_validate_device_state(struct ast_json *json)
+{
+	int res = 1;
+	struct ast_json_iter *iter;
+	int has_name = 0;
+	int has_state = 0;
+
+	for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+		if (strcmp("name", ast_json_object_iter_key(iter)) == 0) {
+			int prop_is_valid;
+			has_name = 1;
+			prop_is_valid = ast_ari_validate_string(
+				ast_json_object_iter_value(iter));
+			if (!prop_is_valid) {
+				ast_log(LOG_ERROR, "ARI DeviceState field name failed validation\n");
+				res = 0;
+			}
+		} else
+		if (strcmp("state", ast_json_object_iter_key(iter)) == 0) {
+			int prop_is_valid;
+			has_state = 1;
+			prop_is_valid = ast_ari_validate_string(
+				ast_json_object_iter_value(iter));
+			if (!prop_is_valid) {
+				ast_log(LOG_ERROR, "ARI DeviceState field state failed validation\n");
+				res = 0;
+			}
+		} else
+		{
+			ast_log(LOG_ERROR,
+				"ARI DeviceState has undocumented field %s\n",
+				ast_json_object_iter_key(iter));
+			res = 0;
+		}
+	}
+
+	if (!has_name) {
+		ast_log(LOG_ERROR, "ARI DeviceState missing required field name\n");
+		res = 0;
+	}
+
+	if (!has_state) {
+		ast_log(LOG_ERROR, "ARI DeviceState missing required field state\n");
+		res = 0;
+	}
+
+	return res;
+}
+
+ari_validator ast_ari_validate_device_state_fn(void)
+{
+	return ast_ari_validate_device_state;
+}
+
 int ast_ari_validate_application_replaced(struct ast_json *json)
 {
 	int res = 1;
@@ -2746,6 +2800,85 @@
 	return ast_ari_validate_channel_varset;
 }
 
+int ast_ari_validate_device_state_changed(struct ast_json *json)
+{
+	int res = 1;
+	struct ast_json_iter *iter;
+	int has_type = 0;
+	int has_application = 0;
+	int has_device_state = 0;
+
+	for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+		if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
+			int prop_is_valid;
+			has_type = 1;
+			prop_is_valid = ast_ari_validate_string(
+				ast_json_object_iter_value(iter));
+			if (!prop_is_valid) {
+				ast_log(LOG_ERROR, "ARI DeviceStateChanged field type failed validation\n");
+				res = 0;
+			}
+		} else
+		if (strcmp("application", ast_json_object_iter_key(iter)) == 0) {
+			int prop_is_valid;
+			has_application = 1;
+			prop_is_valid = ast_ari_validate_string(
+				ast_json_object_iter_value(iter));
+			if (!prop_is_valid) {
+				ast_log(LOG_ERROR, "ARI DeviceStateChanged field application failed validation\n");
+				res = 0;
+			}
+		} else
+		if (strcmp("timestamp", ast_json_object_iter_key(iter)) == 0) {
+			int prop_is_valid;
+			prop_is_valid = ast_ari_validate_date(
+				ast_json_object_iter_value(iter));
+			if (!prop_is_valid) {
+				ast_log(LOG_ERROR, "ARI DeviceStateChanged field timestamp failed validation\n");
+				res = 0;
+			}
+		} else
+		if (strcmp("device_state", ast_json_object_iter_key(iter)) == 0) {
+			int prop_is_valid;
+			has_device_state = 1;
+			prop_is_valid = ast_ari_validate_device_state(
+				ast_json_object_iter_value(iter));
+			if (!prop_is_valid) {
+				ast_log(LOG_ERROR, "ARI DeviceStateChanged field device_state failed validation\n");
+				res = 0;
+			}
+		} else
+		{
+			ast_log(LOG_ERROR,
+				"ARI DeviceStateChanged has undocumented field %s\n",
+				ast_json_object_iter_key(iter));
+			res = 0;
+		}
+	}
+
+	if (!has_type) {
+		ast_log(LOG_ERROR, "ARI DeviceStateChanged missing required field type\n");
+		res = 0;
+	}
+
+	if (!has_application) {
+		ast_log(LOG_ERROR, "ARI DeviceStateChanged missing required field application\n");
+		res = 0;
+	}
+
+	if (!has_device_state) {
+		ast_log(LOG_ERROR, "ARI DeviceStateChanged missing required field device_state\n");
+		res = 0;
+	}
+
+	return res;
+}
+
+ari_validator ast_ari_validate_device_state_changed_fn(void)
+{
+	return ast_ari_validate_device_state_changed;
+}
+
 int ast_ari_validate_endpoint_state_change(struct ast_json *json)
 {
 	int res = 1;
@@ -2887,6 +3020,9 @@
 	if (strcmp("ChannelVarset", discriminator) == 0) {
 		return ast_ari_validate_channel_varset(json);
 	} else
+	if (strcmp("DeviceStateChanged", discriminator) == 0) {
+		return ast_ari_validate_device_state_changed(json);
+	} else
 	if (strcmp("EndpointStateChange", discriminator) == 0) {
 		return ast_ari_validate_endpoint_state_change(json);
 	} else
@@ -3025,6 +3161,9 @@
 	if (strcmp("ChannelVarset", discriminator) == 0) {
 		return ast_ari_validate_channel_varset(json);
 	} else
+	if (strcmp("DeviceStateChanged", discriminator) == 0) {
+		return ast_ari_validate_device_state_changed(json);
+	} else
 	if (strcmp("EndpointStateChange", discriminator) == 0) {
 		return ast_ari_validate_endpoint_state_change(json);
 	} else
@@ -3592,6 +3731,7 @@
 	struct ast_json_iter *iter;
 	int has_bridge_ids = 0;
 	int has_channel_ids = 0;
+	int has_device_names = 0;
 	int has_endpoint_ids = 0;
 	int has_name = 0;
 
@@ -3618,6 +3758,17 @@
 				res = 0;
 			}
 		} else
+		if (strcmp("device_names", ast_json_object_iter_key(iter)) == 0) {
+			int prop_is_valid;
+			has_device_names = 1;
+			prop_is_valid = ast_ari_validate_list(
+				ast_json_object_iter_value(iter),
+				ast_ari_validate_string);
+			if (!prop_is_valid) {
+				ast_log(LOG_ERROR, "ARI Application field device_names failed validation\n");
+				res = 0;
+			}
+		} else
 		if (strcmp("endpoint_ids", ast_json_object_iter_key(iter)) == 0) {
 			int prop_is_valid;
 			has_endpoint_ids = 1;
@@ -3657,6 +3808,11 @@
 		res = 0;
 	}
 
+	if (!has_device_names) {
+		ast_log(LOG_ERROR, "ARI Application missing required field device_names\n");
+		res = 0;
+	}
+
 	if (!has_endpoint_ids) {
 		ast_log(LOG_ERROR, "ARI Application missing required field endpoint_ids\n");
 		res = 0;

Modified: branches/12/res/ari/ari_model_validators.h
URL: http://svnview.digium.com/svn/asterisk/branches/12/res/ari/ari_model_validators.h?view=diff&rev=403134&r1=403133&r2=403134
==============================================================================
--- branches/12/res/ari/ari_model_validators.h (original)
+++ branches/12/res/ari/ari_model_validators.h Sat Nov 23 11:38:29 2013
@@ -481,6 +481,24 @@
 ari_validator ast_ari_validate_playback_fn(void);
 
 /*!
+ * \brief Validator for DeviceState.
+ *
+ * Represents the state of a device.
+ *
+ * \param json JSON object to validate.
+ * \returns True (non-zero) if valid.
+ * \returns False (zero) if invalid.
+ */
+int ast_ari_validate_device_state(struct ast_json *json);
+
+/*!
+ * \brief Function pointer to ast_ari_validate_device_state().
+ *
+ * See \ref ast_ari_model_validators.h for more details.
+ */
+ari_validator ast_ari_validate_device_state_fn(void);
+
+/*!
  * \brief Validator for ApplicationReplaced.
  *
  * Notification that another WebSocket has taken over for an application.
@@ -753,6 +771,24 @@
  * See \ref ast_ari_model_validators.h for more details.
  */
 ari_validator ast_ari_validate_channel_varset_fn(void);
+
+/*!
+ * \brief Validator for DeviceStateChanged.
+ *
+ * Notification that a device state has changed.
+ *
+ * \param json JSON object to validate.
+ * \returns True (non-zero) if valid.
+ * \returns False (zero) if invalid.
+ */
+int ast_ari_validate_device_state_changed(struct ast_json *json);
+
+/*!
+ * \brief Function pointer to ast_ari_validate_device_state_changed().
+ *
+ * See \ref ast_ari_model_validators.h for more details.
+ */
+ari_validator ast_ari_validate_device_state_changed_fn(void);
 
 /*!
  * \brief Validator for EndpointStateChange.
@@ -1052,6 +1088,9 @@
  * - media_uri: string (required)
  * - state: string (required)
  * - target_uri: string (required)
+ * DeviceState
+ * - name: string (required)
+ * - state: string (required)
  * ApplicationReplaced
  * - type: string (required)
  * - application: string (required)
@@ -1143,6 +1182,11 @@
  * - channel: Channel
  * - value: string (required)
  * - variable: string (required)
+ * DeviceStateChanged
+ * - type: string (required)
+ * - application: string (required)
+ * - timestamp: Date
+ * - device_state: DeviceState (required)
  * EndpointStateChange
  * - type: string (required)
  * - application: string (required)
@@ -1187,6 +1231,7 @@
  * Application
  * - bridge_ids: List[string] (required)
  * - channel_ids: List[string] (required)
+ * - device_names: List[string] (required)
  * - endpoint_ids: List[string] (required)
  * - name: string (required)
  */

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=403134&r1=403133&r2=403134
==============================================================================
--- branches/12/res/ari/resource_applications.h (original)
+++ branches/12/res/ari/resource_applications.h Sat Nov 23 11:38:29 2013
@@ -67,7 +67,7 @@
 struct ast_ari_applications_subscribe_args {
 	/*! \brief Application's name */
 	const char *application_name;
-	/*! \brief Array of URI for event source (channel:{channelId}, bridge:{bridgeId}, endpoint:{tech}/{resource} */
+	/*! \brief Array of URI for event source (channel:{channelId}, bridge:{bridgeId}, endpoint:{tech}/{resource}, deviceState:{deviceName} */
 	const char **event_source;
 	/*! \brief Length of event_source array. */
 	size_t event_source_count;
@@ -88,7 +88,7 @@
 struct ast_ari_applications_unsubscribe_args {
 	/*! \brief Application's name */
 	const char *application_name;
-	/*! \brief Array of URI for event source (channel:{channelId}, bridge:{bridgeId}, endpoint:{tech}/{resource} */
+	/*! \brief Array of URI for event source (channel:{channelId}, bridge:{bridgeId}, endpoint:{tech}/{resource}, device_state:{deviceName} */
 	const char **event_source;
 	/*! \brief Length of event_source array. */
 	size_t event_source_count;

Added: branches/12/res/ari/resource_device_states.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/res/ari/resource_device_states.c?view=auto&rev=403134
==============================================================================
--- branches/12/res/ari/resource_device_states.c (added)
+++ branches/12/res/ari/resource_device_states.c Sat Nov 23 11:38:29 2013
@@ -1,0 +1,111 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2012 - 2013, Digium, Inc.
+ *
+ * Kevin Harwell <kharwell 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 /api-docs/deviceStates.{format} implementation- Device state resources
+ *
+ * \author Kevin Harwell <kharwell at digium.com>
+ */
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#include "resource_device_states.h"
+#include "asterisk/stasis_app_device_state.h"
+
+void ast_ari_device_states_list(
+	struct ast_variable *headers,
+	struct ast_ari_device_states_list_args *args,
+	struct ast_ari_response *response)
+{
+	RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
+
+	if (!(json = stasis_app_device_states_to_json())) {
+		ast_ari_response_error(response, 500,
+			"Internal Server Error", "Error building response");
+		return;
+	}
+
+	ast_ari_response_ok(response, json);
+}
+
+void ast_ari_device_states_get(struct ast_variable *headers,
+	struct ast_ari_device_states_get_args *args,
+	struct ast_ari_response *response)
+{
+	RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
+
+	if (!(json = stasis_app_device_state_to_json(
+		      args->device_name, ast_device_state(args->device_name)))) {
+		ast_ari_response_error(response, 500,
+			"Internal Server Error", "Error building response");
+		return;
+	}
+
+	ast_ari_response_ok(response, json);
+}
+
+void ast_ari_device_states_update(struct ast_variable *headers,
+	struct ast_ari_device_states_update_args *args,
+	struct ast_ari_response *response)
+{
+	switch (stasis_app_device_state_update(
+			args->device_name, args->device_state)) {
+	case STASIS_DEVICE_STATE_NOT_CONTROLLED:
+		ast_ari_response_error(response, 409,
+			"Conflict", "Uncontrolled device specified");
+		return;
+	case STASIS_DEVICE_STATE_MISSING:
+		ast_ari_response_error(response, 404,
+			"Not Found", "Device name is missing");
+		return;
+	case STASIS_DEVICE_STATE_UNKNOWN:
+		ast_ari_response_error(response, 500, "Internal Server Error",
+				       "Unknown device");
+		return;
+	case STASIS_DEVICE_STATE_OK:
+	case STASIS_DEVICE_STATE_SUBSCRIBERS: /* shouldn't be returned for update */
+		ast_ari_response_no_content(response);
+	}
+}
+
+void ast_ari_device_states_delete(struct ast_variable *headers,
+	struct ast_ari_device_states_delete_args *args,
+	struct ast_ari_response *response)
+{
+	switch (stasis_app_device_state_delete(args->device_name)) {
+	case STASIS_DEVICE_STATE_NOT_CONTROLLED:
+		ast_ari_response_error(response, 409,
+			"Conflict", "Uncontrolled device specified");
+		return;
+	case STASIS_DEVICE_STATE_MISSING:
+		ast_ari_response_error(response, 404,
+			"Not Found", "Device name is missing");
+		return;
+	case STASIS_DEVICE_STATE_SUBSCRIBERS:
+		ast_ari_response_error(response, 500,
+			"Internal Server Error",
+			"Cannot delete device with subscribers");
+		return;
+	case STASIS_DEVICE_STATE_OK:
+	case STASIS_DEVICE_STATE_UNKNOWN:
+		ast_ari_response_no_content(response);
+	}
+}

Propchange: branches/12/res/ari/resource_device_states.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: branches/12/res/ari/resource_device_states.c
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Rev URL

Propchange: branches/12/res/ari/resource_device_states.c
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: branches/12/res/ari/resource_device_states.h
URL: http://svnview.digium.com/svn/asterisk/branches/12/res/ari/resource_device_states.h?view=auto&rev=403134
==============================================================================
--- branches/12/res/ari/resource_device_states.h (added)
+++ branches/12/res/ari/resource_device_states.h Sat Nov 23 11:38:29 2013
@@ -1,0 +1,95 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2012 - 2013, Digium, Inc.
+ *
+ * Kevin Harwell <kharwell 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 Generated file - declares stubs to be implemented in
+ * res/ari/resource_deviceStates.c
+ *
+ * Device state resources
+ *
+ * \author Kevin Harwell <kharwell at digium.com>
+ */
+
+/*
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ * !!!!!                               DO NOT EDIT                        !!!!!
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ * This file is generated by a mustache template. Please see the original
+ * template in rest-api-templates/ari_resource.h.mustache
+ */
+
+#ifndef _ASTERISK_RESOURCE_DEVICESTATES_H
+#define _ASTERISK_RESOURCE_DEVICESTATES_H
+
+#include "asterisk/ari.h"
+
+/*! \brief Argument struct for ast_ari_device_states_list() */
+struct ast_ari_device_states_list_args {
+};
+/*!
+ * \brief List all ARI controlled device states.
+ *
+ * \param headers HTTP headers
+ * \param args Swagger parameters
+ * \param[out] response HTTP response
+ */
+void ast_ari_device_states_list(struct ast_variable *headers, struct ast_ari_device_states_list_args *args, struct ast_ari_response *response);
+/*! \brief Argument struct for ast_ari_device_states_get() */
+struct ast_ari_device_states_get_args {
+	/*! \brief Name of the device */
+	const char *device_name;
+};
+/*!
+ * \brief Retrieve the current state of a device.
+ *
+ * \param headers HTTP headers
+ * \param args Swagger parameters
+ * \param[out] response HTTP response
+ */
+void ast_ari_device_states_get(struct ast_variable *headers, struct ast_ari_device_states_get_args *args, struct ast_ari_response *response);
+/*! \brief Argument struct for ast_ari_device_states_update() */
+struct ast_ari_device_states_update_args {
+	/*! \brief Name of the device */
+	const char *device_name;
+	/*! \brief Device state value */
+	const char *device_state;
+};
+/*!
+ * \brief Change the state of a device controlled by ARI. (Note - implicitly creates the device state).
+ *
+ * \param headers HTTP headers
+ * \param args Swagger parameters
+ * \param[out] response HTTP response
+ */
+void ast_ari_device_states_update(struct ast_variable *headers, struct ast_ari_device_states_update_args *args, struct ast_ari_response *response);
+/*! \brief Argument struct for ast_ari_device_states_delete() */
+struct ast_ari_device_states_delete_args {
+	/*! \brief Name of the device */
+	const char *device_name;
+};
+/*!
+ * \brief Destroy a device-state controlled by ARI.
+ *
+ * \param headers HTTP headers
+ * \param args Swagger parameters
+ * \param[out] response HTTP response
+ */
+void ast_ari_device_states_delete(struct ast_variable *headers, struct ast_ari_device_states_delete_args *args, struct ast_ari_response *response);
+
+#endif /* _ASTERISK_RESOURCE_DEVICESTATES_H */

Propchange: branches/12/res/ari/resource_device_states.h
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: branches/12/res/ari/resource_device_states.h
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Rev URL

Propchange: branches/12/res/ari/resource_device_states.h
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: branches/12/res/res_ari_device_states.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/res/res_ari_device_states.c?view=auto&rev=403134
==============================================================================
--- branches/12/res/res_ari_device_states.c (added)
+++ branches/12/res/res_ari_device_states.c Sat Nov 23 11:38:29 2013
@@ -1,0 +1,323 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2012 - 2013, Digium, Inc.
+ *
+ * Kevin Harwell <kharwell 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.
+ */
+
+/*
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ * !!!!!                               DO NOT EDIT                        !!!!!
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ * This file is generated by a mustache template. Please see the original
+ * template in rest-api-templates/res_ari_resource.c.mustache
+ */
+
+/*! \file
+ *
+ * \brief Device state resources
+ *
+ * \author Kevin Harwell <kharwell at digium.com>
+ */
+
+/*** MODULEINFO
+	<depend type="module">res_ari</depend>
+	<depend type="module">res_stasis</depend>
+	<support_level>core</support_level>
+ ***/
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#include "asterisk/app.h"
+#include "asterisk/module.h"
+#include "asterisk/stasis_app.h"
+#include "ari/resource_device_states.h"
+#if defined(AST_DEVMODE)
+#include "ari/ari_model_validators.h"
+#endif
+
+#define MAX_VALS 128
+
+/*!
+ * \brief Parameter parsing callback for /deviceStates.
+ * \param get_params GET parameters in the HTTP request.
+ * \param path_vars Path variables extracted from the request.
+ * \param headers HTTP headers.
+ * \param[out] response Response to the HTTP request.
+ */
+static void ast_ari_device_states_list_cb(
+	struct ast_variable *get_params, struct ast_variable *path_vars,
+	struct ast_variable *headers, struct ast_ari_response *response)
+{
+	struct ast_ari_device_states_list_args args = {};
+#if defined(AST_DEVMODE)
+	int is_valid;
+	int code;
+#endif /* AST_DEVMODE */
+
+	ast_ari_device_states_list(headers, &args, response);
+#if defined(AST_DEVMODE)
+	code = response->response_code;
+
+	switch (code) {
+	case 0: /* Implementation is still a stub, or the code wasn't set */
+		is_valid = response->message == NULL;
+		break;
+	case 500: /* Internal Server Error */
+	case 501: /* Not Implemented */
+		is_valid = 1;
+		break;
+	default:
+		if (200 <= code && code <= 299) {
+			is_valid = ast_ari_validate_list(response->message,
+				ast_ari_validate_device_state_fn());
+		} else {
+			ast_log(LOG_ERROR, "Invalid error response %d for /deviceStates\n", code);
+			is_valid = 0;
+		}
+	}
+
+	if (!is_valid) {
+		ast_log(LOG_ERROR, "Response validation failed for /deviceStates\n");
+		ast_ari_response_error(response, 500,
+			"Internal Server Error", "Response validation failed");
+	}
+#endif /* AST_DEVMODE */
+
+fin: __attribute__((unused))
+	return;
+}
+/*!
+ * \brief Parameter parsing callback for /deviceStates/{deviceName}.
+ * \param get_params GET parameters in the HTTP request.
+ * \param path_vars Path variables extracted from the request.
+ * \param headers HTTP headers.
+ * \param[out] response Response to the HTTP request.
+ */
+static void ast_ari_device_states_get_cb(
+	struct ast_variable *get_params, struct ast_variable *path_vars,
+	struct ast_variable *headers, struct ast_ari_response *response)
+{
+	struct ast_ari_device_states_get_args args = {};
+	struct ast_variable *i;
+#if defined(AST_DEVMODE)
+	int is_valid;
+	int code;
+#endif /* AST_DEVMODE */
+
+	for (i = path_vars; i; i = i->next) {
+		if (strcmp(i->name, "deviceName") == 0) {
+			args.device_name = (i->value);
+		} else
+		{}
+	}
+	ast_ari_device_states_get(headers, &args, response);
+#if defined(AST_DEVMODE)
+	code = response->response_code;
+
+	switch (code) {
+	case 0: /* Implementation is still a stub, or the code wasn't set */
+		is_valid = response->message == NULL;
+		break;
+	case 500: /* Internal Server Error */
+	case 501: /* Not Implemented */
+		is_valid = 1;
+		break;
+	default:
+		if (200 <= code && code <= 299) {
+			is_valid = ast_ari_validate_device_state(
+				response->message);
+		} else {
+			ast_log(LOG_ERROR, "Invalid error response %d for /deviceStates/{deviceName}\n", code);
+			is_valid = 0;
+		}
+	}
+
+	if (!is_valid) {
+		ast_log(LOG_ERROR, "Response validation failed for /deviceStates/{deviceName}\n");
+		ast_ari_response_error(response, 500,
+			"Internal Server Error", "Response validation failed");
+	}
+#endif /* AST_DEVMODE */
+
+fin: __attribute__((unused))
+	return;
+}
+/*!
+ * \brief Parameter parsing callback for /deviceStates/{deviceName}.
+ * \param get_params GET parameters in the HTTP request.
+ * \param path_vars Path variables extracted from the request.
+ * \param headers HTTP headers.
+ * \param[out] response Response to the HTTP request.
+ */
+static void ast_ari_device_states_update_cb(
+	struct ast_variable *get_params, struct ast_variable *path_vars,
+	struct ast_variable *headers, struct ast_ari_response *response)
+{
+	struct ast_ari_device_states_update_args args = {};
+	struct ast_variable *i;
+#if defined(AST_DEVMODE)
+	int is_valid;
+	int code;
+#endif /* AST_DEVMODE */
+
+	for (i = get_params; i; i = i->next) {
+		if (strcmp(i->name, "deviceState") == 0) {
+			args.device_state = (i->value);
+		} else
+		{}
+	}
+	for (i = path_vars; i; i = i->next) {
+		if (strcmp(i->name, "deviceName") == 0) {
+			args.device_name = (i->value);
+		} else
+		{}
+	}
+	ast_ari_device_states_update(headers, &args, response);
+#if defined(AST_DEVMODE)
+	code = response->response_code;
+
+	switch (code) {
+	case 0: /* Implementation is still a stub, or the code wasn't set */
+		is_valid = response->message == NULL;
+		break;
+	case 500: /* Internal Server Error */
+	case 501: /* Not Implemented */
+	case 404: /* Device name is missing */
+	case 409: /* Uncontrolled device specified */
+		is_valid = 1;
+		break;
+	default:
+		if (200 <= code && code <= 299) {
+			is_valid = ast_ari_validate_void(
+				response->message);
+		} else {
+			ast_log(LOG_ERROR, "Invalid error response %d for /deviceStates/{deviceName}\n", code);
+			is_valid = 0;
+		}
+	}
+
+	if (!is_valid) {
+		ast_log(LOG_ERROR, "Response validation failed for /deviceStates/{deviceName}\n");
+		ast_ari_response_error(response, 500,
+			"Internal Server Error", "Response validation failed");
+	}
+#endif /* AST_DEVMODE */
+
+fin: __attribute__((unused))
+	return;
+}
+/*!
+ * \brief Parameter parsing callback for /deviceStates/{deviceName}.
+ * \param get_params GET parameters in the HTTP request.
+ * \param path_vars Path variables extracted from the request.
+ * \param headers HTTP headers.
+ * \param[out] response Response to the HTTP request.
+ */
+static void ast_ari_device_states_delete_cb(
+	struct ast_variable *get_params, struct ast_variable *path_vars,
+	struct ast_variable *headers, struct ast_ari_response *response)
+{
+	struct ast_ari_device_states_delete_args args = {};
+	struct ast_variable *i;
+#if defined(AST_DEVMODE)
+	int is_valid;
+	int code;
+#endif /* AST_DEVMODE */
+
+	for (i = path_vars; i; i = i->next) {
+		if (strcmp(i->name, "deviceName") == 0) {
+			args.device_name = (i->value);
+		} else
+		{}
+	}
+	ast_ari_device_states_delete(headers, &args, response);
+#if defined(AST_DEVMODE)
+	code = response->response_code;
+
+	switch (code) {
+	case 0: /* Implementation is still a stub, or the code wasn't set */
+		is_valid = response->message == NULL;
+		break;
+	case 500: /* Internal Server Error */
+	case 501: /* Not Implemented */
+	case 404: /* Device name is missing */
+	case 409: /* Uncontrolled device specified */
+		is_valid = 1;
+		break;
+	default:
+		if (200 <= code && code <= 299) {
+			is_valid = ast_ari_validate_void(
+				response->message);
+		} else {
+			ast_log(LOG_ERROR, "Invalid error response %d for /deviceStates/{deviceName}\n", code);
+			is_valid = 0;
+		}
+	}
+
+	if (!is_valid) {
+		ast_log(LOG_ERROR, "Response validation failed for /deviceStates/{deviceName}\n");
+		ast_ari_response_error(response, 500,
+			"Internal Server Error", "Response validation failed");
+	}
+#endif /* AST_DEVMODE */
+
+fin: __attribute__((unused))
+	return;
+}
+
+/*! \brief REST handler for /api-docs/deviceStates.{format} */
+static struct stasis_rest_handlers deviceStates_deviceName = {
+	.path_segment = "deviceName",
+	.is_wildcard = 1,
+	.callbacks = {
+		[AST_HTTP_GET] = ast_ari_device_states_get_cb,
+		[AST_HTTP_PUT] = ast_ari_device_states_update_cb,
+		[AST_HTTP_DELETE] = ast_ari_device_states_delete_cb,
+	},
+	.num_children = 0,
+	.children = {  }
+};

[... 1965 lines stripped ...]



More information about the asterisk-commits mailing list