[asterisk-commits] eliel: branch eliel/per_member_wrapuptime r188382 - in /team/eliel/per_member...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Apr 14 12:13:04 CDT 2009


Author: eliel
Date: Tue Apr 14 12:13:00 2009
New Revision: 188382

URL: http://svn.digium.com/svn-view/asterisk?view=rev&rev=188382
Log:
Set a way to disable the wrapuptime for the next call.
Implement CLI command 'queue set wrapuptime'.
Implement Manager action 'QueueWrapuptime'.


Modified:
    team/eliel/per_member_wrapuptime/apps/app_queue.c
    team/eliel/per_member_wrapuptime/include/asterisk/cli.h
    team/eliel/per_member_wrapuptime/main/cli.c

Modified: team/eliel/per_member_wrapuptime/apps/app_queue.c
URL: http://svn.digium.com/svn-view/asterisk/team/eliel/per_member_wrapuptime/apps/app_queue.c?view=diff&rev=188382&r1=188381&r2=188382
==============================================================================
--- team/eliel/per_member_wrapuptime/apps/app_queue.c (original)
+++ team/eliel/per_member_wrapuptime/apps/app_queue.c Tue Apr 14 12:13:00 2009
@@ -676,6 +676,7 @@
 	int status;                         /*!< Status of queue member */
 	int paused;                         /*!< Are we paused (not accepting calls)? */
 	int wrapuptime;			    /*!< Member wrapuptime. */
+	int current_wrapuptime;             /*!< This wrapuptime can be modified just for the next call. */
 	time_t lastcall;                    /*!< When last successful call was hungup */
 	struct call_queue *lastqueue;	    /*!< Last queue we received a call */
 	unsigned int dead:1;                /*!< Used to detect members deleted in realtime */
@@ -1107,6 +1108,7 @@
 		cur->penalty = penalty;
 		cur->paused = paused;
 		cur->wrapuptime = wrapuptime;
+		cur->current_wrapuptime = wrapuptime;
 		ast_copy_string(cur->interface, interface, sizeof(cur->interface));
 		if (!ast_strlen_zero(state_interface))
 			ast_copy_string(cur->state_interface, state_interface, sizeof(cur->state_interface));
@@ -2440,7 +2442,7 @@
 	const char *macrocontext, *macroexten;
 
 	/* on entry here, we know that tmp->chan == NULL */
-	if ((tmp->wrapuptime >= 0 && (time(NULL) - tmp->lastcall < tmp->wrapuptime)) ||
+	if ((tmp->member->current_wrapuptime >= 0 && (time(NULL) - tmp->lastcall < tmp->member->current_wrapuptime)) ||
 		(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", 
@@ -2913,6 +2915,7 @@
 						}
 					}
 					peer = o;
+					o->member->current_wrapuptime = o->member->wrapuptime;
 				}
 			} else if (o->chan && (o->chan == winner)) {
 
@@ -3013,6 +3016,7 @@
 									}
 								}
 								peer = o;
+								o->member->current_wrapuptime = o->member->wrapuptime;
 							}
 							break;
 						case AST_CONTROL_BUSY:
@@ -3819,7 +3823,7 @@
 		tmp->oldstatus = cur->status;
 		tmp->lastcall = cur->lastcall;
 		tmp->lastqueue = cur->lastqueue;
-		tmp->wrapuptime = cur->wrapuptime;
+		tmp->wrapuptime = cur->current_wrapuptime;
 		tmp->update_connectedline = 1;
 		ast_copy_string(tmp->interface, cur->interface, sizeof(tmp->interface));
 		/* Special case: If we ring everyone, go ahead and ring them, otherwise
@@ -4365,6 +4369,57 @@
 	return NULL;
 }
 
+/*!
+ * \internal
+ * \brief Set the members wrapuptime.
+ * \param queuename The name of the call queue.
+ * \param interface The members interface.
+ * \param offset The wrapuptime offset in seconds.
+ * \param modify_defaults Modify the static values.
+ * \retval < 0 on error.
+ * \retval 0 on success.
+ */
+static int set_member_wrapuptime(const char *queuename, const char *interface, int offset, int modify_defaults)
+{
+	int foundinterface = 0;
+	struct call_queue *q;
+	struct member *mem;
+	struct ao2_iterator queue_iter;
+
+	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))) {
+				foundinterface++;
+				/* modify static configuration. */
+				if (modify_defaults) {
+					mem->wrapuptime += offset;
+					if (mem->wrapuptime < 0) {
+						mem->wrapuptime = -1;
+					}
+
+					ast_queue_log(q->name, "NONE", interface, "WRAPUPTIME", "%d", mem->wrapuptime);
+					manager_event(EVENT_FLAG_AGENT, "QueueMemberWrapuptime",
+							"Queue: %s\r\n"
+							"Interface: %s\r\n"
+							"Wrapuptime: %d\r\n",
+							q->name, mem->interface, mem->wrapuptime);
+				}
+				/* this wrapuptime will be used only for the next call to this agent. */
+				mem->current_wrapuptime += offset;
+			}
+		}
+		ao2_unlock(q);
+		queue_unref(q);
+	}
+
+	if (!foundinterface) {
+		return -1;
+	}
+
+	return 0;
+}
 
 /*! \brief Dump all members in a specific queue to the database
  *
@@ -6716,6 +6771,34 @@
 	return 0;
 }
 
+/*!
+ * \internal
+ * \brief Manager action to set the queue member wrapuptime.
+ */
+static int manager_queue_member_wrapuptime(struct mansession *s, const struct message *m)
+{
+	const char *interface, *offset, *static_value, *queue;
+	int default_wrapuptime = 0;
+
+	interface = astman_get_header(m, "Interface");
+	queue = astman_get_header(m, "Queue");
+	offset = astman_get_header(m, "Offset");
+	static_value = astman_get_header(m, "Static");
+
+	if (ast_strlen_zero(interface) || ast_strlen_zero(offset)) {
+		astman_send_error(s, m, "Need 'Interface' and 'Offset' parameters.");
+	}
+
+	if (ast_strlen_zero(static_value)) {
+		/* also modify the member static value? */
+		default_wrapuptime = ast_true(static_value);
+	}
+
+	set_member_wrapuptime(queue, interface, atoi(offset), default_wrapuptime);
+
+	return 0;
+}
+
 static char *handle_queue_add_member(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 	char *queuename, *interface, *membername = NULL, *state_interface = NULL;
@@ -7024,6 +7107,91 @@
 	default:
 		return CLI_FAILURE;
 	}
+}
+
+/*! \brief Implement autocomplete for CLI command 'queue set wrapuptime' */
+static char *complete_queue_set_member_wrapuptime(const char *line, const char *word, int pos, int state)
+{
+	static char *opts[] = { "in", "static", NULL };
+
+	/* 0 - queue; 1 - set; 2 - wrapuptime; 3 - <wrapuptime>; 4 - on; 5 - <member>; 6 - in; 7 - <queue>; 8 - current*/
+	switch (pos) {
+	case 3:
+		return ast_cli_complete_number(word, 0, 0x7fffffff, state);
+	case 4:
+		if (!state) {
+			return ast_strdup("on");
+		}
+		break;
+	case 6:
+		return ast_cli_complete(word, opts, state);
+	case 7:
+		if (strstr(line, " in ")) {
+			return complete_queue(line, word, pos, state);
+		}
+		break;
+	case 8:
+		if (!state) {
+			return ast_strdup("static");
+		}
+		break;
+	default:
+		return NULL;
+	}
+
+	return NULL;
+}
+
+/*! \brief Handle CLI command 'queue set wrapuptime'. */
+static char *handle_queue_set_member_wrapuptime(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+	char *queuename = NULL, *interface, *ret;
+	int wrapuptime, member_default = 0;
+
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "queue set wrapuptime";
+		e->usage = 
+		"Usage: queue set wrapuptime <wrapuptime> on <interface> [in <queue>] [static]\n"
+		"	Set a member's wrapuptime in the queue specified. If no queue is specified\n"
+		"	then that interface's wrapuptime is set in all queues to which that interface is a member.\n"
+		"       if 'static' is specified, only modify the wrapuptime for the last call\n";
+		return NULL;
+	case CLI_GENERATE:
+		return complete_queue_set_member_wrapuptime(a->line, a->word, a->pos, a->n);
+	}
+
+	if (a->argc < 6 || a->argc > 9) {
+		return CLI_SHOWUSAGE;
+	} else if (strcasecmp(a->argv[4], "on") || ((a->argc > 6 && strcmp(a->argv[6], "in"))
+		&& (a->argc == 9 && strcasecmp(a->argv[a->argc - 1], "static")))) {
+		return CLI_SHOWUSAGE;
+	}
+
+	if (a->argc == 8) {
+		queuename = a->argv[7];
+	}
+	interface = a->argv[5];
+	wrapuptime = atoi(a->argv[3]);
+
+	if ((a->argc == 7 || a->argc == 9) && !strcasecmp(a->argv[a->argc - 1], "static")) {
+		member_default = 1;
+	}
+
+	if (set_member_wrapuptime(queuename, interface, wrapuptime, !member_default)) {
+		ast_cli(a->fd, "Failed to set wrapuptime on interface '%s'", interface);
+		ret = CLI_FAILURE;
+	} else {
+		ast_cli(a->fd, "Set wrapuptime on interface '%s'", interface);
+		ret = CLI_SUCCESS;
+	}
+
+	if (queuename) {
+		ast_cli(a->fd, " from queue %s", queuename);
+	}
+	ast_cli(a->fd, "\n");
+
+	return ret;
 }
 
 static char *complete_queue_rule_show(const char *line, const char *word, int pos, int state) 
@@ -7194,6 +7362,7 @@
 	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_wrapuptime, "Set wrapuptime for a member of a specified queue"),
 	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"),
@@ -7285,6 +7454,7 @@
 	res |= ast_manager_register("QueuePause", EVENT_FLAG_AGENT, manager_pause_queue_member, "Makes a queue member temporarily unavailable");
 	res |= ast_manager_register("QueueLog", EVENT_FLAG_AGENT, manager_queue_log_custom, "Adds custom entry in queue_log");
 	res |= ast_manager_register("QueuePenalty", EVENT_FLAG_AGENT, manager_queue_member_penalty, "Set the penalty for a queue member"); 
+	res |= ast_manager_register("QueueWrapuptime", EVENT_FLAG_AGENT, manager_queue_member_wrapuptime, "Set the wrapuptime for a queue member"); 
 	res |= ast_manager_register("QueueRule", 0, manager_queue_rule_show, "Queue Rules");
 	res |= ast_manager_register("QueueReload", 0, manager_queue_reload, "Reload a queue, queues, or any sub-section of a queue or queues");
 	res |= ast_manager_register("QueueReset", 0, manager_queue_reset, "Reset queue statistics");

Modified: team/eliel/per_member_wrapuptime/include/asterisk/cli.h
URL: http://svn.digium.com/svn-view/asterisk/team/eliel/per_member_wrapuptime/include/asterisk/cli.h?view=diff&rev=188382&r1=188381&r2=188382
==============================================================================
--- team/eliel/per_member_wrapuptime/include/asterisk/cli.h (original)
+++ team/eliel/per_member_wrapuptime/include/asterisk/cli.h Tue Apr 14 12:13:00 2009
@@ -193,6 +193,15 @@
  */
 char *ast_cli_complete(const char *word, char *const choices[], int pos);
 
+/*!
+ * \brief Helper function to generate possible numbers in the cli.
+ * \param partial The word to complete.
+ * \param min The min number value.
+ * \param max The max number value.
+ * \param n The number of requests made to this function for autocompletion.
+ */
+char *ast_cli_complete_number(const char *partial, unsigned int min, unsigned int max, int n);
+
 /*! 
  * \brief Interprets a command
  * Interpret a command s, sending output to fd if uid:gid has permissions

Modified: team/eliel/per_member_wrapuptime/main/cli.c
URL: http://svn.digium.com/svn-view/asterisk/team/eliel/per_member_wrapuptime/main/cli.c?view=diff&rev=188382&r1=188381&r2=188382
==============================================================================
--- team/eliel/per_member_wrapuptime/main/cli.c (original)
+++ team/eliel/per_member_wrapuptime/main/cli.c Tue Apr 14 12:13:00 2009
@@ -318,7 +318,7 @@
 	return df;
 }
 
-static char *complete_number(const char *partial, unsigned int min, unsigned int max, int n)
+char *ast_cli_complete_number(const char *partial, unsigned int min, unsigned int max, int n)
 {
 	int i, count = 0;
 	unsigned int prospective[2];
@@ -390,7 +390,7 @@
 			char *pos = a->pos == 3 ? argv3 : S_OR(a->argv[4], "");
 			int numbermatch = (ast_strlen_zero(pos) || strchr("123456789", pos[0])) ? 0 : 21;
 			if (a->n < 21 && numbermatch == 0) {
-				return complete_number(pos, 0, 0x7fffffff, a->n);
+				return ast_cli_complete_number(pos, 0, 0x7fffffff, a->n);
 			} else if (pos[0] == '0') {
 				if (a->n == 0) {
 					return ast_strdup("0");




More information about the asterisk-commits mailing list