Index: apps/app_queue.c
===================================================================
--- apps/app_queue.c (revision 191774)
+++ apps/app_queue.c (working copy)
@@ -418,7 +418,7 @@
Returns 0 if queue is found and setqueuevar is defined, -1 otherwise.
-
+
Count number of members answering a queue.
@@ -442,21 +442,6 @@
Returns the number of members currently associated with the specified queuename.
-
-
- Count number of members answering a queue.
-
-
-
-
-
- Returns the number of members currently associated with the specified queuename.
- This function has been deprecated in favor of the QUEUE_MEMBER() function
-
-
- [QUEUE_MEMBER_LIST]
-
-
Count number of calls currently waiting in a queue.
@@ -482,17 +467,51 @@
[QUEUE_MEMBER_COUNT]
-
+
- Gets or sets queue members penalty.
+ Gets or sets queue member fields.
-
-
+
+
+
+
+ Returns or sets the number of answered call counter for queue member
+
+
+ Returns or sets the last call timer for queue member
+
+
+ Returns or sets the penalty of queue member
+
+
+ Returns or sets the paused status for queue member
+
+
+ Returns or sets the wrapuptime on queue member
+
+
+ Returns or sets the wrapuptime on queue member for next call only.
+
+
+ Returns the count of logged-in members for the specified queue (deprecated, use QUEUE_MEMBER_COUNT instead)
+
+
+ Returns the count of logged-in members for the specified queue available to take a call (deprecated, use QUEUE_MEMBER_COUNT instead)
+
+
+ Returns the total amount of members for the specified queue (deprecated, use QUEUE_MEMBER_COUNT instead)
+
+
+
+
- Gets or sets queue members penalty.
+ Gets or sets queue member fields. If is not specified on write, member will be updated in all queues. Read also allows returning count of logged/free/total amount of agents for backward compatibility.
+
+ [QUEUE_MEMBER_COUNT]
+
***/
@@ -686,6 +705,11 @@
char rt_uniqueid[80]; /*!< Unique id of realtime member entry */
};
+#define QUEUE_MEMBER_FIELD_PENALTY "penalty"
+#define QUEUE_MEMBER_FIELD_CALLS "calls"
+#define QUEUE_MEMBER_FIELD_PAUSED "paused"
+#define QUEUE_MEMBER_FIELD_LASTCALL "lastcall"
+
enum empty_conditions {
QUEUE_EMPTY_PENALTY = (1 << 0),
QUEUE_EMPTY_PAUSED = (1 << 1),
@@ -829,7 +853,8 @@
static struct ao2_container *queues;
static void update_realtime_members(struct call_queue *q);
-static int set_member_paused(const char *queuename, const char *interface, const char *reason, int paused);
+static int set_member_field(struct call_queue *q, struct member *mem, const char *field, long value, int relative, const char *reason);
+static struct member *interface_exists(struct call_queue *q, const char *interface);
static void queue_transfer_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan);
/*! \brief sets the QUEUESTATUS channel variable */
@@ -1859,15 +1884,13 @@
static int update_realtime_member_field(struct member *mem, const char *queue_name, const char *field, const char *value)
{
- int ret = -1;
-
if (ast_strlen_zero(mem->rt_uniqueid))
- return ret;
+ return RESULT_FAILURE;
if ((ast_update_realtime("queue_members", "uniqueid", mem->rt_uniqueid, field, value, SENTINEL)) > 0)
- ret = 0;
+ return RESULT_SUCCESS;
- return ret;
+ return RESULT_FAILURE;
}
@@ -2803,10 +2826,15 @@
}
ast_queue_log(qe->parent->name, qe->chan->uniqueid, membername, "RINGNOANSWER", "%d", rnatime);
if (qe->parent->autopause && pause) {
- if (!set_member_paused(qe->parent->name, interface, "Auto-Pause", 1)) {
- ast_verb(3, "Auto-Pausing Queue Member %s in queue %s since they failed to answer.\n", interface, qe->parent->name);
- } else {
- ast_verb(3, "Failed to pause Queue Member %s in queue %s!\n", interface, qe->parent->name);
+ struct member *mem;
+ //TODO: update rna to pass member
+ if ((mem = interface_exists(qe->parent, interface))) {
+ //TODO: check all set_member_field for result
+ if (RESULT_SUCCESS==set_member_field(qe->parent, mem, QUEUE_MEMBER_FIELD_PAUSED, 1, 0, "Auto-Pause")) {
+ ast_verb(3, "Auto-Pausing Queue Member %s in queue %s since they failed to answer.\n", interface, qe->parent->name);
+ } else {
+ ast_verb(3, "Failed to pause Queue Member %s in queue %s!\n", interface, qe->parent->name);
+ }
}
}
return;
@@ -4530,63 +4558,156 @@
return res;
}
-static int set_member_paused(const char *queuename, const char *interface, const char *reason, int paused)
+/* \brief Updates field for identified member and identified queue.
+ * \return Returns RESULT_SUCCESS if update succeeded or RESULT_FAILURE on error.
+*/
+static int set_member_field(struct call_queue *q, struct member *mem, const char *field, long value, int relative, const char *reason)
{
- int found = 0;
+ char *log_event = "UPDATEMEMBER", *manager_event = "QueueMemberUpdate", *strbuf;
+
+ if (!strcasecmp(QUEUE_MEMBER_FIELD_CALLS, field)) {
+
+ if (relative) value = mem->calls+(relative*value);
+ if (value<0) {
+ ast_log(LOG_VERBOSE, "Can't set call count to %ld for queue member %s:%s\n", value, q->name, mem->interface);
+ return RESULT_FAILURE;
+ }
+
+ mem->calls = value;
+ manager_event = "QueueMemberCalls";
+ log_event = "UPDATECALLS";
+ ast_log(LOG_DEBUG, "Setting calls for queue member %s:%s to %ld\n", q->name, mem->interface, value);
+
+ } else if (!strcasecmp(QUEUE_MEMBER_FIELD_LASTCALL, field)) {
+
+ if (relative) value = mem->lastcall+(relative*value);
+ mem->lastcall = value;
+ manager_event = "QueueMemberLastcall";
+ log_event = "UPDATELASTCALL";
+ ast_log(LOG_DEBUG, "Setting lastcall for queue member %s:%s to %ld\n", q->name, mem->interface, value);
+
+ } else if (!strcasecmp(QUEUE_MEMBER_FIELD_PENALTY, field)) {
+
+ if (relative) value = mem->penalty+(relative*value);
+ if (value<0) {
+ ast_log(LOG_VERBOSE, "Can't set penalty to %ld for queue member %s:%s\n", value, q->name, mem->interface);
+ return RESULT_FAILURE;
+ }
+
+ mem->penalty = value;
+ log_event = "PENALTY";
+ manager_event = "QueueMemberPenalty";
+ ast_log(LOG_DEBUG, "Setting penalty for queue member %s:%s to %ld\n", q->name, mem->interface, value);
+
+ } else if (!strcasecmp(QUEUE_MEMBER_FIELD_PAUSED, field)) {
+
+ // TODO: use ast_true
+ if (relative) {
+ ast_log(LOG_VERBOSE, "Can't increment or decrement paused status for queue member %s:%s\n", q->name, mem->interface);
+ return RESULT_FAILURE;
+ } else if (value<0 || value>1) {
+ ast_log(LOG_VERBOSE, "Can't set paused other than 0 or 1 for queue member %s:%s\n", q->name, mem->interface);
+ return RESULT_FAILURE;
+ }
+
+ if (mem->paused == value) {
+ ast_log(LOG_NOTICE, "%spausing already-%spaused queue member %s:%s\n", (value ? "" : "un"), (value ? "" : "un"), q->name, mem->interface);
+ }
+
+ mem->paused = value;
+ manager_event = "QueueMemberPaused";
+ log_event = (value ? "PAUSE" : "UNPAUSE");
+ ast_log(LOG_DEBUG, "Setting paused for queue member %s:%s to %ld\n", q->name, mem->interface, value);
+
+ } else {
+ ast_log(LOG_VERBOSE, "Queue members don't have %s field.!\n", field);
+ return RESULT_FAILURE;
+ }
+
+ if (mem->realtime) {
+ snprintf(strbuf, sizeof(strbuf), "%ld", value);
+ ast_log(LOG_DEBUG, "Updating realtime member field %s to %s\n", field, strbuf);
+ if (!update_realtime_member_field(mem, q->name, field, strbuf)) {
+ return RESULT_FAILURE;
+ }
+ }
+
+ if (queue_persistent_members) {
+ dump_queue_members(q);
+ }
+
+ // TODO: add actual value changed to
+ ast_queue_log(q->name, "NONE", mem->membername, log_event, "%ld|%s", value, S_OR(reason, ""));
+
+ if (!ast_strlen_zero(reason)) {
+ manager_event(EVENT_FLAG_AGENT, manager_event,
+ "Queue: %s\r\n"
+ "Location: %s\r\n"
+ "MemberName: %s\r\n"
+ "Paused: %d\r\n"
+ "Calls: %d\r\n"
+ "Penalty: %d\r\n"
+ "Lastcall: %ld\r\n"
+ "Reason: %s\r\n",
+ q->name, mem->interface, mem->membername, mem->paused, mem->calls, mem->penalty, (long)mem->lastcall, reason);
+ } else {
+ manager_event(EVENT_FLAG_AGENT, manager_event,
+ "Queue: %s\r\n"
+ "Location: %s\r\n"
+ "MemberName: %s\r\n"
+ "Paused: %d\r\n"
+ "Calls: %d\r\n"
+ "Penalty: %d\r\n"
+ "Lastcall: %ld\r\n",
+ q->name, mem->interface, mem->membername, mem->paused, mem->calls, mem->penalty, (long)mem->lastcall);
+ }
+
+ return RESULT_SUCCESS;
+}
+
+/* \brief Finds a queue and member in it, and updates specified field.
+ * \return Returns RESULT_SUCCESS if update succeeded or RESULT_FAILURE on error.
+*/
+static int update_member_field(const char *queuename, const char *interface, const char *field, const char *value_s, const char *reason)
+{
+ int relative = 0;
+ int res;
struct call_queue *q;
struct member *mem;
struct ao2_iterator queue_iter;
- int failed;
+ long value;
+ value = atol(value_s);
+
+ /* Check for increment/decrement */
+ if (!ast_strlen_zero(value_s)) {
+ if (value_s[0]=='+') {
+ relative = +1;
+ if (value==0) value = 1;
+ } else if (value_s[0]=='-') {
+ value = -value;
+ relative = -1;
+ if (value==0) value = 1;
+ }
+ }
+
/* Special event for when all queues are paused - individual events still generated */
/* XXX In all other cases, we use the membername, but since this affects all queues, we cannot */
- if (ast_strlen_zero(queuename))
- ast_queue_log("NONE", "NONE", interface, (paused ? "PAUSEALL" : "UNPAUSEALL"), "%s", "");
+ if (!strcasecmp(QUEUE_MEMBER_FIELD_PAUSED, field) && ast_strlen_zero(queuename))
+ ast_queue_log("NONE", "NONE", interface, (value ? "PAUSEALL" : "UNPAUSEALL"), "%s", "");
queue_iter = ao2_iterator_init(queues, 0);
while ((q = ao2_iterator_next(&queue_iter))) {
ao2_lock(q);
if (ast_strlen_zero(queuename) || !strcasecmp(q->name, queuename)) {
if ((mem = interface_exists(q, interface))) {
- if (mem->paused == paused) {
- ast_debug(1, "%spausing already-%spaused queue member %s:%s\n", (paused ? "" : "un"), (paused ? "" : "un"), q->name, interface);
- }
-
- failed = 0;
- if (mem->realtime) {
- failed = update_realtime_member_field(mem, q->name, "paused", paused ? "1" : "0");
- }
-
- if (failed) {
- ast_log(LOG_WARNING, "Failed %spausing realtime queue member %s:%s\n", (paused ? "" : "un"), q->name, interface);
+ res = set_member_field(q, mem, field, value, relative, reason);
+ if (res == RESULT_FAILURE) {
ao2_ref(mem, -1);
ao2_unlock(q);
continue;
- }
- found++;
- mem->paused = paused;
+ }
- if (queue_persistent_members)
- dump_queue_members(q);
-
- ast_queue_log(q->name, "NONE", mem->membername, (paused ? "PAUSE" : "UNPAUSE"), "%s", S_OR(reason, ""));
-
- if (!ast_strlen_zero(reason)) {
- manager_event(EVENT_FLAG_AGENT, "QueueMemberPaused",
- "Queue: %s\r\n"
- "Location: %s\r\n"
- "MemberName: %s\r\n"
- "Paused: %d\r\n"
- "Reason: %s\r\n",
- q->name, mem->interface, mem->membername, paused, reason);
- } else {
- manager_event(EVENT_FLAG_AGENT, "QueueMemberPaused",
- "Queue: %s\r\n"
- "Location: %s\r\n"
- "MemberName: %s\r\n"
- "Paused: %d\r\n",
- q->name, mem->interface, mem->membername, paused);
- }
ao2_ref(mem, -1);
}
}
@@ -4601,87 +4722,67 @@
queue_unref(q);
}
- return found ? RESULT_SUCCESS : RESULT_FAILURE;
+ return res;
}
-/* \brief Sets members penalty, if queuename=NULL we set member penalty in all the queues. */
-static int set_member_penalty(char *queuename, char *interface, int penalty)
+/* \brief Gets members field
+ * \return Return the member field.
+*/
+static int get_member_field(const char *queuename, const char *interface, const char *field)
{
- int foundinterface = 0, foundqueue = 0;
struct call_queue *q;
struct member *mem;
struct ao2_iterator queue_iter;
+ int ret;
- if (penalty < 0) {
- ast_log(LOG_ERROR, "Invalid penalty (%d)\n", penalty);
+ if (ast_strlen_zero(queuename) || ast_strlen_zero(interface)) {
+ ast_log(LOG_VERBOSE, "Queue name and interface must be specified\n");
return RESULT_FAILURE;
}
queue_iter = ao2_iterator_init(queues, 0);
while ((q = ao2_iterator_next(&queue_iter))) {
ao2_lock(q);
- if (ast_strlen_zero(queuename) || !strcasecmp(q->name, queuename)) {
- foundqueue++;
- if ((mem = interface_exists(q, interface))) {
- foundinterface++;
- mem->penalty = penalty;
-
- ast_queue_log(q->name, "NONE", interface, "PENALTY", "%d", penalty);
- manager_event(EVENT_FLAG_AGENT, "QueueMemberPenalty",
- "Queue: %s\r\n"
- "Location: %s\r\n"
- "Penalty: %d\r\n",
- q->name, mem->interface, penalty);
- ao2_ref(mem, -1);
+ if (!strcasecmp(q->name, queuename)) {
+ mem = interface_exists(q, interface);
+ if (!mem) {
+ ast_log(LOG_VERBOSE, "Member %s not found in queue %s!\n", interface, queuename);
+ ao2_unlock(q);
+ queue_unref(q);
+ return RESULT_FAILURE;
}
+
+ // Do cases for each field
+ if (!strcasecmp(QUEUE_MEMBER_FIELD_CALLS, field)) {
+ ret = mem->calls;
+ } else if (!strcasecmp(QUEUE_MEMBER_FIELD_LASTCALL, field)) {
+ ret = mem->lastcall;
+ } else if (!strcasecmp(QUEUE_MEMBER_FIELD_PENALTY, field)) {
+ ret = mem->penalty;
+ } else if (!strcasecmp(QUEUE_MEMBER_FIELD_PAUSED, field)) {
+ ret = mem->paused;
+ } else {
+ ast_log(LOG_VERBOSE, "Queue members don't have %s field.!\n", field);
+ }
+ ao2_ref(mem, -1);
+ ao2_unlock(q);
+ queue_unref(q);
+ return ret;
}
+
ao2_unlock(q);
queue_unref(q);
}
- if (foundinterface) {
- return RESULT_SUCCESS;
- } else if (!foundqueue) {
- ast_log (LOG_ERROR, "Invalid queuename\n");
- } else {
- ast_log (LOG_ERROR, "Invalid interface\n");
- }
-
return RESULT_FAILURE;
}
-/* \brief Gets members penalty.
+/* \brief Gets members penalty.
* \return Return the members penalty or RESULT_FAILURE on error.
*/
static int get_member_penalty(char *queuename, char *interface)
{
- int foundqueue = 0, penalty;
- struct call_queue *q, tmpq = {
- .name = queuename,
- };
- struct member *mem;
-
- if ((q = ao2_find(queues, &tmpq, OBJ_POINTER))) {
- foundqueue = 1;
- ao2_lock(q);
- if ((mem = interface_exists(q, interface))) {
- penalty = mem->penalty;
- ao2_ref(mem, -1);
- ao2_unlock(q);
- queue_unref(q);
- return penalty;
- }
- ao2_unlock(q);
- queue_unref(q);
- }
-
- /* some useful debuging */
- if (foundqueue)
- ast_log (LOG_ERROR, "Invalid queuename\n");
- else
- ast_log (LOG_ERROR, "Invalid interface\n");
-
- return RESULT_FAILURE;
+ return get_member_field(queuename, interface, QUEUE_MEMBER_FIELD_PENALTY);
}
/*! \brief Reload dynamic queue members persisted into the astdb */
@@ -4806,7 +4907,7 @@
return -1;
}
- if (set_member_paused(args.queuename, args.interface, args.reason, 1)) {
+ if (update_member_field(args.queuename, args.interface, QUEUE_MEMBER_FIELD_PAUSED, "1", args.reason)) {
ast_log(LOG_WARNING, "Attempt to pause interface %s, not found\n", args.interface);
pbx_builtin_setvar_helper(chan, "PQMSTATUS", "NOTFOUND");
return 0;
@@ -4842,7 +4943,7 @@
return -1;
}
- if (set_member_paused(args.queuename, args.interface, args.reason, 0)) {
+ if (update_member_field(args.queuename, args.interface, QUEUE_MEMBER_FIELD_PAUSED, "0", args.reason)) {
ast_log(LOG_WARNING, "Attempt to unpause interface %s, not found\n", args.interface);
pbx_builtin_setvar_helper(chan, "UPQMSTATUS", "NOTFOUND");
return 0;
@@ -5430,49 +5531,6 @@
return 0;
}
-/*!
- * \brief Get the total number of members in a specific queue (Deprecated)
- * \retval number of members
- * \retval -1 on error
-*/
-static int queue_function_qac_dep(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
-{
- int count = 0;
- struct member *m;
- struct call_queue *q;
- struct ao2_iterator mem_iter;
- static int depflag = 1;
-
- if (depflag) {
- depflag = 0;
- ast_log(LOG_NOTICE, "The function QUEUE_MEMBER_COUNT has been deprecated in favor of the QUEUE_MEMBER function and will not be in further releases.\n");
- }
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_ERROR, "%s requires an argument: queuename\n", cmd);
- return -1;
- }
-
- if ((q = load_realtime_queue(data))) {
- ao2_lock(q);
- mem_iter = ao2_iterator_init(q->members, 0);
- while ((m = ao2_iterator_next(&mem_iter))) {
- /* Count the agents who are logged in and presently answering calls */
- if ((m->status != AST_DEVICE_UNAVAILABLE) && (m->status != AST_DEVICE_INVALID)) {
- count++;
- }
- ao2_ref(m, -1);
- }
- ao2_unlock(q);
- queue_unref(q);
- } else
- ast_log(LOG_WARNING, "queue %s was not found\n", data);
-
- snprintf(buf, len, "%d", count);
-
- return 0;
-}
-
/*! \brief Dialplan function QUEUE_WAITING_COUNT() Get number callers waiting in a specific queue */
static int queue_function_queuewaitingcount(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
{
@@ -5558,7 +5616,7 @@
}
/*! \brief Dialplan function QUEUE_MEMBER_PENALTY() Gets the members penalty. */
-static int queue_function_memberpenalty_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
+static int queue_function_memberpenalty_read_dep(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
{
int penalty;
AST_DECLARE_APP_ARGS(args,
@@ -5568,6 +5626,8 @@
/* Make sure the returned value on error is NULL. */
buf[0] = '\0';
+ ast_log(LOG_VERBOSE, "The function QUEUE_MEMBER_PENALTY has been deprecated in favor of the QUEUE_MEMBER function and will not be in further releases.\n");
+
if (ast_strlen_zero(data)) {
ast_log(LOG_ERROR, "Missing argument. QUEUE_MEMBER_PENALTY(,)\n");
return -1;
@@ -5589,14 +5649,15 @@
}
/*! \brief Dialplan function QUEUE_MEMBER_PENALTY() Sets the members penalty. */
-static int queue_function_memberpenalty_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
+static int queue_function_memberpenalty_write_dep(struct ast_channel *chan, const char *cmd, char *data, const char *value)
{
- int penalty;
AST_DECLARE_APP_ARGS(args,
AST_APP_ARG(queuename);
AST_APP_ARG(interface);
);
+ ast_log(LOG_VERBOSE, "The function QUEUE_MEMBER_PENALTY has been deprecated in favor of the QUEUE_MEMBER function and will not be in further releases.\n");
+
if (ast_strlen_zero(data)) {
ast_log(LOG_ERROR, "Missing argument. QUEUE_MEMBER_PENALTY(,)\n");
return -1;
@@ -5609,15 +5670,13 @@
return -1;
}
- penalty = atoi(value);
-
if (ast_strlen_zero(args.interface)) {
ast_log (LOG_ERROR, " parameter can't be null\n");
return -1;
}
/* if queuename = NULL then penalty will be set for interface in all the queues. */
- if (set_member_penalty(args.queuename, args.interface, penalty)) {
+ if (update_member_field(args.queuename, args.interface, QUEUE_MEMBER_FIELD_PENALTY, value, NULL)) {
ast_log(LOG_ERROR, "Invalid interface, queue or penalty\n");
return -1;
}
@@ -5625,19 +5684,83 @@
return 0;
}
+
+
+/*! \brief Dialplan function QUEUE_MEMBER() Gets the member parameters. */
+static int queue_function_member_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
+{
+ int result;
+ AST_DECLARE_APP_ARGS(args,
+ AST_APP_ARG(queuename);
+ AST_APP_ARG(field);
+ AST_APP_ARG(interface);
+ );
+ /* Make sure the returned value on error is NULL. */
+ buf[0] = '\0';
+
+ if (ast_strlen_zero(data)) {
+ ast_log(LOG_ERROR, "Missing argument. QUEUE_MEMBER(,[,])\n");
+ return -1;
+ }
+
+ AST_STANDARD_APP_ARGS(args, data);
+
+ if (args.argc < 2) {
+ ast_log(LOG_ERROR, "Missing argument. QUEUE_MEMBER(,[,])\n");
+ return -1;
+ }
+
+
+ result = get_member_field(args.queuename, args.interface, args.field);
+
+ if (result >= 0) /* remember that buf is already '\0' */
+ snprintf (buf, len, "%d", result);
+
+ return 0;
+}
+
+/*! \brief Dialplan function QUEUE_MEMBER() Sets the member parameters. */
+static int queue_function_member_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
+{
+ AST_DECLARE_APP_ARGS(args,
+ AST_APP_ARG(queuename);
+ AST_APP_ARG(field);
+ AST_APP_ARG(interface);
+ );
+
+ if (ast_strlen_zero(data)) {
+ ast_log(LOG_ERROR, "Missing argument. QUEUE_MEMBER([],[,])\n");
+ return -1;
+ }
+
+ AST_STANDARD_APP_ARGS(args, data);
+
+ if (args.argc < 2) {
+ ast_log(LOG_ERROR, "Missing argument. QUEUE_MEMBER([],[,])\n");
+ return -1;
+ }
+
+ if (!update_member_field(args.queuename, args.interface, args.field, value, NULL)) {
+ return -1;
+ }
+
+ return 0;
+}
+
+
static struct ast_custom_function queuevar_function = {
.name = "QUEUE_VARIABLES",
.read = queue_function_var,
};
-
static struct ast_custom_function queuemembercount_function = {
- .name = "QUEUE_MEMBER",
+ .name = "QUEUE_MEMBER_COUNT",
.read = queue_function_qac,
};
-static struct ast_custom_function queuemembercount_dep = {
- .name = "QUEUE_MEMBER_COUNT",
- .read = queue_function_qac_dep,
+static struct ast_custom_function queuemember_function = {
+ .name = "QUEUE_MEMBER",
+ .read = queue_function_member_read,
+ .write = queue_function_member_write,
};
static struct ast_custom_function queuewaitingcount_function = {
@@ -5650,10 +5773,10 @@
.read = queue_function_queuememberlist,
};
-static struct ast_custom_function queuememberpenalty_function = {
+static struct ast_custom_function queuememberpenalty_dep = {
.name = "QUEUE_MEMBER_PENALTY",
- .read = queue_function_memberpenalty_read,
- .write = queue_function_memberpenalty_write,
+ .read = queue_function_memberpenalty_read_dep,
+ .write = queue_function_memberpenalty_write_dep,
};
/*! \brief Reload the rules defined in queuerules.conf
@@ -6571,7 +6694,7 @@
paused = abs(ast_true(paused_s));
- if (set_member_paused(queuename, interface, reason, paused))
+ if (update_member_field(queuename, interface, QUEUE_MEMBER_FIELD_PAUSED, paused_s, reason))
astman_send_error(s, m, "Interface not found");
else
astman_send_ack(s, m, paused ? "Interface paused successfully" : "Interface unpaused successfully");
@@ -6679,22 +6802,19 @@
static int manager_queue_member_penalty(struct mansession *s, const struct message *m)
{
- const char *queuename, *interface, *penalty_s;
- int penalty;
+ const char *queuename, *interface, *penalty;
interface = astman_get_header(m, "Interface");
- penalty_s = astman_get_header(m, "Penalty");
+ penalty = astman_get_header(m, "Penalty");
/* Optional - if not supplied, set the penalty value for the given Interface in all queues */
queuename = astman_get_header(m, "Queue");
- if (ast_strlen_zero(interface) || ast_strlen_zero(penalty_s)) {
+ if (ast_strlen_zero(interface) || ast_strlen_zero(penalty)) {
astman_send_error(s, m, "Need 'Interface' and 'Penalty' parameters.");
return 0;
}
- penalty = atoi(penalty_s);
-
- if (set_member_penalty((char *)queuename, (char *)interface, penalty))
+ if (update_member_field((char *)queuename, (char *)interface, QUEUE_MEMBER_FIELD_PENALTY, (char *)penalty, NULL))
astman_send_error(s, m, "Invalid interface, queuename or penalty");
else
astman_send_ack(s, m, "Interface penalty set successfully");
@@ -6886,6 +7006,7 @@
{
char *queuename, *interface, *reason;
int paused;
+ char *paused_val;
switch (cmd) {
case CLI_INIT:
@@ -6913,8 +7034,9 @@
queuename = a->argc >= 6 ? a->argv[5] : NULL;
reason = a->argc == 8 ? a->argv[7] : NULL;
paused = !strcasecmp(a->argv[1], "pause");
+ paused_val = paused ? "1" : "0";
- if (set_member_paused(queuename, interface, reason, paused) == RESULT_SUCCESS) {
+ if (update_member_field(queuename, interface, QUEUE_MEMBER_FIELD_PAUSED, paused_val, reason) == RESULT_SUCCESS) {
ast_cli(a->fd, "%spaused interface '%s'", paused ? "" : "un", interface);
if (!ast_strlen_zero(queuename))
ast_cli(a->fd, " in queue '%s'", queuename);
@@ -6933,9 +7055,9 @@
}
}
-static char *complete_queue_set_member_penalty(const char *line, const char *word, int pos, int state)
+static char *complete_queue_set_member(const char *line, const char *word, int pos, int state)
{
- /* 0 - queue; 1 - set; 2 - penalty; 3 - ; 4 - on; 5 - ; 6 - in; 7 - ;*/
+ /* 0 - queue; 1 - set; 2 - penalty|calls|lastcall|paused; 3 - ; 4 - on; 5 - ; 6 - in|because; 7 - ; 8 - because; 9 - reason;*/
switch (pos) {
case 4:
if (state == 0) {
@@ -6951,45 +7073,76 @@
}
case 7:
return complete_queue(line, word, pos, state);
+ case 8:
+ if (state == 0) {
+ return ast_strdup("because");
+ } else {
+ return NULL;
+ }
default:
return NULL;
}
-}
-
-static char *handle_queue_set_member_penalty(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+}
+
+static char *handle_queue_set_member(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
- char *queuename = NULL, *interface;
- int penalty = 0;
+ char *queuename = NULL, *reason = NULL, *interface = NULL, *value = NULL, *field = NULL;
switch (cmd) {
case CLI_INIT:
- e->command = "queue set penalty";
+ e->command = "queue set";
e->usage =
- "Usage: queue set penalty on [in ]\n"
- " Set a member's penalty in the queue specified. If no queue is specified\n"
- " then that interface's penalty is set in all queues to which that interface is a member\n";
+ "Usage: queue set (penalty|calls|paused|lastcall|wrapuptime|nextwrapuptime) [+|-] on [in ] [because ]\n"
+ " Set a member's field in the queue specified. If no queue is specified\n"
+ " then that interface's field is set in all queues to which that interface is a member\n";
return NULL;
case CLI_GENERATE:
- return complete_queue_set_member_penalty(a->line, a->word, a->pos, a->n);
+ return complete_queue_set_member(a->line, a->word, a->pos, a->n);
}
- if (a->argc != 6 && a->argc != 8) {
+ ast_log(LOG_WARNING, "handle_queue_set_member\n");
+
+
+ if (a->argc != 6 && a->argc != 8 && a->argc !=10) {
return CLI_SHOWUSAGE;
- } else if (strcmp(a->argv[4], "on") || (a->argc > 6 && strcmp(a->argv[6], "in"))) {
+ } else if (strcmp(a->argv[4], "on")) {
return CLI_SHOWUSAGE;
+ } else if (a->argc == 6 && (strcmp(a->argv[6], "in") || strcmp(a->argv[6], "because"))) {
+ return CLI_SHOWUSAGE;
+ } else if (a->argc == 7 && (strcmp(a->argv[6], "because"))) {
+ return CLI_SHOWUSAGE;
+ } else if (a->argc >= 8 && strcmp(a->argv[8], "because")) {
+ return CLI_SHOWUSAGE;
}
- if (a->argc == 8)
+ ast_log(LOG_WARNING, "handle_queue_set_member 2\n");
+
+ if (a->argc == 6 && !strcmp(a->argv[6], "in"))
queuename = a->argv[7];
+ if (a->argc == 6 && !strcmp(a->argv[6], "because"))
+ reason = a->argv[7];
+ if (a->argc == 8 && !strcmp(a->argv[8], "because"))
+ reason = a->argv[9];
+
+ ast_log(LOG_WARNING, "handle_queue_set_member 3\n");
+
+ field = a->argv[2];
+ value = a->argv[3];
interface = a->argv[5];
- penalty = atoi(a->argv[3]);
- switch (set_member_penalty(queuename, interface, penalty)) {
+ ast_log(LOG_WARNING, "handle_queue_set_member 4 (field: %s)\n", field);
+
+ if (strcmp(field, "penalty") && strcmp(field, "calls") && strcmp(field, "paused") && strcmp(field, "lastcall")) {
+ return CLI_SHOWUSAGE;
+ }
+ ast_log(LOG_WARNING, "handle_queue_set_member 5\n");
+
+ switch (update_member_field(queuename, interface, field, value, reason)) {
case RESULT_SUCCESS:
- ast_cli(a->fd, "Set penalty on interface '%s' from queue '%s'\n", interface, queuename);
+ ast_cli(a->fd, "Set %s on interface '%s' in queue '%s'\n", field, interface, S_OR(queuename,""));
return CLI_SUCCESS;
case RESULT_FAILURE:
- ast_cli(a->fd, "Failed to set penalty on interface '%s' from queue '%s'\n", interface, queuename);
+ ast_cli(a->fd, "Failed to set %s on interface '%s' in queue '%s'\n", field, interface, S_OR(queuename,""));
return CLI_FAILURE;
default:
return CLI_FAILURE;
@@ -7158,12 +7311,16 @@
static const char qsmp_cmd_usage[] =
"Usage: queue set member penalty from \n";
+static const char qsm_cmd_usage[] =
+"Usage: queue set member (penalty|paused|lastcall|calls|wrapuptime|nextwrapuptime) from \n";
+
+
static struct ast_cli_entry cli_queue[] = {
AST_CLI_DEFINE(queue_show, "Show status of a specified queue"),
AST_CLI_DEFINE(handle_queue_add_member, "Add a channel to a specified queue"),
AST_CLI_DEFINE(handle_queue_remove_member, "Removes a channel from a specified queue"),
AST_CLI_DEFINE(handle_queue_pause_member, "Pause or unpause a queue member"),
- AST_CLI_DEFINE(handle_queue_set_member_penalty, "Set penalty for a channel of a specified queue"),
+ AST_CLI_DEFINE(handle_queue_set_member, "Update queue member fields"),
AST_CLI_DEFINE(handle_queue_rule_show, "Show the rules defined in queuerules.conf"),
AST_CLI_DEFINE(handle_queue_reload, "Reload queues, members, queue rules, or parameters"),
AST_CLI_DEFINE(handle_queue_reset, "Reset statistics for a queue"),
@@ -7194,10 +7351,10 @@
res |= ast_unregister_application(app);
res |= ast_custom_function_unregister(&queuevar_function);
res |= ast_custom_function_unregister(&queuemembercount_function);
- res |= ast_custom_function_unregister(&queuemembercount_dep);
res |= ast_custom_function_unregister(&queuememberlist_function);
res |= ast_custom_function_unregister(&queuewaitingcount_function);
- res |= ast_custom_function_unregister(&queuememberpenalty_function);
+ res |= ast_custom_function_unregister(&queuememberpenalty_dep);
+ res |= ast_custom_function_unregister(&queuemember_function);
if (device_state_sub)
ast_event_unsubscribe(device_state_sub);
@@ -7260,10 +7417,10 @@
res |= ast_manager_register("QueueReset", 0, manager_queue_reset, "Reset queue statistics");
res |= ast_custom_function_register(&queuevar_function);
res |= ast_custom_function_register(&queuemembercount_function);
- res |= ast_custom_function_register(&queuemembercount_dep);
res |= ast_custom_function_register(&queuememberlist_function);
res |= ast_custom_function_register(&queuewaitingcount_function);
- res |= ast_custom_function_register(&queuememberpenalty_function);
+ res |= ast_custom_function_register(&queuememberpenalty_dep);
+ res |= ast_custom_function_register(&queuemember_function);
if (!(devicestate_tps = ast_taskprocessor_get("app_queue", 0))) {
ast_log(LOG_WARNING, "devicestate taskprocessor reference failed - devicestate notifications will not occur\n");
@@ -7292,3 +7449,4 @@
.reload = reload,
);
+