Count number of members answering a queue.
</synopsis>
<syntax>
- <parameter name="queuename" required="true" />
+ <parameter name="queuename" required="false" />
<parameter name="option" required="true">
<enumlist>
<enum name="logged">
<para>Returns the total number of members for the specified queue.</para>
</enum>
<enum name="penalty">
- <para>Gets or sets queue member penalty.</para>
+ <para>Gets or sets queue member penalty. If
+ <replaceable>queuename</replaceable> is not specified
+ when setting the penalty then the penalty is set in all queues
+ the interface is a member.</para>
</enum>
<enum name="paused">
- <para>Gets or sets queue member paused status.</para>
+ <para>Gets or sets queue member paused status. If
+ <replaceable>queuename</replaceable> is not specified
+ when setting the paused status then the paused status is set
+ in all queues the interface is a member.</para>
</enum>
<enum name="ringinuse">
- <para>Gets or sets queue member ringinuse.</para>
+ <para>Gets or sets queue member ringinuse. If
+ <replaceable>queuename</replaceable> is not specified
+ when setting ringinuse then ringinuse is set
+ in all queues the interface is a member.</para>
</enum>
</enumlist>
</parameter>
</syntax>
<description>
<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>
+ <para><replaceable>queuename</replaceable> is required for all read operations.</para>
+ <para><replaceable>interface</replaceable> is required for all member operations.</para>
</description>
<see-also>
<ref type="application">Queue</ref>
return 0;
}
+static struct member *get_interface_helper(struct call_queue *q, const char *interface)
+{
+ struct member *m;
+
+ if (ast_strlen_zero(interface)) {
+ ast_log(LOG_ERROR, "QUEUE_MEMBER: Missing required interface argument.\n");
+ return NULL;
+ }
+
+ m = interface_exists(q, interface);
+ if (!m) {
+ ast_log(LOG_ERROR, "Queue member interface '%s' not in queue '%s'.\n",
+ interface, q->name);
+ }
+ return m;
+}
+
/*!
* \brief Get number either busy / free / ready or total members of a specific queue
* \brief Get or set member properties penalty / paused / ringinuse
* \retval number of members (busy / free / ready / total) or member info (penalty / paused / ringinuse)
* \retval -1 on error
-*/
+ */
static int queue_function_mem_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
{
int count = 0;
buf[0] = '\0';
if (ast_strlen_zero(data)) {
- ast_log(LOG_ERROR, "Missing required argument. %s(<queuename>,<option>[<interface>])\n", cmd);
+ ast_log(LOG_ERROR,
+ "Missing required argument. %s(<queuename>,<option>[,<interface>])\n",
+ cmd);
return -1;
}
AST_STANDARD_APP_ARGS(args, data);
- if (args.argc < 2) {
- ast_log(LOG_ERROR, "Missing required argument. %s(<queuename>,<option>[<interface>])\n", cmd);
+ if (ast_strlen_zero(args.queuename) || ast_strlen_zero(args.option)) {
+ ast_log(LOG_ERROR,
+ "Missing required argument. %s(<queuename>,<option>[,<interface>])\n",
+ cmd);
return -1;
}
ao2_ref(m, -1);
}
ao2_iterator_destroy(&mem_iter);
- } else if (!strcasecmp(args.option, "count") || ast_strlen_zero(args.option)) {
+ } else if (!strcasecmp(args.option, "count")) {
count = ao2_container_count(q->members);
- } else if (!strcasecmp(args.option, "penalty") && !ast_strlen_zero(args.interface) &&
- ((m = interface_exists(q, args.interface)))) {
- count = m->penalty;
- ao2_ref(m, -1);
- } else if (!strcasecmp(args.option, "paused") && !ast_strlen_zero(args.interface) &&
- ((m = interface_exists(q, args.interface)))) {
- count = m->paused;
- ao2_ref(m, -1);
- } else if ( (!strcasecmp(args.option, "ignorebusy") || !strcasecmp(args.option, "ringinuse")) &&
- !ast_strlen_zero(args.interface) &&
- ((m = interface_exists(q, args.interface)))) {
- count = m->ringinuse;
- ao2_ref(m, -1);
- } else if (!ast_strlen_zero(args.interface)) {
- ast_log(LOG_ERROR, "Queue member interface %s not in queue %s\n",
- args.interface, args.queuename);
+ } else if (!strcasecmp(args.option, "penalty")) {
+ m = get_interface_helper(q, args.interface);
+ if (m) {
+ count = m->penalty;
+ ao2_ref(m, -1);
+ }
+ } else if (!strcasecmp(args.option, "paused")) {
+ m = get_interface_helper(q, args.interface);
+ if (m) {
+ count = m->paused;
+ ao2_ref(m, -1);
+ }
+ } else if ((!strcasecmp(args.option, "ignorebusy") /* ignorebusy is legacy */
+ || !strcasecmp(args.option, "ringinuse"))) {
+ m = get_interface_helper(q, args.interface);
+ if (m) {
+ count = m->ringinuse;
+ ao2_ref(m, -1);
+ }
} else {
- ast_log(LOG_ERROR, "Unknown option %s provided to %s, valid values are: "
- "logged, free, ready, count, penalty, paused, ringinuse\n", args.option, cmd);
+ ast_log(LOG_ERROR, "%s: Invalid option '%s' provided.\n", cmd, args.option);
}
ao2_unlock(q);
queue_t_unref(q, "Done with temporary reference in QUEUE_MEMBER()");
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);
);
if (ast_strlen_zero(data)) {
- ast_log(LOG_ERROR, "Missing argument. QUEUE_MEMBER(<queuename>,<option>,<interface>)\n");
+ ast_log(LOG_ERROR,
+ "Missing required argument. %s([<queuename>],<option>,<interface>)\n",
+ cmd);
return -1;
}
AST_STANDARD_APP_ARGS(args, data);
- if (args.argc < 3) {
- ast_log(LOG_ERROR, "Missing argument. QUEUE_MEMBER_PENALTY(<queuename>,<interface>)\n");
+ if (ast_strlen_zero(args.option)
+ || ast_strlen_zero(args.interface)) {
+ ast_log(LOG_ERROR,
+ "Missing required argument. %s([<queuename>],<option>,<interface>)\n",
+ cmd);
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;
- }
+ /*
+ * If queuename is empty then the option will be
+ * set for the interface in all queues.
+ */
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_value(args.queuename, args.interface, MEMBER_PENALTY, memvalue)) {
- ast_log(LOG_ERROR, "Invalid interface, queue or penalty\n");
+ ast_log(LOG_ERROR, "Invalid interface, queue, or penalty\n");
return -1;
}
- } else if ((q = find_load_queue_rt_friendly(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);
- }
- m->paused = (memvalue <= 0) ? 0 : 1;
- ast_devstate_changed(m->paused ? QUEUE_PAUSED_DEVSTATE : QUEUE_UNPAUSED_DEVSTATE,
- AST_DEVSTATE_CACHABLE, "Queue:%s_pause_%s", q->name, args.interface);
-
- } else if ((!strcasecmp(args.option, "ignorebusy")) || (!strcasecmp(args.option, "ringinuse"))) {
- if (m->realtime) {
- update_realtime_member_field(m, q->name, args.option, rtvalue);
- }
-
- m->ringinuse = (memvalue <= 0) ? 0 : 1;
- } else {
- ast_log(LOG_ERROR, "Invalid option, only penalty , paused or ringinuse/ignorebusy are valid\n");
- ao2_ref(m, -1);
- ao2_unlock(q);
- ao2_ref(q, -1);
- return -1;
- }
- ao2_ref(m, -1);
- } else {
- ao2_unlock(q);
- ao2_ref(q, -1);
- ast_log(LOG_ERROR, "Invalid interface for queue\n");
+ } else if (!strcasecmp(args.option, "paused")) {
+ memvalue = (memvalue <= 0) ? 0 : 1;
+ if (set_member_paused(args.queuename, args.interface, NULL, memvalue)) {
+ ast_log(LOG_ERROR, "Invalid interface or queue\n");
return -1;
}
- ao2_unlock(q);
- ao2_ref(q, -1);
- } else {
- ast_log(LOG_ERROR, "Invalid queue\n");
+ } else if (!strcasecmp(args.option, "ignorebusy") /* ignorebusy is legacy */
+ || !strcasecmp(args.option, "ringinuse")) {
+ memvalue = (memvalue <= 0) ? 0 : 1;
+ if (set_member_value(args.queuename, args.interface, MEMBER_RINGINUSE, memvalue)) {
+ ast_log(LOG_ERROR, "Invalid interface or queue\n");
+ return -1;
+ }
+ } else {
+ ast_log(LOG_ERROR, "%s: Invalid option '%s' provided.\n", cmd, args.option);
return -1;
}
return 0;
SCOPED_MUTEX(lock, &root_handler_lock);
- old_size = sizeof(*new_handler) +
- root_handler->num_children * sizeof(handler);
+ old_size = sizeof(*new_handler) + root_handler->num_children * sizeof(handler);
new_size = old_size + sizeof(handler);
new_handler = ao2_alloc(new_size, NULL);
int ast_ari_remove_handler(struct stasis_rest_handlers *handler)
{
- RAII_VAR(struct stasis_rest_handlers *, new_handler, NULL, ao2_cleanup);
- size_t size, i, j;
+ struct stasis_rest_handlers *new_handler;
+ size_t size;
+ size_t i;
+ size_t j;
ast_assert(root_handler != NULL);
ast_mutex_lock(&root_handler_lock);
- size = sizeof(*new_handler) +
- root_handler->num_children * sizeof(handler);
+ size = sizeof(*new_handler) + root_handler->num_children * sizeof(handler);
new_handler = ao2_alloc(size, NULL);
if (!new_handler) {
+ ast_mutex_unlock(&root_handler_lock);
return -1;
}
- memcpy(new_handler, root_handler, sizeof(*new_handler));
+ /* Create replacement root_handler less the handler to remove. */
+ memcpy(new_handler, root_handler, sizeof(*new_handler));
for (i = 0, j = 0; i < root_handler->num_children; ++i) {
if (root_handler->children[i] == handler) {
ast_module_unref(ast_module_info->self);
}
new_handler->num_children = j;
+ /* Replace the old root_handler with the new. */
ao2_cleanup(root_handler);
- ao2_ref(new_handler, +1);
root_handler = new_handler;
+
ast_mutex_unlock(&root_handler_lock);
return 0;
}