summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlec L Davis <sivad.a@paradise.net.nz>2012-09-19 22:33:12 +0000
committerAlec L Davis <sivad.a@paradise.net.nz>2012-09-19 22:33:12 +0000
commit67ca3b912604b61e9a1dfb99c66cfbb9fc35e15f (patch)
tree5e0e36ee29051b4b06946f7c006935dc55b5ed52
parent9d4f8abdc61d1f6a29093e5ce188c1487cbe1c81 (diff)
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/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@373188 65c4cc65-6c06-0410-ace0-fbb531ad65f3
-rw-r--r--CHANGES7
-rw-r--r--apps/app_queue.c50
-rw-r--r--configs/extensions.conf.sample6
3 files changed, 54 insertions, 9 deletions
diff --git a/CHANGES b/CHANGES
index 5ad343db1..78aaae056 100644
--- a/CHANGES
+++ b/CHANGES
@@ -23,6 +23,13 @@ Logging
individual queue, the PAUSEALL/UNPAUSEALL event will only be logged if at
least one member of any queue exists for that interface.
+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 10 to Asterisk 11 --------------------
------------------------------------------------------------------------------
diff --git a/apps/app_queue.c b/apps/app_queue.c
index d6b5a1663..416a4aa06 100644
--- a/apps/app_queue.c
+++ b/apps/app_queue.c
@@ -1660,29 +1660,53 @@ static int handle_statechange(void *datap)
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 (!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 ((slash_pos = strchr(interface, '/'))) {
+ if (!strncasecmp(interface, "Local/", 6) && (slash_pos = strchr(slash_pos + 1, '/'))) {
+ *slash_pos = '\0';
+ }
+ }
+
+ if (!strcasecmp(interface, sc->dev)) {
+ found_member = 1;
+ update_status(q, m, sc->state);
}
}
- if (!strcasecmp(interface, sc->dev)) {
- found = 1;
- update_status(q, m, sc->state);
+ /* check every member until we find one NOT_INUSE */
+ if (!avail && (m->status == AST_DEVICE_NOT_INUSE) && !m->paused) {
+ avail = 1;
+ }
+ 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);
@@ -5852,7 +5876,11 @@ static int remove_from_queue(const char *queuename, const char *interface)
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;
@@ -5933,6 +5961,10 @@ static int add_to_queue(const char *queuename, const char *interface, const char
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;
} else {
res = RES_OUTOFMEMORY;
diff --git a/configs/extensions.conf.sample b/configs/extensions.conf.sample
index b9d21d361..683739a6b 100644
--- a/configs/extensions.conf.sample
+++ b/configs/extensions.conf.sample
@@ -708,6 +708,12 @@ include => demo
;exten => 6600,hint,park:701@parkedcalls
;exten => 6600,1,noop
;
+
+;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
;