summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorRodrigo Ramírez Norambuena <a@rodrigoramirez.com>2017-12-06 23:35:40 -0300
committerRichard Mudgett <rmudgett@digium.com>2017-12-18 17:29:21 -0600
commit5335ad117d1fa9e606041665b1be634bc75c59e8 (patch)
treede240aae6f21484ccc1fbffff83560e8cca2581c /apps
parent7b127e2d20a59850c0ef080afd38c2ade6a34422 (diff)
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
Diffstat (limited to 'apps')
-rw-r--r--apps/app_queue.c66
1 files changed, 59 insertions, 7 deletions
diff --git a/apps/app_queue.c b/apps/app_queue.c
index a140847c6..af8b3b88b 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@digium.com>
*
@@ -1586,6 +1586,7 @@ struct member {
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 */
@@ -1826,6 +1827,21 @@ static int queue_cmp_cb(void *obj, void *arg, int flags)
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.
* \param obj the member being acted on
@@ -2309,8 +2325,12 @@ static int get_member_status(struct call_queue *q, int max_penalty, int min_pena
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 void update_status(struct call_queue *q, struct member *m, const int stat
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 @@ static int is_member_available(struct call_queue *q, struct member *mem)
}
/* 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 @@ static void rt_handle_member_record(struct call_queue *q, char *category, struct
int penalty = 0;
int paused = 0;
int found = 0;
+ int wrapuptime = 0;
int ringinuse = q->ringinuse;
const char *config_val;
@@ -3363,6 +3386,7 @@ static void rt_handle_member_record(struct call_queue *q, char *category, struct
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"));
@@ -3385,6 +3409,13 @@ static void rt_handle_member_record(struct call_queue *q, char *category, struct
}
}
+ if (wrapuptime_str) {
+ wrapuptime = atoi(wrapuptime_str);
+ if (wrapuptime < 0) {
+ wrapuptime = 0;
+ }
+ }
+
if ((config_val = ast_variable_retrieve(member_config, category, realtime_ringinuse_field))) {
if (ast_true(config_val)) {
ringinuse = 1;
@@ -3411,6 +3442,7 @@ static void rt_handle_member_record(struct call_queue *q, char *category, struct
}
m->penalty = penalty;
m->ringinuse = ringinuse;
+ m->wrapuptime = wrapuptime;
found = 1;
ao2_ref(m, -1);
break;
@@ -4343,6 +4375,8 @@ static int member_status_available(int status)
*/
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 @@ static int can_ring_entry(struct queue_ent *qe, struct callattempt *call)
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 @@ static int queue_function_mem_read(struct ast_channel *chan, const char *cmd, ch
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 @@ static void reload_single_member(const char *memberdata, struct call_queue *q)
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 @@ static void reload_single_member(const char *memberdata, struct call_queue *q)
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);