app_queue: Enable set the wrapuptime from AddQueueMember application

This change add ability to set the wrapuptime per-member using the
AddQueueMember application.

The feature to set wrapuptime per member was include in the issue
ASTERISK-27483 for static member by configuration file and was not
added to set from AddQueueMember.

ASTERISK-28055 #close

Change-Id: I7c7ee4a6f804922cd7c42cb02eea26eb3806c6cf
16.3
Rodrigo Ramírez Norambuena 6 years ago committed by Rodrigo Ramirez Norambuena
parent b327b0bbda
commit e806990be2

@ -319,6 +319,7 @@
<parameter name="options" /> <parameter name="options" />
<parameter name="membername" /> <parameter name="membername" />
<parameter name="stateinterface" /> <parameter name="stateinterface" />
<parameter name="wrapuptime" />
</syntax> </syntax>
<description> <description>
<para>Dynamically adds interface to an existing queue. If the interface is <para>Dynamically adds interface to an existing queue. If the interface is
@ -1108,6 +1109,9 @@
<enum name="1"/> <enum name="1"/>
</enumlist> </enumlist>
</parameter> </parameter>
<parameter name="Wrapuptime">
<para>The Wrapup Time of the queue member. If this value is set will override the wrapup time of queue.</para>
</parameter>
</syntax> </syntax>
</managerEventInstance> </managerEventInstance>
</managerEvent> </managerEvent>
@ -2260,7 +2264,7 @@ static void queue_publish_member_blob(struct stasis_message_type *type, struct a
static struct ast_json *queue_member_blob_create(struct call_queue *q, struct member *mem) static struct ast_json *queue_member_blob_create(struct call_queue *q, struct member *mem)
{ {
return ast_json_pack("{s: s, s: s, s: s, s: s, s: s, s: i, s: i, s: i, s: i, s: i, s: i, s: i, s: s, s: i}", return ast_json_pack("{s: s, s: s, s: s, s: s, s: s, s: i, s: i, s: i, s: i, s: i, s: i, s: i, s: s, s: i, s: i}",
"Queue", q->name, "Queue", q->name,
"MemberName", mem->membername, "MemberName", mem->membername,
"Interface", mem->interface, "Interface", mem->interface,
@ -2274,7 +2278,8 @@ static struct ast_json *queue_member_blob_create(struct call_queue *q, struct me
"Status", mem->status, "Status", mem->status,
"Paused", mem->paused, "Paused", mem->paused,
"PausedReason", mem->reason_paused, "PausedReason", mem->reason_paused,
"Ringinuse", mem->ringinuse); "Ringinuse", mem->ringinuse,
"Wrapuptime", mem->wrapuptime);
} }
/*! \brief Check if members are available /*! \brief Check if members are available
@ -2679,7 +2684,7 @@ static void destroy_queue_member_cb(void *obj)
} }
/*! \brief allocate space for new queue member and set fields based on parameters passed */ /*! \brief allocate space for new queue member and set fields based on parameters passed */
static struct member *create_queue_member(const char *interface, const char *membername, int penalty, int paused, const char *state_interface, int ringinuse) static struct member *create_queue_member(const char *interface, const char *membername, int penalty, int paused, const char *state_interface, int ringinuse, int wrapuptime)
{ {
struct member *cur; struct member *cur;
@ -2687,6 +2692,7 @@ static struct member *create_queue_member(const char *interface, const char *mem
cur->ringinuse = ringinuse; cur->ringinuse = ringinuse;
cur->penalty = penalty; cur->penalty = penalty;
cur->paused = paused; cur->paused = paused;
cur->wrapuptime = wrapuptime;
if (paused) { if (paused) {
time(&cur->lastpause); /* Update time of last pause */ time(&cur->lastpause); /* Update time of last pause */
} }
@ -3468,7 +3474,7 @@ static void rt_handle_member_record(struct call_queue *q, char *category, struct
/* Create a new member */ /* Create a new member */
if (!found) { if (!found) {
if ((m = create_queue_member(interface, membername, penalty, paused, state_interface, ringinuse))) { if ((m = create_queue_member(interface, membername, penalty, paused, state_interface, ringinuse, wrapuptime))) {
m->dead = 0; m->dead = 0;
m->realtime = 1; m->realtime = 1;
ast_copy_string(m->rt_uniqueid, rt_uniqueid, sizeof(m->rt_uniqueid)); ast_copy_string(m->rt_uniqueid, rt_uniqueid, sizeof(m->rt_uniqueid));
@ -7260,14 +7266,15 @@ static void dump_queue_members(struct call_queue *pm_queue)
continue; continue;
} }
ast_str_append(&value, 0, "%s%s;%d;%d;%s;%s;%s", ast_str_append(&value, 0, "%s%s;%d;%d;%s;%s;%s;%d",
ast_str_strlen(value) ? "|" : "", ast_str_strlen(value) ? "|" : "",
cur_member->interface, cur_member->interface,
cur_member->penalty, cur_member->penalty,
cur_member->paused, cur_member->paused,
cur_member->membername, cur_member->membername,
cur_member->state_interface, cur_member->state_interface,
cur_member->reason_paused); cur_member->reason_paused,
cur_member->wrapuptime);
ao2_ref(cur_member, -1); ao2_ref(cur_member, -1);
} }
@ -7344,7 +7351,7 @@ static int remove_from_queue(const char *queuename, const char *interface)
* \retval RES_EXISTS queue exists but no members * \retval RES_EXISTS queue exists but no members
* \retval RES_OUT_OF_MEMORY queue exists but not enough memory to create member * \retval RES_OUT_OF_MEMORY queue exists but not enough memory to create member
*/ */
static int add_to_queue(const char *queuename, const char *interface, const char *membername, int penalty, int paused, int dump, const char *state_interface, const char *reason_paused) static int add_to_queue(const char *queuename, const char *interface, const char *membername, int penalty, int paused, int dump, const char *state_interface, const char *reason_paused, int wrapuptime)
{ {
struct call_queue *q; struct call_queue *q;
struct member *new_member, *old_member; struct member *new_member, *old_member;
@ -7358,7 +7365,7 @@ static int add_to_queue(const char *queuename, const char *interface, const char
ao2_lock(q); ao2_lock(q);
if ((old_member = interface_exists(q, interface)) == NULL) { if ((old_member = interface_exists(q, interface)) == NULL) {
if ((new_member = create_queue_member(interface, membername, penalty, paused, state_interface, q->ringinuse))) { if ((new_member = create_queue_member(interface, membername, penalty, paused, state_interface, q->ringinuse, wrapuptime))) {
new_member->dynamic = 1; new_member->dynamic = 1;
if (reason_paused) { if (reason_paused) {
ast_copy_string(new_member->reason_paused, reason_paused, sizeof(new_member->reason_paused)); ast_copy_string(new_member->reason_paused, reason_paused, sizeof(new_member->reason_paused));
@ -7750,6 +7757,8 @@ static void reload_queue_members(void)
int penalty = 0; int penalty = 0;
char *paused_tok; char *paused_tok;
int paused = 0; int paused = 0;
char *wrapuptime_tok;
int wrapuptime = 0;
char *reason_paused; char *reason_paused;
struct ast_db_entry *db_tree; struct ast_db_entry *db_tree;
struct ast_db_entry *entry; struct ast_db_entry *entry;
@ -7798,6 +7807,7 @@ static void reload_queue_members(void)
membername = strsep(&member, ";"); membername = strsep(&member, ";");
state_interface = strsep(&member, ";"); state_interface = strsep(&member, ";");
reason_paused = strsep(&member, ";"); reason_paused = strsep(&member, ";");
wrapuptime_tok = strsep(&member, ";");
if (!penalty_tok) { if (!penalty_tok) {
ast_log(LOG_WARNING, "Error parsing persistent member string for '%s' (penalty)\n", queue_name); ast_log(LOG_WARNING, "Error parsing persistent member string for '%s' (penalty)\n", queue_name);
@ -7819,10 +7829,18 @@ static void reload_queue_members(void)
break; break;
} }
ast_debug(1, "Reload Members: Queue: %s Member: %s Name: %s Penalty: %d Paused: %d ReasonPause: %s\n", if (!ast_strlen_zero(wrapuptime_tok)) {
queue_name, interface, membername, penalty, paused, reason_paused); wrapuptime = strtol(wrapuptime_tok, NULL, 10);
if (errno == ERANGE) {
ast_log(LOG_WARNING, "Error converting wrapuptime: %s: Out of range.\n", wrapuptime_tok);
break;
}
}
ast_debug(1, "Reload Members: Queue: %s Member: %s Name: %s Penalty: %d Paused: %d ReasonPause: %s Wrapuptime: %d\n",
queue_name, interface, membername, penalty, paused, reason_paused, wrapuptime);
if (add_to_queue(queue_name, interface, membername, penalty, paused, 0, state_interface, reason_paused) == RES_OUTOFMEMORY) { if (add_to_queue(queue_name, interface, membername, penalty, paused, 0, state_interface, reason_paused, wrapuptime) == RES_OUTOFMEMORY) {
ast_log(LOG_ERROR, "Out of Memory when reloading persistent queue member\n"); ast_log(LOG_ERROR, "Out of Memory when reloading persistent queue member\n");
break; break;
} }
@ -7984,7 +8002,7 @@ static int rqm_exec(struct ast_channel *chan, const char *data)
static int aqm_exec(struct ast_channel *chan, const char *data) static int aqm_exec(struct ast_channel *chan, const char *data)
{ {
int res=-1; int res=-1;
char *parse, *temppos = NULL; char *parse, *tmp, *temppos = NULL;
AST_DECLARE_APP_ARGS(args, AST_DECLARE_APP_ARGS(args,
AST_APP_ARG(queuename); AST_APP_ARG(queuename);
AST_APP_ARG(interface); AST_APP_ARG(interface);
@ -7992,11 +8010,13 @@ static int aqm_exec(struct ast_channel *chan, const char *data)
AST_APP_ARG(options); AST_APP_ARG(options);
AST_APP_ARG(membername); AST_APP_ARG(membername);
AST_APP_ARG(state_interface); AST_APP_ARG(state_interface);
AST_APP_ARG(wrapuptime);
); );
int penalty = 0; int penalty = 0;
int wrapuptime;
if (ast_strlen_zero(data)) { if (ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "AddQueueMember requires an argument (queuename[,interface[,penalty[,options[,membername[,stateinterface]]]]])\n"); ast_log(LOG_WARNING, "AddQueueMember requires an argument (queuename[,interface[,penalty[,options[,membername[,stateinterface][,wrapuptime]]]]])\n");
return -1; return -1;
} }
@ -8019,7 +8039,18 @@ static int aqm_exec(struct ast_channel *chan, const char *data)
} }
} }
switch (add_to_queue(args.queuename, args.interface, args.membername, penalty, 0, queue_persistent_members, args.state_interface, NULL)) { if (!ast_strlen_zero(args.wrapuptime)) {
tmp = args.wrapuptime;
ast_strip(tmp);
wrapuptime = atoi(tmp);
if (wrapuptime < 0) {
wrapuptime = 0;
}
} else {
wrapuptime = 0;
}
switch (add_to_queue(args.queuename, args.interface, args.membername, penalty, 0, queue_persistent_members, args.state_interface, NULL, wrapuptime)) {
case RES_OKAY: case RES_OKAY:
if (ast_strlen_zero(args.membername) || !log_membername_as_agent) { if (ast_strlen_zero(args.membername) || !log_membername_as_agent) {
ast_queue_log(args.queuename, ast_channel_uniqueid(chan), args.interface, "ADDMEMBER", "%s", ""); ast_queue_log(args.queuename, ast_channel_uniqueid(chan), args.interface, "ADDMEMBER", "%s", "");
@ -9265,7 +9296,7 @@ static void reload_single_member(const char *memberdata, struct call_queue *q)
ast_copy_string(tmpmem.interface, interface, sizeof(tmpmem.interface)); ast_copy_string(tmpmem.interface, interface, sizeof(tmpmem.interface));
cur = ao2_find(q->members, &tmpmem, OBJ_POINTER); cur = ao2_find(q->members, &tmpmem, OBJ_POINTER);
if ((newm = create_queue_member(interface, membername, penalty, cur ? cur->paused : 0, state_interface, ringinuse))) { if ((newm = create_queue_member(interface, membername, penalty, cur ? cur->paused : 0, state_interface, ringinuse, wrapuptime))) {
newm->wrapuptime = wrapuptime; newm->wrapuptime = wrapuptime;
if (cur) { if (cur) {
/* Round Robin Queue Position must be copied if this is replacing an existing member */ /* Round Robin Queue Position must be copied if this is replacing an existing member */
@ -10078,11 +10109,12 @@ static int manager_queues_status(struct mansession *s, const struct message *m)
"Status: %d\r\n" "Status: %d\r\n"
"Paused: %d\r\n" "Paused: %d\r\n"
"PausedReason: %s\r\n" "PausedReason: %s\r\n"
"Wrapuptime: %d\r\n"
"%s" "%s"
"\r\n", "\r\n",
q->name, mem->membername, mem->interface, mem->state_interface, mem->dynamic ? "dynamic" : "static", q->name, mem->membername, mem->interface, mem->state_interface, mem->dynamic ? "dynamic" : "static",
mem->penalty, mem->calls, (int)mem->lastcall, (int)mem->lastpause, mem->starttime ? 1 : 0, mem->status, mem->penalty, mem->calls, (int)mem->lastcall, (int)mem->lastpause, mem->starttime ? 1 : 0, mem->status,
mem->paused, mem->reason_paused, idText); mem->paused, mem->reason_paused, mem->wrapuptime, idText);
++q_items; ++q_items;
} }
ao2_ref(mem, -1); ao2_ref(mem, -1);
@ -10127,8 +10159,8 @@ static int manager_queues_status(struct mansession *s, const struct message *m)
static int manager_add_queue_member(struct mansession *s, const struct message *m) static int manager_add_queue_member(struct mansession *s, const struct message *m)
{ {
const char *queuename, *interface, *penalty_s, *paused_s, *membername, *state_interface; const char *queuename, *interface, *penalty_s, *paused_s, *membername, *state_interface, *wrapuptime_s;
int paused, penalty = 0; int paused, penalty, wrapuptime = 0;
queuename = astman_get_header(m, "Queue"); queuename = astman_get_header(m, "Queue");
interface = astman_get_header(m, "Interface"); interface = astman_get_header(m, "Interface");
@ -10136,6 +10168,7 @@ static int manager_add_queue_member(struct mansession *s, const struct message *
paused_s = astman_get_header(m, "Paused"); paused_s = astman_get_header(m, "Paused");
membername = astman_get_header(m, "MemberName"); membername = astman_get_header(m, "MemberName");
state_interface = astman_get_header(m, "StateInterface"); state_interface = astman_get_header(m, "StateInterface");
wrapuptime_s = astman_get_header(m, "Wrapuptime");
if (ast_strlen_zero(queuename)) { if (ast_strlen_zero(queuename)) {
astman_send_error(s, m, "'Queue' not specified."); astman_send_error(s, m, "'Queue' not specified.");
@ -10153,13 +10186,19 @@ static int manager_add_queue_member(struct mansession *s, const struct message *
penalty = 0; penalty = 0;
} }
if (ast_strlen_zero(wrapuptime_s)) {
wrapuptime = 0;
} else if (sscanf(wrapuptime_s, "%30d", &wrapuptime) != 1 || wrapuptime < 0) {
wrapuptime = 0;
}
if (ast_strlen_zero(paused_s)) { if (ast_strlen_zero(paused_s)) {
paused = 0; paused = 0;
} else { } else {
paused = abs(ast_true(paused_s)); paused = abs(ast_true(paused_s));
} }
switch (add_to_queue(queuename, interface, membername, penalty, paused, queue_persistent_members, state_interface, NULL)) { switch (add_to_queue(queuename, interface, membername, penalty, paused, queue_persistent_members, state_interface, NULL, wrapuptime)) {
case RES_OKAY: case RES_OKAY:
if (ast_strlen_zero(membername) || !log_membername_as_agent) { if (ast_strlen_zero(membername) || !log_membername_as_agent) {
ast_queue_log(queuename, "MANAGER", interface, "ADDMEMBER", "%s", paused ? "PAUSED" : ""); ast_queue_log(queuename, "MANAGER", interface, "ADDMEMBER", "%s", paused ? "PAUSED" : "");
@ -10509,7 +10548,7 @@ static char *handle_queue_add_member(struct ast_cli_entry *e, int cmd, struct as
state_interface = a->argv[11]; state_interface = a->argv[11];
} }
switch (add_to_queue(queuename, interface, membername, penalty, 0, queue_persistent_members, state_interface, NULL)) { switch (add_to_queue(queuename, interface, membername, penalty, 0, queue_persistent_members, state_interface, NULL, 0)) {
case RES_OKAY: case RES_OKAY:
if (ast_strlen_zero(membername) || !log_membername_as_agent) { if (ast_strlen_zero(membername) || !log_membername_as_agent) {
ast_queue_log(queuename, "CLI", interface, "ADDMEMBER", "%s", ""); ast_queue_log(queuename, "CLI", interface, "ADDMEMBER", "%s", "");

Loading…
Cancel
Save