[asterisk-commits] kmoore: branch kmoore/stasis-bridge_events r384803 - in /team/kmoore/stasis-b...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Apr 4 17:00:46 CDT 2013


Author: kmoore
Date: Thu Apr  4 17:00:42 2013
New Revision: 384803

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=384803
Log:
Add manager events

Refactor string hash container into astobj2.c since it's becoming more
commonly used.

Refactor the generic manager event creation mechanism used in
manager_channels.c into manager.c since it is now used in
manager_bridging.c as well and will be a common pattern for manager
events being generated from snapshot diffs of several varieties.

Add manager_bridging.c which includes new manager events: BridgeCreate,
BridgeDestroy, BridgeEnter, BridgeLeave, BridgeVideoSourceChange,
BridgeVideoModeChange, and BridgeMerge. Add documentation for these
events.

Added:
    team/kmoore/stasis-bridge_events/main/manager_bridging.c   (with props)
Modified:
    team/kmoore/stasis-bridge_events/include/asterisk/astobj2.h
    team/kmoore/stasis-bridge_events/include/asterisk/manager.h
    team/kmoore/stasis-bridge_events/include/asterisk/stasis_bridging.h
    team/kmoore/stasis-bridge_events/main/astobj2.c
    team/kmoore/stasis-bridge_events/main/manager.c
    team/kmoore/stasis-bridge_events/main/manager_channels.c
    team/kmoore/stasis-bridge_events/main/stasis_bridging.c

Modified: team/kmoore/stasis-bridge_events/include/asterisk/astobj2.h
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-bridge_events/include/asterisk/astobj2.h?view=diff&rev=384803&r1=384802&r2=384803
==============================================================================
--- team/kmoore/stasis-bridge_events/include/asterisk/astobj2.h (original)
+++ team/kmoore/stasis-bridge_events/include/asterisk/astobj2.h Thu Apr  4 17:00:42 2013
@@ -1883,4 +1883,13 @@
 #define ao2_cleanup(obj) __ao2_cleanup(obj)
 #endif
 void ao2_iterator_cleanup(struct ao2_iterator *iter);
+
+/*!
+ * \since 12
+ * \brief Allocates a hash container for bare strings
+ * \retval AO2 container for strings
+ * \retval NULL if allocation failed
+ */
+struct ao2_container *ao2_str_container_alloc(int buckets);
+
 #endif /* _ASTERISK_ASTOBJ2_H */

Modified: team/kmoore/stasis-bridge_events/include/asterisk/manager.h
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-bridge_events/include/asterisk/manager.h?view=diff&rev=384803&r1=384802&r2=384803
==============================================================================
--- team/kmoore/stasis-bridge_events/include/asterisk/manager.h (original)
+++ team/kmoore/stasis-bridge_events/include/asterisk/manager.h Thu Apr  4 17:00:42 2013
@@ -86,6 +86,7 @@
 #define EVENT_FLAG_CC			(1 << 15) /* Call Completion events */
 #define EVENT_FLAG_AOC			(1 << 16) /* Advice Of Charge events */
 #define EVENT_FLAG_TEST			(1 << 17) /* Test event used to signal the Asterisk Test Suite */
+#define EVENT_FLAG_BRIDGE		(1 << 18) /* Bridge events */
 /*XXX Why shifted by 30? XXX */
 #define EVENT_FLAG_MESSAGE		(1 << 30) /* MESSAGE events. */
 /*@} */
@@ -316,6 +317,39 @@
  */
 struct ast_datastore *astman_datastore_find(struct mansession *s, const struct ast_datastore_info *info, const char *uid);
 
+/*! \brief Struct containing info for an AMI event to send out. */
+struct ast_manager_snapshot_event {
+	/*! event_flags manager_event() flags parameter. */
+	int event_flags;
+	/*!  manager_event manager_event() category. */
+	const char *manager_event;
+	AST_DECLARE_STRING_FIELDS(
+		/* extra fields to include in the event. */
+		AST_STRING_FIELD(extra_fields);
+		);
+};
+
+/*!
+ * \since 12
+ * \brief Construct a \ref snapshot_manager_event.
+ * \param event_flags manager_event() flags parameter.
+ * \param manager_event manager_event() category.
+ * \param extra_fields_fmt Format string for extra fields to include.
+ *                         Or NO_EXTRA_FIELDS for no extra fields.
+ * \return New \ref ast_manager_snapshot_event object.
+ * \return \c NULL on error.
+ */
+struct ast_manager_snapshot_event *
+__attribute__((format(printf, 3, 4)))
+ast_manager_snapshot_event_create(
+	int event_flags,
+	const char *manager_event,
+	const char *extra_fields_fmt,
+	...);
+
+/*! GCC warns about blank or NULL format strings. So, shenanigans! */
+#define NO_EXTRA_FIELDS "%s", ""
+
 /*!
  * \brief Initialize support for AMI channel events.
  * \return 0 on success.
@@ -324,4 +358,12 @@
  */
 int manager_channels_init(void);
 
+/*!
+ * \brief Initialize support for AMI channel events.
+ * \return 0 on success.
+ * \return non-zero on error.
+ * \since 12
+ */
+int manager_bridging_init(void);
+
 #endif /* _ASTERISK_MANAGER_H */

Modified: team/kmoore/stasis-bridge_events/include/asterisk/stasis_bridging.h
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-bridge_events/include/asterisk/stasis_bridging.h?view=diff&rev=384803&r1=384802&r2=384803
==============================================================================
--- team/kmoore/stasis-bridge_events/include/asterisk/stasis_bridging.h (original)
+++ team/kmoore/stasis-bridge_events/include/asterisk/stasis_bridging.h Thu Apr  4 17:00:42 2013
@@ -23,6 +23,11 @@
 extern "C" {
 #endif
 
+#include "asterisk/stringfields.h"
+#include "asterisk/utils.h"
+#include "asterisk/lock.h"
+#include "asterisk/linkedlists.h"
+#include "asterisk/channel.h"
 #include "asterisk/bridging.h"
 
 /*!

Modified: team/kmoore/stasis-bridge_events/main/astobj2.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-bridge_events/main/astobj2.c?view=diff&rev=384803&r1=384802&r2=384803
==============================================================================
--- team/kmoore/stasis-bridge_events/main/astobj2.c (original)
+++ team/kmoore/stasis-bridge_events/main/astobj2.c Thu Apr  4 17:00:42 2013
@@ -5779,3 +5779,18 @@
 
 	return 0;
 }
+
+static int str_hash(const void *obj, const int flags)
+{
+	return ast_str_hash(obj);
+}
+
+static int str_cmp(void *lhs, void *rhs, int flags)
+{
+	return strcmp(lhs, rhs) ? 0 : CMP_MATCH;
+}
+
+struct ao2_container *ao2_str_container_alloc(int buckets)
+{
+	return ao2_container_alloc(buckets, str_hash, str_cmp);
+}

Modified: team/kmoore/stasis-bridge_events/main/manager.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-bridge_events/main/manager.c?view=diff&rev=384803&r1=384802&r2=384803
==============================================================================
--- team/kmoore/stasis-bridge_events/main/manager.c (original)
+++ team/kmoore/stasis-bridge_events/main/manager.c Thu Apr  4 17:00:42 2013
@@ -7497,6 +7497,10 @@
 		return -1;
 	}
 
+	if (manager_bridging_init()) {
+		return -1;
+	}
+
 	if (!registered) {
 		/* Register default actions */
 		ast_manager_register_xml_core("Ping", 0, action_ping);
@@ -8007,3 +8011,45 @@
 
 	return datastore;
 }
+
+static void snapshot_manager_event_dtor(void *obj)
+{
+	struct ast_manager_snapshot_event *ev = obj;
+	ast_string_field_free_memory(ev);
+}
+
+struct ast_manager_snapshot_event *
+__attribute__((format(printf, 3, 4)))
+ast_manager_snapshot_event_create(
+	int event_flags,
+	const char *manager_event,
+	const char *extra_fields_fmt,
+	...)
+{
+	RAII_VAR(struct ast_manager_snapshot_event *, ev, NULL, ao2_cleanup);
+	va_list argp;
+
+	ast_assert(extra_fields_fmt != NULL);
+	ast_assert(manager_event != NULL);
+
+	ev = ao2_alloc(sizeof(*ev), snapshot_manager_event_dtor);
+	if (!ev) {
+		return NULL;
+	}
+
+	if (ast_string_field_init(ev, 20)) {
+		return NULL;
+	}
+
+	ev->manager_event = manager_event;
+	ev->event_flags = event_flags;
+
+	va_start(argp, extra_fields_fmt);
+	ast_string_field_ptr_build_va(ev, &ev->extra_fields, extra_fields_fmt,
+				      argp);
+	va_end(argp);
+
+	ao2_ref(ev, +1);
+	return ev;
+}
+

Added: team/kmoore/stasis-bridge_events/main/manager_bridging.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-bridge_events/main/manager_bridging.c?view=auto&rev=384803
==============================================================================
--- team/kmoore/stasis-bridge_events/main/manager_bridging.c (added)
+++ team/kmoore/stasis-bridge_events/main/manager_bridging.c Thu Apr  4 17:00:42 2013
@@ -1,0 +1,384 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * Kinsey Moore <kmoore 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 The Asterisk Management Interface - AMI (bridge event handling)
+ *
+ * \author Kinsey Moore <kmoore at digium.com>
+ */
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#include "asterisk/stasis_bridging.h"
+#include "asterisk/manager.h"
+#include "asterisk/stasis_message_router.h"
+
+static struct stasis_message_router *bridge_state_router;
+
+/*** DOCUMENTATION
+	<managerEvent language="en_US" name="BridgeCreate">
+		<managerEventInstance class="EVENT_FLAG_BRIDGE">
+			<synopsis>Raised when a bridge is created.</synopsis>
+			<syntax>
+				<parameter name="BridgeUniqueid">
+				</parameter>
+				<parameter name="BridgeType">
+					<para>The type of bridge</para>
+				</parameter>
+			</syntax>
+		</managerEventInstance>
+	</managerEvent>
+	<managerEvent language="en_US" name="BridgeDestroy">
+		<managerEventInstance class="EVENT_FLAG_BRIDGE">
+			<synopsis>Raised when a bridge is destroyed.</synopsis>
+			<syntax>
+				<xi:include xpointer="xpointer(/docs/managerEvent[@name='BridgeCreate']/managerEventInstance/syntax/parameter)" />
+			</syntax>
+		</managerEventInstance>
+	</managerEvent>
+	<managerEvent language="en_US" name="BridgeEnter">
+		<managerEventInstance class="EVENT_FLAG_BRIDGE">
+			<synopsis>Raised when a channel enters a bridge.</synopsis>
+			<syntax>
+				<xi:include xpointer="xpointer(/docs/managerEvent[@name='BridgeCreate']/managerEventInstance/syntax/parameter)" />
+				<parameter name="Uniqueid">
+					<para>The uniqueid of the channel entering the bridge</para>
+				</parameter>
+			</syntax>
+		</managerEventInstance>
+	</managerEvent>
+	<managerEvent language="en_US" name="BridgeLeave">
+		<managerEventInstance class="EVENT_FLAG_BRIDGE">
+			<synopsis>Raised when a channel leaves a bridge.</synopsis>
+			<syntax>
+				<xi:include xpointer="xpointer(/docs/managerEvent[@name='BridgeCreate']/managerEventInstance/syntax/parameter)" />
+				<parameter name="Uniqueid">
+					<para>The uniqueid of the channel leaving the bridge</para>
+				</parameter>
+			</syntax>
+		</managerEventInstance>
+	</managerEvent>
+	<managerEvent language="en_US" name="BridgeVideoSourceChange">
+		<managerEventInstance class="EVENT_FLAG_BRIDGE">
+			<synopsis>Raised when the video source for a bridge changes.</synopsis>
+			<syntax>
+				<xi:include xpointer="xpointer(/docs/managerEvent[@name='BridgeCreate']/managerEventInstance/syntax/parameter)" />
+				<parameter name="Uniqueid">
+					<para>The uniqueid of the channel that is the current video source</para>
+				</parameter>
+			</syntax>
+		</managerEventInstance>
+	</managerEvent>
+	<managerEvent language="en_US" name="BridgeVideoModeChange">
+		<managerEventInstance class="EVENT_FLAG_BRIDGE">
+			<synopsis>Raised when the video mode for a bridge changes.</synopsis>
+			<syntax>
+				<xi:include xpointer="xpointer(/docs/managerEvent[@name='BridgeCreate']/managerEventInstance/syntax/parameter)" />
+				<parameter name="BridgeVideoMode">
+					<enumlist>
+						<enum name="none"/>
+						<enum name="single"/>
+						<enum name="talker"/>
+					</enumlist>
+				</parameter>
+			</syntax>
+		</managerEventInstance>
+	</managerEvent>
+ ***/
+
+/*!
+ * \brief Generate the AMI message body from a bridge snapshot
+ * \internal
+ *
+ * \param snapshot the bridge snapshot for which to generate an AMI message
+ *                 body
+ *
+ * \retval NULL on error
+ * \retval ast_str* on success (must be ast_freed by caller)
+ */
+static struct ast_str *manager_build_bridge_state_string(
+	const struct ast_bridge_snapshot *snapshot,
+	const char *suffix)
+{
+	struct ast_str *out = ast_str_create(1024);
+	int res = 0;
+	if (!out) {
+		return NULL;
+	}
+	res = ast_str_set(&out, 0,
+		"BridgeUniqueid%s: %s\r\n"
+		"BridgeType%s: %s\r\n",
+		suffix, snapshot->uniqueid,
+		suffix, snapshot->technology);
+
+	if (!res) {
+		return NULL;
+	}
+
+	return out;
+}
+
+/*! \brief Typedef for callbacks that get called on channel snapshot updates */
+typedef struct ast_manager_snapshot_event *(*bridge_snapshot_monitor)(
+	struct ast_bridge_snapshot *old_snapshot,
+	struct ast_bridge_snapshot *new_snapshot);
+
+/*! \brief Handle bridge creation */
+static struct ast_manager_snapshot_event *bridge_create(
+	struct ast_bridge_snapshot *old_snapshot,
+	struct ast_bridge_snapshot *new_snapshot)
+{
+	if (!new_snapshot || old_snapshot) {
+		return NULL;
+	}
+
+	return ast_manager_snapshot_event_create(
+		EVENT_FLAG_BRIDGE, "BridgeCreate", NO_EXTRA_FIELDS);
+}
+
+/*! \brief Handle bridge destruction */
+static struct ast_manager_snapshot_event *bridge_destroy(
+	struct ast_bridge_snapshot *old_snapshot,
+	struct ast_bridge_snapshot *new_snapshot)
+{
+	if (new_snapshot || !old_snapshot) {
+		return NULL;
+	}
+
+	return ast_manager_snapshot_event_create(
+		EVENT_FLAG_BRIDGE, "BridgeDestroy", NO_EXTRA_FIELDS);
+}
+
+static int find_diff(void *uniqueid, void *arg, void *data, int flags)
+{
+	struct ao2_container *secondary = arg;
+	char **out = data;
+	RAII_VAR(char *, ao2_uniqueid, NULL, ao2_cleanup);
+
+	ao2_uniqueid = ao2_find(secondary, uniqueid, OBJ_KEY);
+	if (!ao2_uniqueid) {
+		*out = uniqueid;
+		return CMP_STOP;
+	}
+
+	return 0;
+}
+
+/*! \brief Handle channels entering and leaving */
+static struct ast_manager_snapshot_event *bridge_channel_diff(
+	struct ast_bridge_snapshot *old_snapshot,
+	struct ast_bridge_snapshot *new_snapshot)
+{
+	char *new_diff = NULL;
+	char *old_diff = NULL;
+
+	if (!new_snapshot || !old_snapshot
+		|| ao2_container_count(new_snapshot->channels)
+			== ao2_container_count(old_snapshot->channels)) {
+		return NULL;
+	}
+
+	/* get the diff channel on the new snapshot */
+	ao2_callback_data(new_snapshot->channels, OBJ_NODATA, find_diff, old_snapshot->channels, &new_diff);
+
+	if (new_diff) {
+		return ast_manager_snapshot_event_create(
+			EVENT_FLAG_BRIDGE, "BridgeEnter",
+			"Uniqueid: %s\r\n", new_diff);
+	}
+
+	/* get the diff channel on the old snapshot */
+	ao2_callback_data(old_snapshot->channels, OBJ_NODATA, find_diff, new_snapshot->channels, &old_diff);
+
+	if (old_diff) {
+		return ast_manager_snapshot_event_create(
+			EVENT_FLAG_BRIDGE, "BridgeLeave",
+			"Uniqueid: %s\r\n", old_diff);
+	}
+
+	return NULL;
+}
+
+/*! \brief Handle bridge video source change */
+static struct ast_manager_snapshot_event *bridge_video_source(
+	struct ast_bridge_snapshot *old_snapshot,
+	struct ast_bridge_snapshot *new_snapshot)
+{
+	if (!new_snapshot || !old_snapshot) {
+		return NULL;
+	}
+
+	if (!strcmp(new_snapshot->video_source, old_snapshot->video_source)) {
+		return NULL;
+	}
+
+	return ast_manager_snapshot_event_create(
+		EVENT_FLAG_BRIDGE, "BridgeVideoSourceChange",
+		"Uniqueid: %s\r\n", new_snapshot->video_source);
+}
+
+static const char *video_mode_to_str(enum ast_bridge_video_mode_type video_mode)
+{
+	switch (video_mode) {
+	case AST_BRIDGE_VIDEO_MODE_NONE:
+		return "none";
+	case AST_BRIDGE_VIDEO_MODE_SINGLE_SRC:
+		return "single";
+	case AST_BRIDGE_VIDEO_MODE_TALKER_SRC:
+		return "talker";
+	}
+	return NULL;
+}
+
+/*! \brief Handle bridge video mode change */
+static struct ast_manager_snapshot_event *bridge_video_mode(
+	struct ast_bridge_snapshot *old_snapshot,
+	struct ast_bridge_snapshot *new_snapshot)
+{
+	if (!new_snapshot || !old_snapshot) {
+		return NULL;
+	}
+
+	if (new_snapshot->video_mode == old_snapshot->video_mode) {
+		return NULL;
+	}
+
+	return ast_manager_snapshot_event_create(
+		EVENT_FLAG_BRIDGE, "BridgeVideoModeChange",
+		"BridgeVideoMode: %s\r\n", video_mode_to_str(new_snapshot->video_mode));
+}
+
+bridge_snapshot_monitor bridge_monitors[] = {
+	bridge_create,
+	bridge_destroy,
+	bridge_channel_diff,
+	bridge_video_mode,
+	bridge_video_source,
+};
+
+static void bridge_snapshot_update(void *data, struct stasis_subscription *sub,
+				    struct stasis_topic *topic,
+				    struct stasis_message *message)
+{
+	RAII_VAR(struct ast_str *, bridge_event_string, NULL, ast_free);
+	struct stasis_cache_update *update;
+	struct ast_bridge_snapshot *old_snapshot;
+	struct ast_bridge_snapshot *new_snapshot;
+	size_t i;
+
+	update = stasis_message_data(message);
+
+	if (ast_bridge_snapshot_type() != update->type) {
+		return;
+	}
+
+	old_snapshot = stasis_message_data(update->old_snapshot);
+	new_snapshot = stasis_message_data(update->new_snapshot);
+
+	for (i = 0; i < ARRAY_LEN(bridge_monitors); ++i) {
+		RAII_VAR(struct ast_manager_snapshot_event *, ev, NULL, ao2_cleanup);
+		ev = bridge_monitors[i](old_snapshot, new_snapshot);
+
+		if (!ev) {
+			continue;
+		}
+
+		/* If we haven't already, build the channel event string */
+		if (!bridge_event_string) {
+			bridge_event_string =
+				manager_build_bridge_state_string(
+					new_snapshot ? new_snapshot : old_snapshot, "");
+			if (!bridge_event_string) {
+				return;
+			}
+		}
+
+		manager_event(ev->event_flags, ev->manager_event, "%s%s",
+			ast_str_buffer(bridge_event_string),
+			ev->extra_fields);
+	}
+}
+
+static void bridge_merge_cb(void *data, struct stasis_subscription *sub,
+				    struct stasis_topic *topic,
+				    struct stasis_message *message)
+{
+	struct ast_bridge_merge_message *merge_msg = stasis_message_data(message);
+	RAII_VAR(struct ast_str *, to_text, NULL, ast_free);
+	RAII_VAR(struct ast_str *, from_text, NULL, ast_free);
+
+	ast_assert(merge_msg->to != NULL);
+	ast_assert(merge_msg->from != NULL);
+
+	to_text = manager_build_bridge_state_string(merge_msg->to, "To");
+	from_text = manager_build_bridge_state_string(merge_msg->from, "From");
+
+	manager_event(EVENT_FLAG_BRIDGE, "BridgeMerge",
+		"%s"
+		"%s",
+		ast_str_buffer(to_text),
+		ast_str_buffer(from_text));
+}
+
+static void manager_bridging_shutdown(void)
+{
+	stasis_message_router_unsubscribe(bridge_state_router);
+	bridge_state_router = NULL;
+}
+
+int manager_bridging_init(void)
+{
+	int ret = 0;
+
+	if (bridge_state_router) {
+		/* Already initialized */
+		return 0;
+	}
+
+	ast_register_atexit(manager_bridging_shutdown);
+
+	bridge_state_router = stasis_message_router_create(
+		stasis_caching_get_topic(ast_bridge_topic_all_cached()));
+
+	if (!bridge_state_router) {
+		return -1;
+	}
+
+	ret |= stasis_message_router_add(bridge_state_router,
+					 stasis_cache_update_type(),
+					 bridge_snapshot_update,
+					 NULL);
+
+	ret |= stasis_message_router_add(bridge_state_router,
+					 ast_bridge_merge_message_type(),
+					 bridge_merge_cb,
+					 NULL);
+
+	/* If somehow we failed to add any routes, just shut down the whole
+	 * thing and fail it.
+	 */
+	if (ret) {
+		manager_bridging_shutdown();
+		return -1;
+	}
+
+	return 0;
+}

Propchange: team/kmoore/stasis-bridge_events/main/manager_bridging.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/kmoore/stasis-bridge_events/main/manager_bridging.c
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: team/kmoore/stasis-bridge_events/main/manager_bridging.c
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: team/kmoore/stasis-bridge_events/main/manager_channels.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-bridge_events/main/manager_channels.c?view=diff&rev=384803&r1=384802&r2=384803
==============================================================================
--- team/kmoore/stasis-bridge_events/main/manager_channels.c (original)
+++ team/kmoore/stasis-bridge_events/main/manager_channels.c Thu Apr  4 17:00:42 2013
@@ -216,78 +216,13 @@
 	return out;
 }
 
-/*! \brief Struct containing info for an AMI channel event to send out. */
-struct snapshot_manager_event {
-	/*! event_flags manager_event() flags parameter. */
-	int event_flags;
-	/*!  manager_event manager_event() category. */
-	const char *manager_event;
-	AST_DECLARE_STRING_FIELDS(
-		/* extra fields to include in the event. */
-		AST_STRING_FIELD(extra_fields);
-		);
-};
-
-static void snapshot_manager_event_dtor(void *obj)
-{
-	struct snapshot_manager_event *ev = obj;
-	ast_string_field_free_memory(ev);
-}
-
-/*!
- * \brief Construct a \ref snapshot_manager_event.
- * \param event_flags manager_event() flags parameter.
- * \param manager_event manager_event() category.
- * \param extra_fields_fmt Format string for extra fields to include.
- *                         Or NO_EXTRA_FIELDS for no extra fields.
- * \return New \ref snapshot_manager_event object.
- * \return \c NULL on error.
- */
-static struct snapshot_manager_event *
-__attribute__((format(printf, 3, 4)))
-snapshot_manager_event_create(
-	int event_flags,
-	const char *manager_event,
-	const char *extra_fields_fmt,
-	...)
-{
-	RAII_VAR(struct snapshot_manager_event *, ev, NULL, ao2_cleanup);
-	va_list argp;
-
-	ast_assert(extra_fields_fmt != NULL);
-	ast_assert(manager_event != NULL);
-
-	ev = ao2_alloc(sizeof(*ev), snapshot_manager_event_dtor);
-	if (!ev) {
-		return NULL;
-	}
-
-	if (ast_string_field_init(ev, 20)) {
-		return NULL;
-	}
-
-	ev->manager_event = manager_event;
-	ev->event_flags = event_flags;
-
-	va_start(argp, extra_fields_fmt);
-	ast_string_field_ptr_build_va(ev, &ev->extra_fields, extra_fields_fmt,
-				      argp);
-	va_end(argp);
-
-	ao2_ref(ev, +1);
-	return ev;
-}
-
-/*! GCC warns about blank or NULL format strings. So, shenanigans! */
-#define NO_EXTRA_FIELDS "%s", ""
-
 /*! \brief Typedef for callbacks that get called on channel snapshot updates */
-typedef struct snapshot_manager_event *(*snapshot_monitor)(
+typedef struct ast_manager_snapshot_event *(*channel_snapshot_monitor)(
 	struct ast_channel_snapshot *old_snapshot,
 	struct ast_channel_snapshot *new_snapshot);
 
 /*! \brief Handle channel state changes */
-static struct snapshot_manager_event *channel_state_change(
+static struct ast_manager_snapshot_event *channel_state_change(
 	struct ast_channel_snapshot *old_snapshot,
 	struct ast_channel_snapshot *new_snapshot)
 {
@@ -304,7 +239,7 @@
 	 */
 
 	if (!old_snapshot) {
-		return snapshot_manager_event_create(
+		return ast_manager_snapshot_event_create(
 			EVENT_FLAG_CALL, "Newchannel", NO_EXTRA_FIELDS);
 	}
 
@@ -312,7 +247,7 @@
 	is_hungup = ast_test_flag(&new_snapshot->flags, AST_FLAG_ZOMBIE) ? 1 : 0;
 
 	if (!was_hungup && is_hungup) {
-		return snapshot_manager_event_create(
+		return ast_manager_snapshot_event_create(
 			EVENT_FLAG_CALL, "Hangup",
 			"Cause: %d\r\n"
 			"Cause-txt: %s\r\n",
@@ -321,7 +256,7 @@
 	}
 
 	if (old_snapshot->state != new_snapshot->state) {
-		return snapshot_manager_event_create(
+		return ast_manager_snapshot_event_create(
 			EVENT_FLAG_CALL, "Newstate", NO_EXTRA_FIELDS);
 	}
 
@@ -357,7 +292,7 @@
 		strcmp(old_snapshot->exten, new_snapshot->exten) == 0;
 }
 
-static struct snapshot_manager_event *channel_newexten(
+static struct ast_manager_snapshot_event *channel_newexten(
 	struct ast_channel_snapshot *old_snapshot,
 	struct ast_channel_snapshot *new_snapshot)
 {
@@ -376,7 +311,7 @@
 	}
 
 	/* DEPRECATED: Extension field deprecated in 12; remove in 14 */
-	return snapshot_manager_event_create(
+	return ast_manager_snapshot_event_create(
 		EVENT_FLAG_CALL, "Newexten",
 		"Extension: %s\r\n"
 		"Application: %s\r\n"
@@ -403,7 +338,7 @@
 		strcmp(old_snapshot->caller_name, new_snapshot->caller_name) == 0;
 }
 
-static struct snapshot_manager_event *channel_new_callerid(
+static struct ast_manager_snapshot_event *channel_new_callerid(
 	struct ast_channel_snapshot *old_snapshot,
 	struct ast_channel_snapshot *new_snapshot)
 {
@@ -416,14 +351,14 @@
 		return NULL;
 	}
 
-	return snapshot_manager_event_create(
+	return ast_manager_snapshot_event_create(
 		EVENT_FLAG_CALL, "NewCallerid",
 		"CID-CallingPres: %d (%s)\r\n",
 		new_snapshot->caller_pres,
 		ast_describe_caller_presentation(new_snapshot->caller_pres));
 }
 
-snapshot_monitor monitors[] = {
+channel_snapshot_monitor channel_monitors[] = {
 	channel_state_change,
 	channel_newexten,
 	channel_new_callerid
@@ -448,9 +383,9 @@
 	old_snapshot = stasis_message_data(update->old_snapshot);
 	new_snapshot = stasis_message_data(update->new_snapshot);
 
-	for (i = 0; i < ARRAY_LEN(monitors); ++i) {
-		RAII_VAR(struct snapshot_manager_event *, ev, NULL, ao2_cleanup);
-		ev = monitors[i](old_snapshot, new_snapshot);
+	for (i = 0; i < ARRAY_LEN(channel_monitors); ++i) {
+		RAII_VAR(struct ast_manager_snapshot_event *, ev, NULL, ao2_cleanup);
+		ev = channel_monitors[i](old_snapshot, new_snapshot);
 
 		if (!ev) {
 			continue;

Modified: team/kmoore/stasis-bridge_events/main/stasis_bridging.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-bridge_events/main/stasis_bridging.c?view=diff&rev=384803&r1=384802&r2=384803
==============================================================================
--- team/kmoore/stasis-bridge_events/main/stasis_bridging.c (original)
+++ team/kmoore/stasis-bridge_events/main/stasis_bridging.c Thu Apr  4 17:00:42 2013
@@ -58,16 +58,6 @@
 	snapshot->channels = NULL;
 }
 
-static int chan_hash(const void *obj, const int flags)
-{
-	return ast_str_hash(obj);
-}
-
-static int chan_cmp(void *lhs, void *rhs, int flags)
-{
-	return strcmp(lhs, rhs) ? 0 : CMP_MATCH;
-}
-
 struct ast_bridge_snapshot *ast_bridge_snapshot_create(struct ast_bridge *bridge)
 {
 	RAII_VAR(struct ast_bridge_snapshot *, snapshot, NULL, ao2_cleanup);
@@ -79,7 +69,7 @@
 		return NULL;
 	}
 
-	snapshot->channels = ao2_container_alloc(SNAPSHOT_CHANNELS_BUCKETS, chan_hash, chan_cmp);
+	snapshot->channels = ao2_str_container_alloc(SNAPSHOT_CHANNELS_BUCKETS);
 	if (!snapshot->channels) {
 		return NULL;
 	}




More information about the asterisk-commits mailing list