[Asterisk-cvs] asterisk/apps app_chanisavail.c, 1.9, 1.10 app_dial.c, 1.97, 1.98 app_meetme.c, 1.63, 1.64 app_queue.c, 1.91, 1.92

markster at lists.digium.com markster at lists.digium.com
Tue Oct 26 18:22:19 CDT 2004


Update of /usr/cvsroot/asterisk/apps
In directory mongoose.digium.com:/tmp/cvs-serv3701/apps

Modified Files:
	app_chanisavail.c app_dial.c app_meetme.c app_queue.c 
Log Message:
Pass concept of status back, permit "leaveempty" to work with static agents who are not loggedon (bug #2719)


Index: app_chanisavail.c
===================================================================
RCS file: /usr/cvsroot/asterisk/apps/app_chanisavail.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- app_chanisavail.c	2 Oct 2004 00:58:31 -0000	1.9
+++ app_chanisavail.c	26 Oct 2004 22:25:43 -0000	1.10
@@ -51,6 +51,7 @@
 static int chanavail_exec(struct ast_channel *chan, void *data)
 {
 	int res=-1;
+	int status;
 	struct localuser *u;
 	char info[512], tmp[512], *peers, *tech, *number, *rest, *cur;
 	struct ast_channel *tempchan;
@@ -80,20 +81,24 @@
 			}
 			*number = '\0';
 			number++;
-			if ((tempchan = ast_request(tech, chan->nativeformats, number))) {
+			if ((tempchan = ast_request(tech, chan->nativeformats, number, &status))) {
 					pbx_builtin_setvar_helper(chan, "AVAILCHAN", tempchan->name);
 					/* Store the originally used channel too */
 					snprintf(tmp, sizeof(tmp), "%s/%s", tech, number);
 					pbx_builtin_setvar_helper(chan, "AVAILORIGCHAN", tmp);
+					snprintf(tmp, sizeof(tmp), "%d", status);
+					pbx_builtin_setvar_helper(chan, "AVAILSTATUS", tmp);
 					ast_hangup(tempchan);
 					tempchan = NULL;
 					res = 1;
 					break;
+			} else {
+				snprintf(tmp, sizeof(tmp), "%d", status);
+				pbx_builtin_setvar_helper(chan, "AVAILSTATUS", tmp);
 			}
 			cur = rest;
 		} while (cur);
 	}
-
 	if (res < 1) {
 		pbx_builtin_setvar_helper(chan, "AVAILCHAN", "");
 		pbx_builtin_setvar_helper(chan, "AVAILORIGCHAN", "");

Index: app_dial.c
===================================================================
RCS file: /usr/cvsroot/asterisk/apps/app_dial.c,v
retrieving revision 1.97
retrieving revision 1.98
diff -u -d -r1.97 -r1.98
--- app_dial.c	7 Oct 2004 18:28:49 -0000	1.97
+++ app_dial.c	26 Oct 2004 22:25:43 -0000	1.98
@@ -26,6 +26,7 @@
 #include <asterisk/callerid.h>
 #include <asterisk/utils.h>
 #include <asterisk/app.h>
+#include <asterisk/causes.h>
 #include <stdlib.h>
 #include <errno.h>
 #include <unistd.h>
@@ -134,14 +135,32 @@
 
 #define AST_MAX_WATCHERS 256
 
-static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localuser *outgoing, int *to, int *allowredir_in, int *allowredir_out, int *allowdisconnect_in, int *allowdisconnect_out, int *sentringing, char *status, size_t statussize)
+#define HANDLE_CAUSE(blah, bleh) do { \
+	switch(cause) { \
+	case AST_CAUSE_BUSY: \
+		if (bleh->cdr) \
+			ast_cdr_busy(bleh->cdr); \
+		numbusy++; \
+	case AST_CAUSE_CONGESTION: \
+	case AST_CAUSE_UNREGISTERED: \
+		if (bleh->cdr) \
+			ast_cdr_busy(bleh->cdr); \
+		numcongestion++; \
+	default: \
+		numnochan++; \
+	} \
+} while(0)
+
+
+static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localuser *outgoing, int *to, int *allowredir_in, int *allowredir_out, int *allowdisconnect_in, int *allowdisconnect_out, int *sentringing, char *status, size_t statussize, int busystart, int nochanstart, int congestionstart)
 {
 	struct localuser *o;
 	int found;
 	int numlines;
-	int numbusy = 0;
-	int numcongestion = 0;
-	int numnochan = 0;
+	int numbusy = busystart;
+	int numcongestion = congestionstart;
+	int numnochan = nochanstart;
+	int cause;
 	int orig = *to;
 	struct ast_frame *f;
 	struct ast_channel *peer = NULL;
@@ -227,11 +246,11 @@
 					if (option_verbose > 2)
 						ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, o->chan->name);
 					/* Setup parameters */
-					o->chan = ast_request(tech, in->nativeformats, stuff);
+					o->chan = ast_request(tech, in->nativeformats, stuff, &cause);
 					if (!o->chan) {
 						ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s'\n", tech, stuff);
 						o->stillgoing = 0;
-						numnochan++;
+						HANDLE_CAUSE(cause, in);
 					} else {
 						if (o->chan->cid.cid_num)
 							free(o->chan->cid.cid_num);
@@ -317,9 +336,7 @@
 							ast_hangup(o->chan);
 							o->chan = NULL;
 							o->stillgoing = 0;
-							if (in->cdr)
-								ast_cdr_busy(in->cdr);
-							numbusy++;
+							HANDLE_CAUSE(AST_CAUSE_BUSY, in);
 							break;
 						case AST_CONTROL_CONGESTION:
 							if (option_verbose > 2)
@@ -328,9 +345,7 @@
 							ast_hangup(o->chan);
 							o->chan = NULL;
 							o->stillgoing = 0;
-							if (in->cdr)
-								ast_cdr_busy(in->cdr);
-							numcongestion++;
+							HANDLE_CAUSE(AST_CAUSE_CONGESTION, in);
 							break;
 						case AST_CONTROL_RINGING:
 							if (option_verbose > 2)
@@ -433,6 +448,10 @@
 	int privacy=0;
 	int announce=0;
 	int resetcdr=0;
+	int numbusy = 0;
+	int numcongestion = 0;
+	int numnochan = 0;
+	int cause;
 	char numsubst[AST_MAX_EXTENSION];
 	char restofit[AST_MAX_EXTENSION];
 	char *transfer = NULL;
@@ -738,14 +757,11 @@
 				ast_log(LOG_DEBUG, "Dialing by extension %s\n", numsubst);
 		}
 		/* Request the peer */
-		tmp->chan = ast_request(tech, chan->nativeformats, numsubst);
+		tmp->chan = ast_request(tech, chan->nativeformats, numsubst, &cause);
 		if (!tmp->chan) {
 			/* If we can't, just go on to the next call */
 			ast_log(LOG_NOTICE, "Unable to create channel of type '%s'\n", tech);
-			if (chan->cdr)
-				ast_cdr_busy(chan->cdr);
-			free(tmp);
-			cur = rest;
+			HANDLE_CAUSE(cause, chan);
 			continue;
 		}
 		if (!ast_strlen_zero(tmp->chan->call_forward)) {
@@ -767,11 +783,10 @@
 				ast_verbose(VERBOSE_PREFIX_3 "Forwarding %s to '%s/%s' (thanks to %s)\n", chan->name, tech, stuff, tmp->chan->name);
 			/* Setup parameters */
 			ast_hangup(tmp->chan);
-			tmp->chan = ast_request(tech, chan->nativeformats, stuff);
+			tmp->chan = ast_request(tech, chan->nativeformats, stuff, &cause);
 			if (!tmp->chan) {
 				ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s'\n", tech, stuff);
-				free(tmp);
-				cur = rest;
+				HANDLE_CAUSE(cause, chan);
 				continue;
 			}
 		}
@@ -847,8 +862,7 @@
 			else if (option_verbose > 2)
 				ast_verbose(VERBOSE_PREFIX_3 "Couldn't call %s\n", numsubst);
 			ast_hangup(tmp->chan);
-			free(tmp);
-			cur = rest;
+			tmp->chan = NULL;
 			continue;
 		} else
 			if (option_verbose > 2)
@@ -888,7 +902,7 @@
 		strncpy(status, "CHANUNAVAIL", sizeof(status) - 1);
 
 	time(&start_time);
-	peer = wait_for_answer(chan, outgoing, &to, &allowredir_in, &allowredir_out, &allowdisconnect_in, &allowdisconnect_out, &sentringing, status, sizeof(status));
+	peer = wait_for_answer(chan, outgoing, &to, &allowredir_in, &allowredir_out, &allowdisconnect_in, &allowdisconnect_out, &sentringing, status, sizeof(status), numbusy, numnochan, numcongestion);
 
 	if (!peer) {
 		if (to) 

Index: app_meetme.c
===================================================================
RCS file: /usr/cvsroot/asterisk/apps/app_meetme.c,v
retrieving revision 1.63
retrieving revision 1.64
diff -u -d -r1.63 -r1.64
--- app_meetme.c	20 Oct 2004 04:27:31 -0000	1.63
+++ app_meetme.c	26 Oct 2004 22:25:43 -0000	1.64
@@ -222,7 +222,7 @@
 			strncpy(cnf->confno, confno, sizeof(cnf->confno) - 1);
 			strncpy(cnf->pin, pin, sizeof(cnf->pin) - 1);
 			cnf->markedusers = 0;
-			cnf->chan = ast_request("zap", AST_FORMAT_ULAW, "pseudo");
+			cnf->chan = ast_request("zap", AST_FORMAT_ULAW, "pseudo", NULL);
 			if (cnf->chan) {
 				cnf->fd = cnf->chan->fds[0];	/* for use by conf_play() */
 			} else {

Index: app_queue.c
===================================================================
RCS file: /usr/cvsroot/asterisk/apps/app_queue.c,v
retrieving revision 1.91
retrieving revision 1.92
diff -u -d -r1.91 -r1.92
--- app_queue.c	5 Oct 2004 06:46:11 -0000	1.91
+++ app_queue.c	26 Oct 2004 22:25:43 -0000	1.92
@@ -45,6 +45,7 @@
 #include <asterisk/config.h>
 #include <asterisk/monitor.h>
 #include <asterisk/utils.h>
+#include <asterisk/causes.h>
 #include <stdlib.h>
 #include <errno.h>
 #include <unistd.h>
@@ -145,6 +146,7 @@
 	char tech[40];
 	int stillgoing;
 	int metric;
+	int oldstatus;
 	int allowredirect_in;
 	int allowredirect_out;
 	int ringbackonly;
@@ -182,6 +184,7 @@
 	int penalty;				/* Are we a last resort? */
 	int calls;					/* Number of calls serviced by this member */
 	int dynamic;				/* Are we dynamically added? */
+	int status;					/* Status of queue member */
 	time_t lastcall;			/* When last successful call was hungup */
 	struct member *next;		/* Next member */
 };
@@ -280,6 +283,26 @@
 	new->opos = *pos;
 }
 
+static int has_no_members(struct ast_call_queue *q)
+{
+	struct member *member;
+	int empty = 1;
+	member = q->members;
+	while(empty && member) {
+		switch(member->status) {
+		case AST_CAUSE_NOSUCHDRIVER:
+		case AST_CAUSE_UNREGISTERED:
+			/* Not logged on, etc */
+			break;
+		default:
+			/* Not empty */
+			empty = 0;
+		}
+		member = member->next;
+	}
+	return empty;
+}
+
 static int join_queue(char *queuename, struct queue_ent *qe)
 {
 	struct ast_call_queue *q;
@@ -293,7 +316,7 @@
 		if (!strcasecmp(q->name, queuename)) {
 			/* This is our one */
 			ast_mutex_lock(&q->lock);
-			if ((q->members || q->joinempty) && (!q->maxlen || (q->count < q->maxlen))) {
+			if ((!has_no_members(q) || q->joinempty || !q->head) && (!q->maxlen || (q->count < q->maxlen))) {
 				/* There's space for us, put us at the right position inside
 				 * the queue. 
 				 * Take into account the priority of the calling user */
@@ -551,9 +574,29 @@
 	}
 }
 
+static int update_status(struct ast_call_queue *q, struct member *member, int status)
+{
+	struct member *cur;
+	/* Since a reload could have taken place, we have to traverse the list to
+		be sure it's still valid */
+	ast_mutex_lock(&q->lock);
+	cur = q->members;
+	while(cur) {
+		if (member == cur) {
+			cur->status = status;
+			break;
+		}
+		cur = cur->next;
+	}
+	q->callscompleted++;
+	ast_mutex_unlock(&q->lock);
+	return 0;
+}
+
 static int ring_entry(struct queue_ent *qe, struct localuser *tmp)
 {
 	int res;
+	int status;
 	if (qe->parent->wrapuptime && (time(NULL) - tmp->lastcall < qe->parent->wrapuptime)) {
 		ast_log(LOG_DEBUG, "Wrapuptime not yet expired for %s/%s\n", tmp->tech, tmp->numsubst);
 		if (qe->chan->cdr)
@@ -562,7 +605,7 @@
 		return 0;
 	}
 	/* Request the peer */
-	tmp->chan = ast_request(tmp->tech, qe->chan->nativeformats, tmp->numsubst);
+	tmp->chan = ast_request(tmp->tech, qe->chan->nativeformats, tmp->numsubst, &status);
 	if (!tmp->chan) {			/* If we can't, just go on to the next call */
 #if 0
 		ast_log(LOG_NOTICE, "Unable to create channel of type '%s'\n", cur->tech);
@@ -570,8 +613,11 @@
 		if (qe->chan->cdr)
 			ast_cdr_busy(qe->chan->cdr);
 		tmp->stillgoing = 0;
+		update_status(qe->parent, tmp->member, status);
 		return 0;
-	}
+	} else if (status != tmp->oldstatus) 
+		update_status(qe->parent, tmp->member, status);
+	
 	tmp->chan->appl = "AppQueue";
 	tmp->chan->data = "(Outgoing Line)";
 	tmp->chan->whentohangup = 0;
@@ -728,6 +774,7 @@
 	struct localuser *o;
 	int found;
 	int numlines;
+	int status;
 	int sentringing = 0;
 	int numbusies = 0;
 	int numnochan = 0;
@@ -795,7 +842,9 @@
 					if (option_verbose > 2)
 						ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, o->chan->name);
 					/* Setup parameters */
-					o->chan = ast_request(tech, in->nativeformats, stuff);
+					o->chan = ast_request(tech, in->nativeformats, stuff, &status);
+					if (status != o->oldstatus) 
+						update_status(qe->parent, o->member, status);						
 					if (!o->chan) {
 						ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s'\n", tech, stuff);
 						o->stillgoing = 0;
@@ -997,7 +1046,7 @@
 		}
 
 		/* leave the queue if no agents, if enabled */
-		if (!(qe->parent->members) && qe->parent->leavewhenempty) {
+		if (has_no_members(qe->parent) && qe->parent->leavewhenempty) {
 			leave_queue(qe);
 			break;
 		}
@@ -1163,6 +1212,7 @@
 		tmp->member = cur;		/* Never directly dereference!  Could change on reload */
 		strncpy(tmp->tech, cur->tech, sizeof(tmp->tech)-1);
 		strncpy(tmp->numsubst, cur->loc, sizeof(tmp->numsubst)-1);
+		tmp->oldstatus = cur->status;
 		tmp->lastcall = cur->lastcall;
 		/* If we're dialing by extension, look at the extension to know what to dial */
 		if ((newnum = strstr(tmp->numsubst, "BYEXTENSION"))) {
@@ -1728,6 +1778,7 @@
 			}
 		}
 		if (!res) {
+			int makeannouncement = 0;
 			for (;;) {
 				/* This is the wait loop for the head caller*/
 				/* To exit, they may get their call answered; */
@@ -1740,15 +1791,12 @@
 					break;
 				}
 
-				/* leave the queue if no agents, if enabled */
-				if (!((qe.parent)->members) && (qe.parent)->leavewhenempty) {
-					leave_queue(&qe);
-					break;
+				if (makeannouncement) {
+					/* Make a position announcement, if enabled */
+					if (qe.parent->announcefrequency && !ringing)
+						say_position(&qe);
 				}
-
-				/* Make a position announcement, if enabled */
-				if (qe.parent->announcefrequency && !ringing)
-					say_position(&qe);
+				makeannouncement = 1;
 
 				/* Try calling all queue members for 'timeout' seconds */
 				res = try_calling(&qe, options, announceoverride, url, &go_on);
@@ -1761,6 +1809,12 @@
 					break;
 				}
 
+				/* leave the queue if no agents, if enabled */
+				if (has_no_members(qe.parent) && (qe.parent->leavewhenempty)) {
+					res = 0;
+					break;
+				}
+
 				/* Leave if we have exceeded our queuetimeout */
 				if (qe.queuetimeout && ( (time(NULL) - qe.start) >= qe.queuetimeout) ) {
 					res = 0;
@@ -2037,6 +2091,30 @@
 	ast_mutex_unlock(&qlock);
 }
 
+static char *status2str(int status, char *buf, int buflen)
+{
+	switch(status) {
+	case AST_CAUSE_BUSY:
+		strncpy(buf, "busy", buflen - 1);
+		break;
+	case AST_CAUSE_CONGESTION:
+		strncpy(buf, "congestion", buflen - 1);
+		break;
+	case AST_CAUSE_FAILURE:
+		strncpy(buf, "failure", buflen - 1);
+		break;
+	case AST_CAUSE_UNREGISTERED:
+		strncpy(buf, "unregistered", buflen - 1);
+		break;
+	case AST_CAUSE_NOSUCHDRIVER:
+		strncpy(buf, "nosuchdriver", buflen - 1);
+		break;
+	default:
+		snprintf(buf, buflen, "unknown status %d", status);
+	}
+	return buf;
+}
+
 static int __queues_show(int fd, int argc, char **argv, int queue_show)
 {
 	struct ast_call_queue *q;
@@ -2046,6 +2124,7 @@
 	time_t now;
 	char max[80] = "";
 	char calls[80] = "";
+	char tmpbuf[80] = "";
 	float sl = 0;
 
 	time(&now);
@@ -2092,6 +2171,8 @@
 					max[0] = '\0';
 				if (mem->dynamic)
 					strncat(max, " (dynamic)", sizeof(max) - strlen(max) - 1);
+				if (mem->status)
+					snprintf(max + strlen(max), sizeof(max) - strlen(max), " (%s)", status2str(mem->status, tmpbuf, sizeof(tmpbuf)));
 				if (mem->calls) {
 					snprintf(calls, sizeof(calls), " has taken %d calls (last was %ld secs ago)",
 							mem->calls, (long)(time(NULL) - mem->lastcall));




More information about the svn-commits mailing list