[asterisk-commits] irroot: branch irroot/app_queue_skill r325535 - in /team/irroot/app_queue_ski...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Jun 29 09:37:36 CDT 2011
Author: irroot
Date: Wed Jun 29 09:37:32 2011
New Revision: 325535
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=325535
Log:
Resolved Conflicts Introduced with r324364
Modified:
team/irroot/app_queue_skill/ (props changed)
team/irroot/app_queue_skill/CHANGES
team/irroot/app_queue_skill/UPGRADE.txt
team/irroot/app_queue_skill/apps/app_queue.c
team/irroot/app_queue_skill/configs/queues.conf.sample
Propchange: team/irroot/app_queue_skill/
------------------------------------------------------------------------------
automerge = *
Propchange: team/irroot/app_queue_skill/
------------------------------------------------------------------------------
svn:mergeinfo = /trunk:322065-325534
Modified: team/irroot/app_queue_skill/CHANGES
URL: http://svnview.digium.com/svn/asterisk/team/irroot/app_queue_skill/CHANGES?view=diff&rev=325535&r1=325534&r2=325535
==============================================================================
--- team/irroot/app_queue_skill/CHANGES (original)
+++ team/irroot/app_queue_skill/CHANGES Wed Jun 29 09:37:32 2011
@@ -439,6 +439,15 @@
supports sending the event arguments to 5 individual fields, although it
will fallback to the previous data definition, if the new table layout is
not found.
+ * Added general option negative_penalty_invalid default off. when set
+ members are seen as invalid/logged out when there penalty is negative.
+ for realtime members when set remove from queue will set penalty to -1.
+ * Added queue option autopausedelay when autopause is enabled it will be
+ delayed for this number of seconds since last successful call if there
+ was no prior call the agent will be autopaused immediately.
+ * Added member option ignorebusy this when set and ringinuse is not
+ will allow per member control of multiple calls as ringinuse does for
+ the Queue.
mISDN channel driver (chan_misdn) changes
----------------------------------------
Modified: team/irroot/app_queue_skill/UPGRADE.txt
URL: http://svnview.digium.com/svn/asterisk/team/irroot/app_queue_skill/UPGRADE.txt?view=diff&rev=325535&r1=325534&r2=325535
==============================================================================
--- team/irroot/app_queue_skill/UPGRADE.txt (original)
+++ team/irroot/app_queue_skill/UPGRADE.txt Wed Jun 29 09:37:32 2011
@@ -50,5 +50,9 @@
- the autoservice now defaults to being on by default
- autoservice_start() and autoservice_start() no longer return a value.
+Queue:
+ - Mark QUEUE_MEMBER_PENALTY Deprecated it never worked for realtime members
+ - QUEUE_MEMBER is now R/W supporting setting paused, ignorebusy and penalty.
+
===========================================================
===========================================================
Modified: team/irroot/app_queue_skill/apps/app_queue.c
URL: http://svnview.digium.com/svn/asterisk/team/irroot/app_queue_skill/apps/app_queue.c?view=diff&rev=325535&r1=325534&r2=325535
==============================================================================
--- team/irroot/app_queue_skill/apps/app_queue.c (original)
+++ team/irroot/app_queue_skill/apps/app_queue.c Wed Jun 29 09:37:32 2011
@@ -521,11 +521,25 @@
<enum name="count">
<para>Returns the total number of members for the specified queue.</para>
</enum>
+ <enum name="penalty">
+ <para>Gets or sets queue member penalty.</para>
+ </enum>
+ <enum name="paused">
+ <para>Gets or sets queue member paused status.</para>
+ </enum>
+ <enum name="ignorebusy">
+ <para>Gets or sets queue member ignorebusy.</para>
+ </enum>
</enumlist>
</parameter>
+ <parameter name="interface" required="false" />
</syntax>
<description>
- <para>Returns the number of members currently associated with the specified <replaceable>queuename</replaceable>.</para>
+ <para>Allows access to queue counts [R] and member information [R/W].</para>
+ <para>
+ <replaceable>queuename</replaceable> is required for all operations
+ <replaceable>interface</replaceable> is required for all member operations.
+ </para>
</description>
<see-also>
<ref type="application">Queue</ref>
@@ -658,6 +672,7 @@
</syntax>
<description>
<para>Gets or sets queue members penalty.</para>
+ <warning><para>This function has been deprecated in favor of the <literal>QUEUE_MEMBER()</literal> function</para></warning>
</description>
<see-also>
<ref type="application">Queue</ref>
@@ -936,6 +951,9 @@
/*! \brief queues.conf [general] option */
static int update_cdr = 0;
+/*! \brief queues.conf [general] option */
+static int negative_penalty_invalid = 0;
+
enum queue_result {
QUEUE_UNKNOWN = 0,
QUEUE_TIMEOUT = 1,
@@ -1137,6 +1155,7 @@
unsigned int dead:1; /*!< Used to detect members deleted in realtime */
unsigned int delme:1; /*!< Flag to delete entry on reload */
char rt_uniqueid[80]; /*!< Unique id of realtime member entry */
+ unsigned int ignorebusy:1; /*!< Flag to ignore member if the status is not available */
};
enum empty_conditions {
@@ -1254,6 +1273,7 @@
int timeout; /*!< How long to wait for an answer */
int weight; /*!< Respective weight */
int autopause; /*!< Auto pause queue members if they fail to answer */
+ int autopausedelay; /*!< Delay auto pause for autopausedelay seconds since last call */
int timeoutpriority; /*!< Do we allow a fraction of the timeout to occur for a ring? */
/* Queue strategy things */
@@ -1285,6 +1305,7 @@
static struct ao2_container *queues;
static void update_realtime_members(struct call_queue *q);
+static struct member *interface_exists(struct call_queue *q, const char *interface);
static int set_member_paused(const char *queuename, const char *interface, const char *reason, int paused);
static void queue_transfer_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan);
@@ -1808,6 +1829,7 @@
q->numperiodicannounce = 0;
q->autopause = QUEUE_AUTOPAUSE_OFF;
q->timeoutpriority = TIMEOUT_PRIORITY_APP;
+ q->autopausedelay = 0;
if (!q->members) {
if (q->strategy == QUEUE_STRATEGY_LINEAR || q->strategy == QUEUE_STRATEGY_RRORDERED)
/* linear strategy depends on order, so we have to place all members in a single bucket */
@@ -2113,6 +2135,8 @@
q->montype = 1;
} else if (!strcasecmp(param, "autopause")) {
q->autopause = autopause2int(val);
+ } else if (!strcasecmp(param, "autopausedelay")) {
+ q->autopausedelay = atoi(val);
} else if (!strcasecmp(param, "maxlen")) {
q->maxlen = atoi(val);
if (q->maxlen < 0)
@@ -2191,7 +2215,9 @@
int penalty = 0;
int paused = 0;
int found = 0;
-
+ int ignorebusy = 0;
+
+ const char *config_val;
const char *rt_uniqueid = ast_variable_retrieve(member_config, interface, "uniqueid");
const char *membername = S_OR(ast_variable_retrieve(member_config, interface, "membername"), interface);
const char *state_interface = S_OR(ast_variable_retrieve(member_config, interface, "state_interface"), interface);
@@ -2206,14 +2232,23 @@
if (penalty_str) {
penalty = atoi(penalty_str);
- if (penalty < 0)
+ if ((penalty < 0) && negative_penalty_invalid) {
+ return;
+ } else if (penalty < 0) {
penalty = 0;
+ }
}
if (paused_str) {
paused = atoi(paused_str);
if (paused < 0)
paused = 0;
+ }
+
+ if ((config_val = ast_variable_retrieve(member_config, interface, "ignorebusy"))) {
+ ignorebusy = ast_true(config_val);
+ } else {
+ ignorebusy = 1;
}
/* Find member by realtime uniqueid and update */
@@ -2226,8 +2261,9 @@
m->paused = paused;
if (strcasecmp(state_interface, m->state_interface)) {
ast_copy_string(m->state_interface, state_interface, sizeof(m->state_interface));
- }
+ }
m->penalty = penalty;
+ m->ignorebusy = ignorebusy;
if (!ast_strlen_zero(skills)) {
ast_copy_string(m->skills, skills, sizeof(m->skills));
} else {
@@ -2247,7 +2283,8 @@
if ((m = create_queue_member(interface, membername, penalty, paused, state_interface, skills))) {
m->dead = 0;
m->realtime = 1;
-+ update_queue_ent_skills_next_check(q);
+ m->ignorebusy = ignorebusy;
+ update_queue_ent_skills_next_check(q);
ast_copy_string(m->rt_uniqueid, rt_uniqueid, sizeof(m->rt_uniqueid));
ast_queue_log(q->name, "REALTIME", m->interface, "ADDMEMBER", "%s", "");
ao2_link(q->members, m);
@@ -3926,17 +3963,25 @@
mem_iter = ao2_iterator_init(q->members, 0);
while ((mem = ao2_iterator_next(&mem_iter))) {
switch (mem->status) {
- case AST_DEVICE_INUSE:
- if (!q->ringinuse)
+ case AST_DEVICE_INVALID:
+ case AST_DEVICE_UNAVAILABLE:
break;
- /* else fall through */
- case AST_DEVICE_NOT_INUSE:
- case AST_DEVICE_UNKNOWN:
- if (!mem->paused &&
-+ (!qe || member_is_selected(qe, mem))) {
- avl++;
- }
- break;
+ case AST_DEVICE_INUSE:
+ case AST_DEVICE_BUSY:
+ case AST_DEVICE_RINGING:
+ case AST_DEVICE_RINGINUSE:
+ case AST_DEVICE_ONHOLD:
+ if ((!q->ringinuse) || (!mem->ignorebusy)) {
+ break;
+ }
+ /* else fall through */
+ case AST_DEVICE_NOT_INUSE:
+ case AST_DEVICE_UNKNOWN:
+ if (!mem->paused) &&
+ (!qe || member_is_selected(qe, mem))) {
+ avl++;
+ }
+ break;
}
ao2_ref(mem, -1);
@@ -4064,34 +4109,49 @@
char tech[256];
char *location;
const char *macrocontext, *macroexten;
+ enum ast_device_state newstate;
/* on entry here, we know that tmp->chan == NULL */
+ if (tmp->member->paused) {
+ ast_debug(1, "%s paused, can't receive call\n", tmp->interface);
+ if (qe->chan->cdr) {
+ ast_cdr_busy(qe->chan->cdr);
+ }
+ tmp->stillgoing = 0;
+ return 0;
+ }
+
if ((tmp->lastqueue && tmp->lastqueue->wrapuptime && (time(NULL) - tmp->lastcall < tmp->lastqueue->wrapuptime)) ||
(!tmp->lastqueue && qe->parent->wrapuptime && (time(NULL) - tmp->lastcall < qe->parent->wrapuptime))) {
- ast_debug(1, "Wrapuptime not yet expired on queue %s for %s\n",
+ ast_debug(1, "Wrapuptime not yet expired on queue %s for %s\n",
(tmp->lastqueue ? tmp->lastqueue->name : qe->parent->name), tmp->interface);
- if (qe->chan->cdr)
+ if (qe->chan->cdr) {
ast_cdr_busy(qe->chan->cdr);
+ }
tmp->stillgoing = 0;
(*busies)++;
return 0;
}
- if (!qe->parent->ringinuse && (tmp->member->status != AST_DEVICE_NOT_INUSE) && (tmp->member->status != AST_DEVICE_UNKNOWN)) {
- ast_debug(1, "%s in use, can't receive call\n", tmp->interface);
- if (qe->chan->cdr)
- ast_cdr_busy(qe->chan->cdr);
- tmp->stillgoing = 0;
- return 0;
- }
-
- if (tmp->member->paused) {
- ast_debug(1, "%s paused, can't receive call\n", tmp->interface);
- if (qe->chan->cdr)
- ast_cdr_busy(qe->chan->cdr);
- tmp->stillgoing = 0;
- return 0;
- }
+ if (!qe->parent->ringinuse || !tmp->member->ignorebusy) {
+ if ((tmp->member->status == AST_DEVICE_UNKNOWN) || (tmp->member->status == AST_DEVICE_NOT_INUSE)) {
+ newstate = ast_parse_device_state(tmp->member->interface);
+ if (newstate != tmp->member->status) {
+ ast_log(LOG_ERROR, "Found a channel matching iterface %s while status was %i changed to %i\n",
+ tmp->member->interface, tmp->member->status, newstate);
+ update_status(qe->parent, tmp->member, newstate);
+ }
+ }
+ if ((tmp->member->status != AST_DEVICE_NOT_INUSE) && (tmp->member->status != AST_DEVICE_UNKNOWN)) {
+ ast_debug(1, "%s in use, can't receive call\n", tmp->interface);
+ if (qe->chan->cdr) {
+ ast_cdr_busy(qe->chan->cdr);
+ }
+ tmp->stillgoing = 0;
+ return 0;
+ }
+ }
+
if (!member_is_selected(qe, tmp->member)) {
if (option_debug)
@@ -4104,8 +4164,9 @@
if (use_weight && compare_weight(qe->parent,tmp->member)) {
ast_debug(1, "Priority queue delaying call to %s:%s\n", qe->parent->name, tmp->interface);
- if (qe->chan->cdr)
+ if (qe->chan->cdr) {
ast_cdr_busy(qe->chan->cdr);
+ }
tmp->stillgoing = 0;
(*busies)++;
return 0;
@@ -4120,8 +4181,9 @@
/* Request the peer */
tmp->chan = ast_request(tech, qe->chan->nativeformats, qe->chan, location, &status);
if (!tmp->chan) { /* If we can't, just go on to the next call */
- if (qe->chan->cdr)
+ if (qe->chan->cdr) {
ast_cdr_busy(qe->chan->cdr);
+ }
tmp->stillgoing = 0;
ao2_lock(qe->parent);
@@ -4460,6 +4522,18 @@
}
ast_queue_log(qe->parent->name, qe->chan->uniqueid, membername, "RINGNOANSWER", "%d", rnatime);
if (qe->parent->autopause != QUEUE_AUTOPAUSE_OFF && pause) {
+ if (qe->parent->autopausedelay > 0) {
+ struct member *mem;
+ ao2_lock(qe->parent);
+ if ((mem = interface_exists(qe->parent, interface))) {
+ time_t idletime = time(&idletime)-mem->lastcall;
+ if ((mem->lastcall != 0) && (qe->parent->autopausedelay > idletime)) {
+ ao2_unlock(qe->parent);
+ return;
+ }
+ }
+ ao2_unlock(qe->parent);
+ }
if (qe->parent->autopause == QUEUE_AUTOPAUSE_ON) {
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",
@@ -5778,8 +5852,9 @@
else
ast_moh_stop(qe->chan);
/* If appropriate, log that we have a destination channel */
- if (qe->chan->cdr)
+ if (qe->chan->cdr) {
ast_cdr_setdestchan(qe->chan->cdr, peer->name);
+ }
/* Make sure channels are compatible */
res = ast_channel_make_compatible(qe->chan, peer);
if (res < 0) {
@@ -5859,10 +5934,11 @@
if (mixmonapp) {
ast_debug(1, "Starting MixMonitor as requested.\n");
if (!monitorfilename) {
- if (qe->chan->cdr)
+ if (qe->chan->cdr) {
ast_copy_string(tmpid, qe->chan->cdr->uniqueid, sizeof(tmpid));
- else
+ } else {
snprintf(tmpid, sizeof(tmpid), "chan-%lx", ast_random());
+ }
} else {
const char *m = monitorfilename;
for (p = tmpid2; p < tmpid2 + sizeof(tmpid2) - 1; p++, m++) {
@@ -5929,12 +6005,13 @@
ast_debug(1, "Arguments being passed to MixMonitor: %s\n", mixmonargs);
/* We purposely lock the CDR so that pbx_exec does not update the application data */
- if (qe->chan->cdr)
+ if (qe->chan->cdr) {
ast_set_flag(qe->chan->cdr, AST_CDR_FLAG_LOCKED);
+ }
pbx_exec(qe->chan, mixmonapp, mixmonargs);
- if (qe->chan->cdr)
+ if (qe->chan->cdr) {
ast_clear_flag(qe->chan->cdr, AST_CDR_FLAG_LOCKED);
-
+ }
} else {
ast_log(LOG_WARNING, "Asked to run MixMonitor on this call, but cannot find the MixMonitor app!\n");
}
@@ -6253,7 +6330,10 @@
ao2_lock(q);
if ((mem = ao2_find(q->members, &tmpmem, OBJ_POINTER))) {
/* XXX future changes should beware of this assumption!! */
- if (!mem->dynamic) {
+ /*Change Penalty on realtime users*/
+ if (mem->realtime && !ast_strlen_zero(mem->rt_uniqueid) && negative_penalty_invalid) {
+ update_realtime_member_field(mem, q->name, "penalty", "-1");
+ } else if (!mem->dynamic) {
ao2_ref(mem, -1);
ao2_unlock(q);
queue_t_unref(q, "Interface wasn't dynamic, expiring temporary reference");
@@ -6440,35 +6520,34 @@
int foundinterface = 0, foundqueue = 0;
struct call_queue *q;
struct member *mem;
- struct ao2_iterator queue_iter;
-
- if (penalty < 0) {
+ char rtpenalty[80];
+
+ if (penalty < 0 && !negative_penalty_invalid) {
ast_log(LOG_ERROR, "Invalid penalty (%d)\n", penalty);
return RESULT_FAILURE;
}
- queue_iter = ao2_iterator_init(queues, 0);
- while ((q = ao2_t_iterator_next(&queue_iter, "Iterate through queues"))) {
+ if ((q = load_realtime_queue(queuename))) {
+ foundqueue++;
ao2_lock(q);
- if (ast_strlen_zero(queuename) || !strcasecmp(q->name, queuename)) {
- foundqueue++;
- if ((mem = interface_exists(q, interface))) {
- foundinterface++;
+ if ((mem = interface_exists(q, interface))) {
+ foundinterface++;
+ if (!mem->realtime) {
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);
- }
+ } else {
+ sprintf(rtpenalty,"%i", penalty);
+ update_realtime_member_field(mem, q->name, "penalty", rtpenalty);
+ }
+ 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);
}
ao2_unlock(q);
- queue_t_unref(q, "Done with iterator");
- }
- ao2_iterator_destroy(&queue_iter);
+ }
if (foundinterface) {
return RESULT_SUCCESS;
@@ -7271,31 +7350,37 @@
return 0;
}
-/*!
+/*!
* \brief Get number either busy / free / ready or total members of a specific queue
- * \retval number of members (busy / free / ready / total)
+ * \brief Get or set member properties penalty / paused / ignorebusy
+ * \retval number of members (busy / free / ready / total) or member info (penalty / paused / ignorebusy)
* \retval -1 on error
*/
-static int queue_function_qac(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
+static int queue_function_mem_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
{
int count = 0;
struct member *m;
struct ao2_iterator mem_iter;
struct call_queue *q;
- char *option;
+
+ AST_DECLARE_APP_ARGS(args,
+ AST_APP_ARG(queuename);
+ AST_APP_ARG(option);
+ AST_APP_ARG(interface);
+ );
+ /* Make sure the returned value on error is zero length string. */
+ buf[0] = '\0';
if (ast_strlen_zero(data)) {
ast_log(LOG_ERROR, "%s requires an argument: queuename\n", cmd);
return -1;
}
- if ((option = strchr(data, ',')))
- *option++ = '\0';
- else
- option = "logged";
- if ((q = load_realtime_queue(data))) {
+ AST_STANDARD_APP_ARGS(args, data);
+
+ if ((q = load_realtime_queue(args.queuename))) {
ao2_lock(q);
- if (!strcasecmp(option, "logged")) {
+ if (!strcasecmp(args.option, "logged")) {
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 */
@@ -7305,7 +7390,7 @@
ao2_ref(m, -1);
}
ao2_iterator_destroy(&mem_iter);
- } else if (!strcasecmp(option, "free")) {
+ } else if (!strcasecmp(args.option, "free")) {
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 */
@@ -7315,7 +7400,7 @@
ao2_ref(m, -1);
}
ao2_iterator_destroy(&mem_iter);
- } else if (!strcasecmp(option, "ready")) {
+ } else if (!strcasecmp(args.option, "ready")) {
time_t now;
time(&now);
mem_iter = ao2_iterator_init(q->members, 0);
@@ -7328,22 +7413,104 @@
ao2_ref(m, -1);
}
ao2_iterator_destroy(&mem_iter);
- } else /* must be "count" */
+ } else if (!strcasecmp(args.option, "count") || ast_strlen_zero(args.option)) {
count = q->membercount;
+ } else if (!strcasecmp(args.option, "penalty") && !ast_strlen_zero(args.interface) &&
+ ((m = interface_exists(q, args.interface)))) {
+ count = m->penalty;
+ } else if (!strcasecmp(args.option, "paused") && !ast_strlen_zero(args.interface) &&
+ ((m = interface_exists(q, args.interface)))) {
+ count = m->paused;
+ } else if (!strcasecmp(args.option, "ignorebusy") && !ast_strlen_zero(args.interface) &&
+ ((m = interface_exists(q, args.interface)))) {
+ count = m->ignorebusy;
+ }
ao2_unlock(q);
queue_t_unref(q, "Done with temporary reference in QUEUE_MEMBER()");
- } else
- ast_log(LOG_WARNING, "queue %s was not found\n", data);
+ } else {
+ ast_log(LOG_WARNING, "queue %s was not found\n", args.queuename);
+ }
snprintf(buf, len, "%d", count);
return 0;
}
-/*!
+/*! \brief Dialplan function QUEUE_MEMBER() Sets the members penalty / paused / ignorebusy. */
+static int queue_function_mem_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
+{
+ int memvalue;
+ struct call_queue *q;
+ struct member *m;
+ char rtvalue[80];
+
+ AST_DECLARE_APP_ARGS(args,
+ AST_APP_ARG(queuename);
+ AST_APP_ARG(option);
+ AST_APP_ARG(interface);
+ );
+
+ if (ast_strlen_zero(data)) {
+ ast_log(LOG_ERROR, "Missing argument. QUEUE_MEMBER(<queuename>,<option>,<interface>)\n");
+ return -1;
+ }
+
+ AST_STANDARD_APP_ARGS(args, data);
+
+ if (args.argc < 3) {
+ ast_log(LOG_ERROR, "Missing argument. QUEUE_MEMBER_PENALTY(<queuename>,<interface>)\n");
+ return -1;
+ }
+
+ if (ast_strlen_zero(args.interface) && ast_strlen_zero(args.option)) {
+ ast_log (LOG_ERROR, "<interface> and <option> parameter's can't be null\n");
+ return -1;
+ }
+
+ memvalue = atoi(value);
+
+ if (!strcasecmp(args.option, "penalty")) {
+ /* if queuename = NULL then penalty will be set for interface in all the queues.*/
+ if (set_member_penalty(args.queuename, args.interface, memvalue)) {
+ ast_log(LOG_ERROR, "Invalid interface, queue or penalty\n");
+ return -1;
+ }
+ } else if ((q = load_realtime_queue(args.queuename))) {
+ ao2_lock(q);
+ if ((m = interface_exists(q, args.interface))) {
+ sprintf(rtvalue, "%s",(memvalue <= 0) ? "0" : "1");
+ if (!strcasecmp(args.option, "paused")) {
+ if (m->realtime) {
+ update_realtime_member_field(m, q->name, args.option, rtvalue);
+ } else {
+ m->paused = (memvalue <= 0) ? 0 : 1;
+ }
+ } else if (!strcasecmp(args.option, "ignorebusy")) {
+ if (m->realtime) {
+ update_realtime_member_field(m, q->name, args.option, rtvalue);
+ } else {
+ m->ignorebusy = (memvalue <= 0) ? 0 : 1;
+ }
+ } else {
+ ast_log(LOG_ERROR, "Invalid option, only penalty , paused or ignorebusy are valid\n");
+ return -1;
+ }
+ } else {
+ ast_log(LOG_ERROR, "Invalid interface or queue\n");
+ return -1;
+ }
+ ao2_unlock(q);
+ } else {
+ ast_log(LOG_ERROR, "Invalid queue\n");
+ return -1;
+ }
+ return 0;
+}
+
+/*!
* \brief Get the total number of members in a specific queue (Deprecated)
- * \retval number of members
- * \retval -1 on error
+ * \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)
{
@@ -7549,7 +7716,8 @@
static struct ast_custom_function queuemembercount_function = {
.name = "QUEUE_MEMBER",
- .read = queue_function_qac,
+ .read = queue_function_mem_read,
+ .write = queue_function_mem_write,
};
static struct ast_custom_function queuemembercount_dep = {
@@ -7747,8 +7915,9 @@
{
const char *general_val = NULL;
queue_persistent_members = 0;
- if ((general_val = ast_variable_retrieve(cfg, "general", "persistentmembers")))
+ if ((general_val = ast_variable_retrieve(cfg, "general", "persistentmembers"))) {
queue_persistent_members = ast_true(general_val);
+ }
autofill_default = 0;
if ((general_val = ast_variable_retrieve(cfg, "general", "autofill")))
autofill_default = ast_true(general_val);
@@ -7763,6 +7932,9 @@
shared_lastcall = 0;
if ((general_val = ast_variable_retrieve(cfg, "general", "shared_lastcall")))
shared_lastcall = ast_true(general_val);
+ negative_penalty_invalid = 0;
+ if ((general_val = ast_variable_retrieve(cfg, "general", "negative_penalty_invalid")))
+ negative_penalty_invalid = ast_true(general_val);
}
/*! \brief reload information pertaining to a single member
Modified: team/irroot/app_queue_skill/configs/queues.conf.sample
URL: http://svnview.digium.com/svn/asterisk/team/irroot/app_queue_skill/configs/queues.conf.sample?view=diff&rev=325535&r1=325534&r2=325535
==============================================================================
--- team/irroot/app_queue_skill/configs/queues.conf.sample (original)
+++ team/irroot/app_queue_skill/configs/queues.conf.sample Wed Jun 29 09:37:32 2011
@@ -60,6 +60,10 @@
; The default value is yes.
;
;shared_lastcall=no
+;
+; Negative_penalty_invalid will treat members with a negative penalty as logged off
+;
+;negative_penalty_invalid = no
;
;[markq]
;
@@ -195,6 +199,10 @@
; yes: Member will be paused only in the queue where the timeout took place
; all: Memeber will be paused in all queues he/she is a member
;autopause=yes
+;
+; Autopausedelay delay autopause for autopausedelay seconds from the
+; last call if a member has not taken a call the delay has no effect.
+;autopausedelay=60
;
; Maximum number of people waiting in the queue (0 for unlimited)
;
@@ -459,6 +467,9 @@
; uncomment this option. (Note: only the SIP channel driver currently is able
; to report 'in use'.)
;
+; A member can have the ignorebusy flag set or unset when ringinuse is set to
+; allow a per member control.
+;
; ringinuse = no
;
; If you wish to have a delay before the member is connected to the caller (or
More information about the asterisk-commits
mailing list