<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>