diff options
author | George Joseph <gjoseph@digium.com> | 2017-12-19 14:15:48 -0600 |
---|---|---|
committer | Gerrit Code Review <gerrit2@gerrit.digium.api> | 2017-12-19 14:15:48 -0600 |
commit | 5554bc6b530cd8470e6cbba4d551a346cca1f1f9 (patch) | |
tree | d8c91f39529e03dbe23521706e853d1f60120a94 /apps | |
parent | a100baccb54f8a43b74f2241fe06f5efb326bab0 (diff) | |
parent | 5335ad117d1fa9e606041665b1be634bc75c59e8 (diff) |
Merge "app_queue: Add feature to set wrapuptime on the queue member"
Diffstat (limited to 'apps')
-rw-r--r-- | apps/app_queue.c | 66 |
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); |