[Asterisk-code-review] app queue: Add feature to set wrapuptime on the queue member (asterisk[master])

George Joseph asteriskteam at digium.com
Tue Dec 19 14:15:49 CST 2017


George Joseph has submitted this change and it was merged. ( https://gerrit.asterisk.org/7460 )

Change subject: app_queue: Add feature to set wrapuptime on the queue member
......................................................................

app_queue: Add feature to set wrapuptime on the queue member

This patch adds the ability to set the wrapuptime on the queue member
config.

When the option is set the wrapuptime on the queue member is used instead
of the queue's wrapuptime.

ASTERISK-27483 #close

Change-Id: I11c85809537f974eb44dc5bbf82bcedd8a458902
---
M CHANGES
M apps/app_queue.c
M configs/samples/queues.conf.sample
A contrib/ast-db-manage/config/versions/e2f04d309071_add_wrapuptime_to_queue_members.py
4 files changed, 88 insertions(+), 8 deletions(-)

Approvals:
  Richard Mudgett: Looks good to me, but someone else must approve
  George Joseph: Looks good to me, approved; Approved for Submit



diff --git a/CHANGES b/CHANGES
index bd1ca67..bd11c6c 100644
--- a/CHANGES
+++ b/CHANGES
@@ -37,6 +37,12 @@
  * The ContactInfo event's contact_status field is now set to "NonQualified"
    when a contact exists but has not been qualified.
 
+app_queue
+------------------
+ * Added the ability to set the wrapuptime in the configuration of member.
+   When set the wrapuptime on the member is used instead of the wrapuptime
+   defined for the queue itself.
+
 ------------------------------------------------------------------------------
 --- Functionality changes from Asterisk 15.1.0 to Asterisk 15.2.0 ------------
 ------------------------------------------------------------------------------
diff --git a/apps/app_queue.c b/apps/app_queue.c
index a140847..af8b3b8 100644
--- a/apps/app_queue.c
+++ b/apps/app_queue.c
@@ -1,7 +1,7 @@
 /*
  * Asterisk -- An open source telephony toolkit.
  *
- * Copyright (C) 1999 - 2016, Digium, Inc.
+ * Copyright (C) 1999 - 2017, Digium, Inc.
  *
  * Mark Spencer <markster at digium.com>
  *
@@ -1586,6 +1586,7 @@
 	char reason_paused[80];              /*!< Reason of paused if member is paused */
 	int queuepos;                        /*!< In what order (pertains to certain strategies) should this member be called? */
 	int callcompletedinsl;               /*!< Whether the current call was completed within service level */
+	int wrapuptime;                      /*!< Wrapup Time */
 	time_t starttime;                    /*!< The time at which the member answered the current caller. */
 	time_t lastcall;                     /*!< When last successful call was hungup */
 	time_t lastpause;                    /*!< When started the last pause */
@@ -1824,6 +1825,21 @@
 {
 	struct call_queue *q = obj, *q2 = arg;
 	return !strcasecmp(q->name, q2->name) ? CMP_MATCH | CMP_STOP : 0;
+}
+
+/*!
+ * \brief Return wrapuptime
+ *
+ * This function checks if wrapuptime in member is set and return this value.
+ * Otherwise return value the wrapuptime in the queue configuration
+ * \return integer value
+ */
+static int get_wrapuptime(struct call_queue *q, struct member *member)
+{
+	if (member->wrapuptime) {
+		return member->wrapuptime;
+	}
+	return q->wrapuptime;
 }
 
 /*! \internal
@@ -2309,8 +2325,12 @@
 			if (member->paused && (conditions & QUEUE_EMPTY_PAUSED)) {
 				ast_debug(4, "%s is unavailable because he is paused'\n", member->membername);
 				break;
-			} else if ((conditions & QUEUE_EMPTY_WRAPUP) && member->lastcall && q->wrapuptime && (time(NULL) - q->wrapuptime < member->lastcall)) {
-				ast_debug(4, "%s is unavailable because it has only been %d seconds since his last call (wrapup time is %d)\n", member->membername, (int) (time(NULL) - member->lastcall), q->wrapuptime);
+			} else if ((conditions & QUEUE_EMPTY_WRAPUP)
+				&& member->lastcall
+				&& get_wrapuptime(q, member)
+				&& (time(NULL) - get_wrapuptime(q, member) < member->lastcall)) {
+				ast_debug(4, "%s is unavailable because it has only been %d seconds since his last call (wrapup time is %d)\n",
+					member->membername, (int) (time(NULL) - member->lastcall), get_wrapuptime(q, member));
 				break;
 			} else {
 				ao2_ref(member, -1);
@@ -2436,6 +2456,7 @@
 static int is_member_available(struct call_queue *q, struct member *mem)
 {
 	int available = 0;
+	int wrapuptime;
 
 	switch (mem->status) {
 		case AST_DEVICE_INVALID:
@@ -2459,7 +2480,8 @@
 	}
 
 	/* Let wrapuptimes override device state availability */
-	if (mem->lastcall && q->wrapuptime && (time(NULL) - q->wrapuptime < mem->lastcall)) {
+	wrapuptime = get_wrapuptime(q, mem);
+	if (mem->lastcall && wrapuptime && (time(NULL) - wrapuptime < mem->lastcall)) {
 		available = 0;
 	}
 	return available;
@@ -3354,6 +3376,7 @@
 	int penalty = 0;
 	int paused  = 0;
 	int found = 0;
+	int wrapuptime = 0;
 	int ringinuse = q->ringinuse;
 
 	const char *config_val;
@@ -3363,6 +3386,7 @@
 	const char *state_interface = S_OR(ast_variable_retrieve(member_config, category, "state_interface"), interface);
 	const char *penalty_str = ast_variable_retrieve(member_config, category, "penalty");
 	const char *paused_str = ast_variable_retrieve(member_config, category, "paused");
+	const char *wrapuptime_str = ast_variable_retrieve(member_config, category, "wrapuptime");
 
 	if (ast_strlen_zero(rt_uniqueid)) {
 		ast_log(LOG_WARNING, "Realtime field uniqueid is empty for member %s\n", S_OR(membername, "NULL"));
@@ -3382,6 +3406,13 @@
 		paused = atoi(paused_str);
 		if (paused < 0) {
 			paused = 0;
+		}
+	}
+
+	if (wrapuptime_str) {
+		wrapuptime = atoi(wrapuptime_str);
+		if (wrapuptime < 0) {
+			wrapuptime = 0;
 		}
 	}
 
@@ -3411,6 +3442,7 @@
 			}
 			m->penalty = penalty;
 			m->ringinuse = ringinuse;
+			m->wrapuptime = wrapuptime;
 			found = 1;
 			ao2_ref(m, -1);
 			break;
@@ -4343,6 +4375,8 @@
  */
 static int can_ring_entry(struct queue_ent *qe, struct callattempt *call)
 {
+	int wrapuptime;
+
 	if (call->member->paused) {
 		ast_debug(1, "%s paused, can't receive call\n", call->interface);
 		return 0;
@@ -4353,8 +4387,12 @@
 		return 0;
 	}
 
-	if ((call->lastqueue && call->lastqueue->wrapuptime && (time(NULL) - call->lastcall < call->lastqueue->wrapuptime))
-		|| (!call->lastqueue && qe->parent->wrapuptime && (time(NULL) - call->lastcall < qe->parent->wrapuptime))) {
+	if (call->lastqueue) {
+		wrapuptime = get_wrapuptime(call->lastqueue, call->member);
+	} else {
+		wrapuptime = get_wrapuptime(qe->parent, call->member);
+	}
+	if (wrapuptime && time(NULL) - call->lastcall < wrapuptime) {
 		ast_debug(1, "Wrapuptime not yet expired on queue %s for %s\n",
 			(call->lastqueue ? call->lastqueue->name : qe->parent->name),
 			call->interface);
@@ -8554,7 +8592,7 @@
 			while ((m = ao2_iterator_next(&mem_iter))) {
 				/* Count the agents who are logged in, not paused and not wrapping up */
 				if ((m->status == AST_DEVICE_NOT_INUSE) && (!m->paused) &&
-						!(m->lastcall && q->wrapuptime && ((now - q->wrapuptime) < m->lastcall))) {
+						!(m->lastcall && get_wrapuptime(q, m) && ((now - get_wrapuptime(q, m)) < m->lastcall))) {
 					count++;
 				}
 				ao2_ref(m, -1);
@@ -9098,12 +9136,14 @@
 	struct member tmpmem;
 	int penalty;
 	int ringinuse;
+	int wrapuptime;
 	AST_DECLARE_APP_ARGS(args,
 		AST_APP_ARG(interface);
 		AST_APP_ARG(penalty);
 		AST_APP_ARG(membername);
 		AST_APP_ARG(state_interface);
 		AST_APP_ARG(ringinuse);
+		AST_APP_ARG(wrapuptime);
 	);
 
 	if (ast_strlen_zero(memberdata)) {
@@ -9158,11 +9198,23 @@
 		ringinuse = q->ringinuse;
 	}
 
+	if (!ast_strlen_zero(args.wrapuptime)) {
+		tmp = args.wrapuptime;
+		ast_strip(tmp);
+		wrapuptime = atoi(tmp);
+		if (wrapuptime < 0) {
+			wrapuptime = 0;
+		}
+	} else {
+		wrapuptime = 0;
+	}
+
 	/* Find the old position in the list */
 	ast_copy_string(tmpmem.interface, interface, sizeof(tmpmem.interface));
 	cur = ao2_find(q->members, &tmpmem, OBJ_POINTER);
 
 	if ((newm = create_queue_member(interface, membername, penalty, cur ? cur->paused : 0, state_interface, ringinuse))) {
+		newm->wrapuptime = wrapuptime;
 		if (cur) {
 			/* Round Robin Queue Position must be copied if this is replacing an existing member */
 			ao2_lock(q->members);
diff --git a/configs/samples/queues.conf.sample b/configs/samples/queues.conf.sample
index 3e7cbd8..226a3a9 100644
--- a/configs/samples/queues.conf.sample
+++ b/configs/samples/queues.conf.sample
@@ -551,7 +551,7 @@
 ; must also preload pbx_config.so and chan_local.so (or pbx_ael.so, pbx_lua.so,
 ; or pbx_realtime.so, depending on how your dialplan is configured).
 ;
-; syntax: member => interface,[,penalty][,membername][,state_interface][,ringinuse]
+; syntax: member => interface,[,penalty][,membername][,state_interface][,ringinuse][,wrapuptime]
 ;
 ;member => DAHDI/1
 ;member => DAHDI/2,10
diff --git a/contrib/ast-db-manage/config/versions/e2f04d309071_add_wrapuptime_to_queue_members.py b/contrib/ast-db-manage/config/versions/e2f04d309071_add_wrapuptime_to_queue_members.py
new file mode 100644
index 0000000..fdb1416
--- /dev/null
+++ b/contrib/ast-db-manage/config/versions/e2f04d309071_add_wrapuptime_to_queue_members.py
@@ -0,0 +1,22 @@
+"""add wrapuptime to queue_members
+
+Revision ID: e2f04d309071
+Revises: 041c0d3d1857
+Create Date: 2017-12-07 08:32:45.360857
+
+"""
+
+# revision identifiers, used by Alembic.
+revision = 'e2f04d309071'
+down_revision = '041c0d3d1857'
+
+from alembic import op
+import sqlalchemy as sa
+
+
+def upgrade():
+    op.add_column('queue_members', sa.Column('wrapuptime', sa.Integer))
+
+
+def downgrade():
+    op.drop_column('queue_members', 'wrapuptime')

-- 
To view, visit https://gerrit.asterisk.org/7460
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-MessageType: merged
Gerrit-Change-Id: I11c85809537f974eb44dc5bbf82bcedd8a458902
Gerrit-Change-Number: 7460
Gerrit-PatchSet: 5
Gerrit-Owner: Rodrigo Ramirez Norambuena <a at rodrigoramirez.com>
Gerrit-Reviewer: George Joseph <gjoseph at digium.com>
Gerrit-Reviewer: Jenkins2
Gerrit-Reviewer: Joshua Colp <jcolp at digium.com>
Gerrit-Reviewer: Richard Mudgett <rmudgett at digium.com>
Gerrit-Reviewer: Rodrigo Ramirez Norambuena <a at rodrigoramirez.com>
Gerrit-Reviewer: Sean Bright <sean.bright at gmail.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20171219/1a0040df/attachment-0001.html>


More information about the asterisk-code-review mailing list