[asterisk-commits] mjordan: branch mjordan/ami-refactoring r388381 - in /team/mjordan/ami-refact...
SVN commits to the Asterisk project
asterisk-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 asterisk-commits
mailing list