[svn-commits] mjordan: branch mjordan/ami-refactoring r388381 - in /team/mjordan/ami-refact...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Fri May 10 15:52:51 CDT 2013


Author: mjordan
Date: Fri May 10 15:52:49 2013
New Revision: 388381

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=388381
Log:
The beginnings of an AMI topic/message type

This patch introduces a generic AMI message type/topic. Several things
need to use this, but at this point I'm not sure if that will include
the system topic/messages or not.

Modified:
    team/mjordan/ami-refactoring/apps/app_chanspy.c
    team/mjordan/ami-refactoring/apps/app_minivm.c
    team/mjordan/ami-refactoring/include/asterisk/json.h
    team/mjordan/ami-refactoring/include/asterisk/manager.h
    team/mjordan/ami-refactoring/main/asterisk.c
    team/mjordan/ami-refactoring/main/json.c
    team/mjordan/ami-refactoring/main/manager.c
    team/mjordan/ami-refactoring/main/manager_mwi.c

Modified: team/mjordan/ami-refactoring/apps/app_chanspy.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/ami-refactoring/apps/app_chanspy.c?view=diff&rev=388381&r1=388380&r2=388381
==============================================================================
--- team/mjordan/ami-refactoring/apps/app_chanspy.c (original)
+++ team/mjordan/ami-refactoring/apps/app_chanspy.c Fri May 10 15:52:49 2013
@@ -518,19 +518,16 @@
 	}
 }
 
-static int pack_channel_into_message(struct ast_channel *chan, const char *role, struct ast_multi_channel_blob *payload)
+static int pack_channel_into_message(struct ast_channel *chan, const char *role,
+									 struct ast_multi_channel_blob *payload)
 {
-	RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
-	struct ast_channel_snapshot *snapshot;
-
-	message = stasis_cache_get(ast_channel_topic_all_cached(),
-			ast_channel_snapshot_type(),
-			ast_channel_uniqueid(chan));
-	if (!message) {
+	RAII_VAR(struct ast_channel_snapshot *, snapshot,
+			ast_channel_get_cached_snapshot(ast_channel_uniqueid(chan)),
+			ao2_cleanup);
+
+	if (!snapshot) {
 		return -1;
 	}
-	snapshot = stasis_message_data(message);
-	ao2_ref(snapshot, +1);
 	ast_multi_channel_blob_add_channel(payload, role, snapshot);
 	return 0;
 }
@@ -542,7 +539,9 @@
  * \start start If non-zero, the spying is starting. Otherwise, the spyer is
  * finishing
  */
-static void publish_chanspy_message(struct ast_channel *spyer, struct ast_channel *spyee, int start)
+static void publish_chanspy_message(struct ast_channel *spyer,
+									struct ast_channel *spyee,
+									int start)
 {
 	RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
 	RAII_VAR(struct ast_multi_channel_blob *, payload, NULL, ao2_cleanup);

Modified: team/mjordan/ami-refactoring/apps/app_minivm.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/ami-refactoring/apps/app_minivm.c?view=diff&rev=388381&r1=388380&r2=388381
==============================================================================
--- team/mjordan/ami-refactoring/apps/app_minivm.c (original)
+++ team/mjordan/ami-refactoring/apps/app_minivm.c Fri May 10 15:52:49 2013
@@ -173,9 +173,8 @@
 #include "asterisk/utils.h"
 #include "asterisk/linkedlists.h"
 #include "asterisk/callerid.h"
-#include "asterisk/event.h"
 #include "asterisk/stasis.h"
-#include "asterisk/stasis_channels.h"
+#include "asterisk/json.h"
 
 /*** DOCUMENTATION
 <application name="MinivmRecord" language="en_US">
@@ -1785,15 +1784,6 @@
 	int res = 0;
 	char oldlocale[100];
 	const char *counter;
-	RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
-	RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
-	RAII_VAR(struct ast_mwi_state *, mwi_state, NULL, ao2_cleanup);
-	RAII_VAR(struct stasis_message *, chan_message,
-		stasis_cache_get(ast_channel_topic_all_cached(),
-				ast_channel_snapshot_type(),
-				ast_channel_uniqueid(chan)),
-		ao2_cleanup);
-	struct stasis_topic *mailbox_specific_topic;
 
 	if (!ast_strlen_zero(vmu->attachfmt)) {
 		if (strstr(format, vmu->attachfmt)) {
@@ -1853,41 +1843,8 @@
 		res = sendmail(etemplate, vmu, cidnum, cidname, filename, messageformat, duration, etemplate->attachment, MVM_MESSAGE_PAGE, counter);
 	}
 
-	blob = ast_json_pack("{s: s, s: s, s: s}",
-			     "type", "minivm",
-			     "action", "SentNotification",
-			     "counter", counter);
-	if (!blob) {
-		res = 1;
-		goto notify_cleanup;
-	}
-
-	mwi_state = ast_mwi_create(vmu->username, vmu->domain);
-	if (!mwi_state) {
-		res = 1;
-		goto notify_cleanup;
-	}
-
-	if (chan_message) {
-		mwi_state->snapshot = stasis_message_data(chan_message);
-		ao2_ref(mwi_state->snapshot, +1);
-	}
-
-	msg = ast_mwi_blob_create(mwi_state, blob);
-	if (!msg) {
-		res = 1;
-		goto notify_cleanup;
-	}
-	mailbox_specific_topic = ast_mwi_topic(mwi_state->uniqueid);
-	if (!mailbox_specific_topic) {
-		res = 1;
-		goto notify_cleanup;
-	}
-	stasis_publish(mailbox_specific_topic, msg);
-
 	run_externnotify(chan, vmu);		/* Run external notification */
 
-notify_cleanup:
 	if (etemplate->locale) {
 		setlocale(LC_TIME, oldlocale); /* Rest to old locale */
 	}

Modified: team/mjordan/ami-refactoring/include/asterisk/json.h
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/ami-refactoring/include/asterisk/json.h?view=diff&rev=388381&r1=388380&r2=388381
==============================================================================
--- team/mjordan/ami-refactoring/include/asterisk/json.h (original)
+++ team/mjordan/ami-refactoring/include/asterisk/json.h Fri May 10 15:52:49 2013
@@ -600,6 +600,15 @@
 const char *ast_json_object_iter_key(struct ast_json_iter *iter);
 
 /*!
+ * \brief Retrieve the iterator object for a particular key
+ * \since 12.0.0
+ *
+ * \param key Key of the field the \c ast_json_iter points to
+ * \return \ref ast_json_iter object that points to \a key
+ */
+struct ast_json_iter *ast_json_object_key_to_iter(const char *key);
+
+/*!
  * \brief Get the value from an iterator.
  * \since 12.0.0
  *
@@ -625,6 +634,23 @@
  * \return -1 on error.
  */
 int ast_json_object_iter_set(struct ast_json *object, struct ast_json_iter *iter, struct ast_json *value);
+
+/*!
+ * \brief Iterate over key/value pairs
+ *
+ * \note This is a reproduction of the jansson library's \ref json_object_foreach
+ * using the equivalent ast_* wrapper functions. This creates a for loop using the various
+ * iteration function calls.
+ *
+ * \param object The \ref ast_json object that contains key/value tuples to iterate over
+ * \param key A \c const char pointer key for the key/value tuple
+ * \param value A \ref ast_json object for the key/value tuple
+ */
+#define ast_json_object_foreach(object, key, value) \
+	for (key = ast_json_object_iter_key(ast_json_object_iter(object)); \
+		key && (value = ast_json_object_iter_value(ast_json_object_key_to_iter(key))); \
+		key = ast_json_object_iter_key(ast_json_object_iter_next(object, ast_json_object_key_to_iter(key))))
+
 
 /*!@}*/
 

Modified: team/mjordan/ami-refactoring/include/asterisk/manager.h
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/ami-refactoring/include/asterisk/manager.h?view=diff&rev=388381&r1=388380&r2=388381
==============================================================================
--- team/mjordan/ami-refactoring/include/asterisk/manager.h (original)
+++ team/mjordan/ami-refactoring/include/asterisk/manager.h Fri May 10 15:52:49 2013
@@ -373,6 +373,22 @@
 
 /*!
  * \since 12
+ * \brief Get the \ref stasis_message_type for generic messages
+ *
+ * A generic AMI message expects a JSON only payload. The payload must have the following
+ * structure:
+ * {type: s, class_type: i, event: [ {s: s}, ...] }
+ *
+ * - type is the AMI event type
+ * - class_type is the class authorization type for the event
+ * - event is a list of key/value tuples to be sent out in the message
+ *
+ * \retval A \ref stasis_message_type for AMI messages
+ */
+struct stasis_message_type *ast_manager_get_generic_type(void);
+
+/*!
+ * \since 12
  * \brief Get the \ref stasis topic for AMI
  *
  * \retval The \ref stasis topic for AMI
@@ -380,6 +396,22 @@
  */
 struct stasis_topic *ast_manager_get_topic(void);
 
+struct ast_json;
+
+/*!
+ * \since 12
+ * \brief Publish a generic \ref stasis_message_type to the \ref stasis_topic for AMI
+ *
+ * Publishes a message to the \ref stasis message bus solely for the consumption of AMI.
+ * The message will be of the type provided by \ref ast_manager_get_type, and will be
+ * published to the topic provided by \ref ast_manager_get_topic. As such, the JSON must
+ * be constructed as defined by the \ref ast_manager_get_type message.
+ *
+ * \retval 0 on success
+ * \retval -1 on failure
+ */
+int ast_manager_publish_message(struct ast_json *json);
+
 /*!
  * \since 12
  * \brief Get the \ref stasis_message_router for AMI

Modified: team/mjordan/ami-refactoring/main/asterisk.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/ami-refactoring/main/asterisk.c?view=diff&rev=388381&r1=388380&r2=388381
==============================================================================
--- team/mjordan/ami-refactoring/main/asterisk.c (original)
+++ team/mjordan/ami-refactoring/main/asterisk.c Fri May 10 15:52:49 2013
@@ -1118,8 +1118,6 @@
 /*!
  * \brief Publish a \ref system_status_type message over \ref stasis
  *
- * \note The JSON object must contain a 'type' field
- *
  * \param payload The JSON payload to send with the message
  */
 static void publish_system_message(struct ast_json *obj)
@@ -1129,12 +1127,6 @@
 	struct ast_json *type;
 
 	if (!obj) {
-		return;
-	}
-
-	type = ast_json_object_get(obj, "type");
-	if (type == NULL) {
-		ast_log(LOG_ERROR, "Invalid JSON for system message; missing type field\n");
 		return;
 	}
 

Modified: team/mjordan/ami-refactoring/main/json.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/ami-refactoring/main/json.c?view=diff&rev=388381&r1=388380&r2=388381
==============================================================================
--- team/mjordan/ami-refactoring/main/json.c (original)
+++ team/mjordan/ami-refactoring/main/json.c Fri May 10 15:52:49 2013
@@ -330,6 +330,10 @@
 {
 	return json_object_iter_key(iter);
 }
+struct ast_json_iter *ast_json_object_key_to_iter(const char *key)
+{
+	return (struct ast_json_iter *)json_object_key_to_iter(key);
+}
 struct ast_json *ast_json_object_iter_value(struct ast_json_iter *iter)
 {
 	return (struct ast_json *)json_object_iter_value(iter);

Modified: team/mjordan/ami-refactoring/main/manager.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/ami-refactoring/main/manager.c?view=diff&rev=388381&r1=388380&r2=388381
==============================================================================
--- team/mjordan/ami-refactoring/main/manager.c (original)
+++ team/mjordan/ami-refactoring/main/manager.c Fri May 10 15:52:49 2013
@@ -1215,6 +1215,12 @@
 static enum add_filter_result manager_add_filter(const char *filter_pattern, struct ao2_container *whitefilters, struct ao2_container *blackfilters);
 
 /*!
+ * @{ \brief Define AMI message types.
+ */
+STASIS_MESSAGE_TYPE_DEFN(ast_manager_get_generic_type);
+/*! @} */
+
+/*!
  * \internal
  * \brief Find a registered action object.
  *
@@ -1246,6 +1252,61 @@
 struct stasis_message_router *ast_manager_get_message_router(void)
 {
 	return stasis_router;
+}
+
+static void manager_generic_msg_cb(void *data, struct stasis_subscription *sub,
+				    struct stasis_topic *topic,
+				    struct stasis_message *message)
+{
+	struct ast_json_payload *payload = stasis_message_data(message);
+	int class_type = ast_json_integer_get(ast_json_object_get(payload->json, "class_type"));
+	const char *type = ast_json_string_get(ast_json_object_get(payload->json, "type"));
+	struct ast_json *event = ast_json_object_get(payload->json, "event");
+	struct ast_str *event_buffer = ast_str_alloca(256);
+	struct ast_json *value;
+	const char *key;
+
+	if (!event_buffer) {
+		return;
+	}
+
+	ast_json_object_foreach(event, key, value) {
+		ast_str_append(&event_buffer, 0, "%s: %s\r\n", key, ast_json_string_get(value));
+	}
+	manager_event(class_type, type, "%s", ast_str_buffer(event_buffer));
+}
+
+int ast_manager_publish_message(struct ast_json *obj)
+{
+	RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
+	RAII_VAR(struct ast_json_payload *, payload, NULL, ao2_cleanup);
+	struct ast_json *type = ast_json_object_get(obj, "type");
+	struct ast_json *class_type = ast_json_object_get(obj, "class_type");
+	struct ast_json *event = ast_json_object_get(obj, "event");
+
+	if (!type) {
+		ast_log(AST_LOG_ERROR, "Attempt to send generic manager event without type field\n");
+		return -1;
+	}
+	if (!class_type) {
+		ast_log(AST_LOG_ERROR, "Attempt to send generic manager event without class type field\n");
+		return -1;
+	}
+	if (!event) {
+		ast_log(AST_LOG_ERROR, "Attempt to send generic manager event without event payload\n");
+		return -1;
+	}
+
+	payload = ast_json_payload_create(obj);
+	if (!payload) {
+		return -1;
+	}
+	message = stasis_message_create(ast_manager_get_generic_type(), payload);
+	if (!message) {
+		return -1;
+	}
+	stasis_publish(ast_manager_get_topic(), message);
+	return 0;
 }
 
 /*! \brief Add a custom hook to be called when an event is fired */
@@ -7489,6 +7550,7 @@
 	}
 	ao2_cleanup(manager_topic);
 	manager_topic = NULL;
+	STASIS_MESSAGE_TYPE_CLEANUP(ast_manager_get_generic_type);
 
 	ast_tcptls_server_stop(&ami_desc);
 	ast_tcptls_server_stop(&amis_desc);
@@ -7515,18 +7577,27 @@
 		manager_free_user(user);
 	}
 }
+
 
 /*! \brief Initialize all \ref stasis topics and routers used by the various
  * sub-components of AMI
  */
 static int manager_subscriptions_init(void)
 {
+	STASIS_MESSAGE_TYPE_INIT(ast_manager_get_generic_type);
 	manager_topic = stasis_topic_create("manager_topic");
 	if (!manager_topic) {
 		return -1;
 	}
 	stasis_router = stasis_message_router_create(manager_topic);
 	if (!stasis_router) {
+		return -1;
+	}
+
+	if (stasis_message_router_add(stasis_router,
+					 ast_manager_get_generic_type(),
+					 manager_generic_msg_cb,
+					 NULL)) {
 		return -1;
 	}
 	return 0;

Modified: team/mjordan/ami-refactoring/main/manager_mwi.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/ami-refactoring/main/manager_mwi.c?view=diff&rev=388381&r1=388380&r2=388381
==============================================================================
--- team/mjordan/ami-refactoring/main/manager_mwi.c (original)
+++ team/mjordan/ami-refactoring/main/manager_mwi.c Fri May 10 15:52:49 2013
@@ -37,36 +37,6 @@
 
 /*** DOCUMENTATION
  ***/
-
-static void mwi_minivm_cb(struct ast_mwi_blob *obj)
-{
-	RAII_VAR(struct ast_str *, channel_event_string, NULL, ast_free);
-	const char *action = ast_json_string_get(ast_json_object_get(obj->blob, "action"));
-	const char *counter = ast_json_string_get(ast_json_object_get(obj->blob, "counter"));
-
-	channel_event_string = ast_manager_build_channel_state_string(obj->mwi_state->snapshot);
-
-	manager_event(EVENT_FLAG_CALL, "MiniVoiceMail",
-			"%s"
-			"Action: %s\r\n"
-			"Mailbox: %s\r\n"
-			"Counter: %s\r\n",
-			action,
-			ast_str_buffer(channel_event_string),
-			obj->mwi_state->uniqueid,
-			counter);
-}
-
-static void mwi_blob_cb(void *data, struct stasis_subscription *sub,
-				    struct stasis_topic *topic,
-				    struct stasis_message *message)
-{
-	struct ast_mwi_blob *obj = stasis_message_data(message);
-
-	if (!strcmp("minivm", ast_mwi_blob_json_type(obj))) {
-		mwi_minivm_cb(obj);
-	}
-}
 
 static void mwi_update_cb(void *data, struct stasis_subscription *sub,
 				    struct stasis_topic *topic,
@@ -156,10 +126,6 @@
 					 ast_mwi_state_type(),
 					 mwi_update_cb,
 					 NULL);
-	ret |= stasis_message_router_add(message_router,
-					 ast_mwi_blob_type(),
-					 mwi_blob_cb,
-					 NULL);
 
 	/* If somehow we failed to add any routes, just shut down the whole
 	 * thing and fail it.




More information about the svn-commits mailing list