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

Rodrigo Ramirez Norambuena asteriskteam at digium.com
Wed Dec 6 20:36:57 CST 2017


Rodrigo Ramirez Norambuena has uploaded this change for review. ( https://gerrit.asterisk.org/7460


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

app_queue: Add feature to set wrapuptime in the member

This patch include the availability to set the wrapuptime in the
member config.

When is set the wrapuptime in the member is use this instead of the
queue.

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



  git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/60/7460/1

diff --git a/CHANGES b/CHANGES
index b2b7409..436f6ed 100644
--- a/CHANGES
+++ b/CHANGES
@@ -26,6 +26,12 @@
    headers be retrieved from the REFER message and made accessible to the
    dialplan in the hash TRANSFER_DATA.
 
+app_queue
+------------------
+ * Added the availability to set the wrapuptime in the configuration of member.
+   When is set the wrapuptime in the member is used this instead of the 
+   configuration on queue.
+
 ------------------------------------------------------------------------------
 --- 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 801695f..edb58c5 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>
  *
@@ -1587,6 +1587,7 @@
 	int callcompletedinsl;               /*!< Whether the current call was completed within service level */
 	time_t starttime;                    /*!< The time at which the member answered the current caller. */
 	time_t lastcall;                     /*!< When last successful call was hungup */
+	int wrapuptime;                      /*!< Wrapup Time */
 	time_t lastpause;                    /*!< When started the last pause */
 	struct call_queue *lastqueue;	     /*!< Last queue we received a call */
 	unsigned int dead:1;                 /*!< Used to detect members deleted in realtime */
@@ -1824,6 +1825,20 @@
 	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
  * \brief ao2_callback, Decreases queuepos of all followers with a queuepos greater than arg.
@@ -2308,8 +2323,8 @@
 			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);
@@ -2435,6 +2450,7 @@
 static int is_member_available(struct call_queue *q, struct member *mem)
 {
 	int available = 0;
+	int wrapuptime = get_wrapuptime(q, mem);
 
 	switch (mem->status) {
 		case AST_DEVICE_INVALID:
@@ -2458,7 +2474,7 @@
 	}
 
 	/* Let wrapuptimes override device state availability */
-	if (mem->lastcall && q->wrapuptime && (time(NULL) - q->wrapuptime < mem->lastcall)) {
+	if (mem->lastcall && wrapuptime && (time(NULL) - wrapuptime < mem->lastcall)) {
 		available = 0;
 	}
 	return available;
@@ -3340,6 +3356,7 @@
 	int penalty = 0;
 	int paused  = 0;
 	int found = 0;
+	int wrapuptime = 0;
 	int ringinuse = q->ringinuse;
 
 	const char *config_val;
@@ -3349,6 +3366,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"));
@@ -3368,6 +3386,13 @@
 		paused = atoi(paused_str);
 		if (paused < 0) {
 			paused = 0;
+		}
+	}
+
+	if (wrapuptime_str) {
+		wrapuptime = atoi(wrapuptime_str);
+		if (wrapuptime < 0) {
+			wrapuptime = 0;
 		}
 	}
 
@@ -3397,6 +3422,7 @@
 			}
 			m->penalty = penalty;
 			m->ringinuse = ringinuse;
+			m->wrapuptime = wrapuptime;
 			found = 1;
 			ao2_ref(m, -1);
 			break;
@@ -4329,6 +4355,15 @@
  */
 static int can_ring_entry(struct queue_ent *qe, struct callattempt *call)
 {
+
+	 int wrapuptime = 0;
+
+	 if (call->lastqueue){
+		 wrapuptime = get_wrapuptime(call->lastqueue, call->member);
+	 } else if(qe->parent){
+		 wrapuptime = get_wrapuptime(qe->parent, call->member);
+	 }
+
 	if (call->member->paused) {
 		ast_debug(1, "%s paused, can't receive call\n", call->interface);
 		return 0;
@@ -4339,8 +4374,9 @@
 		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 && (time(NULL) - call->lastcall < wrapuptime))
+		|| (!call->lastqueue && 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);
@@ -8540,7 +8576,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);
@@ -9084,12 +9120,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)) {
@@ -9144,11 +9182,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/8b85c32f5750_add_wrapuptime_to_queue_members.py b/contrib/ast-db-manage/config/versions/8b85c32f5750_add_wrapuptime_to_queue_members.py
new file mode 100644
index 0000000..dec2428
--- /dev/null
+++ b/contrib/ast-db-manage/config/versions/8b85c32f5750_add_wrapuptime_to_queue_members.py
@@ -0,0 +1,22 @@
+"""add wrapuptime to queue_members
+
+Revision ID: 8b85c32f5750
+Revises: 2da192dbbc65
+Create Date: 2017-09-18 20:02:34.138260
+
+"""
+
+# revision identifiers, used by Alembic.
+revision = '8b85c32f5750'
+down_revision = '2da192dbbc65'
+
+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: newchange
Gerrit-Change-Id: I11c85809537f974eb44dc5bbf82bcedd8a458902
Gerrit-Change-Number: 7460
Gerrit-PatchSet: 1
Gerrit-Owner: Rodrigo Ramirez Norambuena <a at rodrigoramirez.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20171206/7abe45ef/attachment-0001.html>


More information about the asterisk-code-review mailing list