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

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Mar 28 17:24:19 CDT 2008


Author: mmichelson
Date: Fri Mar 28 17:24:18 2008
New Revision: 111890

URL: http://svn.digium.com/view/asterisk?view=rev&rev=111890
Log:
Primitive move towards having subscribers for events
tied to manager connections. When a manager logs in, an event is
sent telling us that we should now start monitoring events that
that subscriber wants to know about. Right now, just to make sure
it was working at all, if anyone logs into manager, they'll see
queue member status changes on their manager connection.

This provides the foundation for what's to come, and that's quite
exciting.


Modified:
    team/group/manager2/include/asterisk/event_defs.h
    team/group/manager2/main/event.c
    team/group/manager2/main/manager.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=111890&r1=111889&r2=111890
==============================================================================
--- team/group/manager2/include/asterisk/event_defs.h (original)
+++ team/group/manager2/include/asterisk/event_defs.h Fri Mar 28 17:24:18 2008
@@ -57,8 +57,9 @@
 	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 = 18,
+	AST_EVENT_TOTAL = 19,
 };
 
 
@@ -169,6 +170,10 @@
 	 AST_EVENT_IE_DESTINATION_UNIQUEID = 0x1F,
 	 /*! Channel variable */
 	 AST_EVENT_IE_CHANVAR = 0x20,
+	 /*! A file descriptor */
+	 AST_EVENT_IE_FD = 0x21,
+	 /*! A username */
+	 AST_EVENT_IE_USERNAME = 0x22,
 };
 /*!
  * \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=111890&r1=111889&r2=111890
==============================================================================
--- team/group/manager2/main/event.c (original)
+++ team/group/manager2/main/event.c Fri Mar 28 17:24:18 2008
@@ -155,6 +155,8 @@
 	{AST_EVENT_IE_PLTYPE_UINT,	"RingTime"},                    /*!< AST_EVENT_IE_QUEUE_RINGTIME 30 */
 	{AST_EVENT_IE_PLTYPE_STR,	"DestinationUniqueID"},         /*!< AST_EVENT_IE_DESTINATION_UNIQUEID 31 */
 	{AST_EVENT_IE_PLTYPE_STR,	"Variable"},                    /*!< AST_EVENT_IE_CHANVAR 32 */
+	{AST_EVENT_IE_PLTYPE_UINT,	"FileDescriptor"},              /*!< AST_EVENT_IE_FD 33 */
+	{AST_EVENT_IE_PLTYPE_STR,	"Username"},                    /*!< AST_EVENT_IE_USERNAME 34 */
 };
 
 enum ast_event_ie_pltype  ast_event_ie_get_pltype(enum ast_event_ie_type ie) 

Modified: team/group/manager2/main/manager.c
URL: http://svn.digium.com/view/asterisk/team/group/manager2/main/manager.c?view=diff&rev=111890&r1=111889&r2=111890
==============================================================================
--- team/group/manager2/main/manager.c (original)
+++ team/group/manager2/main/manager.c Fri Mar 28 17:24:18 2008
@@ -74,6 +74,7 @@
 #include "asterisk/term.h"
 #include "asterisk/astobj2.h"
 #include "asterisk/features.h"
+#include "asterisk/event.h"
 
 enum error_type {
 	UNKNOWN_ACTION = 1,
@@ -1594,6 +1595,7 @@
 
 static int action_login(struct mansession *s, const struct message *m)
 {
+	struct ast_event *event;
 	if (authenticate(s, m)) {
 		sleep(1);
 		astman_send_error(s, m, "Authentication failed");
@@ -1604,6 +1606,13 @@
 		ast_verb(2, "%sManager '%s' logged on from %s\n", (s->managerid ? "HTTP " : ""), s->username, ast_inet_ntoa(s->sin.sin_addr));
 	ast_log(LOG_EVENT, "%sManager '%s' logged on from %s\n", (s->managerid ? "HTTP " : ""), s->username, ast_inet_ntoa(s->sin.sin_addr));
 	astman_send_ack(s, m, "Authentication accepted");
+
+	event = ast_event_new (AST_EVENT_MANAGER_LOGIN,
+			AST_EVENT_IE_FD, s->fd,
+			AST_EVENT_IE_USERNAME, s->username,
+			AST_EVENT_IE_END);
+
+	ast_event_queue(event);
 	return 0;
 }
 

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=111890&r1=111889&r2=111890
==============================================================================
--- team/group/manager2/res/res_manager2.c (original)
+++ team/group/manager2/res/res_manager2.c Fri Mar 28 17:24:18 2008
@@ -4,56 +4,35 @@
 #include "asterisk/utils.h"
 #include "asterisk/linkedlists.h"
 
-struct event_map {
-	const enum ast_event_type type;
-	const char *name;
-} queue_map [] = { /*Queue events*/
-	{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"},
-};
-
 struct info_event {
 	AST_LIST_ENTRY(info_event) list;
 	struct ast_event *event;
 };
 
-static struct {
+struct subscriber {
+	char name[80];
+	int fd;
 	unsigned int stop:1;
 	pthread_t thread;
 	ast_cond_t cond;
 	ast_mutex_t lock;
 	AST_LIST_HEAD_NOLOCK(, info_event) info_events;
-} info_thread = {
-	.thread = AST_PTHREADT_NULL,
 };
-
 
 AST_LIST_HEAD_STATIC(info_events, info_event);
 
 #define QUEUE_EVENT_BEGIN AST_EVENT_QUEUE_MEMBER_STATUS
-/*Right now size this as the number of event types which exist
- * Will probably modify this later
- */
-struct ast_event_sub *manager_sub[AST_EVENT_TOTAL];
+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
  *
  * \param[in] event the event we have subscribed to
- * \param[in] ignore unused parameter
+ * \param[in] data the subscriber we're sending the event to
  */
-static void info_cb(const struct ast_event *event, void *ignore)
+static void info_cb(const struct ast_event *event, void *data)
 {
+	struct subscriber *sub = data;
 	struct info_event *new_event = ast_calloc(1, sizeof(*new_event));
 	if (!new_event)
 		/* OH CRAP! */
@@ -63,35 +42,37 @@
 		/* OH CRAP! */
 		return;
 
-	ast_mutex_lock(&info_thread.lock);
-	AST_LIST_INSERT_TAIL(&info_thread.info_events, new_event, list); 
-	ast_cond_signal(&info_thread.cond);
-	ast_mutex_unlock(&info_thread.lock);
+	ast_mutex_lock(&sub->lock);
+	AST_LIST_INSERT_TAIL(&sub->info_events, new_event, list); 
+	ast_cond_signal(&sub->cond);
+	ast_mutex_unlock(&sub->lock);
 }
 
 AST_THREADSTORAGE(manager_event_buf);
 #define MANAGER_EVENT_BUF_INITSIZE   256
 /*! \brief The handler for manager subscriptions
  * In its rudimentary stage here, all this does is iterate
- * through the IEs in the event and print them as debug messages
+ * through the IEs in the event and write them to the fd
+ * that we got from manager
  */
-static void *event_spitter(void *thisvariableissoimportantiamafraidtoactuallyuseit)
+static void *event_spitter(void *data)
 {
 	struct info_event *event = NULL;
+	struct subscriber *sub = data;
 	
-	while (!info_thread.stop) {
+	while (!sub->stop) {
 		struct ast_event_iterator iter;
 		int res = 0;
 		struct ast_str *buf;
-		ast_mutex_lock(&info_thread.lock);
-		if (!(event = AST_LIST_REMOVE_HEAD(&info_thread.info_events, list))) {
-			ast_cond_wait(&info_thread.cond, &info_thread.lock);
-			event = AST_LIST_REMOVE_HEAD(&info_thread.info_events, list);
+		ast_mutex_lock(&sub->lock);
+		if (!(event = AST_LIST_REMOVE_HEAD(&sub->info_events, list))) {
+			ast_cond_wait(&sub->cond, &sub->lock);
+			event = AST_LIST_REMOVE_HEAD(&sub->info_events, list);
 		}
-		ast_mutex_unlock(&info_thread.lock);
+		ast_mutex_unlock(&sub->lock);
 
 		/* break if it's time to stop this thread's execution */
-		if (info_thread.stop) {
+		if (sub->stop) {
 			break;
 		}
 
@@ -113,11 +94,8 @@
 				ast_str_append(&buf, 0, "%s: %u\r\n", ast_event_ie_get_name(ie_type), ast_event_iterator_get_ie_uint(&iter));
 		}
 
-		/*Now we need to write the string to manager socket...
-		 * for now continue to output to console
-		 */
-		ast_debug(0, "%s", buf->str);
-
+		ast_str_append(&buf, 0, "%s", "\r\n");
+		write(sub->fd, buf->str, buf->used);
 		ast_event_destroy(event->event);
 		ast_free(event);
 		event = NULL;
@@ -128,7 +106,7 @@
 		ast_free(event);
 	}
 
-	while ((event = AST_LIST_REMOVE_HEAD(&info_thread.info_events, list))) {
+	while ((event = AST_LIST_REMOVE_HEAD(&sub->info_events, list))) {
 		ast_event_destroy(event->event);
 		ast_free(event);
 	}
@@ -136,36 +114,66 @@
 	return NULL;
 }
 
+/*! \brief set up the subscriber's thread
+ * This may not need to be a separate function, but 
+ * dammit I feel like doing it this way in case more
+ * thread setup enters into here later, you jerk
+ */
+static void setup_thread(struct subscriber *sub)
+{
+	sub->thread = AST_PTHREADT_NULL;
+	ast_mutex_init(&sub->lock);
+	ast_cond_init(&sub->cond, NULL);
+}
+
+/*! \brief This is the callback which is called when
+ * a someone logs into the manager interface. It tells us that someone
+ * wants to receive event notification from us. This function initializes
+ * the subscriber struct and starts the thread which waits for events so
+ * it can spit them out in string form
+ *
+ * \param event the event which caused this thread to execute. ATM the only
+ * type of event that will cause this is AST_EVENT_MANAGER_LOGIN, but that
+ * can certainly change
+ */
+static void subscribe_start(const struct ast_event *event, void *ignore)
+{
+	struct subscriber *sub;
+
+	if (!(sub = ast_calloc(1, sizeof(*sub)))) {
+		/* OH CRAP */
+		ast_log(LOG_WARNING, "Unable to allocate memory for event subscriber! Aborting!\n");
+		return;
+	}
+
+	ast_copy_string(sub->name, ast_event_get_ie_str(event, AST_EVENT_IE_USERNAME), sizeof(sub->name));
+	sub->fd = ast_event_get_ie_uint(event, AST_EVENT_IE_FD);
+
+	ast_debug(3, "Event subscriber %s logged in\n", sub->name);
+
+	setup_thread(sub);
+
+	/* Just for testing purposes, let's subscribe to queue member device state changes */
+	ast_event_subscribe(AST_EVENT_QUEUE_MEMBER_STATUS, info_cb, sub, AST_EVENT_IE_END);
+	ast_pthread_create_background(&sub->thread, NULL, event_spitter, sub);
+}
+
 static int unload_module(void)
 {
-	int i;
-	for (i = 0; i < AST_EVENT_TOTAL; i++) {
-		if (manager_sub[i]) {
-			ast_event_unsubscribe(manager_sub[i]);
-			manager_sub[i] = NULL;
-		}
+	if (login_sub) {
+		ast_event_unsubscribe(login_sub);
 	}
-	if (info_thread.thread != AST_PTHREADT_NULL) {
-		info_thread.stop = 1;
-		ast_mutex_lock(&info_thread.lock);
-		ast_cond_signal(&info_thread.cond);
-		ast_mutex_unlock(&info_thread.lock);
-		pthread_join(info_thread.thread, NULL);
-	}
-	ast_mutex_destroy(&info_thread.lock);
 	return 0;
 }
 
 static int load_module(void)
 {
-	int i;
-	for (i = 0; i < (sizeof(queue_map) / sizeof(queue_map[0])); i++) {
-		manager_sub[i] = ast_event_subscribe(queue_map[i].type, info_cb, NULL, AST_EVENT_IE_END);
+	if (!(login_sub = ast_event_subscribe(AST_EVENT_MANAGER_LOGIN, subscribe_start, NULL, AST_EVENT_IE_END))) {
+		ast_log(LOG_WARNING, "Failed to subscribe to manager login events!\n");
+		return AST_MODULE_LOAD_DECLINE;
 	}
-	ast_mutex_init(&info_thread.lock);
-	ast_cond_init(&info_thread.cond, NULL);
-	ast_pthread_create_background(&info_thread.thread, NULL, event_spitter, NULL);
-	return AST_MODULE_LOAD_SUCCESS; 
+	
+	return AST_MODULE_LOAD_SUCCESS;
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Manager",




More information about the asterisk-commits mailing list