<p>Rodrigo Ramirez Norambuena has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/7460">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">app_queue: Add feature to set wrapuptime in the member<br><br>This patch include the availability to set the wrapuptime in the<br>member config.<br><br>When is set the wrapuptime in the member is use this instead of the<br>queue.<br><br>Change-Id: I11c85809537f974eb44dc5bbf82bcedd8a458902<br>---<br>M CHANGES<br>M apps/app_queue.c<br>M configs/samples/queues.conf.sample<br>A contrib/ast-db-manage/config/versions/8b85c32f5750_add_wrapuptime_to_queue_members.py<br>4 files changed, 86 insertions(+), 8 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/60/7460/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/CHANGES b/CHANGES<br>index b2b7409..436f6ed 100644<br>--- a/CHANGES<br>+++ b/CHANGES<br>@@ -26,6 +26,12 @@<br> headers be retrieved from the REFER message and made accessible to the<br> dialplan in the hash TRANSFER_DATA.<br> <br>+app_queue<br>+------------------<br>+ * Added the availability to set the wrapuptime in the configuration of member.<br>+ When is set the wrapuptime in the member is used this instead of the <br>+ configuration on queue.<br>+<br> ------------------------------------------------------------------------------<br> --- Functionality changes from Asterisk 15.1.0 to Asterisk 15.2.0 ------------<br> ------------------------------------------------------------------------------<br>diff --git a/apps/app_queue.c b/apps/app_queue.c<br>index 801695f..edb58c5 100644<br>--- a/apps/app_queue.c<br>+++ b/apps/app_queue.c<br>@@ -1,7 +1,7 @@<br> /*<br> * Asterisk -- An open source telephony toolkit.<br> *<br>- * Copyright (C) 1999 - 2016, Digium, Inc.<br>+ * Copyright (C) 1999 - 2017, Digium, Inc.<br> *<br> * Mark Spencer <markster@digium.com><br> *<br>@@ -1587,6 +1587,7 @@<br> int callcompletedinsl; /*!< Whether the current call was completed within service level */<br> time_t starttime; /*!< The time at which the member answered the current caller. */<br> time_t lastcall; /*!< When last successful call was hungup */<br>+ int wrapuptime; /*!< Wrapup Time */<br> time_t lastpause; /*!< When started the last pause */<br> struct call_queue *lastqueue; /*!< Last queue we received a call */<br> unsigned int dead:1; /*!< Used to detect members deleted in realtime */<br>@@ -1824,6 +1825,20 @@<br> struct call_queue *q = obj, *q2 = arg;<br> return !strcasecmp(q->name, q2->name) ? CMP_MATCH | CMP_STOP : 0;<br> }<br>+<br>+/*! \brief Return wrapuptime<br>+ *<br>+ * This function checks if wrapuptime in member is set and return this value.<br>+ * Otherwise return value the wrapuptime in the queue configuration<br>+ * \return integer value<br>+ */<br>+static int get_wrapuptime(struct call_queue *q, struct member *member)<br>+{<br>+ if (member->wrapuptime)<br>+ return member->wrapuptime;<br>+ return q->wrapuptime;<br>+}<br>+<br> <br> /*! \internal<br> * \brief ao2_callback, Decreases queuepos of all followers with a queuepos greater than arg.<br>@@ -2308,8 +2323,8 @@<br> if (member->paused && (conditions & QUEUE_EMPTY_PAUSED)) {<br> ast_debug(4, "%s is unavailable because he is paused'\n", member->membername);<br> break;<br>- } else if ((conditions & QUEUE_EMPTY_WRAPUP) && member->lastcall && q->wrapuptime && (time(NULL) - q->wrapuptime < member->lastcall)) {<br>- 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);<br>+ } else if ((conditions & QUEUE_EMPTY_WRAPUP) && member->lastcall && get_wrapuptime(q, member) && (time(NULL) - get_wrapuptime(q, member) < member->lastcall)) {<br>+ 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));<br> break;<br> } else {<br> ao2_ref(member, -1);<br>@@ -2435,6 +2450,7 @@<br> static int is_member_available(struct call_queue *q, struct member *mem)<br> {<br> int available = 0;<br>+ int wrapuptime = get_wrapuptime(q, mem);<br> <br> switch (mem->status) {<br> case AST_DEVICE_INVALID:<br>@@ -2458,7 +2474,7 @@<br> }<br> <br> /* Let wrapuptimes override device state availability */<br>- if (mem->lastcall && q->wrapuptime && (time(NULL) - q->wrapuptime < mem->lastcall)) {<br>+ if (mem->lastcall && wrapuptime && (time(NULL) - wrapuptime < mem->lastcall)) {<br> available = 0;<br> }<br> return available;<br>@@ -3340,6 +3356,7 @@<br> int penalty = 0;<br> int paused = 0;<br> int found = 0;<br>+ int wrapuptime = 0;<br> int ringinuse = q->ringinuse;<br> <br> const char *config_val;<br>@@ -3349,6 +3366,7 @@<br> const char *state_interface = S_OR(ast_variable_retrieve(member_config, category, "state_interface"), interface);<br> const char *penalty_str = ast_variable_retrieve(member_config, category, "penalty");<br> const char *paused_str = ast_variable_retrieve(member_config, category, "paused");<br>+ const char *wrapuptime_str = ast_variable_retrieve(member_config, category, "wrapuptime");<br> <br> if (ast_strlen_zero(rt_uniqueid)) {<br> ast_log(LOG_WARNING, "Realtime field uniqueid is empty for member %s\n", S_OR(membername, "NULL"));<br>@@ -3368,6 +3386,13 @@<br> paused = atoi(paused_str);<br> if (paused < 0) {<br> paused = 0;<br>+ }<br>+ }<br>+<br>+ if (wrapuptime_str) {<br>+ wrapuptime = atoi(wrapuptime_str);<br>+ if (wrapuptime < 0) {<br>+ wrapuptime = 0;<br> }<br> }<br> <br>@@ -3397,6 +3422,7 @@<br> }<br> m->penalty = penalty;<br> m->ringinuse = ringinuse;<br>+ m->wrapuptime = wrapuptime;<br> found = 1;<br> ao2_ref(m, -1);<br> break;<br>@@ -4329,6 +4355,15 @@<br> */<br> static int can_ring_entry(struct queue_ent *qe, struct callattempt *call)<br> {<br>+<br>+ int wrapuptime = 0;<br>+<br>+ if (call->lastqueue){<br>+ wrapuptime = get_wrapuptime(call->lastqueue, call->member);<br>+ } else if(qe->parent){<br>+ wrapuptime = get_wrapuptime(qe->parent, call->member);<br>+ }<br>+<br> if (call->member->paused) {<br> ast_debug(1, "%s paused, can't receive call\n", call->interface);<br> return 0;<br>@@ -4339,8 +4374,9 @@<br> return 0;<br> }<br> <br>- if ((call->lastqueue && call->lastqueue->wrapuptime && (time(NULL) - call->lastcall < call->lastqueue->wrapuptime))<br>- || (!call->lastqueue && qe->parent->wrapuptime && (time(NULL) - call->lastcall < qe->parent->wrapuptime))) {<br>+<br>+ if ((call->lastqueue && wrapuptime && (time(NULL) - call->lastcall < wrapuptime))<br>+ || (!call->lastqueue && wrapuptime && (time(NULL) - call->lastcall < wrapuptime))) {<br> ast_debug(1, "Wrapuptime not yet expired on queue %s for %s\n",<br> (call->lastqueue ? call->lastqueue->name : qe->parent->name),<br> call->interface);<br>@@ -8540,7 +8576,7 @@<br> while ((m = ao2_iterator_next(&mem_iter))) {<br> /* Count the agents who are logged in, not paused and not wrapping up */<br> if ((m->status == AST_DEVICE_NOT_INUSE) && (!m->paused) &&<br>- !(m->lastcall && q->wrapuptime && ((now - q->wrapuptime) < m->lastcall))) {<br>+ !(m->lastcall && get_wrapuptime(q, m) && ((now - get_wrapuptime(q, m)) < m->lastcall))) {<br> count++;<br> }<br> ao2_ref(m, -1);<br>@@ -9084,12 +9120,14 @@<br> struct member tmpmem;<br> int penalty;<br> int ringinuse;<br>+ int wrapuptime;<br> AST_DECLARE_APP_ARGS(args,<br> AST_APP_ARG(interface);<br> AST_APP_ARG(penalty);<br> AST_APP_ARG(membername);<br> AST_APP_ARG(state_interface);<br> AST_APP_ARG(ringinuse);<br>+ AST_APP_ARG(wrapuptime);<br> );<br> <br> if (ast_strlen_zero(memberdata)) {<br>@@ -9144,11 +9182,23 @@<br> ringinuse = q->ringinuse;<br> }<br> <br>+ if (!ast_strlen_zero(args.wrapuptime)) {<br>+ tmp = args.wrapuptime;<br>+ ast_strip(tmp);<br>+ wrapuptime = atoi(tmp);<br>+ if (wrapuptime < 0) {<br>+ wrapuptime = 0;<br>+ }<br>+ } else {<br>+ wrapuptime = 0;<br>+ }<br>+<br> /* Find the old position in the list */<br> ast_copy_string(tmpmem.interface, interface, sizeof(tmpmem.interface));<br> cur = ao2_find(q->members, &tmpmem, OBJ_POINTER);<br> <br> if ((newm = create_queue_member(interface, membername, penalty, cur ? cur->paused : 0, state_interface, ringinuse))) {<br>+ newm->wrapuptime = wrapuptime;<br> if (cur) {<br> /* Round Robin Queue Position must be copied if this is replacing an existing member */<br> ao2_lock(q->members);<br>diff --git a/configs/samples/queues.conf.sample b/configs/samples/queues.conf.sample<br>index 3e7cbd8..226a3a9 100644<br>--- a/configs/samples/queues.conf.sample<br>+++ b/configs/samples/queues.conf.sample<br>@@ -551,7 +551,7 @@<br> ; must also preload pbx_config.so and chan_local.so (or pbx_ael.so, pbx_lua.so,<br> ; or pbx_realtime.so, depending on how your dialplan is configured).<br> ;<br>-; syntax: member => interface,[,penalty][,membername][,state_interface][,ringinuse]<br>+; syntax: member => interface,[,penalty][,membername][,state_interface][,ringinuse][,wrapuptime]<br> ;<br> ;member => DAHDI/1<br> ;member => DAHDI/2,10<br>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<br>new file mode 100644<br>index 0000000..dec2428<br>--- /dev/null<br>+++ b/contrib/ast-db-manage/config/versions/8b85c32f5750_add_wrapuptime_to_queue_members.py<br>@@ -0,0 +1,22 @@<br>+"""add wrapuptime to queue_members<br>+<br>+Revision ID: 8b85c32f5750<br>+Revises: 2da192dbbc65<br>+Create Date: 2017-09-18 20:02:34.138260<br>+<br>+"""<br>+<br>+# revision identifiers, used by Alembic.<br>+revision = '8b85c32f5750'<br>+down_revision = '2da192dbbc65'<br>+<br>+from alembic import op<br>+import sqlalchemy as sa<br>+<br>+<br>+def upgrade():<br>+ op.add_column('queue_members', sa.Column('wrapuptime', sa.Integer))<br>+<br>+<br>+def downgrade():<br>+ op.drop_column('queue_members', 'wrapuptime')<br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/7460">change 7460</a>. To unsubscribe, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/7460"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I11c85809537f974eb44dc5bbf82bcedd8a458902 </div>
<div style="display:none"> Gerrit-Change-Number: 7460 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Rodrigo Ramirez Norambuena <a@rodrigoramirez.com> </div>