[svn-commits] mjordan: branch 11 r373240 - in /branches/11: ./ apps/ configs/

SVN commits to the Digium repositories svn-commits at lists.digium.com
Thu Sep 20 13:59:12 CDT 2012


Author: mjordan
Date: Thu Sep 20 13:59:05 2012
New Revision: 373240

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=373240
Log:
app_queue: Support an 'agent available' hint

Sets INUSE when no free agents, NOT_INUSE when an agent is free.  

modifes handle_statechange() scan members loop to scan for a free agent
and updates the Queue:queuename_avial devstate.

Previously exited early if the member was found in the queue.

Now Exits later when both a member was found, and a free agent was found.


alecdavis (license 585)
Reported by: Alec Davis
Tested by: alecdavis

Review: https://reviewboard.asterisk.org/r/2121/

~~~~

Support all ways a member can be available for 'agent available' hints

Alec's patch in r373188 added the ability to subscribe to a hint for when
Queue members are available.  This patch modifies the check that determines
when a Queue member is available by refactoring the availability checks in
num_available_members into a shared function is_member_available.  This
should now handle the ringinuse option, as well as device state values
other than AST_DEVICE_NOT_INUSE.


Modified:
    branches/11/CHANGES
    branches/11/apps/app_queue.c
    branches/11/configs/extensions.conf.sample

Modified: branches/11/CHANGES
URL: http://svnview.digium.com/svn/asterisk/branches/11/CHANGES?view=diff&rev=373240&r1=373239&r2=373240
==============================================================================
--- branches/11/CHANGES (original)
+++ branches/11/CHANGES Thu Sep 20 13:59:05 2012
@@ -689,6 +689,13 @@
    its value to determine the directory to assume is the top-level directory of
    the source tree.  If the variable is not set, it defaults to the current
    behavior and uses the current working directory.
+
+Queue
+-------------------
+ * Add queue available hint.  exten => 8501,hint,Queue:markq_avail
+   Note: the suffix '_avail' after the queuename.
+   Reports 'InUse' for no logged in agents or no free agents.
+   Reports 'Idle' when an agent is free.
 
 ------------------------------------------------------------------------------
 --- Functionality changes from Asterisk 1.8 to Asterisk 10 -------------------

Modified: branches/11/apps/app_queue.c
URL: http://svnview.digium.com/svn/asterisk/branches/11/apps/app_queue.c?view=diff&rev=373240&r1=373239&r2=373240
==============================================================================
--- branches/11/apps/app_queue.c (original)
+++ branches/11/apps/app_queue.c Thu Sep 20 13:59:05 2012
@@ -1652,6 +1652,39 @@
 	return 0;
 }
 
+/*!
+ * \internal \brief Determine if a queue member is available
+ * \retval 1 if the member is available
+ * \retval 0 if the member is not available
+ */
+static int is_member_available(struct member *mem)
+{
+	int available = 0;
+
+	switch (mem->status) {
+		case AST_DEVICE_INVALID:
+		case AST_DEVICE_UNAVAILABLE:
+			break;
+		case AST_DEVICE_INUSE:
+		case AST_DEVICE_BUSY:
+		case AST_DEVICE_RINGING:
+		case AST_DEVICE_RINGINUSE:
+		case AST_DEVICE_ONHOLD:
+			if (!mem->ringinuse) {
+				break;
+			}
+			/* else fall through */
+		case AST_DEVICE_NOT_INUSE:
+		case AST_DEVICE_UNKNOWN:
+			if (!mem->paused) {
+				available = 1;
+			}
+			break;
+	}
+
+	return available;
+}
+
 /*! \brief set a member's status based on device state of that member's interface*/
 static int handle_statechange(void *datap)
 {
@@ -1660,29 +1693,53 @@
 	struct member *m;
 	struct call_queue *q;
 	char interface[80], *slash_pos;
-	int found = 0;
+	int found = 0;			/* Found this member in any queue */
+	int found_member;		/* Found this member in this queue */
+	int avail = 0;			/* Found an available member in this queue */
 
 	qiter = ao2_iterator_init(queues, 0);
 	while ((q = ao2_t_iterator_next(&qiter, "Iterate over queues"))) {
 		ao2_lock(q);
 
+		avail = 0;
+		found_member = 0;
 		miter = ao2_iterator_init(q->members, 0);
 		for (; (m = ao2_iterator_next(&miter)); ao2_ref(m, -1)) {
-			ast_copy_string(interface, m->state_interface, sizeof(interface));
-
-			if ((slash_pos = strchr(interface, '/'))) {
-				if (!strncasecmp(interface, "Local/", 6) && (slash_pos = strchr(slash_pos + 1, '/'))) {
-					*slash_pos = '\0';
+			if (!found_member) {
+				ast_copy_string(interface, m->state_interface, sizeof(interface));
+
+				if ((slash_pos = strchr(interface, '/'))) {
+					if (!strncasecmp(interface, "Local/", 6) && (slash_pos = strchr(slash_pos + 1, '/'))) {
+						*slash_pos = '\0';
+					}
 				}
-			}
-
-			if (!strcasecmp(interface, sc->dev)) {
-				found = 1;
-				update_status(q, m, sc->state);
+
+				if (!strcasecmp(interface, sc->dev)) {
+					found_member = 1;
+					update_status(q, m, sc->state);
+				}
+			}
+
+			/* check every member until we find one NOT_INUSE */
+			if (!avail) {
+				avail = is_member_available(m);
+			}
+			if (avail && found_member) {
+				/* early exit as we've found an available member and the member of interest */
 				ao2_ref(m, -1);
 				break;
 			}
 		}
+
+		if (found_member) {
+			found = 1;
+			if (avail) {
+				ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Queue:%s_avail", q->name);
+			} else {
+				ast_devstate_changed(AST_DEVICE_INUSE, "Queue:%s_avail", q->name);
+			}
+		}
+
 		ao2_iterator_destroy(&miter);
 
 		ao2_unlock(q);
@@ -3234,26 +3291,8 @@
 
 	mem_iter = ao2_iterator_init(q->members, 0);
 	while ((mem = ao2_iterator_next(&mem_iter))) {
-		switch (mem->status) {
-			case AST_DEVICE_INVALID:
-			case AST_DEVICE_UNAVAILABLE:
-				break;
-			case AST_DEVICE_INUSE:
-			case AST_DEVICE_BUSY:
-			case AST_DEVICE_RINGING:
-			case AST_DEVICE_RINGINUSE:
-			case AST_DEVICE_ONHOLD:
-				if (!mem->ringinuse) {
-					break;
-				}
-				/* else fall through */
-			case AST_DEVICE_NOT_INUSE:
-			case AST_DEVICE_UNKNOWN:
-				if (!mem->paused) {
-					avl++;
-				}
-				break;
-		}
+
+		avl += is_member_available(mem);
 		ao2_ref(mem, -1);
 
 		/* If autofill is not enabled or if the queue's strategy is ringall, then
@@ -5859,7 +5898,11 @@
 			if (queue_persistent_members) {
 				dump_queue_members(q);
 			}
-			
+
+			if (!ao2_container_count(q->members)) {
+				ast_devstate_changed(AST_DEVICE_INUSE, "Queue:%s_avail", q->name);
+			}
+
 			res = RES_OKAY;
 		} else {
 			res = RES_EXISTS;
@@ -5938,6 +5981,10 @@
 
 			if (dump) {
 				dump_queue_members(q);
+			}
+
+			if (ao2_container_count(q->members) == 1) {
+				ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Queue:%s_avail", q->name);
 			}
 
 			res = RES_OKAY;

Modified: branches/11/configs/extensions.conf.sample
URL: http://svnview.digium.com/svn/asterisk/branches/11/configs/extensions.conf.sample?view=diff&rev=373240&r1=373239&r2=373240
==============================================================================
--- branches/11/configs/extensions.conf.sample (original)
+++ branches/11/configs/extensions.conf.sample Thu Sep 20 13:59:05 2012
@@ -713,6 +713,12 @@
 ;exten => 8502,hint,Queue:markq
 ;exten => 8502,1,Queue(markq)
 ;
+
+;To subscribe to the availability of a free member in the 'markq' queue.
+;Note: '_avail' is added to the QueueName
+;exten => 8501,hint,Queue:markq_avail
+;exten => 8501,1,Queue(markq)
+
 ; Some other handy things are an extension for checking voicemail via
 ; voicemailmain
 ;




More information about the svn-commits mailing list