[svn-commits] eliel: branch eliel/per_member_wrapuptime r188121 - /team/eliel/per_member_wr...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Mon Apr 13 15:20:04 CDT 2009


Author: eliel
Date: Mon Apr 13 15:20:00 2009
New Revision: 188121

URL: http://svn.digium.com/svn-view/asterisk?view=rev&rev=188121
Log:
- Add a per member wrapuptime configuration.
- Check the member wrapuptime configuration and then the wrapuptime for the queue.


Modified:
    team/eliel/per_member_wrapuptime/apps/app_queue.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=188121&r1=188120&r2=188121
==============================================================================
--- team/eliel/per_member_wrapuptime/apps/app_queue.c (original)
+++ team/eliel/per_member_wrapuptime/apps/app_queue.c Mon Apr 13 15:20:00 2009
@@ -626,6 +626,7 @@
 	char interface[256];
 	int stillgoing;
 	int metric;
+	int wrapuptime;
 	int oldstatus;
 	time_t lastcall;
 	struct call_queue *lastqueue;
@@ -674,6 +675,7 @@
 	int realtime;                       /*!< Is this member realtime? */
 	int status;                         /*!< Status of queue member */
 	int paused;                         /*!< Are we paused (not accepting calls)? */
+	int wrapuptime;			    /*!< Member wrapuptime. */
 	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 */
@@ -974,8 +976,9 @@
 			if (member->paused && (conditions & QUEUE_EMPTY_PAUSED)) {
 				ast_debug(4, "%s is unavailable because he is paused'\n", member->membername);
 				break;
-			} else if ((conditions & QUEUE_EMPTY_WRAPUP) && member->lastcall && q->wrapuptime && (time(NULL) - q->wrapuptime < member->lastcall)) {
-				ast_debug(4, "%s is unavailable because it has only been %d seconds since his last call (wrapup time is %d)\n", member->membername, (int) (time(NULL) - member->lastcall), q->wrapuptime);
+			} else if ((conditions & QUEUE_EMPTY_WRAPUP) && member->lastcall
+				&& q->wrapuptime && (time(NULL) - (member->wrapuptime >= 0 ? member->wrapuptime : q->wrapuptime) < member->lastcall)) {
+				ast_debug(4, "%s is unavailable because it has only been %d seconds since his last call (wrapup time is %d)\n", member->membername, (int) (time(NULL) - member->lastcall), (member->wrapuptime >= 0 ? member->wrapuptime : q->wrapuptime));
 				break;
 			} else {
 				ao2_unlock(q);
@@ -1096,13 +1099,14 @@
 }
 
 /*! \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)
+static struct member *create_queue_member(const char *interface, const char *membername, int penalty, int paused, const char *state_interface, int wrapuptime)
 {
 	struct member *cur;
 	
 	if ((cur = ao2_alloc(sizeof(*cur), NULL))) {
 		cur->penalty = penalty;
 		cur->paused = paused;
+		cur->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));
@@ -1546,13 +1550,14 @@
  * Search for member in queue, if found update penalty/paused state,
  * if no memeber exists create one flag it as a RT member and add to queue member list. 
 */
-static void rt_handle_member_record(struct call_queue *q, char *interface, const char *rt_uniqueid, const char *membername, const char *penalty_str, const char *paused_str, const char* state_interface)
+static void rt_handle_member_record(struct call_queue *q, char *interface, const char *rt_uniqueid, const char *membername, const char *penalty_str, const char *paused_str, const char* state_interface, const char *wrapuptime_str)
 {
 	struct member *m;
 	struct ao2_iterator mem_iter;
 	int penalty = 0;
 	int paused  = 0;
 	int found = 0;
+	int wrapuptime = -1;
 
 	if (penalty_str) {
 		penalty = atoi(penalty_str);
@@ -1564,6 +1569,10 @@
 		paused = atoi(paused_str);
 		if (paused < 0)
 			paused = 0;
+	}
+
+	if (wrapuptime_str) {
+		wrapuptime = atoi(wrapuptime_str);
 	}
 
  	/* Find member by realtime uniqueid and update */
@@ -1587,7 +1596,7 @@
 
  	/* Create a new member */
  	if (!found) {
-		if ((m = create_queue_member(interface, membername, penalty, paused, state_interface))) {
+		if ((m = create_queue_member(interface, membername, penalty, paused, state_interface, wrapuptime))) {
 			m->dead = 0;
 			m->realtime = 1;
 			ast_copy_string(m->rt_uniqueid, rt_uniqueid, sizeof(m->rt_uniqueid));
@@ -1769,7 +1778,8 @@
 			S_OR(ast_variable_retrieve(member_config, interface, "membername"),interface),
 			ast_variable_retrieve(member_config, interface, "penalty"),
 			ast_variable_retrieve(member_config, interface, "paused"),
-			S_OR(ast_variable_retrieve(member_config, interface, "state_interface"),interface));
+			S_OR(ast_variable_retrieve(member_config, interface, "state_interface"),interface),
+			ast_variable_retrieve(member_config, interface, "wrapuptime"));
 	}
 
 	/* Delete all realtime members that have been deleted in DB. */
@@ -1894,7 +1904,8 @@
 			S_OR(ast_variable_retrieve(member_config, interface, "membername"), interface),
 			ast_variable_retrieve(member_config, interface, "penalty"),
 			ast_variable_retrieve(member_config, interface, "paused"),
-			S_OR(ast_variable_retrieve(member_config, interface, "state_interface"), interface));
+			S_OR(ast_variable_retrieve(member_config, interface, "state_interface"), interface),
+			ast_variable_retrieve(member_config, interface, "wrapuptime"));
 	}
 
 	/* Delete all realtime members that have been deleted in DB. */
@@ -2429,7 +2440,8 @@
 	const char *macrocontext, *macroexten;
 
 	/* on entry here, we know that tmp->chan == NULL */
-	if ((tmp->lastqueue && tmp->lastqueue->wrapuptime && (time(NULL) - tmp->lastcall < tmp->lastqueue->wrapuptime)) ||
+	if ((tmp->wrapuptime >= 0 && (time(NULL) - tmp->lastcall < tmp->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", 
 				(tmp->lastqueue ? tmp->lastqueue->name : qe->parent->name), tmp->interface);
@@ -3807,6 +3819,7 @@
 		tmp->oldstatus = cur->status;
 		tmp->lastcall = cur->lastcall;
 		tmp->lastqueue = cur->lastqueue;
+		tmp->wrapuptime = cur->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
@@ -4455,7 +4468,7 @@
  * \retval RES_EXISTS queue exists but no members
  * \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)
+static int add_to_queue(const char *queuename, const char *interface, const char *membername, int penalty, int paused, int wrapuptime, int dump, const char *state_interface)
 {
 	struct call_queue *q;
 	struct member *new_member, *old_member;
@@ -4470,7 +4483,7 @@
 
 	ao2_lock(q);
 	if ((old_member = interface_exists(q, interface)) == NULL) {
-		if ((new_member = create_queue_member(interface, membername, penalty, paused, state_interface))) {
+		if ((new_member = create_queue_member(interface, membername, penalty, paused, state_interface, wrapuptime))) {
 			new_member->dynamic = 1;
 			ao2_link(q->members, new_member);
 			q->membercount++;
@@ -4671,8 +4684,8 @@
 	char *interface;
 	char *membername = NULL;
 	char *state_interface;
-	char *penalty_tok;
-	int penalty = 0;
+	char *penalty_tok, *wrapuptime_tok;
+	int penalty = 0, wrapuptime = -1;
 	char *paused_tok;
 	int paused = 0;
 	struct ast_db_entry *db_tree;
@@ -4721,6 +4734,7 @@
 			paused_tok = strsep(&member, ";");
 			membername = strsep(&member, ";");
 			state_interface = strsep(&member, ";");
+			wrapuptime_tok = strsep(&member, ";");
 
 			if (!penalty_tok) {
 				ast_log(LOG_WARNING, "Error parsing persistent member string for '%s' (penalty)\n", queue_name);
@@ -4742,9 +4756,14 @@
 				break;
 			}
 
-			ast_debug(1, "Reload Members: Queue: %s  Member: %s  Name: %s  Penalty: %d  Paused: %d\n", queue_name, interface, membername, penalty, paused);
+			if (wrapuptime_tok) {
+				wrapuptime = strtol(wrapuptime_tok, NULL, 10);
+			}
+
+			ast_debug(1, "Reload Members: Queue: %s  Member: %s  Name: %s  Penalty: %d  Paused: %d  Wrapuptime: %d\n",
+					queue_name, interface, membername, penalty, paused, wrapuptime);
 			
-			if (add_to_queue(queue_name, interface, membername, penalty, paused, 0, state_interface) == RES_OUTOFMEMORY) {
+			if (add_to_queue(queue_name, interface, membername, penalty, paused, wrapuptime, 0, state_interface) == RES_OUTOFMEMORY) {
 				ast_log(LOG_ERROR, "Out of Memory when reloading persistent queue member\n");
 				break;
 			}
@@ -4900,8 +4919,10 @@
 		AST_APP_ARG(options);
 		AST_APP_ARG(membername);
 		AST_APP_ARG(state_interface);
+		AST_APP_ARG(wrapuptime);
 	);
 	int penalty = 0;
+	int wrapuptime = -1;
 
 	if (ast_strlen_zero(data)) {
 		ast_log(LOG_WARNING, "AddQueueMember requires an argument (queuename[,interface[,penalty[,options[,membername[,stateinterface]]]]])\n");
@@ -4926,7 +4947,11 @@
 		}
 	}
 
-	switch (add_to_queue(args.queuename, args.interface, args.membername, penalty, 0, queue_persistent_members, args.state_interface)) {
+	if (!ast_strlen_zero(args.wrapuptime)) {
+		wrapuptime = atoi(args.wrapuptime);
+	}
+
+	switch (add_to_queue(args.queuename, args.interface, args.membername, penalty, 0, wrapuptime, queue_persistent_members, args.state_interface)) {
 	case RES_OKAY:
 		ast_queue_log(args.queuename, chan->uniqueid, args.interface, "ADDMEMBER", "%s", "");
 		ast_log(LOG_NOTICE, "Added interface '%s' to queue '%s'\n", args.interface, args.queuename);
@@ -5714,12 +5739,13 @@
 	char *parse;
 	struct member *cur, *newm;
 	struct member tmpmem;
-	int penalty;
+	int penalty, wrapuptime;
 	AST_DECLARE_APP_ARGS(args,
 		AST_APP_ARG(interface);
 		AST_APP_ARG(penalty);
 		AST_APP_ARG(membername);
 		AST_APP_ARG(state_interface);
+		AST_APP_ARG(wrapuptime);
 	);
 
 	if (ast_strlen_zero(memberdata)) {
@@ -5758,10 +5784,16 @@
 		state_interface = interface;
 	}
 
+	if (!ast_strlen_zero(args.wrapuptime)) {
+		wrapuptime = atoi(args.wrapuptime);
+	} else {
+		wrapuptime = -1;
+	}
+
 	/* Find the old position in the list */
 	ast_copy_string(tmpmem.interface, interface, sizeof(tmpmem.interface));
 	cur = ao2_find(q->members, &tmpmem, OBJ_POINTER | OBJ_UNLINK);
-	if ((newm = create_queue_member(interface, membername, penalty, cur ? cur->paused : 0, state_interface))) {
+	if ((newm = create_queue_member(interface, membername, penalty, cur ? cur->paused : 0, state_interface, wrapuptime))) {
 		ao2_link(q->members, newm);
 		ao2_ref(newm, -1);
 	}
@@ -6149,8 +6181,11 @@
 					mem->realtime ? " (realtime)" : "",
 					mem->paused ? " (paused)" : "",
 					ast_devstate2str(mem->status));
+				if (mem->wrapuptime >= 0) {
+					ast_str_append(&out, 0, " (wrapuptime = %d)", mem->wrapuptime);
+				}
 				if (mem->calls)
-					ast_str_append(&out, 0, " has taken %d calls (last was %ld secs ago)",
+					ast_str_append(&out, 0, " has taken %d calls (last was %ld secs ago) ",
 						mem->calls, (long) (time(NULL) - mem->lastcall));
 				else
 					ast_str_append(&out, 0, " has taken no calls yet");
@@ -6439,8 +6474,8 @@
 
 static int manager_add_queue_member(struct mansession *s, const struct message *m)
 {
-	const char *queuename, *interface, *penalty_s, *paused_s, *membername, *state_interface;
-	int paused, penalty = 0;
+	const char *queuename, *interface, *penalty_s, *paused_s, *membername, *state_interface, *wrapuptime_s;
+	int paused, penalty = 0, wrapuptime = -1;
 
 	queuename = astman_get_header(m, "Queue");
 	interface = astman_get_header(m, "Interface");
@@ -6448,6 +6483,7 @@
 	paused_s = astman_get_header(m, "Paused");
 	membername = astman_get_header(m, "MemberName");
 	state_interface = astman_get_header(m, "StateInterface");
+	wrapuptime_s = astman_get_header(m, "Wrapuptime");
 
 	if (ast_strlen_zero(queuename)) {
 		astman_send_error(s, m, "'Queue' not specified.");
@@ -6469,7 +6505,11 @@
 	else
 		paused = abs(ast_true(paused_s));
 
-	switch (add_to_queue(queuename, interface, membername, penalty, paused, queue_persistent_members, state_interface)) {
+	if (!ast_strlen_zero(wrapuptime_s)) {
+		wrapuptime = atoi(wrapuptime_s);
+	}
+
+	switch (add_to_queue(queuename, interface, membername, penalty, paused, wrapuptime, queue_persistent_members, state_interface)) {
 	case RES_OKAY:
 		ast_queue_log(queuename, "MANAGER", interface, "ADDMEMBER", "%s", "");
 		astman_send_ack(s, m, "Added interface to queue");
@@ -6616,7 +6656,7 @@
 
 static char *complete_queue_add_member(const char *line, const char *word, int pos, int state)
 {
-	/* 0 - queue; 1 - add; 2 - member; 3 - <interface>; 4 - to; 5 - <queue>; 6 - penalty; 7 - <penalty>; 8 - as; 9 - <membername> */
+	/* 0 - queue; 1 - add; 2 - member; 3 - <interface>; 4 - to; 5 - <queue>; 6 - penalty; 7 - <penalty>; 8 - wrapuptime; 9 - <wrapuptime>; 10 - as; 11 - <membername> */
 	switch (pos) {
 	case 3: /* Don't attempt to complete name of interface (infinite possibilities) */
 		return NULL;
@@ -6636,9 +6676,15 @@
 		} else {
 			return NULL;
 		}
-	case 8: /* only one possible match, "as" */
+	case 8:
+		return state == 0 ? ast_strdup("wrapuptime") : NULL;
+	case 9:
+		return NULL;
+	case 10: /* only one possible match, "as" */
 		return state == 0 ? ast_strdup("as") : NULL;
-	case 9: /* Don't attempt to complete name of member (infinite possibilities) */
+	case 11:
+		return state == 0 ? ast_strdup("state_interface") : NULL;
+	case 12: /* Don't attempt to complete name of member (infinite possibilities) */
 		return NULL;
 	default:
 		return NULL;
@@ -6673,28 +6719,30 @@
 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;
-	int penalty;
+	int penalty, wrapuptime = -1;
 
 	switch ( cmd ) {
 	case CLI_INIT:
 		e->command = "queue add member";
 		e->usage =
-			"Usage: queue add member <channel> to <queue> [[[penalty <penalty>] as <membername>] state_interface <interface>]\n"
+			"Usage: queue add member <channel> to <queue> [[[[penalty <penalty>] wrapuptime <wrapuptime>] as <membername>] state_interface <interface>]\n"
 			"       Add a channel to a queue with optionally:  a penalty, membername and a state_interface\n";
 		return NULL;
 	case CLI_GENERATE:
 		return complete_queue_add_member(a->line, a->word, a->pos, a->n);
 	}
 
-	if ((a->argc != 6) && (a->argc != 8) && (a->argc != 10) && (a->argc != 12)) {
+	if ((a->argc != 6) && (a->argc != 8) && (a->argc != 10) && (a->argc != 12) && (a->argc != 14)) {
 		return CLI_SHOWUSAGE;
 	} else if (strcmp(a->argv[4], "to")) {
 		return CLI_SHOWUSAGE;
 	} else if ((a->argc >= 8) && strcmp(a->argv[6], "penalty")) {
 		return CLI_SHOWUSAGE;
-	} else if ((a->argc >= 10) && strcmp(a->argv[8], "as")) {
+	} else if ((a->argc >= 10) && strcmp(a->argv[8], "wrapuptime")) {
 		return CLI_SHOWUSAGE;
-	} else if ((a->argc == 12) && strcmp(a->argv[10], "state_interface")) {
+	} else if ((a->argc >= 12) && strcmp(a->argv[10], "as")) {
+		return CLI_SHOWUSAGE;
+	} else if ((a->argc == 14) && strcmp(a->argv[12], "state_interface")) {
 		return CLI_SHOWUSAGE;
 	}
 
@@ -6714,15 +6762,29 @@
 		penalty = 0;
 	}
 
-	if (a->argc >= 10) {
+	if (a->argc >= 14) {
+		if (sscanf(a->argv[9], "%d", &wrapuptime) == 1) {
+			if (wrapuptime < 0) {
+				ast_cli(a->fd, "Wrapuptime must be >= 0\n");
+				wrapuptime = -1;
+			}
+		} else {
+			ast_cli(a->fd, "Wrapuptime must be an integer >= 0\n");
+			wrapuptime = -1;
+		}
+	} else {
+		wrapuptime = -1;
+	}
+
+	if (a->argc >= 12) {
 		membername = a->argv[9];
 	}
 
-	if (a->argc >= 12) {
+	if (a->argc >= 14) {
 		state_interface = a->argv[11];
 	}
 
-	switch (add_to_queue(queuename, interface, membername, penalty, 0, queue_persistent_members, state_interface)) {
+	switch (add_to_queue(queuename, interface, membername, penalty, 0, wrapuptime, queue_persistent_members, state_interface)) {
 	case RES_OKAY:
 		ast_queue_log(queuename, "CLI", interface, "ADDMEMBER", "%s", "");
 		ast_cli(a->fd, "Added interface '%s' to queue '%s'\n", interface, queuename);




More information about the svn-commits mailing list