[asterisk-commits] kmoore: branch kmoore/stasis-bridging-channel_events r386775 - in /team/kmoor...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Sat Apr 27 22:45:22 CDT 2013


Author: kmoore
Date: Sat Apr 27 22:45:18 2013
New Revision: 386775

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=386775
Log:
Use documentation-based stasis-http event generation

This generates JSON event creation functions from the JSON
documentation describing those events as well as generates
wiki documentation from that information. This prevents the situation
currently encountered in AMI where many events go entirely undocumented
by forcing creation of documentation before the event can be created
and sent.

Added:
    team/kmoore/stasis-bridging-channel_events/rest-api-templates/event_function_decl.mustache   (with props)
Modified:
    team/kmoore/stasis-bridging-channel_events/include/asterisk/stasis_bridging.h
    team/kmoore/stasis-bridging-channel_events/main/stasis_bridging.c
    team/kmoore/stasis-bridging-channel_events/res/res_stasis.c
    team/kmoore/stasis-bridging-channel_events/res/res_stasis_http_events.c
    team/kmoore/stasis-bridging-channel_events/res/stasis_http/resource_events.h
    team/kmoore/stasis-bridging-channel_events/rest-api-templates/asterisk_processor.py
    team/kmoore/stasis-bridging-channel_events/rest-api-templates/res_stasis_http_resource.c.mustache
    team/kmoore/stasis-bridging-channel_events/rest-api-templates/stasis_http_resource.h.mustache
    team/kmoore/stasis-bridging-channel_events/rest-api-templates/swagger_model.py
    team/kmoore/stasis-bridging-channel_events/rest-api/api-docs/events.json

Modified: team/kmoore/stasis-bridging-channel_events/include/asterisk/stasis_bridging.h
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-bridging-channel_events/include/asterisk/stasis_bridging.h?view=diff&rev=386775&r1=386774&r2=386775
==============================================================================
--- team/kmoore/stasis-bridging-channel_events/include/asterisk/stasis_bridging.h (original)
+++ team/kmoore/stasis-bridging-channel_events/include/asterisk/stasis_bridging.h Sat Apr 27 22:45:18 2013
@@ -204,6 +204,13 @@
 void ast_bridge_publish_leave(struct ast_bridge *bridge, struct ast_channel *chan);
 
 /*!
+ * \brief Build a JSON object from a \ref ast_bridge_snapshot.
+ * \return JSON object representing bridge snapshot.
+ * \return \c NULL on error
+ */
+struct ast_json *ast_bridge_snapshot_to_json(const struct ast_bridge_snapshot *snapshot);
+
+/*!
  * \brief Dispose of the stasis bridging topics and message types
  */
 void ast_stasis_bridging_shutdown(void);

Modified: team/kmoore/stasis-bridging-channel_events/main/stasis_bridging.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-bridging-channel_events/main/stasis_bridging.c?view=diff&rev=386775&r1=386774&r2=386775
==============================================================================
--- team/kmoore/stasis-bridging-channel_events/main/stasis_bridging.c (original)
+++ team/kmoore/stasis-bridging-channel_events/main/stasis_bridging.c Sat Apr 27 22:45:18 2013
@@ -145,6 +145,20 @@
 	stasis_publish(ast_bridge_topic(bridge), msg);
 }
 
+static void bridge_publish_state_from_blob(struct ast_bridge_blob *obj)
+{
+	RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
+
+	ast_assert(obj != NULL);
+
+	msg = stasis_message_create(ast_bridge_snapshot_type(), obj->bridge);
+	if (!msg) {
+		return;
+	}
+
+	stasis_publish(stasis_topic_pool_get_topic(bridge_topic_pool, obj->bridge->uniqueid), msg);
+}
+
 struct stasis_message_type *ast_bridge_merge_message_type(void)
 {
 	return bridge_merge_message_type;
@@ -282,8 +296,6 @@
 	RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
 	RAII_VAR(struct ast_json *, enter_json, NULL, ast_json_unref);
 
-	ast_bridge_publish_state(bridge);
-
 	enter_json = ast_json_pack("{s: s}",
 			"type", "enter");
 
@@ -292,15 +304,15 @@
 		return;
 	}
 
+	/* enter blob first, then state */
 	stasis_publish(ast_bridge_topic(bridge), msg);
+	bridge_publish_state_from_blob(stasis_message_data(msg));
 }
 
 void ast_bridge_publish_leave(struct ast_bridge *bridge, struct ast_channel *chan)
 {
 	RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
 	RAII_VAR(struct ast_json *, leave_json, NULL, ast_json_unref);
-
-	ast_bridge_publish_state(bridge);
 
 	leave_json = ast_json_pack("{s: s}",
 			"type", "leave");
@@ -310,7 +322,29 @@
 		return;
 	}
 
+	/* state first, then leave blob (opposite of enter, preserves nesting of events) */
+	bridge_publish_state_from_blob(stasis_message_data(msg));
 	stasis_publish(ast_bridge_topic(bridge), msg);
+}
+
+struct ast_json *ast_bridge_snapshot_to_json(const struct ast_bridge_snapshot *snapshot)
+{
+	RAII_VAR(struct ast_json *, json_chan, NULL, ast_json_unref);
+	int r = 0;
+
+	if (snapshot == NULL) {
+		return NULL;
+	}
+
+	json_chan = ast_json_object_create();
+	if (!json_chan) { ast_log(LOG_ERROR, "Error creating channel json object\n"); return NULL; }
+
+	r = ast_json_object_set(json_chan, "bridge-uniqueid", ast_json_string_create(snapshot->uniqueid));
+	if (r) { ast_log(LOG_ERROR, "Error adding attrib to channel json object\n"); return NULL; }
+	r = ast_json_object_set(json_chan, "bridge-technology", ast_json_string_create(snapshot->technology));
+	if (r) { ast_log(LOG_ERROR, "Error adding attrib to channel json object\n"); return NULL; }
+
+	return ast_json_ref(json_chan);
 }
 
 void ast_stasis_bridging_shutdown(void)

Modified: team/kmoore/stasis-bridging-channel_events/res/res_stasis.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-bridging-channel_events/res/res_stasis.c?view=diff&rev=386775&r1=386774&r2=386775
==============================================================================
--- team/kmoore/stasis-bridging-channel_events/res/res_stasis.c (original)
+++ team/kmoore/stasis-bridging-channel_events/res/res_stasis.c Sat Apr 27 22:45:18 2013
@@ -41,6 +41,7 @@
 #include "asterisk/strings.h"
 #include "asterisk/stasis_message_router.h"
 #include "asterisk/callerid.h"
+#include "stasis_http/resource_events.h"
 
 /*! Time to wait for a frame in the application */
 #define MAX_WAIT_MS 200
@@ -411,43 +412,11 @@
 	return *retval;
 }
 
-static struct ast_json *app_channel_event_create(
-	const char *event_name,
-	const struct ast_channel_snapshot *snapshot,
-	const struct ast_json *extra_info)
-{
-	RAII_VAR(struct ast_json *, message, NULL, ast_json_unref);
-	RAII_VAR(struct ast_json *, event, NULL, ast_json_unref);
-
-	if (extra_info) {
-		event = ast_json_deep_copy(extra_info);
-	} else {
-		event = ast_json_object_create();
-	}
-
-	if (snapshot) {
-		int ret;
-
-		/* Mustn't already have a channel field */
-		ast_assert(ast_json_object_get(event, "channel") == NULL);
-
-		ret = ast_json_object_set(
-			event,
-			"channel", ast_channel_snapshot_to_json(snapshot));
-		if (ret != 0) {
-			return NULL;
-		}
-	}
-
-	message = ast_json_pack("{s: o}", event_name, ast_json_ref(event));
-
-	return ast_json_ref(message);
-}
-
 static int send_start_msg(struct app *app, struct ast_channel *chan,
 			  int argc, char *argv[])
 {
 	RAII_VAR(struct ast_json *, msg, NULL, ast_json_unref);
+	RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
 	RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
 
 	struct ast_json *json_args;
@@ -461,19 +430,13 @@
 		return -1;
 	}
 
-	msg = ast_json_pack("{s: {s: [], s: o}}",
-			    "stasis-start",
-			    "args",
-			    "channel", ast_channel_snapshot_to_json(snapshot));
-
-	if (!msg) {
+	blob = ast_json_pack("{s: []}", "args");
+	if (!blob) {
 		return -1;
 	}
 
 	/* Append arguments to args array */
-	json_args = ast_json_object_get(
-		ast_json_object_get(msg, "stasis-start"),
-		"args");
+	json_args = ast_json_object_get(blob, "args");
 	ast_assert(json_args != NULL);
 	for (i = 0; i < argc; ++i) {
 		int r = ast_json_array_append(json_args,
@@ -484,6 +447,11 @@
 		}
 	}
 
+	msg = stasis_json_event_stasis_start_create(snapshot, blob);
+	if (!msg) {
+		return -1;
+	}
+
 	app_send(app, msg);
 	return 0;
 }
@@ -500,7 +468,8 @@
 	if (snapshot == NULL) {
 		return -1;
 	}
-	msg = app_channel_event_create("stasis-end", snapshot, NULL);
+
+	msg = stasis_json_event_stasis_end_create(snapshot);
 	if (!msg) {
 		return -1;
 	}
@@ -552,27 +521,23 @@
 	struct ast_channel_snapshot *new_snapshot)
 {
 	RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
-	char *event_name = NULL;
+	struct ast_channel_snapshot *snapshot = new_snapshot ? new_snapshot : old_snapshot;
 
 	if (!old_snapshot) {
-		event_name = "channel-event-create";
+		return stasis_json_event_channel_created_create(snapshot);
 	} else if (!new_snapshot) {
-		event_name = "channel-event-destroy";
 		json = ast_json_pack("{s: i, s: s}",
-			"Cause", old_snapshot->hangupcause,
-			"Cause-txt", ast_cause2str(old_snapshot->hangupcause));
+			"Cause", snapshot->hangupcause,
+			"Cause-txt", ast_cause2str(snapshot->hangupcause));
 		if (!json) {
 			return NULL;
 		}
+		return stasis_json_event_channel_destroyed_create(snapshot, json);
 	} else if (old_snapshot->state != new_snapshot->state) {
-		event_name = "channel-event-state";
-	}
-
-	if (!event_name) {
-		return NULL;
-	}
-
-	return app_channel_event_create(event_name, new_snapshot ? new_snapshot : old_snapshot, json);
+		return stasis_json_event_channel_state_change_create(snapshot);
+	}
+
+	return NULL;
 }
 
 static struct ast_json *channel_dialplan(
@@ -602,7 +567,7 @@
 		return NULL;
 	}
 
-	return app_channel_event_create("channel-event-dialplan", new_snapshot, json);
+	return stasis_json_event_channel_dialplan_create(new_snapshot, json);
 }
 
 static struct ast_json *channel_callerid(
@@ -627,7 +592,7 @@
 		return NULL;
 	}
 
-	return app_channel_event_create("channel-event-callerid", new_snapshot, json);
+	return stasis_json_event_channel_caller_id_create(new_snapshot, json);
 }
 
 static struct ast_json *channel_snapshot(
@@ -638,7 +603,7 @@
 		return NULL;
 	}
 
-	return app_channel_event_create("channel-snapshot", new_snapshot, NULL);
+	return stasis_json_event_channel_snapshot_create(new_snapshot);
 }
 
 channel_snapshot_monitor channel_monitors[] = {
@@ -898,10 +863,16 @@
 
 	if (app) {
 		RAII_VAR(struct ast_json *, msg, NULL, ast_json_unref);
+		RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
 		SCOPED_LOCK(app_lock, app, ao2_lock, ao2_unlock);
 
-		msg = app_channel_event_create("application-replaced", NULL, NULL);
-		app->handler(app->data, app_name, msg);
+		blob = ast_json_pack("{s: s}", "application", app_name);
+		if (blob) {
+			msg = stasis_json_event_application_replaced_create(blob);
+			if (msg) {
+				app->handler(app->data, app_name, msg);
+			}
+		}
 
 		app->handler = handler;
 		ao2_cleanup(app->data);
@@ -951,16 +922,22 @@
 		return NULL;
 	}
 
-	return app_channel_event_create("channel-event-dtmf-received", obj->snapshot, extra);
-}
-
-static struct ast_json *handle_blob_generic(struct ast_channel_blob *obj)
-{
-	RAII_VAR(struct ast_str *, event_name, ast_str_create(32), ast_free);
-
-	ast_str_set(&event_name, 0, "channel-event-%s", ast_channel_blob_json_type(obj));
-
-	return app_channel_event_create(ast_str_buffer(event_name), obj->snapshot, obj->blob);
+	return stasis_json_event_channel_dtmf_received_create(obj->snapshot, extra);
+}
+
+static struct ast_json *handle_blob_userevent(struct ast_channel_blob *obj)
+{
+	return stasis_json_event_channel_userevent_create(obj->snapshot, obj->blob);
+}
+
+static struct ast_json *handle_blob_hangup_request(struct ast_channel_blob *obj)
+{
+	return stasis_json_event_channel_hangup_request_create(obj->snapshot, obj->blob);
+}
+
+static struct ast_json *handle_blob_varset(struct ast_channel_blob *obj)
+{
+	return stasis_json_event_channel_varset_create(obj->snapshot, obj->blob);
 }
 
 static void register_blob_handler(const char *blob_type, channel_blob_handler_cb blob_type_handler_cb)
@@ -1014,9 +991,9 @@
 		return AST_MODULE_LOAD_FAILURE;
 	}
 
-	register_blob_handler("userevent", handle_blob_generic);
-	register_blob_handler("hangup_request", handle_blob_generic);
-	register_blob_handler("varset", handle_blob_generic);
+	register_blob_handler("userevent", handle_blob_userevent);
+	register_blob_handler("hangup_request", handle_blob_hangup_request);
+	register_blob_handler("varset", handle_blob_varset);
 	register_blob_handler("dtmf_end", handle_blob_dtmf);
 
 	channel_router = stasis_message_router_create(stasis_caching_get_topic(ast_channel_topic_all_cached()));

Modified: team/kmoore/stasis-bridging-channel_events/res/res_stasis_http_events.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-bridging-channel_events/res/res_stasis_http_events.c?view=diff&rev=386775&r1=386774&r2=386775
==============================================================================
--- team/kmoore/stasis-bridging-channel_events/res/res_stasis_http_events.c (original)
+++ team/kmoore/stasis-bridging-channel_events/res/res_stasis_http_events.c Sat Apr 27 22:45:18 2013
@@ -42,6 +42,8 @@
 
 #include "asterisk/module.h"
 #include "stasis_http/resource_events.h"
+#include "asterisk/stasis_channels.h"
+#include "asterisk/stasis_bridging.h"
 
 /*!
  * \brief Parameter parsing callback for /events.
@@ -76,6 +78,664 @@
 	.children = {  }
 };
 
+struct ast_json *stasis_json_event_channel_userevent_create(
+	struct ast_channel_snapshot *channel_snapshot,
+	struct ast_json *blob
+	)
+{
+	RAII_VAR(struct ast_json *, message, NULL, ast_json_unref);
+	RAII_VAR(struct ast_json *, event, NULL, ast_json_unref);
+	struct ast_json *validator;
+	int ret;
+
+	ast_assert(channel_snapshot != NULL);
+	ast_assert(blob != NULL);
+	ast_assert(ast_json_object_get(blob, "channel") == NULL);
+	ast_assert(ast_json_object_get(blob, "type") == NULL);
+
+	validator = ast_json_object_get(blob, "eventname");
+	if (validator) {
+		/* do validation? XXX */
+	} else {
+		/* fail message generation if the required parameter doesn't exist */
+		return NULL;
+	}
+
+	validator = ast_json_object_get(blob, "Body");
+	if (validator) {
+		/* do validation? XXX */
+	} else {
+		/* fail message generation if the required parameter doesn't exist */
+		return NULL;
+	}
+
+	event = ast_json_deep_copy(blob);
+	if (!event) {
+		return NULL;
+	}
+
+	ret = ast_json_object_set(event,
+		"channel", ast_channel_snapshot_to_json(channel_snapshot));
+	if (ret) {
+		return NULL;
+	}
+
+	message = ast_json_pack("{s: o}", "channel_userevent", ast_json_ref(event));
+	if (!message) {
+		return NULL;
+	}
+
+	return ast_json_ref(message);
+}
+
+struct ast_json *stasis_json_event_bridge_created_create(
+	struct ast_bridge_snapshot *bridge_snapshot
+	)
+{
+	RAII_VAR(struct ast_json *, message, NULL, ast_json_unref);
+	RAII_VAR(struct ast_json *, event, NULL, ast_json_unref);
+	int ret;
+
+	ast_assert(bridge_snapshot != NULL);
+
+	event = ast_json_object_create();
+	if (!event) {
+		return NULL;
+	}
+
+	ret = ast_json_object_set(event,
+		"bridge", ast_bridge_snapshot_to_json(bridge_snapshot));
+	if (ret) {
+		return NULL;
+	}
+
+	message = ast_json_pack("{s: o}", "bridge_created", ast_json_ref(event));
+	if (!message) {
+		return NULL;
+	}
+
+	return ast_json_ref(message);
+}
+
+struct ast_json *stasis_json_event_channel_destroyed_create(
+	struct ast_channel_snapshot *channel_snapshot,
+	struct ast_json *blob
+	)
+{
+	RAII_VAR(struct ast_json *, message, NULL, ast_json_unref);
+	RAII_VAR(struct ast_json *, event, NULL, ast_json_unref);
+	struct ast_json *validator;
+	int ret;
+
+	ast_assert(channel_snapshot != NULL);
+	ast_assert(blob != NULL);
+	ast_assert(ast_json_object_get(blob, "channel") == NULL);
+	ast_assert(ast_json_object_get(blob, "type") == NULL);
+
+	validator = ast_json_object_get(blob, "Cause-txt");
+	if (validator) {
+		/* do validation? XXX */
+	} else {
+		/* fail message generation if the required parameter doesn't exist */
+		return NULL;
+	}
+
+	validator = ast_json_object_get(blob, "Cause");
+	if (validator) {
+		/* do validation? XXX */
+	} else {
+		/* fail message generation if the required parameter doesn't exist */
+		return NULL;
+	}
+
+	event = ast_json_deep_copy(blob);
+	if (!event) {
+		return NULL;
+	}
+
+	ret = ast_json_object_set(event,
+		"channel", ast_channel_snapshot_to_json(channel_snapshot));
+	if (ret) {
+		return NULL;
+	}
+
+	message = ast_json_pack("{s: o}", "channel_destroyed", ast_json_ref(event));
+	if (!message) {
+		return NULL;
+	}
+
+	return ast_json_ref(message);
+}
+
+struct ast_json *stasis_json_event_channel_snapshot_create(
+	struct ast_channel_snapshot *channel_snapshot
+	)
+{
+	RAII_VAR(struct ast_json *, message, NULL, ast_json_unref);
+	RAII_VAR(struct ast_json *, event, NULL, ast_json_unref);
+	int ret;
+
+	ast_assert(channel_snapshot != NULL);
+
+	event = ast_json_object_create();
+	if (!event) {
+		return NULL;
+	}
+
+	ret = ast_json_object_set(event,
+		"channel", ast_channel_snapshot_to_json(channel_snapshot));
+	if (ret) {
+		return NULL;
+	}
+
+	message = ast_json_pack("{s: o}", "channel_snapshot", ast_json_ref(event));
+	if (!message) {
+		return NULL;
+	}
+
+	return ast_json_ref(message);
+}
+
+struct ast_json *stasis_json_event_channel_caller_id_create(
+	struct ast_channel_snapshot *channel_snapshot,
+	struct ast_json *blob
+	)
+{
+	RAII_VAR(struct ast_json *, message, NULL, ast_json_unref);
+	RAII_VAR(struct ast_json *, event, NULL, ast_json_unref);
+	struct ast_json *validator;
+	int ret;
+
+	ast_assert(channel_snapshot != NULL);
+	ast_assert(blob != NULL);
+	ast_assert(ast_json_object_get(blob, "channel") == NULL);
+	ast_assert(ast_json_object_get(blob, "type") == NULL);
+
+	validator = ast_json_object_get(blob, "CallerPresentation-txt");
+	if (validator) {
+		/* do validation? XXX */
+	} else {
+		/* fail message generation if the required parameter doesn't exist */
+		return NULL;
+	}
+
+	validator = ast_json_object_get(blob, "CallerPresentation");
+	if (validator) {
+		/* do validation? XXX */
+	} else {
+		/* fail message generation if the required parameter doesn't exist */
+		return NULL;
+	}
+
+	event = ast_json_deep_copy(blob);
+	if (!event) {
+		return NULL;
+	}
+
+	ret = ast_json_object_set(event,
+		"channel", ast_channel_snapshot_to_json(channel_snapshot));
+	if (ret) {
+		return NULL;
+	}
+
+	message = ast_json_pack("{s: o}", "channel_caller_id", ast_json_ref(event));
+	if (!message) {
+		return NULL;
+	}
+
+	return ast_json_ref(message);
+}
+
+struct ast_json *stasis_json_event_channel_hangup_request_create(
+	struct ast_channel_snapshot *channel_snapshot,
+	struct ast_json *blob
+	)
+{
+	RAII_VAR(struct ast_json *, message, NULL, ast_json_unref);
+	RAII_VAR(struct ast_json *, event, NULL, ast_json_unref);
+	struct ast_json *validator;
+	int ret;
+
+	ast_assert(channel_snapshot != NULL);
+	ast_assert(blob != NULL);
+	ast_assert(ast_json_object_get(blob, "channel") == NULL);
+	ast_assert(ast_json_object_get(blob, "type") == NULL);
+
+	validator = ast_json_object_get(blob, "soft");
+	if (validator) {
+		/* do validation? XXX */
+	}
+
+	validator = ast_json_object_get(blob, "cause");
+	if (validator) {
+		/* do validation? XXX */
+	}
+
+	event = ast_json_deep_copy(blob);
+	if (!event) {
+		return NULL;
+	}
+
+	ret = ast_json_object_set(event,
+		"channel", ast_channel_snapshot_to_json(channel_snapshot));
+	if (ret) {
+		return NULL;
+	}
+
+	message = ast_json_pack("{s: o}", "channel_hangup_request", ast_json_ref(event));
+	if (!message) {
+		return NULL;
+	}
+
+	return ast_json_ref(message);
+}
+
+struct ast_json *stasis_json_event_bridge_destroyed_create(
+	struct ast_bridge_snapshot *bridge_snapshot
+	)
+{
+	RAII_VAR(struct ast_json *, message, NULL, ast_json_unref);
+	RAII_VAR(struct ast_json *, event, NULL, ast_json_unref);
+	int ret;
+
+	ast_assert(bridge_snapshot != NULL);
+
+	event = ast_json_object_create();
+	if (!event) {
+		return NULL;
+	}
+
+	ret = ast_json_object_set(event,
+		"bridge", ast_bridge_snapshot_to_json(bridge_snapshot));
+	if (ret) {
+		return NULL;
+	}
+
+	message = ast_json_pack("{s: o}", "bridge_destroyed", ast_json_ref(event));
+	if (!message) {
+		return NULL;
+	}
+
+	return ast_json_ref(message);
+}
+
+struct ast_json *stasis_json_event_application_replaced_create(
+	struct ast_json *blob
+	)
+{
+	RAII_VAR(struct ast_json *, message, NULL, ast_json_unref);
+	RAII_VAR(struct ast_json *, event, NULL, ast_json_unref);
+	struct ast_json *validator;
+
+	ast_assert(blob != NULL);
+	ast_assert(ast_json_object_get(blob, "type") == NULL);
+
+	validator = ast_json_object_get(blob, "application");
+	if (validator) {
+		/* do validation? XXX */
+	} else {
+		/* fail message generation if the required parameter doesn't exist */
+		return NULL;
+	}
+
+	event = ast_json_deep_copy(blob);
+	if (!event) {
+		return NULL;
+	}
+
+	message = ast_json_pack("{s: o}", "application_replaced", ast_json_ref(event));
+	if (!message) {
+		return NULL;
+	}
+
+	return ast_json_ref(message);
+}
+
+struct ast_json *stasis_json_event_channel_varset_create(
+	struct ast_channel_snapshot *channel_snapshot,
+	struct ast_json *blob
+	)
+{
+	RAII_VAR(struct ast_json *, message, NULL, ast_json_unref);
+	RAII_VAR(struct ast_json *, event, NULL, ast_json_unref);
+	struct ast_json *validator;
+	int ret;
+
+	ast_assert(channel_snapshot != NULL);
+	ast_assert(blob != NULL);
+	ast_assert(ast_json_object_get(blob, "channel") == NULL);
+	ast_assert(ast_json_object_get(blob, "type") == NULL);
+
+	validator = ast_json_object_get(blob, "variable");
+	if (validator) {
+		/* do validation? XXX */
+	} else {
+		/* fail message generation if the required parameter doesn't exist */
+		return NULL;
+	}
+
+	validator = ast_json_object_get(blob, "value");
+	if (validator) {
+		/* do validation? XXX */
+	} else {
+		/* fail message generation if the required parameter doesn't exist */
+		return NULL;
+	}
+
+	event = ast_json_deep_copy(blob);
+	if (!event) {
+		return NULL;
+	}
+
+	ret = ast_json_object_set(event,
+		"channel", ast_channel_snapshot_to_json(channel_snapshot));
+	if (ret) {
+		return NULL;
+	}
+
+	message = ast_json_pack("{s: o}", "channel_varset", ast_json_ref(event));
+	if (!message) {
+		return NULL;
+	}
+
+	return ast_json_ref(message);
+}
+
+struct ast_json *stasis_json_event_channel_left_bridge_create(
+	struct ast_bridge_snapshot *bridge_snapshot,
+	struct ast_channel_snapshot *channel_snapshot
+	)
+{
+	RAII_VAR(struct ast_json *, message, NULL, ast_json_unref);
+	RAII_VAR(struct ast_json *, event, NULL, ast_json_unref);
+	int ret;
+
+	ast_assert(channel_snapshot != NULL);
+	ast_assert(bridge_snapshot != NULL);
+
+	event = ast_json_object_create();
+	if (!event) {
+		return NULL;
+	}
+
+	ret = ast_json_object_set(event,
+		"channel", ast_channel_snapshot_to_json(channel_snapshot));
+	if (ret) {
+		return NULL;
+	}
+
+	ret = ast_json_object_set(event,
+		"bridge", ast_bridge_snapshot_to_json(bridge_snapshot));
+	if (ret) {
+		return NULL;
+	}
+
+	message = ast_json_pack("{s: o}", "channel_left_bridge", ast_json_ref(event));
+	if (!message) {
+		return NULL;
+	}
+
+	return ast_json_ref(message);
+}
+
+struct ast_json *stasis_json_event_channel_created_create(
+	struct ast_channel_snapshot *channel_snapshot
+	)
+{
+	RAII_VAR(struct ast_json *, message, NULL, ast_json_unref);
+	RAII_VAR(struct ast_json *, event, NULL, ast_json_unref);
+	int ret;
+
+	ast_assert(channel_snapshot != NULL);
+
+	event = ast_json_object_create();
+	if (!event) {
+		return NULL;
+	}
+
+	ret = ast_json_object_set(event,
+		"channel", ast_channel_snapshot_to_json(channel_snapshot));
+	if (ret) {
+		return NULL;
+	}
+
+	message = ast_json_pack("{s: o}", "channel_created", ast_json_ref(event));
+	if (!message) {
+		return NULL;
+	}
+
+	return ast_json_ref(message);
+}
+
+struct ast_json *stasis_json_event_stasis_start_create(
+	struct ast_channel_snapshot *channel_snapshot,
+	struct ast_json *blob
+	)
+{
+	RAII_VAR(struct ast_json *, message, NULL, ast_json_unref);
+	RAII_VAR(struct ast_json *, event, NULL, ast_json_unref);
+	struct ast_json *validator;
+	int ret;
+
+	ast_assert(channel_snapshot != NULL);
+	ast_assert(blob != NULL);
+	ast_assert(ast_json_object_get(blob, "channel") == NULL);
+	ast_assert(ast_json_object_get(blob, "type") == NULL);
+
+	validator = ast_json_object_get(blob, "args");
+	if (validator) {
+		/* do validation? XXX */
+	} else {
+		/* fail message generation if the required parameter doesn't exist */
+		return NULL;
+	}
+
+	event = ast_json_deep_copy(blob);
+	if (!event) {
+		return NULL;
+	}
+
+	ret = ast_json_object_set(event,
+		"channel", ast_channel_snapshot_to_json(channel_snapshot));
+	if (ret) {
+		return NULL;
+	}
+
+	message = ast_json_pack("{s: o}", "stasis_start", ast_json_ref(event));
+	if (!message) {
+		return NULL;
+	}
+
+	return ast_json_ref(message);
+}
+
+struct ast_json *stasis_json_event_channel_dialplan_create(
+	struct ast_channel_snapshot *channel_snapshot,
+	struct ast_json *blob
+	)
+{
+	RAII_VAR(struct ast_json *, message, NULL, ast_json_unref);
+	RAII_VAR(struct ast_json *, event, NULL, ast_json_unref);
+	struct ast_json *validator;
+	int ret;
+
+	ast_assert(channel_snapshot != NULL);
+	ast_assert(blob != NULL);
+	ast_assert(ast_json_object_get(blob, "channel") == NULL);
+	ast_assert(ast_json_object_get(blob, "type") == NULL);
+
+	validator = ast_json_object_get(blob, "Application");
+	if (validator) {
+		/* do validation? XXX */
+	} else {
+		/* fail message generation if the required parameter doesn't exist */
+		return NULL;
+	}
+
+	validator = ast_json_object_get(blob, "ApplicationData");
+	if (validator) {
+		/* do validation? XXX */
+	} else {
+		/* fail message generation if the required parameter doesn't exist */
+		return NULL;
+	}
+
+	event = ast_json_deep_copy(blob);
+	if (!event) {
+		return NULL;
+	}
+
+	ret = ast_json_object_set(event,
+		"channel", ast_channel_snapshot_to_json(channel_snapshot));
+	if (ret) {
+		return NULL;
+	}
+
+	message = ast_json_pack("{s: o}", "channel_dialplan", ast_json_ref(event));
+	if (!message) {
+		return NULL;
+	}
+
+	return ast_json_ref(message);
+}
+
+struct ast_json *stasis_json_event_channel_state_change_create(
+	struct ast_channel_snapshot *channel_snapshot
+	)
+{
+	RAII_VAR(struct ast_json *, message, NULL, ast_json_unref);
+	RAII_VAR(struct ast_json *, event, NULL, ast_json_unref);
+	int ret;
+
+	ast_assert(channel_snapshot != NULL);
+
+	event = ast_json_object_create();
+	if (!event) {
+		return NULL;
+	}
+
+	ret = ast_json_object_set(event,
+		"channel", ast_channel_snapshot_to_json(channel_snapshot));
+	if (ret) {
+		return NULL;
+	}
+
+	message = ast_json_pack("{s: o}", "channel_state_change", ast_json_ref(event));
+	if (!message) {
+		return NULL;
+	}
+
+	return ast_json_ref(message);
+}
+
+struct ast_json *stasis_json_event_channel_entered_bridge_create(
+	struct ast_bridge_snapshot *bridge_snapshot,
+	struct ast_channel_snapshot *channel_snapshot
+	)
+{
+	RAII_VAR(struct ast_json *, message, NULL, ast_json_unref);
+	RAII_VAR(struct ast_json *, event, NULL, ast_json_unref);
+	int ret;
+
+	ast_assert(channel_snapshot != NULL);
+	ast_assert(bridge_snapshot != NULL);
+
+	event = ast_json_object_create();
+	if (!event) {
+		return NULL;
+	}
+
+	ret = ast_json_object_set(event,
+		"channel", ast_channel_snapshot_to_json(channel_snapshot));
+	if (ret) {
+		return NULL;
+	}
+
+	ret = ast_json_object_set(event,
+		"bridge", ast_bridge_snapshot_to_json(bridge_snapshot));
+	if (ret) {
+		return NULL;
+	}
+
+	message = ast_json_pack("{s: o}", "channel_entered_bridge", ast_json_ref(event));
+	if (!message) {
+		return NULL;
+	}
+
+	return ast_json_ref(message);
+}
+
+struct ast_json *stasis_json_event_channel_dtmf_received_create(
+	struct ast_channel_snapshot *channel_snapshot,
+	struct ast_json *blob
+	)
+{
+	RAII_VAR(struct ast_json *, message, NULL, ast_json_unref);
+	RAII_VAR(struct ast_json *, event, NULL, ast_json_unref);
+	struct ast_json *validator;
+	int ret;
+
+	ast_assert(channel_snapshot != NULL);
+	ast_assert(blob != NULL);
+	ast_assert(ast_json_object_get(blob, "channel") == NULL);
+	ast_assert(ast_json_object_get(blob, "type") == NULL);
+
+	validator = ast_json_object_get(blob, "digit");
+	if (validator) {
+		/* do validation? XXX */
+	} else {
+		/* fail message generation if the required parameter doesn't exist */
+		return NULL;
+	}
+
+	event = ast_json_deep_copy(blob);
+	if (!event) {
+		return NULL;
+	}
+
+	ret = ast_json_object_set(event,
+		"channel", ast_channel_snapshot_to_json(channel_snapshot));
+	if (ret) {
+		return NULL;
+	}
+
+	message = ast_json_pack("{s: o}", "channel_dtmf_received", ast_json_ref(event));
+	if (!message) {
+		return NULL;
+	}
+
+	return ast_json_ref(message);
+}
+
+struct ast_json *stasis_json_event_stasis_end_create(
+	struct ast_channel_snapshot *channel_snapshot
+	)
+{
+	RAII_VAR(struct ast_json *, message, NULL, ast_json_unref);
+	RAII_VAR(struct ast_json *, event, NULL, ast_json_unref);
+	int ret;
+
+	ast_assert(channel_snapshot != NULL);
+
+	event = ast_json_object_create();
+	if (!event) {
+		return NULL;
+	}
+
+	ret = ast_json_object_set(event,
+		"channel", ast_channel_snapshot_to_json(channel_snapshot));
+	if (ret) {
+		return NULL;
+	}
+
+	message = ast_json_pack("{s: o}", "stasis_end", ast_json_ref(event));
+	if (!message) {
+		return NULL;
+	}
+
+	return ast_json_ref(message);
+}
+
 static int load_module(void)
 {
 	return stasis_http_add_handler(&events);

Modified: team/kmoore/stasis-bridging-channel_events/res/stasis_http/resource_events.h
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-bridging-channel_events/res/stasis_http/resource_events.h?view=diff&rev=386775&r1=386774&r2=386775
==============================================================================
--- team/kmoore/stasis-bridging-channel_events/res/stasis_http/resource_events.h (original)
+++ team/kmoore/stasis-bridging-channel_events/res/stasis_http/resource_events.h Sat Apr 27 22:45:18 2013
@@ -55,42 +55,301 @@
  */
 void stasis_http_event_websocket(struct ast_variable *headers, struct ast_event_websocket_args *args, struct stasis_http_response *response);
 
+struct ast_channel_snapshot;
+struct ast_bridge_snapshot;
+
+/*!
+ * \brief Channel changed Caller ID.
+ *
+ * \param channel The channel that signaled the user event.
+ * \param blob JSON blob containing the following parameters:
+ * - eventname: string - The name of the user event. (required)
+ * - Body: string - The additional body parameters for the user event. (required)
+ *
+ * \retval NULL on error
+ * \retval JSON (ast_json) describing the event
+ */
+struct ast_json *stasis_json_event_channel_userevent_create(
+	struct ast_channel_snapshot *channel_snapshot,
+	struct ast_json *blob
+	);
+
+/*!
+ * \brief Notification that a bridge has been created.
+ *
+ * \param bridge The bridge to be used to generate this event
+ *
+ * \retval NULL on error
+ * \retval JSON (ast_json) describing the event
+ */
+struct ast_json *stasis_json_event_bridge_created_create(
+	struct ast_bridge_snapshot *bridge_snapshot
+	);
+
+/*!
+ * \brief Notification that a channel has been destroyed.
+ *
+ * \param channel The channel to be used to generate this event
+ * \param blob JSON blob containing the following parameters:
+ * - Cause-txt: string - Text representation of the cause of the hangup (required)
+ * - Cause: integer - Integer representation of the cause of the hangup (required)
+ *
+ * \retval NULL on error
+ * \retval JSON (ast_json) describing the event
+ */
+struct ast_json *stasis_json_event_channel_destroyed_create(
+	struct ast_channel_snapshot *channel_snapshot,
+	struct ast_json *blob
+	);
+
+/*!
+ * \brief Some part of channel state changed.
+ *
+ * \param channel The channel to be used to generate this event
+ *
+ * \retval NULL on error
+ * \retval JSON (ast_json) describing the event
+ */
+struct ast_json *stasis_json_event_channel_snapshot_create(
+	struct ast_channel_snapshot *channel_snapshot
+	);
+
+/*!
+ * \brief Channel changed Caller ID.
+ *
+ * \param channel The channel that changed Caller ID.
+ * \param blob JSON blob containing the following parameters:
+ * - CallerPresentation-txt: string - The text representation of the Caller Presentation value. (required)
+ * - CallerPresentation: integer - The integer representation of the Caller Presentation value. (required)
+ *
+ * \retval NULL on error
+ * \retval JSON (ast_json) describing the event
+ */
+struct ast_json *stasis_json_event_channel_caller_id_create(
+	struct ast_channel_snapshot *channel_snapshot,
+	struct ast_json *blob
+	);
+
+/*!
+ * \brief Channel changed Caller ID.
+ *
+ * \param channel The channel on which the hangup was requested.
+ * \param blob JSON blob containing the following parameters:
+ * - soft: integer - Whether the hangup request was a soft hangup request. 
+ * - cause: integer - Integer representation of the cause of the hangup 
+ *
+ * \retval NULL on error
+ * \retval JSON (ast_json) describing the event
+ */
+struct ast_json *stasis_json_event_channel_hangup_request_create(
+	struct ast_channel_snapshot *channel_snapshot,
+	struct ast_json *blob
+	);
+
+/*!
+ * \brief Notification that a bridge has been destroyed.
+ *
+ * \param bridge The bridge to be used to generate this event
+ *
+ * \retval NULL on error
+ * \retval JSON (ast_json) describing the event
+ */
+struct ast_json *stasis_json_event_bridge_destroyed_create(
+	struct ast_bridge_snapshot *bridge_snapshot
+	);
+
+/*!
+ * \brief Notification that another WebSocket has taken over for an application.
+ *
+ * \param blob JSON blob containing the following parameters:
+ * - application: string (required)
+ *
+ * \retval NULL on error
+ * \retval JSON (ast_json) describing the event
+ */
+struct ast_json *stasis_json_event_application_replaced_create(
+	struct ast_json *blob
+	);
+
+/*!
+ * \brief Channel variable changed.
+ *
+ * \param channel The channel on which the variable was set.
+ * \param blob JSON blob containing the following parameters:
+ * - variable: string - The variable that changed. (required)
+ * - value: string - The new value of the variable. (required)
+ *
+ * \retval NULL on error
+ * \retval JSON (ast_json) describing the event
+ */
+struct ast_json *stasis_json_event_channel_varset_create(
+	struct ast_channel_snapshot *channel_snapshot,
+	struct ast_json *blob
+	);
+
+/*!
+ * \brief Notification that a channel has left a bridge.
+ *
+ * \param channel The channel to be used to generate this event
+ * \param bridge The bridge to be used to generate this event
+ *
+ * \retval NULL on error
+ * \retval JSON (ast_json) describing the event
+ */
+struct ast_json *stasis_json_event_channel_left_bridge_create(
+	struct ast_bridge_snapshot *bridge_snapshot,
+	struct ast_channel_snapshot *channel_snapshot
+	);
+
+/*!
+ * \brief Notification that a channel has been created.
+ *
+ * \param channel The channel to be used to generate this event
+ *
+ * \retval NULL on error
+ * \retval JSON (ast_json) describing the event
+ */
+struct ast_json *stasis_json_event_channel_created_create(
+	struct ast_channel_snapshot *channel_snapshot
+	);
+
+/*!
+ * \brief Notification that a channel has entered a Stasis appliction.
+ *
+ * \param channel The channel to be used to generate this event
+ * \param blob JSON blob containing the following parameters:
+ * - args: List[string] - Arguments to the application (required)
+ *
+ * \retval NULL on error
+ * \retval JSON (ast_json) describing the event
+ */
+struct ast_json *stasis_json_event_stasis_start_create(
+	struct ast_channel_snapshot *channel_snapshot,
+	struct ast_json *blob
+	);
+
+/*!
+ * \brief Channel changed location in the dialplan.
+ *
+ * \param channel The channel that changed dialplan location.
+ * \param blob JSON blob containing the following parameters:
+ * - Application: string - The application that the channel is currently in. (required)
+ * - ApplicationData: string - The data that was passed to the application when it was invoked. (required)
+ *
+ * \retval NULL on error
+ * \retval JSON (ast_json) describing the event
+ */
+struct ast_json *stasis_json_event_channel_dialplan_create(
+	struct ast_channel_snapshot *channel_snapshot,
+	struct ast_json *blob
+	);
+
+/*!
+ * \brief Notification of a channel's state change.
+ *
+ * \param channel The channel to be used to generate this event
+ *
+ * \retval NULL on error
+ * \retval JSON (ast_json) describing the event
+ */
+struct ast_json *stasis_json_event_channel_state_change_create(
+	struct ast_channel_snapshot *channel_snapshot
+	);
+
+/*!
+ * \brief Notification that a channel has entered a bridge.
+ *
+ * \param channel The channel to be used to generate this event
+ * \param bridge The bridge to be used to generate this event
+ *
+ * \retval NULL on error
+ * \retval JSON (ast_json) describing the event
+ */
+struct ast_json *stasis_json_event_channel_entered_bridge_create(
+	struct ast_bridge_snapshot *bridge_snapshot,
+	struct ast_channel_snapshot *channel_snapshot
+	);
+
+/*!
+ * \brief DTMF received on a channel.
+ *
+ * \param channel The channel on which DTMF was received
+ * \param blob JSON blob containing the following parameters:
+ * - digit: string - DTMF digit received (0-9, A-E, # or *) (required)
+ *
+ * \retval NULL on error
+ * \retval JSON (ast_json) describing the event
+ */
+struct ast_json *stasis_json_event_channel_dtmf_received_create(
+	struct ast_channel_snapshot *channel_snapshot,
+	struct ast_json *blob
+	);
+
+/*!
+ * \brief Notification that a channel has left a Stasis appliction.
+ *
+ * \param channel The channel to be used to generate this event
+ *
+ * \retval NULL on error
+ * \retval JSON (ast_json) describing the event
+ */
+struct ast_json *stasis_json_event_stasis_end_create(
+	struct ast_channel_snapshot *channel_snapshot
+	);
+
 /*
  * JSON models
  *
- * DtmfReceived
- * - digit: string 
- * - channel: Channel 
- * BridgeCreated
- * - bridge: Bridge 
- * BridgeDestroyed
- * - bridge: Bridge 
- * ApplicationReplaced
- * - application: string 
- * ChannelLeftBridge
- * - bridge: Bridge 
- * - channel: Channel 
- * StasisStart
- * - args: List[string] 
- * - channel_info: Channel 
- * StasisEnd
- * - channel_info: Channel 
- * ChannelStateChange
- * - channel_info: Channel 
- * ChannelEnteredBridge
- * - bridge: Bridge 
- * - channel: Channel 
- * Event
- * - stasis_start: StasisStart 
- * - channel_entered_bridge: ChannelEnteredBridge 
- * - channel_left_bridge: ChannelLeftBridge 
- * - application_replaced: ApplicationReplaced 
- * - channel_state_change: ChannelStateChange 
- * - bridge_created: BridgeCreated 
+ * ChannelUserevent (channel_userevent)
+ * - channel - The channel that signaled the user event.
+ * - eventname: string (required)
+ * - Body: string (required)
+ * BridgeCreated (bridge_created)
+ * - bridge - of the bridge variety
+ * ChannelDestroyed (channel_destroyed)
+ * - channel - of the channel variety
+ * - Cause-txt: string (required)
+ * - Cause: integer (required)
+ * ChannelSnapshot (channel_snapshot)
+ * - channel - of the channel variety
+ * ChannelCallerId (channel_caller_id)
+ * - channel - The channel that changed Caller ID.
+ * - CallerPresentation-txt: string (required)
+ * - CallerPresentation: integer (required)
+ * ChannelHangupRequest (channel_hangup_request)
+ * - channel - The channel on which the hangup was requested.
+ * - soft: integer 
+ * - cause: integer 
+ * BridgeDestroyed (bridge_destroyed)
+ * - bridge - of the bridge variety
+ * ApplicationReplaced (application_replaced)
  * - application: string (required)
- * - stasis_end: StasisEnd 
- * - dtmf_received: DtmfReceived 
- * - bridge_destroyed: BridgeDestroyed 
+ * ChannelVarset (channel_varset)
+ * - channel - The channel on which the variable was set.
+ * - variable: string (required)
+ * - value: string (required)
+ * ChannelLeftBridge (channel_left_bridge)
+ * - channel - of the channel variety
+ * - bridge - of the bridge variety
+ * ChannelCreated (channel_created)
+ * - channel - of the channel variety
+ * StasisStart (stasis_start)
+ * - channel - of the channel variety
+ * - args: List[string] (required)
+ * ChannelDialplan (channel_dialplan)

[... 642 lines stripped ...]



More information about the asterisk-commits mailing list