[asterisk-commits] mmichelson: branch group/manager2 r113591 - in /team/group/manager2: include/...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Apr 8 18:23:50 CDT 2008


Author: mmichelson
Date: Tue Apr  8 18:23:50 2008
New Revision: 113591

URL: http://svn.digium.com/view/asterisk?view=rev&rev=113591
Log:
This is a progress checkin. I suspect this doesn't even actually compile at this point...

Now at module load time, a configuration file, subscribers.conf, is parsed to see what users
are defined and what their filter preferences are. Right now, the only way of specifying filtering
info is to have an "event=" line in the config file. This will correspond to an event type, meaning
that subscriber wishes to see output when an event of that type occurs. In order to accommodate this,
I added a new mapping in event.c which maps enum ast_event_types to a string representation of their names
as well as a function to get an ast_event_type given its name as input.

This checkin covers the setup of the filter, and leaves the functions in a state where they should
be easy to expand on later, since they will invariably need lots of expansion. This does not yet implement
the use of the filters when subscribing to events. That will be the next item on the agenda once I have
what's written compiling properly.


Modified:
    team/group/manager2/include/asterisk/event_defs.h
    team/group/manager2/main/event.c
    team/group/manager2/res/res_manager2.c

Modified: team/group/manager2/include/asterisk/event_defs.h
URL: http://svn.digium.com/view/asterisk/team/group/manager2/include/asterisk/event_defs.h?view=diff&rev=113591&r1=113590&r2=113591
==============================================================================
--- team/group/manager2/include/asterisk/event_defs.h (original)
+++ team/group/manager2/include/asterisk/event_defs.h Tue Apr  8 18:23:50 2008
@@ -57,9 +57,8 @@
 	AST_EVENT_QUEUE_MEMBER_ADDED = 15,
 	AST_EVENT_QUEUE_MEMBER_PAUSED = 16,
 	AST_EVENT_QUEUE_MEMBER_PENALTY = 17,
-	AST_EVENT_MANAGER_LOGIN = 18,
 	/*! Number of event types.  This should be the last event type + 1 */
-	AST_EVENT_TOTAL = 19,
+	AST_EVENT_TOTAL = 18,
 };
 
 
@@ -174,7 +173,7 @@
 	 AST_EVENT_IE_FD = 0x21,
 	 /*! A username */
 	 AST_EVENT_IE_USERNAME = 0x22,
-	 AST_EVENT_IE_LAST = 0x22,
+	 AST_EVENT_IE_LAST = 0x23,
 };
 /*!
  * \brief Payload types for event information elements

Modified: team/group/manager2/main/event.c
URL: http://svn.digium.com/view/asterisk/team/group/manager2/main/event.c?view=diff&rev=113591&r1=113590&r2=113591
==============================================================================
--- team/group/manager2/main/event.c (original)
+++ team/group/manager2/main/event.c Tue Apr  8 18:23:50 2008
@@ -117,6 +117,31 @@
  * for events that express some sort of state.  So, when someone first
  * needs to know this state, it can get the last known state from the cache. */
 static AST_RWLIST_HEAD(ast_event_ref_list, ast_event_ref) ast_event_cache[AST_EVENT_TOTAL];
+
+struct ast_event_map {
+	enum ast_event_type event;
+	const char *name;
+} event_name_map [] = {
+	{AST_EVENT_ALL, "All"},
+	{AST_EVENT_CUSTOM, "Custom"},
+	{AST_EVENT_MWI, "MWI"},
+	{AST_EVENT_SUB, "Subscribe"},
+	{AST_EVENT_UNSUB, "Unsubscribe"},
+	{AST_EVENT_DEVICE_STATE, "DeviceState"},
+	{AST_EVENT_QUEUE_MEMBER_STATUS, "QueueMemberStatus"},
+	{AST_EVENT_QUEUE_JOIN, "QueueJoin"},
+	{AST_EVENT_QUEUE_LEAVE, "QueueLeave"},
+	{AST_EVENT_QUEUE_MEMBER_CALLED, "QueueMemberCalled"},
+	{AST_EVENT_QUEUE_CALLER_ABANDON, "QueueCallerAbandon"},
+	{AST_EVENT_QUEUE_MEMBER_COMPLETE, "QueueMemberComplete"},
+	{AST_EVENT_QUEUE_MEMBER_DUMP, "QueueMemberDump"},
+	{AST_EVENT_QUEUE_MEMBER_CONNECT, "QueueMemberConnect"},
+	{AST_EVENT_QUEUE_MEMBER_REMOVED, "QueueMemberRemoved"},
+	{AST_EVENT_QUEUE_MEMBER_ADDED, "QueueMemberAdded"},
+	{AST_EVENT_QUEUE_MEMBER_PAUSED, "QueueMemberPaused"},
+	{AST_EVENT_QUEUE_MEMBER_PENALTY, "QueueMemberPenalty"},
+	{AST_EVENT_TOTAL, "Total"},
+}
 
 struct ast_event_ie_map {
 	enum ast_event_ie_type ie;
@@ -160,6 +185,24 @@
 	{AST_EVENT_IE_USERNAME, AST_EVENT_IE_PLTYPE_STR,	"Username"},                    /*!< AST_EVENT_IE_USERNAME 34 */
 };
 
+enum ast_event_type ast_event_get_event_by_name(const char *event_name)
+{
+	enum ast_event_type iterator;
+	int found = 0;
+	/*XXX Is there a better way than O(N) of doing this? */
+	for (iterator = AST_EVENT_ALL; iterator < AST_EVENT_TOTAL; iterator++) {
+		if (!strcasecmp(event_name, event_name_map[iterator].name)) {
+			found = 1;
+			break;
+		}
+	}
+
+	if (found)
+		return iterator;
+	else
+		return -1;
+}
+
 enum ast_event_ie_pltype  ast_event_ie_get_pltype(enum ast_event_ie_type ie) 
 {
 	if (ie > 0 && ie < AST_EVENT_IE_LAST && 

Modified: team/group/manager2/res/res_manager2.c
URL: http://svn.digium.com/view/asterisk/team/group/manager2/res/res_manager2.c?view=diff&rev=113591&r1=113590&r2=113591
==============================================================================
--- team/group/manager2/res/res_manager2.c (original)
+++ team/group/manager2/res/res_manager2.c Tue Apr  8 18:23:50 2008
@@ -55,20 +55,37 @@
 	.worker_fn = subscribe_start,
 };
 
-struct subscriber {
-	char name[80];
+/* Each of these represents a logged in subscriber
+ * Each of these will have its own thread in which it
+ * executes.
+ */
+struct subscriber_instance {
+	struct subscriber *sub;
 	FILE* f;
 	unsigned int stop:1;
 	pthread_t thread;
 	ast_cond_t cond;
 	ast_mutex_t lock;
+	AST_LIST_HEAD_NOLOCK(, info_event) info_events;
+}
+
+/* Each of these represents an event subscriber defined
+ * in the subscribers.conf file. These probably should be
+ * refcounted since multiple subscriber_instances could
+ * reference the same subscriber.
+ */
+struct subscriber {
+	char name[80];
+	struct subscriber_filter *filter;
 	AST_LIST_ENTRY(subscriber) list;
-	AST_LIST_HEAD_NOLOCK(, info_event) info_events;
 };
 
+struct subscriber_filter {
+	enum ast_event_type[800]; /* Totally arbitrary number for the time being */
+	int num_events;           /* Number of events we're subscribed to. Used for iteration purposes */
+};
+
 AST_LIST_HEAD_STATIC(subscribers, subscriber);
-
-struct ast_event_sub *login_sub;
 
 /*! \brief Take our event and put it into our own queue
  * to ease the load of the main event queue
@@ -78,7 +95,7 @@
  */
 static void info_cb(const struct ast_event *event, void *data)
 {
-	struct subscriber *sub = data;
+	struct subscriber_instance *sub = data;
 	struct info_event *new_event = ast_calloc(1, sizeof(*new_event));
 	if (!new_event)
 		/* OH CRAP! */
@@ -104,7 +121,7 @@
 static void *event_spitter(void *data)
 {
 	struct info_event *event = NULL;
-	struct subscriber *sub = data;
+	struct subscriber_instance *sub = data;
 	
 	while (!sub->stop) {
 		struct ast_event_iterator iter;
@@ -195,8 +212,8 @@
 	}
 
 	/* For now, hard code "mark" as the name */
-
 	ast_copy_string(sub->name, "mark", sizeof(sub->name));
+	sub->filter = get_filter_info(sub->name);
 	sub->f = ser->f;
 
 	ast_debug(3, "Event subscriber %s logged in\n", sub->name);
@@ -263,18 +280,111 @@
 	ast_tcptls_server_start(&event_server);
 }
 
+/*! \brief Iterate through the user's filter settings. Currently, we only support
+ * subscribing to specific events by name. IE-specific settings will be added later
+ *
+ * \param [in] subscriber_name The name of the subscriber for whom we're setting up
+ * filtering information
+ */
+static struct subscriber_filter *setup_filter(struct ast_config *cfg, const char *subscriber_name)
+{
+	struct subscriber_filter *new_filter = NULL;
+	struct ast_variable *var = NULL;
+	int event_index = 0;
+
+	if (!(new_filter = ast_calloc(1, sizeof(*new_filter)))) {
+		/* OH CRAP */
+		return NULL;
+	}
+
+	for (var = ast_variable_browse(cfg, subscriber_name); var; var = var->next) {
+		if (!strcasecmp(var->name, "event")) {
+			enum ast_event_type new_type = ast_event_get_type_by_name(var->value);
+			if (new_type != -1) {
+				new_filter->events[event_index++] = new_type;
+			} else {
+				ast_log(LOG_WARNING, "Error parsing event type '%s' on line %d; not added to filter!\n", var->value, var->lineno);
+			}
+		} else {
+			ast_log(LOG_WARNING, "Don't know how to handle option '%s' on line %d\n", var->name, var->lineno);
+		}
+	}
+
+	new_filter->num_events = event_index;
+
+	return new_filter;
+}
+
+/*! \brief Set up the subscribers here. This is done when the
+ * configuration file is loaded. This sets up the subscriber-specific
+ * information (just a name right now). We defer filtering setup to
+ * the setup_filter() function
+ */
+static struct subscriber *sub_init(struct ast_config *cfg, const char *subscriber_name)
+{
+	struct subscriber *sub_iter = NULL, *new_subscriber = NULL;
+	int already_exists = 0;
+	/* First things first, let's see if this subscriber is already
+	 * in the list. If he is, then abort
+	 */
+	AST_LIST_LOCK(&subscribers);
+	AST_LIST_TRAVERSE(&subscribers, sub_iter, list) {
+		if (!strcasecmp(sub_iter->name, subscriber_name)) {
+			already_exists = 1;
+		}
+	}
+	AST_LIST_UNLOCK(&subscribers);
+
+	if (already_exists) {
+		ast_log(LOG_WARNING, "Skipping subscriber '%s' since this subscriber has already been defined!\n", subscriber_name);
+		return NULL;
+	}
+
+	/* This guy's not in the list, so let's make a new one and get the necessary info */
+	if (!(new_subscriber = ast_calloc(1, sizeof(*new_subscriber)))) {
+		/*OH CRAP*/
+		return NULL;
+	}
+
+	ast_copy_string(new_subscriber->name, subscriber_name, sizeof(new_subscriber->name));
+	new_subscriber->filter = setup_filter(cfg, subscriber_name);
+	return new_subscriber;
+}
+
+static int load_config(void)
+{
+	struct ast_config *cfg = NULL;
+	char *cat = NULL;
+	struct ast_flags cfg_flags = {0,};
+
+	if (!(cfg = ast_config_load("subscribers.conf", cfg_flags))) {
+		/*OH CRAP*/
+		return -1;
+	}
+
+	while ((cat = ast_category_browse(cfg, cat))) {
+		struct subscriber sub = NULL;
+		if (!(sub = sub_init(cat))) {
+			/* OH CRAP */
+			continue;
+		}
+		AST_LIST_INSERT_TAIL(&subscribers, sub, list);
+	}
+
+	ast_config_destroy(cfg);
+
+	return 0;
+}
+
 static int unload_module(void)
 {
-	if (login_sub) {
-		ast_event_unsubscribe(login_sub);
-	}
 	return 0;
 }
 
 static int load_module(void)
 {
+	setup_filters();
 	start_socket();
-	
 	return AST_MODULE_LOAD_SUCCESS;
 }
 




More information about the asterisk-commits mailing list