[asterisk-commits] russell: branch russell/events r84549 - /team/russell/events/pbx/pbx_dundi.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Oct 3 13:49:24 CDT 2007


Author: russell
Date: Wed Oct  3 13:49:23 2007
New Revision: 84549

URL: http://svn.digium.com/view/asterisk?view=rev&rev=84549
Log:
Add most of the code for parsing the distributed event mappings from
dundi.conf and building the related data structures

Modified:
    team/russell/events/pbx/pbx_dundi.c

Modified: team/russell/events/pbx/pbx_dundi.c
URL: http://svn.digium.com/view/asterisk/team/russell/events/pbx/pbx_dundi.c?view=diff&rev=84549&r1=84548&r2=84549
==============================================================================
--- team/russell/events/pbx/pbx_dundi.c (original)
+++ team/russell/events/pbx/pbx_dundi.c Wed Oct  3 13:49:23 2007
@@ -77,6 +77,7 @@
 #include "asterisk/aes.h"
 #include "asterisk/app.h"
 #include "asterisk/astobj2.h"
+#include "asterisk/event.h"
 
 #include "dundi-parser.h"
 
@@ -272,15 +273,39 @@
 static AST_LIST_HEAD_NOLOCK_STATIC(requests, dundi_request);
 static AST_LIST_HEAD_NOLOCK_STATIC(alltrans, dundi_transaction);
 
+/*!
+ * \brief A publish event mapping
+ *
+ * This structure represents event mappings from dundi.conf.  A publish event
+ * mapping takes a description of a subset of events that occur on this node
+ * and sends them out into the specified DUNDi context so that other nodes may
+ * be aware of the events.
+ *
+ * An example usage (and the only one supported at the time of this writing) is
+ * for sharing MWI state change events for voicemail boxes.  That way, other
+ * nodes in a DUNDi context can be informed about mailbox contents changes so
+ * that they can then inform the phones that they have registered locally.
+ */
 struct pub_event_map {
 	AST_DECLARE_STRING_FIELDS(
+		/*! The DUNDi context where events are being published to */
 		AST_STRING_FIELD(context);
 	);
+	/*! This is the Asterisk event type being published */
+	enum ast_event_type event_type;
+	/*! Parameters from the configuration used to build the internal event
+	 *  subscription, which limit what events get published into a DUNDi 
+	 *  context. */
+	struct ast_variable *parameters;
+	/*! This is the internal event subscription for events coming from 
+	 *  this node to be published into the mapped DUNDi context */
+	struct ast_event_sub *event_sub;
+	/*! This object has been marked to get destroyed */
 	unsigned int delme:1;
 };
 
 #define EVENT_MAP_BUCKETS	17
-/*! Publish event mappings */
+/*! The container of publish event mappings */
 static struct ao2_container *pub_event_maps;
 
 /*!
@@ -4623,9 +4648,152 @@
 	}
 }
 
+static void pub_event_map_destructor(void *obj)
+{
+	struct pub_event_map *pub_event_map = obj;
+
+	ast_variables_destroy(pub_event_map->parameters);
+
+	if (pub_event_map->event_sub)
+		pub_event_map->event_sub = ast_event_unsubscribe(pub_event_map->event_sub);
+
+	ast_string_field_free_all(pub_event_map);
+}
+
+#if 0
+static inline struct pub_event_map *pub_event_map_ref(strut pub_event_map *map)
+{
+	ao2_ref(map, +1);
+	return map;
+}
+#endif
+
+static inline struct pub_event_map *pub_event_map_unref(struct pub_event_map *map)
+{
+	ao2_ref(map, -1);
+	return NULL;
+}
+
+/*!
+ * \brief Clean up a string
+ *
+ * Remove leading and trailing whitespace.  This will modify the string passed.
+ *
+ * \return The modified string.  If there was leading whitespace, the return
+ *         value will point to the first non-whitespace character.  Any
+ *         trailing whitespace will have been removed.
+ */
+static char *clean_string(char *s)
+{
+	size_t len;
+
+	if (ast_strlen_zero(s))
+		return s;
+
+	s = ast_skip_blanks(s);
+	for (len = strlen(s); s[len] < 33; s[len] = '\0', len = strlen(s)) 
+		;
+	
+	return s;
+}
+
+static void ast_event_cb(const struct ast_event *event, void *data)
+{
+	struct pub_event_map *pub_event_map = data;
+
+	ast_debug(1, "Got an event to publish to DUNDi context '%s'\n",
+		pub_event_map->context);
+}
+
+static enum ast_event_type get_event_type(const char *val)
+{
+	if (!strcasecmp(val, "mwi"))
+		return AST_EVENT_MWI;
+	
+	return -1;
+}
+
+/*!
+ * \brief Parse an event mapping from dundi.conf
+ */
 static void add_publish_event_mapping(const char *val)
 {
-
+	struct pub_event_map *pub_event_map;
+	char *context, *event_type_s, *params, *cur_param;
+	enum ast_event_type event_type;
+
+	params = ast_strdupa(val);
+
+	context = strsep(&params, ",");
+	context = clean_string(context);
+
+	event_type_s = strsep(&params, ",");
+	event_type_s = clean_string(event_type_s);
+	if (ast_strlen_zero(event_type_s)) {
+		ast_log(LOG_ERROR, "publish_event mapping missing event type: '%s'\n", val);
+		return;
+	}
+
+	event_type = get_event_type(event_type_s);
+	if (event_type == -1) {
+		ast_log(LOG_ERROR, "event type '%s' is not valid for a DUNDi event mapping.\n",
+			event_type_s);
+		return;
+	}
+
+	if (!(pub_event_map = ao2_alloc(sizeof(*pub_event_map), pub_event_map_destructor)))
+		return;
+	
+	if (ast_string_field_init(pub_event_map, 16))
+		goto return_unref;
+
+	ast_string_field_set(pub_event_map, context, context);
+
+	pub_event_map->event_type = event_type;
+
+	pub_event_map->event_sub = ast_event_subscribe_new(event_type, ast_event_cb, 
+		pub_event_map);
+	if (!pub_event_map->event_sub)
+		goto return_unref;
+
+	params = clean_string(params);
+	for (cur_param = strsep(&params, ","); !ast_strlen_zero(cur_param); 
+			cur_param = strsep(&params, ",")) {
+		struct ast_variable *v;
+		char *param_name, *param_value;
+
+		param_value = clean_string(cur_param);
+		param_name = strsep(&param_value, "=");
+		if (ast_strlen_zero(param_name) || ast_strlen_zero(param_value)) {
+			ast_log(LOG_ERROR, "invalid event mapping in dundi.conf\n");
+			goto return_unref;
+		}
+
+		param_name = clean_string(param_name);
+		param_value = clean_string(param_value);
+
+		if (!(v = ast_variable_new(param_name, param_value, "")))
+			goto return_unref;
+
+		if (pub_event_map->parameters)
+			v->next = pub_event_map->parameters;
+		pub_event_map->parameters = v;
+
+		/* XXX add param to sub */
+	}
+
+	if (ast_event_sub_activate(pub_event_map->event_sub)) {
+		ast_log(LOG_ERROR, "Failed to activate internal event subscription "
+			"for event mapping\n");
+		goto return_unref;
+	}
+
+	ao2_link(pub_event_maps, pub_event_map);
+
+	return;
+
+return_unref:
+	pub_event_map_unref(pub_event_map);
 }
 
 static int set_config(char *config_file, struct sockaddr_in* sin, int reload)




More information about the asterisk-commits mailing list