[asterisk-commits] mmichelson: branch group/CCSS r216184 - in /team/group/CCSS: include/asterisk...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Sep 3 15:54:58 CDT 2009


Author: mmichelson
Date: Thu Sep  3 15:54:53 2009
New Revision: 216184

URL: http://svn.asterisk.org/svn-view/asterisk?view=rev&rev=216184
Log:
More progress regarding passing state changes up
a monitor tree. I'm getting some weird compilation
errors right now. I'll work on getting those cleared
up next.


Modified:
    team/group/CCSS/include/asterisk/ccss.h
    team/group/CCSS/main/ccss.c

Modified: team/group/CCSS/include/asterisk/ccss.h
URL: http://svn.asterisk.org/svn-view/asterisk/team/group/CCSS/include/asterisk/ccss.h?view=diff&rev=216184&r1=216183&r2=216184
==============================================================================
--- team/group/CCSS/include/asterisk/ccss.h (original)
+++ team/group/CCSS/include/asterisk/ccss.h Thu Sep  3 15:54:53 2009
@@ -26,6 +26,7 @@
 
 #include "asterisk.h"
 #include "asterisk/linkedlists.h"
+#include "asterisk/devicestate.h"
 
 enum ast_cc_service_type {
 	/* No Service available/requested */
@@ -504,6 +505,22 @@
 	const struct ast_cc_monitor_callbacks *callbacks;
 	/*! Data specific to a monitor implementation */
 	void *private_data;
+	/* When a device monitor has a state change, it will
+	 * determine what link to send the change announcement
+	 * on, and then it will keep a pointer to that saved
+	 * link. This way, the monitor is sure to continue
+	 * communicating with the same upstream extension
+	 * monitor even if a lower-weighted link should
+	 * become unsuspended
+	 */
+	struct ast_cc_monitor_link *saved_link;
+	/* The current state of the device monitor's device.
+	 * Even though not all device monitors subscribe
+	 * to device state, the monitors should be able to
+	 * translate the state information into this type
+	 * for uniformity.
+	 */
+	enum ast_device_state state;
 	/*! The name of the device/extension being monitored */
 	char name[1];
 };

Modified: team/group/CCSS/main/ccss.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/group/CCSS/main/ccss.c?view=diff&rev=216184&r1=216183&r2=216184
==============================================================================
--- team/group/CCSS/main/ccss.c (original)
+++ team/group/CCSS/main/ccss.c Thu Sep  3 15:54:53 2009
@@ -959,6 +959,11 @@
 	char debug[1];
 };
 
+struct cc_devstate_args {
+	enum ast_device_state state;
+	struct ast_cc_monitor *monitor;
+};
+
 static void destroy_link(struct ast_cc_monitor_link *link)
 {
 	ao2_ref(link->child, -1);
@@ -991,10 +996,93 @@
 	}
 }
 
+/*!
+ * \brief pass a state change up the monitor tree
+ *
+ * When a device monitor has had a state change, it will try
+ * to find the proper upstream link to report on. This is the
+ * function which is called to do so. Unless there was
+ * some terrible construction error, the monitor passed to this
+ * function will always be an extension monitor or the root monitor.
+ * Extension monitors will check the state machine to see what the
+ * current state is. If the state is one where getting the monitored
+ * device's status would be useful, then the extension monitor will
+ * report it upstream.
+ *
+ * If the root monitor should be notified of a status change, then this
+ * means that the state change has been screened to the point that
+ * the core should be alerted of it. The root monitor will request a
+ * core state machine change to the CC_CALLEE_READY state
+ */
+static int pass_state_up(struct ast_cc_monitor *monitor, enum ast_device_state state, int core_id)
+{
+	/* STUB */
+	return 0;
+}
+
+/*!
+ * \brief process a reported device state change from a monitor
+ *
+ * Since this executes in the core taskprocessor thread,
+ * there is no need to worry about doing any locking of
+ * lists or links.
+ * \param datap pointer to the monitor reporting the state change
+ */
 static int cc_devstate_change(void *datap)
 {
-	/* STUB */
-	return 0;
+	/* Let's map this out a bit.
+	   The device being monitored has
+	   had a device state change.
+
+	   According to architecture doc, the device monitor
+	   should report the state change to a parent extension
+	   monitor. In choosing which one to report the change
+	   to, it should choose the lowest weighted unsuspended
+	   link. That's easy enough to find.
+
+	   It's important that once we have picked a link, we
+	   need to continue feeding information to that link
+	   until it goes away or becomes suspended. So the
+	   monitor is going to keep a pointer to whichever
+	   link it has chosen. This will change if the link
+	   gets destroyed or becomes suspended.
+	 */
+	struct cc_devstate_args *args = datap;
+	enum ast_device_state state = args->state;
+	struct ast_cc_monitor *monitor = args->monitor;
+	struct ast_cc_monitor_link *link = monitor->saved_link;
+
+	monitor->state = state;
+
+	if (link && !link->is_suspended) {
+		return pass_state_up(link->parent, state, link->core_id);
+	}
+
+	/* Dang, we need to find the lowest weighted unsuspended
+	   link. Link weights are established at the time that CC
+	   requests are issued. Since weights increase chronologically
+	   and links are always added to the tail of the list, we
+	   know that links at the head are weighted lower than links
+	   at the end of the list.
+	 */
+	AST_LIST_TRAVERSE(&monitor->parent_links, link, next_parent) {
+		if (!link->is_suspended) {
+			break;
+		}
+	}
+
+	if (!link) {
+		/* Hmm, all upstream links are suspended. Nothing wrong with
+		   that. It just means that there's no one to report this
+		   change to. Since we've saved the current state on the
+		   monitor, we'll be able to report this state upstream
+		   as soon as one of the links becomes unsuspended.
+		 */
+		return 0;
+	}
+
+	/* We found a link to report on. Yay */
+	return pass_state_up(link->parent, state, link->core_id);
 }
 
 static int cc_do_state_change(void *datap)
@@ -1307,7 +1395,15 @@
 	 * so that all monitor operations can be serialized. Locks?! We don't need
 	 * no steenkin' locks!
 	 */
-	ast_taskprocessor_push(cc_core_taskprocessor, cc_devstate_change, userdata);
+	struct cc_devstate_args *args = ast_calloc(1, sizeof(*args));
+
+	if (!args) {
+		return;
+	}
+
+	args->state = ast_event_get_ie_uint(event, AST_EVENT_IE_STATE);
+	args->monitor = userdata;
+	ast_taskprocessor_push(cc_core_taskprocessor, cc_devstate_change, args);
 	return;
 }
 




More information about the asterisk-commits mailing list