From 17e2416f680cd15be8a23d4b119642ad0e305f26 Mon Sep 17 00:00:00 2001
From: Mark Spencer <markster@digium.com>
Date: Sat, 13 Mar 2004 06:00:41 +0000
Subject: [PATCH] Merge queue changes from Bug #214

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@2415 65c4cc65-6c06-0410-ace0-fbb531ad65f3
---
 CHANGES                       |   2 +
 Makefile                      |   2 +-
 apps/app_queue.c              | 304 +++++++++++++++++++++++++++++++---
 configs/queues.conf.sample    |  34 ++++
 sounds.txt                    |  12 ++
 sounds/queue-callswaiting.gsm | Bin 0 -> 3366 bytes
 sounds/queue-holdtime.gsm     | Bin 0 -> 4026 bytes
 sounds/queue-minutes.gsm      | Bin 0 -> 1056 bytes
 sounds/queue-thankyou.gsm     | Bin 0 -> 2739 bytes
 sounds/queue-thereare.gsm     | Bin 0 -> 3234 bytes
 sounds/queue-youarenext.gsm   | Bin 0 -> 8283 bytes
 11 files changed, 333 insertions(+), 21 deletions(-)
 create mode 100755 sounds/queue-callswaiting.gsm
 create mode 100755 sounds/queue-holdtime.gsm
 create mode 100755 sounds/queue-minutes.gsm
 create mode 100755 sounds/queue-thankyou.gsm
 create mode 100755 sounds/queue-thereare.gsm
 create mode 100755 sounds/queue-youarenext.gsm

diff --git a/CHANGES b/CHANGES
index 58728c7c7f..f2a13716b5 100755
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,5 @@
+ -- ADPCM Standardization
+ -- Numerous bug fixes
  -- Add IAX2 Firmware Support
  -- Add G.726 support
  -- Add ices/icecast support
diff --git a/Makefile b/Makefile
index da0aab927d..e8fbe76616 100755
--- a/Makefile
+++ b/Makefile
@@ -269,7 +269,7 @@ datafiles: all
 			exit 1; \
 		fi; \
 	done
-	for x in sounds/vm-* sounds/transfer* sounds/pbx-* sounds/ss-* sounds/beep* sounds/dir-* sounds/conf-* sounds/agent-* sounds/invalid* sounds/tt-* sounds/auth-* sounds/privacy-*; do \
+	for x in sounds/vm-* sounds/transfer* sounds/pbx-* sounds/ss-* sounds/beep* sounds/dir-* sounds/conf-* sounds/agent-* sounds/invalid* sounds/tt-* sounds/auth-* sounds/privacy-* sounds/queue-*; do \
 		if grep -q "^%`basename $$x`%" sounds.txt; then \
 			install -m 644 $$x $(DESTDIR)$(ASTVARLIBDIR)/sounds ; \
 		else \
diff --git a/apps/app_queue.c b/apps/app_queue.c
index 2f762497d9..8094904b06 100755
--- a/apps/app_queue.c
+++ b/apps/app_queue.c
@@ -7,6 +7,21 @@
  *
  * Mark Spencer <markster@linux-support.net>
  *
+ * These features added by David C. Troy <dave@toad.net>:
+ *    - Per-queue holdtime calculation
+ *    - Estimated holdtime announcement
+ *    - Position announcement
+ *    - Abandoned/completed call counters
+ *    - Failout timer passed as optional app parameter
+ *    - Optional monitoring of calls, started when call is answered
+ *
+ * Patch Version 1.07 2003-12-24 01
+ *
+ * Added servicelevel statistic by Michiel Betel <michiel@betel.nl>
+ *
+ * Fixed ot work with CVS as of 2004-02-25 and released as 1.07a
+ * by Matthew Enger <m.enger@xi.com.au>
+ *
  * This program is free software, distributed under the terms of
  * the GNU General Public License
  */
@@ -25,6 +40,7 @@
 #include <asterisk/cli.h>
 #include <asterisk/manager.h> /* JDG */
 #include <asterisk/config.h>
+#include <asterisk/monitor.h>
 #include <stdlib.h>
 #include <errno.h>
 #include <unistd.h>
@@ -67,7 +83,7 @@ static char *app = "Queue";
 static char *synopsis = "Queue a call for a call queue";
 
 static char *descrip =
-"  Queue(queuename[|options[|URL][|announceoverride]]):\n"
+"  Queue(queuename[|options[|URL][|announceoverride][|timeout]]):\n"
 "Queues an incoming call in a particular call queue as defined in queues.conf.\n"
 "  This application returns -1 if the originating channel hangs up, or if the\n"
 "call is bridged and  either of the parties in the bridge terminate the call.\n"
@@ -81,7 +97,9 @@ static char *descrip =
 "  In addition to transferring the call, a call may be parked and then picked\n"
 "up by another user.\n"
 "  The optional URL will be sent to the called party if the channel supports\n"
-"it.\n";
+"it.\n"
+"  The timeout will cause the queue to fail out after a specified number of\n"
+"seconds, checked between each queues.conf 'timeout' and 'retry' cycle.\n";
 
 // [PHM 06/26/03]
 static char *app_aqm = "AddQueueMember" ;
@@ -127,12 +145,15 @@ LOCAL_USER_DECL;
 struct queue_ent {
 	struct ast_call_queue *parent;	/* What queue is our parent */
 	char moh[80];				/* Name of musiconhold to be used */
-	char announce[80];		/* Announcement to play */
+	char announce[80];		/* Announcement to play for member when call is answered */
 	char context[80];		/* Context when user exits queue */
 	int pos;					/* Where we are in the queue */
+	int last_pos_said;              /* Last position we told the user */
+	time_t last_pos;                /* Last time we told the user their position */
 	int opos;					/* Where we started in the queue */
 	int handled;				/* Whether our call was handled */
 	time_t start;				/* When we started holding */
+	int queuetimeout;               /* How many seconds before timing out of queue */
 	struct ast_channel *chan;	/* Our channel */
 	struct queue_ent *next;		/* The next queue entry */
 };
@@ -151,10 +172,24 @@ struct ast_call_queue {
 	ast_mutex_t	lock;	
 	char name[80];			/* Name of the queue */
 	char moh[80];			/* Name of musiconhold to be used */
-	char announce[80];		/* Announcement to play */
-	char context[80];		/* Announcement to play */
+	char announce[80];		/* Announcement to play when call is answered */
+	char context[80];		/* Context for this queue */
 	int strategy;			/* Queueing strategy */
-	int announcetimeout;	/* How often to announce their position */
+	int announcefrequency;          /* How often to announce their position */
+	int announceholdtime;           /* When to announce holdtime: 0 = never, -1 = every announcement, 1 = only once */
+	int holdtime;                   /* Current avg holdtime for this queue, based on recursive boxcar filter */
+	int callscompleted;             /* Number of queue calls completed */
+	int callsabandoned;             /* Number of queue calls abandoned */
+	int servicelevel;               /* seconds setting for servicelevel*/
+	int callscompletedinsl;         /* Number of queue calls answererd with servicelevel*/
+	char monfmt[8];                 /* Format to use when recording calls */
+	char sound_next[80];            /* Sound file: "Your call is now first in line" (def. queue-youarenext) */
+	char sound_thereare[80];        /* Sound file: "There are currently" (def. queue-thereare) */
+	char sound_calls[80];           /* Sound file: "calls waiting to speak to a representative." (def. queue-callswaiting)*/
+	char sound_holdtime[80];        /* Sound file: "The current estimated total holdtime is" (def. queue-holdtime) */
+	char sound_minutes[80];         /* Sound file: "minutes." (def. queue-minutes) */
+	char sound_thanks[80];          /* Sound file: "Thank you for your patience." (def. queue-thankyou) */
+
 	int count;				/* How many entries are in the queue */
 	int maxlen;				/* Max number of entries in queue */
 
@@ -288,6 +323,102 @@ static void destroy_queue(struct ast_call_queue *q)
 	free(q);
 }
 
+static int play_file(struct ast_channel *chan, char *filename)
+{
+	int res;
+
+	ast_stopstream(chan);
+	res = ast_streamfile(chan, filename, chan->language);
+
+	if (!res)
+		res = ast_waitstream(chan, "");
+	else
+		res = 0;
+
+	if (res) {
+		ast_log(LOG_WARNING, "ast_streamfile failed on %s \n", chan->name);
+		res = 0;
+	}
+	ast_stopstream(chan);
+
+	return res;
+}
+
+static int say_position(struct queue_ent *qe)
+{
+	int res = 0, avgholdmins;
+	time_t now;
+
+	/* Check to see if this is ludicrous -- if we just announced position, don't do it again*/
+	time(&now);
+	if ( (now - qe->last_pos) < 15 )
+		return -1;
+
+	/* If either our position has changed, or we are over the freq timer, say position */
+	if ( (qe->last_pos_said == qe->pos) && ((now - qe->last_pos) < qe->parent->announcefrequency) )
+		return -1;
+
+	ast_moh_stop(qe->chan);
+	/* Say we're next, if we are */
+	if (qe->pos == 1) {
+		res += play_file(qe->chan, qe->parent->sound_next);
+		goto posout;
+	} else {
+		res += play_file(qe->chan, qe->parent->sound_thereare);
+		res += ast_say_number(qe->chan, qe->pos, AST_DIGIT_ANY, qe->chan->language);
+		res += play_file(qe->chan, qe->parent->sound_calls);
+	}
+
+	/* Round hold time to nearest minute */
+	avgholdmins = ( (qe->parent->holdtime + 30) - (now - qe->start) ) / 60;
+	ast_verbose(VERBOSE_PREFIX_3 "Hold time for %s is %d minutes\n", qe->parent->name, avgholdmins);
+
+	/* If the hold time is >1 min, if it's enabled, and if it's not
+	   supposed to be only once and we have already said it, say it */
+	if (avgholdmins > 1 && (qe->parent->announceholdtime) && (!(qe->parent->announceholdtime==1 && qe->last_pos)) ) {
+		res += play_file(qe->chan, qe->parent->sound_holdtime);
+		res += ast_say_number(qe->chan, avgholdmins, AST_DIGIT_ANY, qe->chan->language);
+		res += play_file(qe->chan, qe->parent->sound_minutes);
+	}
+
+	posout:
+	/* Set our last_pos indicators */
+ 	qe->last_pos = now;
+	qe->last_pos_said = qe->pos;
+
+	ast_verbose(VERBOSE_PREFIX_3 "Told %s in %s their queue position (which was %d)\n", qe->chan->name, qe->parent->name, qe->pos);
+	res += play_file(qe->chan, qe->parent->sound_thanks);
+	ast_moh_start(qe->chan, qe->moh);
+
+	return (res>0);
+}
+
+static void record_abandoned(struct queue_ent *qe)
+{
+	ast_mutex_lock(&qe->parent->lock);
+	qe->parent->callsabandoned++;
+	ast_mutex_unlock(&qe->parent->lock);
+}
+
+static void recalc_holdtime(struct queue_ent *qe)
+{
+	int oldvalue, newvalue;
+
+	/* Calculate holdtime using a recursive boxcar filter */
+	/* Thanks to SRT for this contribution */
+	/* 2^2 (4) is the filter coefficient; a higher exponent would give old entries more weight */
+
+	newvalue = time(NULL) - qe->start;
+
+	ast_mutex_lock(&qe->parent->lock);
+	if (newvalue <= qe->parent->servicelevel)
+       		qe->parent->callscompletedinsl++;
+	oldvalue = qe->parent->holdtime;
+	qe->parent->holdtime = (((oldvalue << 2) - oldvalue) + newvalue) >> 2;
+	ast_mutex_unlock(&qe->parent->lock);
+}
+
+
 static void leave_queue(struct queue_ent *qe)
 {
 	struct ast_call_queue *q;
@@ -317,6 +448,7 @@ ast_log(LOG_NOTICE, "Queue '%s' Leave, Channel '%s'\n", q->name, qe->chan->name
 			else
 				q->head = cur->next;
 		} else {
+			/* Renumber the people after us in the queue based on a new count */
 			cur->pos = ++pos;
 			prev = cur;
 		}
@@ -611,12 +743,29 @@ static int wait_our_turn(struct queue_ent *qe)
 {
 	struct queue_ent *ch;
 	int res = 0;
+	time_t now;
+
+	/* This is the holding pen for callers 2 through maxlen */
 	for (;;) {
 		/* Atomically read the parent head -- does not need a lock */
 		ch = qe->parent->head;
+
 		/* If we are now at the top of the head, break out */
-		if (qe->parent->head == qe)
+		if (qe == ch)
+			break;
+
+		/* If we have timed out, break out */
+		if ( qe->queuetimeout ) {
+			time(&now);
+			if ( (now - qe->start) >= qe->queuetimeout )
 			break;
+		}
+
+		/* Make a position announcement, if enabled */
+		if (qe->parent->announcefrequency)
+			say_position(qe);
+
+
 		/* Wait a second before checking again */
 		res = ast_waitfordigit(qe->chan, RECHECK * 1000);
 		if (res)
@@ -640,6 +789,7 @@ static int update_queue(struct ast_call_queue *q, struct localuser *user)
 		}
 		cur = cur->next;
 	}
+	q->callscompleted++;
 	ast_mutex_unlock(&q->lock);
 	return 0;
 }
@@ -793,6 +943,7 @@ static int try_calling(struct queue_ent *qe, char *options, char *announceoverri
 	if (!peer) {
 		if (to) {
 			/* Musta gotten hung up */
+			record_abandoned(qe);
 			res = -1;
 		} else {
 			if (digit && valid_exit(qe, digit))
@@ -817,6 +968,7 @@ static int try_calling(struct queue_ent *qe, char *options, char *announceoverri
 			ast_channel_setoption(peer,AST_OPTION_TONE_VERIFY,&zapx,sizeof(char),0);
 		}
 		/* Update parameters for the queue */
+		recalc_holdtime(qe);
 		update_queue(qe->parent, lpeer);
 		hanguptree(outgoing, peer);
 		/* Stop music on hold */
@@ -849,6 +1001,10 @@ static int try_calling(struct queue_ent *qe, char *options, char *announceoverri
 			ast_hangup(peer);
 			return -1;
 		}
+		/* Begin Monitoring */
+		if (qe->parent->monfmt && *qe->parent->monfmt) {
+			ast_monitor_start( peer, qe->parent->monfmt, qe->chan->cdr->uniqueid, 1 );
+		}
 		/* Drop out of the queue at this point, to prepare for next caller */
 		leave_queue(qe);			
  		/* JDG: sendurl */
@@ -1120,6 +1276,7 @@ static int queue_exec(struct ast_channel *chan, void *data)
 	char *options = NULL;
 	char *url = NULL;
 	char *announceoverride = NULL;
+	char *queuetimeoutstr = NULL;
 	/* whether to exit Queue application after the timeout hits */
 	int go_on = 0;
 
@@ -1134,6 +1291,9 @@ static int queue_exec(struct ast_channel *chan, void *data)
 	}
 	
 	LOCAL_USER_ADD(u);
+
+	/* Setup our queue entry */
+	memset(&qe, 0, sizeof(qe));
 	
 	/* Parse our arguments XXX Check for failure XXX */
 	strncpy(info, (char *)data, strlen((char *)data) + AST_MAX_EXTENSION-1);
@@ -1151,25 +1311,39 @@ static int queue_exec(struct ast_channel *chan, void *data)
 				if (announceoverride) {
 					*announceoverride = '\0';
 					announceoverride++;
+					queuetimeoutstr = strchr(announceoverride, '|');
+					if (queuetimeoutstr) {
+						*queuetimeoutstr = '\0';
+						queuetimeoutstr++;
+						qe.queuetimeout = atoi(queuetimeoutstr);
+					} else {
+						qe.queuetimeout = 0;
 				}
 			}
 		}
 	}
-	if (option_debug)
-		ast_log(LOG_DEBUG, "queue: %s, options: %s, url: %s, announce: %s\n",
-					queuename, options, url, announceoverride);
-	/* Setup our queue entry */
-	memset(&qe, 0, sizeof(qe));
+	}
+
+	printf("queue: %s, options: %s, url: %s, announce: %s, timeout: %d\n",
+		queuename, options, url, announceoverride, qe.queuetimeout);
+
+
 	qe.chan = chan;
 	qe.start = time(NULL);
+	qe.last_pos_said = 0;
+	qe.last_pos = 0;
 	if (!join_queue(queuename, &qe)) {
 		ast_queue_log(queuename, chan->uniqueid, "NONE", "ENTERQUEUE", "%s|%s", url ? url : "", chan->callerid ? chan->callerid : "");
 		/* Start music on hold */
 		ast_moh_start(chan, qe.moh);
 		for (;;) {
+			/* This is the wait loop for callers 2 through maxlen */
+
 			res = wait_our_turn(&qe);
 			/* If they hungup, return immediately */
 			if (res < 0) {
+				/* Record this abandoned call */
+				record_abandoned(&qe);
 				ast_queue_log(queuename, chan->uniqueid, "NONE", "ABANDON", "%d|%d|%ld", qe.pos, qe.opos, (long)time(NULL) - qe.start);
 				if (option_verbose > 2) {
 					ast_verbose(VERBOSE_PREFIX_3 "User disconnected while waiting their turn\n");
@@ -1186,6 +1360,22 @@ static int queue_exec(struct ast_channel *chan, void *data)
 		}
 		if (!res) {
 			for (;;) {
+				/* This is the wait loop for the head caller*/
+				/* To exit, they may get their call answered; */
+				/* they may dial a digit from the queue context; */
+				/* or, they may may timeout. */
+
+				/* Leave if we have exceeded our queuetimeout */
+				if (qe.queuetimeout && ( (time(NULL) - qe.start) >= qe.queuetimeout) ) {
+					res = 0;
+					break;
+				}
+
+				/* Make a position announcement, if enabled */
+				if (qe.parent->announcefrequency)
+					say_position(&qe);
+
+				/* Try calling all queue members for 'timeout' seconds */
 				res = try_calling(&qe, options, announceoverride, url, &go_on);
 				if (res) {
 					if (res < 0) {
@@ -1195,6 +1385,14 @@ static int queue_exec(struct ast_channel *chan, void *data)
 						ast_queue_log(queuename, chan->uniqueid, "NONE", "EXITWITHKEY", "%c|%d", res, qe.pos);
 					break;
 				}
+
+				/* Leave if we have exceeded our queuetimeout */
+				if (qe.queuetimeout && ( (time(NULL) - qe.start) >= qe.queuetimeout) ) {
+					res = 0;
+					break;
+				}
+
+				/* OK, we didn't get anybody; wait for 'retry' seconds; may get a digit to exit with */
 				res = wait_a_bit(&qe);
 				if (res < 0) {
 					ast_queue_log(queuename, chan->uniqueid, "NONE", "ABANDON", "%d|%d|%ld", qe.pos, qe.opos, (long)time(NULL) - qe.start);
@@ -1208,18 +1406,20 @@ static int queue_exec(struct ast_channel *chan, void *data)
 					ast_queue_log(queuename, chan->uniqueid, "NONE", "EXITWITHKEY", "%c|%d", res, qe.pos);
 					break;
 				}
-				/* exit after a timeout if 'n' option enabled */
+				/* exit after 'timeout' cycle if 'n' option enabled */
 				if (go_on) {
 					ast_queue_log(queuename, chan->uniqueid, "NONE", "EXITWITHTIMEOUT", "%d", qe.pos);
 					res = 0;
 					break;
 				}
+
 			}
 		}
 		/* Don't allow return code > 0 */
 		if (res > 0 && res != AST_PBX_KEEPALIVE) {
 			res = 0;	
 			ast_moh_stop(chan);
+			ast_stopstream(chan);
 		}
 		leave_queue(&qe);
 	} else {
@@ -1281,10 +1481,24 @@ static void reload_queues(void)
 				q->retry = 0;
 				q->timeout = -1;
 				q->maxlen = 0;
+				q->announcefrequency = 0;
+				q->announceholdtime = 0;
+				q->holdtime = 0;
+				q->callscompleted = 0;
+				q->callsabandoned = 0;
+				q->callscompletedinsl = 0;
+				q->servicelevel = 0;
 				free_members(q, 0);
 				strcpy(q->moh, "");
 				strcpy(q->announce, "");
 				strcpy(q->context, "");
+				strcpy(q->monfmt, "");
+				strcpy(q->sound_next, "queue-youarenext");
+				strcpy(q->sound_thereare, "queue-thereare");
+				strcpy(q->sound_calls, "queue-callswaiting");
+				strcpy(q->sound_holdtime, "queue-holdtime");
+				strcpy(q->sound_minutes, "queue-minutes");
+				strcpy(q->sound_thanks, "queue-thankyou");
 				prev = q->members;
 				if (prev) {
 					/* find the end of any dynamic members */
@@ -1329,10 +1543,30 @@ static void reload_queues(void)
 						strncpy(q->context, var->value, sizeof(q->context) - 1);
 					} else if (!strcasecmp(var->name, "timeout")) {
 						q->timeout = atoi(var->value);
+					} else if (!strcasecmp(var->name, "monitor-format")) {
+						strncpy(q->monfmt, var->value, sizeof(q->monfmt) - 1);
+					} else if (!strcasecmp(var->name, "queue-youarenext")) {
+						strncpy(q->sound_next, var->value, sizeof(q->sound_next) - 1);
+					} else if (!strcasecmp(var->name, "queue-thereare")) {
+						strncpy(q->sound_thereare, var->value, sizeof(q->sound_thereare) - 1);
+					} else if (!strcasecmp(var->name, "queue-callswaiting")) {
+						strncpy(q->sound_calls, var->value, sizeof(q->sound_calls) - 1);
+					} else if (!strcasecmp(var->name, "queue-holdtime")) {
+						strncpy(q->sound_holdtime, var->value, sizeof(q->sound_holdtime) - 1);
+					} else if (!strcasecmp(var->name, "queue-minutes")) {
+						strncpy(q->sound_minutes, var->value, sizeof(q->sound_minutes) - 1);
+					} else if (!strcasecmp(var->name, "queue-thankyou")) {
+						strncpy(q->sound_thanks, var->value, sizeof(q->sound_thanks) - 1);
+					} else if (!strcasecmp(var->name, "announce-frequency")) {
+						q->announcefrequency = atoi(var->value);
+					} else if (!strcasecmp(var->name, "announce-holdtime")) {
+						q->announceholdtime = (!strcasecmp(var->value,"once")) ? 1 : ast_true(var->value);
 					} else if (!strcasecmp(var->name, "retry")) {
 						q->retry = atoi(var->value);
 					} else if (!strcasecmp(var->name, "maxlen")) {
 						q->maxlen = atoi(var->value);
+					} else if (!strcasecmp(var->name, "servicelevel")) {
+						q->servicelevel= atoi(var->value);
 					} else if (!strcasecmp(var->name, "strategy")) {
 						q->strategy = strat2int(var->value);
 						if (q->strategy < 0) {
@@ -1390,6 +1624,8 @@ static int __queues_show(int fd, int argc, char **argv, int queue_show)
 	time_t now;
 	char max[80];
 	char calls[80];
+	float sl = 0;
+
 	time(&now);
 	if ((!queue_show && argc != 2) || (queue_show && argc != 3))
 		return RESULT_SHOWUSAGE;
@@ -1420,7 +1656,11 @@ static int __queues_show(int fd, int argc, char **argv, int queue_show)
 			snprintf(max, sizeof(max), "%d", q->maxlen);
 		else
 			strcpy(max, "unlimited");
-		ast_cli(fd, "%-12.12s has %d calls (max %s) in '%s' strategy\n", q->name, q->count, max, int2strat(q->strategy));
+		sl = 0;
+		if(q->callscompleted > 0)
+			sl = 100*((float)q->callscompletedinsl/(float)q->callscompleted);
+		ast_cli(fd, "%-12.12s has %d calls (max %s) in '%s' strategy (%ds holdtime), C:%d, A:%d, SL:%2.1f%% within %ds\n",
+			q->name, q->count, max, int2strat(q->strategy), q->holdtime, q->callscompleted, q->callsabandoned,sl,q->servicelevel);
 		if (q->members) {
 			ast_cli(fd, "   Members: \n");
 			for (mem = q->members; mem; mem = mem->next) {
@@ -1502,6 +1742,8 @@ static int manager_queues_status( struct mansession *s, struct message *m )
 	char idText[256] = "";
 	struct ast_call_queue *q;
 	struct queue_ent *qe;
+	float sl = 0;
+	struct member *mem;
 	astman_send_ack(s, m, "Queue status will follow");
 	time(&now);
 	ast_mutex_lock(&qlock);
@@ -1511,21 +1753,43 @@ static int manager_queues_status( struct mansession *s, struct message *m )
 	}
 	while(q) {
 		ast_mutex_lock(&q->lock);
+
+		/* List queue properties */
+		if(q->callscompleted > 0)
+			sl = 100*((float)q->callscompletedinsl/(float)q->callscompleted);
 		ast_cli(s->fd, "Event: QueueParams\r\n"
 					"Queue: %s\r\n"
 					"Max: %d\r\n"
 					"Calls: %d\r\n"
+					"Holdtime: %d\r\n"
+					"Completed: %d\r\n"
+					"Abandoned: %d\r\n"
+					"ServiceLevel: %d\r\n"
+					"ServicelevelPerf: %2.1f\r\n"
 					"%s"
 					"\r\n",
-						q->name, q->maxlen, q->count,idText);
-#if 0
-		/* Do we care about queue members? */					
+						q->name, q->maxlen, q->count, q->holdtime, q->callscompleted,
+						q->callsabandoned, q->servicelevel, sl, idText);
+
+		/* List Queue Members */
 		for (mem = q->members; mem; mem = mem->next) 
-			ast_cli(fd, "      %s/%s\n", mem->tech, mem->loc);
-#endif			
+			ast_cli(s->fd, "Event: QueueMember\r\n"
+				"Queue: %s\r\n"
+				"Location: %s/%s\r\n"
+				"Membership: %s\r\n"
+				"Penalty: %d\r\n"
+				"CallsTaken: %d\r\n"
+				"LastCall: %ld\r\n"
+				"%s"
+				"\r\n",
+					q->name, mem->tech, mem->loc, mem->dynamic ? "dynamic" : "static",
+					mem->penalty, mem->calls, mem->lastcall, idText);
+
+		/* List Queue Entries */
+
 		pos = 1;
 		for (qe = q->head; qe; qe = qe->next) 
-			ast_cli(s->fd, "Event: QueueMember\r\n"
+			ast_cli(s->fd, "Event: QueueEntry\r\n"
 				"Queue: %s\r\n"
 				"Position: %d\r\n"
 				"Channel: %s\r\n"
diff --git a/configs/queues.conf.sample b/configs/queues.conf.sample
index dff5da17e2..75dabab540 100755
--- a/configs/queues.conf.sample
+++ b/configs/queues.conf.sample
@@ -2,6 +2,11 @@
 ;
 ; Global settings for call queues
 ;   (none exist currently)
+;
+; Note that a timeout to fail out of a queue may be passed as part of application call
+; from extensions.conf:
+; Queue(queuename|[options]|[optionalurl]|[announceoverride]|[timeout])
+; example: Queue(dave|t|||45)
 
 [default]
 ;
@@ -53,6 +58,35 @@
 ;
 ;maxlen = 0
 ;
+;
+; How often to announce queue position and/or estimated holdtime to caller (0=off)
+;
+;announce-frequency = 90 
+;
+; Should we include estimated hold time in position announcements?
+; Either yes, no, or only once; hold time will not be announced if <1 minute
+;
+;announce-holdtime = yes|no|once
+;
+; Use these sound files in making position/holdtime announcements.  The
+; defaults are as listed below -- change only if you need to.
+;
+;queue-youarenext = queue-youarenext		("You are now first in line.")
+;queue-thereare	= queue-thereare		("There are")
+;queue-callswaiting = queue-callswaiting	("calls waiting.")
+;queue-holdtime = queue-holdtime		("The current est. holdtime is")
+;queue-minutes = queue-minutes			("minutes.")
+;queue-thankyou = queue-thankyou		("Thank you for your patience.")
+;
+; Calls may be recorded using Asterisk's monitor resource
+; This can be enabled from within the Queue application, starting recording
+; when the call is actually picked up; thus, only successful calls are
+; recorded, and you are not recording while people are listening to MOH.
+; To enable monitoring, simply specify "monitor-format";  it will be disabled
+; otherwise.
+;
+; monitor-format = gsm|wav|wav49
+;
 ; Each member of this call queue is listed on a separate line in
 ; the form technology/dialstring.  "member" means a normal member of a
 ; queue.  An optional penalty may be specified after a comma, such that
diff --git a/sounds.txt b/sounds.txt
index dea1946428..833f8805ee 100755
--- a/sounds.txt
+++ b/sounds.txt
@@ -72,6 +72,18 @@
 
 %pbx-transfer.gsm%Transfer.
 
+%queue-callswaiting.gsm%Waiting to speak with a representative
+
+%queue-holdtime.gsm%The estimated hold time is currently
+
+%queue-minutes.gsm%Minutes
+
+%queue-thankyou.gsm%Thank you for your patience
+
+%queue-thereare.gsm%You are currently caller number
+
+%queue-youarenext.gsm%Your call is now first in line and will be answered by the next available representative.
+
 %ss-noservice.gsm%The number you have dialed is not in service. Please check the number and try again.
 
 %transfer.gsm%Please hold while I try that extension.
diff --git a/sounds/queue-callswaiting.gsm b/sounds/queue-callswaiting.gsm
new file mode 100755
index 0000000000000000000000000000000000000000..60596fd8b9ed51d289bcd8e3b34cb9aa38460f7f
GIT binary patch
literal 3366
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

literal 0
HcmV?d00001

diff --git a/sounds/queue-holdtime.gsm b/sounds/queue-holdtime.gsm
new file mode 100755
index 0000000000000000000000000000000000000000..fd3e03cc610bb6f6502ce25547a5f546b52ded66
GIT binary patch
literal 4026
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
YZM{H@E`U!91T#Ir6}}#csmH+o1&x&p6951J

literal 0
HcmV?d00001

diff --git a/sounds/queue-minutes.gsm b/sounds/queue-minutes.gsm
new file mode 100755
index 0000000000000000000000000000000000000000..e7053f7de9293075c6b386afdf3934d4250f6b48
GIT binary patch
literal 1056
zcmV+*1mFA7=Hz9eP#{SpjkhCIU`Zp6M;mycNhFd;+k}8QY_=q&(QVWzV}U@qWNDhy
zhd|jHXEiK`V6^OtX%U3rxl_6_<IywBDPn;j)aGrv;lV)K+m*F+f8Yxvk@n7iK*dwh
zH6+nCykR20Af<AOG}V5<=FL&7YP`UjqjyBq*uggEu_mk5Aw2R$d&SFhAPH`5X(1YN
zT?l;&dZm)FVtZ*>auug7)S+GJMSCe&#cDewyGBObdO9(G1lKLHE){`A_gKKoEYo3i
z;SIrMF^RUv5`p61VWBua!z5bztT^3+LigYq8E(?weX+*HBUl$=N3(~9AJeTmUWY>=
zYPnD(%*0x^a2B1>YQ*K+jKrJVZMRyCBHv<V+Y8=8cG6DPrr@E<(mKYk(Ja*|V(y|i
zigmQNQsGisay2cW!FX9xHl<ZS`r1iK)YBkMY1~_(Y?37vcUNJ#>uENfx5miik`5(Q
zLYds&7D3b9M0$j-f}Pck>|(T|GQToOs$T)=0((r)yyG<?ZTBPBBm{BEVMWOtZM0`l
z!)~35!ii^ODbuPr<7q@T;hn1$*CjLV0c!(E8;&+K;G#~YlrmInVxQfO=N)AOw3-&n
zB-kn%W`o-TxfE_OOzz`cUctm0-hzX@lDO^NA*&KH$sg9^A|}M#;yojvMjBdy^)xox
zZQi0O1G&cR;DHMfZJ|BZ;~67_aUoXZ=&0h}!b#PN$m-!?#`15r<=~+!8*rxB)fz&d
z65zr2DsD*JazL9JY1?Jc065~NINYdUHKcmSanfaroutsfSmkO)W5r-eC6Q8FV!$0<
zsYZHWz$TB<<oeRzlad`_V9I22$z8P|7<z`8b6kK|Oi`yKxS(Y#OuXgPA7hzR#-K@C
zO&Ha{09P5(RGVA?IV6qP<etDuE0STP*4<-OQ|bUpopM;@oFF$Fj!7-<z)0F_6pn15
zMp0R`oY&=p+1hx(CY3H7B(p$hrP9Z3b6{G1tyb5C#77*GM&H<JbS2VfBnq6aHr#$e
zIHZn5>EvLz<1xc2>L66t&X_sb@RQz)uK?w;XuN3EVI@;71e1P&HDHa$F5ICg<?Y*U
z*|Dr*j8Nf7^0P{zp#ZGcox-l!K{Gq9y&aUn_M&ko64`LHmfUc`n%WK4T+G3k+l$yq
zQbA7gim4lv!0Mw`(*)Wttls3XV3?Iz)ef$~T`S*M)4ag3EU=~;zM)F(aiJaAv6S9j
z@PRg?PR})<;a2LBOp2DEgOX0fL$yGx<gKAC*(hU4QN-Zs8f`eE>cHgNZMhTdAay9#
zt8?A}%Pfj!^w?}_T0*?QcQlKTopeA#-A$<?vLHm`Y9}L_;5Q^`#}n3GdR<ZM05;=I
axm(r%IV5sg-P!;-T#hLuPyk5el1U`eUKT9?

literal 0
HcmV?d00001

diff --git a/sounds/queue-thankyou.gsm b/sounds/queue-thankyou.gsm
new file mode 100755
index 0000000000000000000000000000000000000000..c611f5b78329bb4d9eccfa0a9f222cd9eb080a60
GIT binary patch
literal 2739
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

literal 0
HcmV?d00001

diff --git a/sounds/queue-thereare.gsm b/sounds/queue-thereare.gsm
new file mode 100755
index 0000000000000000000000000000000000000000..cb6cdd44c2cc2f31abcd5fd4871ed9176b287542
GIT binary patch
literal 3234
zcmV;T3|;fn8-3+tP(U{%jyma50BIy~*(HF0IUAD6BU>Oei<^58)tVM|Q&oVVl(|W5
zTLHA1@u_58K*~}RQKenMO&l;<+|-#KwbNbUYg0yhZC$}s(oMQ(xdHs6i8>-(p-eJz
zIaAb`E;bWg!L&P)OC!6Y2$HTzCA(qNf^lf$y8_u`VaBxA;01QuU*t(7kpKf-WNZKS
zLWEyLsb;##09)gw+mXo-*(L-p(P1Y5)cWfhRi@Tq@@E`V!xUGZG{8~kGnbM?n%15b
zYs#CZsV8(p7?y~mZ>7r_;b`61GDO$gX<EyYB+t^{ju%^w$9Uy%27c1!Cp0Oan$pF)
z5RU9CiA5+e?;PmTXOt6hheZr~int_%#JtnYp7z3prsPXUg}-BP{a8H;((RHGvwZ}c
z9&0u#c;xuyB0Zb6L%bAvIS}t8sU}i|-O}r;NwTdZ@~c-%3UNdw-mQo`ZzanbqUl?2
zM524mQeV_7qe?Js<7q4d?bmImv@Uigk86fyVyJl|Yp1w*in&kJu#1*pYskf8hA#4J
z=(5jQQr2tbtfVkUo@>U}1R2Rq)bMMfn4wA8BVx&9*XBmx=B|)!2x**zPc+$UQf0C@
zhSaNs8K`f_M%_wyDsQCY;t9GurzZI9X@ff7XVVaR$eh$Ebq>+tCp5f~N*1dGZj6ho
zV&cZsCAt}jw8m@bkQ}bl=8PR-v}88eZC_p1W3vOYT<O$82@`j;;?5wEf5W5`(=U|W
z*v=sQbBP-j&LFE2tk)vI0J%(3wCmiU7rrd??bIxLCTYl^R*i1!Qlj8Q@`bw|+#p1e
zZMxESfHb4gxTM&)gwdhqz*`tdsq;}G%Nw@IzFEsi+?-b>TTQ0irrMa<bd-)^goq5$
zrfiDUDyh>)DCFKKXxwG|Z{Dg|3RO$=**2VyT4u|H;wgUPU?x|~X}YnjsU0Y`M4j#@
zkKd@tpxCr@lG9SiPb)PUB-(}Oppnd+x~DS7hbIws$f>N=K&98JGtSI^NPQYE#hP}f
zM0;|!sM^O`ypa<e=%#TY8SLHFC_EQcZiX=wxaOO*gjG|5Zm8abxU6xw$K0el6Jm36
z)aX27VxOcQY+0pboP(`WE32EDgQJ|yu{oV&$4usC*wd<PVPk0{N^fxr<7q;;hgQg$
zoP+f(jH>3FBgVyw#|6{uRaRQjB4ONtS2Jqkvm>@PGt$DnWJ0TLpTWfhiptE>>TMZf
z)qxo!z)0n7qEa+<*$!=DJF8;HaBqTkIjz|0)@MFhif@D{-j0atr-ay`s<|X{<W*d6
zGP-jF$tHruWY{S+pF?-a)Z<ml7<tH}D!oR`d!w=Qt|X7UMs|xzAHUb7HCqFL#XgjG
zH;;uznbx(2)Q2SXe`GY}&1hcQN=Y5npGDflk0o-!j#2B@#w0V9FI3$JM0||cl;X%C
z<C02k)E;I|M4rYI%dtr$s3Io8w>74;LRf(+^)0r+*5e>IoYG{Sk{QOKU0f+LB*NiX
zv{k1y(7{CH?P%k4z!kW})cw*WtYPThV9e}tNR8g08zs5+vw)xrq9ns&*+9!HjRRfM
z-;AalV1S#W(6?i9U{@nj%L=gITAhf*uHvCc<!wiL)Ej+bWmUq&@UR-)fnqB)a1dKs
zf!Pl7&t7K&7e=bwywc!(9;IOeHv?)^<Y6I7S()1?!lGMrXr<L*LQ`z9xD(Ueb(<Am
zL8)nd_SC}xlm(hyY-5EvAhpJ&U1(P0W3=1Vo=q=9VaMoPsE^HGM%UwRk{?|L2XmTB
z8og!7Zj!~~)}1`_Lcc^L*Pa)sV*})kLFb{xWkp$e5$9t;!2ew1nAf2dc2dbiS=(+_
z)XO7Agp$=ZXG2!vLA_$nB-tx&wuRT99kSBTB01B#ohEAmfNc4>o7ExtDM8Ph)dNW5
zu0(^^o)$97Yk>!vF*u`bVj-V~TO?~@IU)*6)YT$8Ep9eL)mcX}0@VU7+*0Kn*8#_U
zut{6i!I=^(-AmbFW|?S^sMZ-TGK$v$ZxoeQWo<z)HkGes+aZZ6acd=UL3Hbu7U9*|
zE%M88Aj6zaxme_&#+m}Ff#v}2+;uk+l%R<<jyoFGTt!ul+CZrrakqxF;JJ#fTPvu*
zIhuBDRm1>k8j-ad)Z1*G5bB^R+h)X^=Abm&Z8<E8KsK9kxh=i`H*IaXB-!S(rCNhv
z$t~9FEpGtbBxyHn>LAF`D3p+^%C_5Ww<p;5onl~Hk0joDQ5#eUa#r53RiFwq-SRnM
z#3{7ow8kCRt(6)Yu&Nsq(#3D>DYAo6xnx|)He{uFW3Gj0UmXl;)^Ma&o9jq*s#IpF
znx;%VmC9n!sixhty&CB%fJL+Y;?*u{)&W$>kWuc}6R4<F7B@*m?ugeBE!W&ohe04k
z`>xb8TG|3srbLoM*=3}sNep7v`tFC?oJe<N@krR)N2w{)Hbg0cok!-<6Du8>$ynPO
zSmfy?c@b4+w3_BdL#oMa)Aux~0+_}|MRG|c<wC|FYP@@yLclrCNz>(GgU*t^+SB%0
zX^@$M@ujY;;F+Y0B(hZznMCI#mna3}B<C!)whYsBf#F%>COI6HK%|#r^=34OlH()i
zZZHd!;Uzn4aE_$XwNYiFmm^u5jd5MzqPrC*w=Lk}R?>X8ap1z#$bCoV(lU9S>*B$t
z3gxY)<e?ZwrMtW6!Qk#IJ7S#yVN`ClYtk#D){~n;#v_s|qftS?a*bOfRYEZHk2_jX
z<2bplJk!$bds;(Lq)?rwtt(K+5<OkpQ=90qYjMd{ok$^~a!DN1X^hfBoko#!)mp0U
z<p%GK)uEpy6D*C_%bx`iI*Cmi)TCCD1D{2QWR7=R?+4M-t=jBSr9^s>Ra2t{g>8*#
zBh_R!(*mOh2`jBw-BDzW)sAIbp+tonu=iS{fr=vO#VOR|KO0F=M1^F{=&Pe6g`x56
zWT68xEP5|o@nVsc(dgpUVkWBC@nsWav3A-~ft)y{dX%4|DAI19RG$SS8kNsg)ZsR+
zke|XDV&_=x?L?Vc>UgT3VybL%RJyXm2(6OMQ_$(IbsDy#BnvX#qUs?6qtH2inju7#
z&an3EA?A~^RA<oe++`Y4fm+H<*qvB_zX(Z6+^nGekRr!QQ6SrUNLMn@^4sMaRUqv%
zXv$+%0Gn-TryQvOr)7zuV^yH!<aNB;(_WR4&9A7(B$5^*Qz^$Ku{2*%2$!n1CdE_8
zyGxB%C)6Uf4TMt3DcrTD0#|9TTy;hnQ)qW{a<@lSrYhpB^Uu^ItkJ?(2!%22M^#rR
zGB=&MDz8Nr57(zxu?Cz`Tzcfwse+=yTP5MiPc_rCCHQ1Vq?fYCyHkud^Rq;HwT>{x
z(yVHx1Y09H(~+vpw8Ql*PP19G!^PCGOAWTe63>&VEYYiyUR%tf2!pcPW6&WgtRbZL
z)ImueaRwX0f!VBb#@Nv-qiU&a!Kq(POB`aMGZU*e?!cis*@?x|V1ZdQY?Ca|ucPu|
zV!)QSsleS~V695BDG|VdSsTqME5iWP-ErjI(5|#5DPthVB1)^O#-N`qY^NP$;MUc#
zNQ%iI#@>y_?a;BTUFmATl;U?a9MHhn;gz=~>VOEF*+9{%fEezPYa`U<Yznh`;HJ?`
zO?F~|ZDUQj3zopERqg2|)uqWC<s_`q=WUwsX2r{7L<uHb$Vp^!Cc0Rqs-=zC2wx=g
zD!MqT)Fe)xpj`uwrqSBvy96{5^G76K1l3?}JtMtC$6R7Ot<+^cBH+K{ILqO2oMS_1
zc1lEr!y?`_H>V=OLI+>AEi2RJCtlINLb_XhMC@NdB{ECVjJ-kV+O(_2y<)dyRkGjG
zsb-o{yCK)3dPu>$L9VotIaReH5;b|pp;;nG6sp6d(&twiQCC7Yi0(+HSHVLRxJ+JE
zAxTg-j@_jpzSJ(p<<hEeQcR&DK4lKKB<!NvqY^n?l!4@+8Od&vp%6ux&2!RgcU6kk
z!I53D=t+q|^7}R<rG&xV6|9LK$brh_A~~kg=1$&_fg(7>j#n#uqKQ<lRAjcHyB>&F
zTzJ7|#yYo>)MPc{@^pcyt!_02aKSfI!f3SKp(zZ`!E@3;=(1`@-PI*LVj-TOs+_6C
zM9{#;8*8@_grL~;aw}uLU`6$3S>@JeJe4TmAXO{T-^=cRDxx;J3{rqdqfN9M;($34
zB{}QXBs^td&fqxPPgxaaphn}d$sE#vI^&LJ<)a{J9-28M)nR+>0)D_bQ*Fl^jvz+c
Ul1C#@07)d0NhDAJNhFd<BvdM7rvLx|

literal 0
HcmV?d00001

diff --git a/sounds/queue-youarenext.gsm b/sounds/queue-youarenext.gsm
new file mode 100755
index 0000000000000000000000000000000000000000..3d543965a682d418b5ebd0043a2bfb359f3b57da
GIT binary patch
literal 8283
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

literal 0
HcmV?d00001

-- 
GitLab