[asterisk-commits] murf: branch murf/bug9228 r58412 - /team/murf/bug9228/apps/

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Thu Mar 8 09:56:30 MST 2007


Author: murf
Date: Thu Mar  8 10:56:30 2007
New Revision: 58412

URL: http://svn.digium.com/view/asterisk?view=rev&rev=58412
Log:
upgraded app_queue and app_rpt to allow gosubs along with macros, for the sake of AEL, which can't define macros, only gosubs

Modified:
    team/murf/bug9228/apps/app_queue.c
    team/murf/bug9228/apps/app_rpt.c

Modified: team/murf/bug9228/apps/app_queue.c
URL: http://svn.digium.com/view/asterisk/team/murf/bug9228/apps/app_queue.c?view=diff&rev=58412&r1=58411&r2=58412
==============================================================================
--- team/murf/bug9228/apps/app_queue.c (original)
+++ team/murf/bug9228/apps/app_queue.c Thu Mar  8 10:56:30 2007
@@ -127,7 +127,7 @@
 static char *synopsis = "Queue a call for a call queue";
 
 static char *descrip =
-"  Queue(queuename[|options[|URL][|announceoverride][|timeout][|AGI][|macro]):\n"
+"  Queue(queuename[|options[|URL][|announceoverride][|timeout][|AGI][|macro][|gosub]):\n"
 "Queues an incoming call in a particular call queue as defined in queues.conf.\n"
 "This application will return to the dialplan if the queue does not exist, or\n"
 "any of the join options cause the caller to not enter the queue.\n"
@@ -151,6 +151,8 @@
 "  The optional AGI parameter will setup an AGI script to be executed on the \n"
 "calling party's channel once they are connected to a queue member.\n"
 "  The optional macro parameter will run a macro on the \n"
+"calling party's channel once they are connected to a queue member.\n"
+"  The optional gosub parameter will run a gosub on the \n"
 "calling party's channel once they are connected to a queue member.\n"
 "  The timeout will cause the queue to fail out after a specified number of\n"
 "seconds, checked between each queues.conf 'timeout' and 'retry' cycle.\n"
@@ -376,6 +378,7 @@
 	char monfmt[8];                     /*!< Format to use when recording calls */
 	int montype;                        /*!< Monitor type  Monitor vs. MixMonitor */
 	char membermacro[32];               /*!< Macro to run upon member connection */
+	char membergosub[32];               /*!< Gosub to run upon member connection */
 	char sound_next[80];                /*!< Sound file: "Your call is now first in line" (def. queue-youarenext) */
 	char sound_thereare[80];            /*!< Sound file: "There are currently" (def. queue-thereare) */
 	char sound_calls[80];               /*!< Sound file: "calls waiting to speak to a representative." (def. queue-callswaiting)*/
@@ -683,6 +686,7 @@
 	q->autofill = autofill_default;
 	q->montype = montype_default;
 	q->membermacro[0] = '\0';
+	q->membergosub[0] = '\0';
 	q->moh[0] = '\0';
 	q->announce[0] = '\0';
 	q->context[0] = '\0';
@@ -827,6 +831,8 @@
 		ast_copy_string(q->monfmt, val, sizeof(q->monfmt));
 	} else if (!strcasecmp(param, "membermacro")) {
 		ast_copy_string(q->membermacro, val, sizeof(q->membermacro));
+	} else if (!strcasecmp(param, "membergosub")) {
+		ast_copy_string(q->membergosub, val, sizeof(q->membergosub));
 	} else if (!strcasecmp(param, "queue-youarenext")) {
 		ast_copy_string(q->sound_next, val, sizeof(q->sound_next));
 	} else if (!strcasecmp(param, "queue-thereare")) {
@@ -2372,7 +2378,7 @@
 		qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, vars_len) : "");
 }
 
-static int try_calling(struct queue_ent *qe, const char *options, char *announceoverride, const char *url, int *go_on, const char *agi, const char *macro)
+static int try_calling(struct queue_ent *qe, const char *options, char *announceoverride, const char *url, int *go_on, const char *agi, const char *macro, const char *gosub)
 {
 	struct member *cur;
 	struct callattempt *outgoing = NULL; /* the list of calls we are building */
@@ -2397,6 +2403,7 @@
 	char nondataquality = 1;
 	char *agiexec = NULL;
 	char *macroexec = NULL;
+	char *gosubexec = NULL;
 	int ret = 0;
 	const char *monitorfilename;
 	const char *monitor_exec;
@@ -2749,6 +2756,43 @@
 			}
 		}
 
+		/* run a gosub for this connection if defined. The gosub simply returns, no action is taken on the result */
+		/* use gosub from dialplan if passed as a option, otherwise use the default queue gosub */
+		if (!ast_strlen_zero(gosub)) {
+				gosubexec = ast_strdupa(gosub);
+		} else {
+			if (qe->parent->membergosub)
+				gosubexec = ast_strdupa(qe->parent->membergosub);
+		}
+
+		if (!ast_strlen_zero(gosubexec)) {
+			if (option_debug)
+				ast_log(LOG_DEBUG, "app_queue: gosub=%s.\n", gosubexec);
+			
+			res = ast_autoservice_start(qe->chan);
+			if (res) {
+				ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
+				res = -1;
+			}
+			
+			app = pbx_findapp("Gosub");
+			
+			if (app) {
+				res = pbx_exec(qe->chan, app, gosubexec);
+				if (option_debug)
+					ast_log(LOG_DEBUG, "Gosub exited with status %d\n", res);
+				res = 0;
+			} else {
+				ast_log(LOG_ERROR, "Could not find application Gosub\n");
+				res = -1;
+			}
+		
+			if (ast_autoservice_stop(qe->chan) < 0) {
+				ast_log(LOG_ERROR, "Could not stop autoservice on calling channel\n");
+				res = -1;
+			}
+		}
+
 		if (!ast_strlen_zero(agi)) {
 			if (option_debug)
 				ast_log(LOG_DEBUG, "app_queue: agi=%s.\n", agi);
@@ -3415,6 +3459,7 @@
 		AST_APP_ARG(queuetimeoutstr);
 		AST_APP_ARG(agi);
 		AST_APP_ARG(macro);
+		AST_APP_ARG(gosub);
 	);
 	/* Our queue entry */
 	struct queue_ent qe;
@@ -3557,7 +3602,7 @@
 				}
 
 				/* Try calling all queue members for 'timeout' seconds */
-				res = try_calling(&qe, args.options, args.announceoverride, args.url, &go_on, args.agi, args.macro);
+				res = try_calling(&qe, args.options, args.announceoverride, args.url, &go_on, args.agi, args.macro, args.gosub);
 				if (res) {
 					if (res < 0) {
 						if (!qe.handled) {

Modified: team/murf/bug9228/apps/app_rpt.c
URL: http://svn.digium.com/view/asterisk/team/murf/bug9228/apps/app_rpt.c?view=diff&rev=58412&r1=58411&r2=58412
==============================================================================
--- team/murf/bug9228/apps/app_rpt.c (original)
+++ team/murf/bug9228/apps/app_rpt.c Thu Mar  8 10:56:30 2007
@@ -133,8 +133,11 @@
 
 #define	MAXDTMF 32
 #define	MAXMACRO 2048
+#define	MAXGOSUB 2048
 #define	MACROTIME 100
+#define	GOSUBTIME 100
 #define	MACROPTIME 500
+#define	GOSUBPTIME 500
 #define	DTMF_TIMEOUT 3
 
 #ifdef	__RPT_NOTCH
@@ -157,6 +160,7 @@
 #define	NODES "nodes"
 #define MEMORY "memory"
 #define MACRO "macro"
+#define GOSUB "gosub"
 #define	FUNCTIONS "functions"
 #define TELEMETRY "telemetry"
 #define MORSE "morse"
@@ -183,7 +187,7 @@
 enum {ID, PROC, TERM, COMPLETE, UNKEY, REMDISC, REMALREADY, REMNOTFOUND, REMGO,
 	CONNECTED, CONNFAIL, STATUS, TIMEOUT, ID1, STATS_TIME,
 	STATS_VERSION, IDTALKOVER, ARB_ALPHA, TEST_TONE, REV_PATCH,
-	TAILMSG, MACRO_NOTFOUND, MACRO_BUSY, LASTNODEKEY};
+	TAILMSG, MACRO_NOTFOUND, GOSUB_NOTFOUND, MACRO_BUSY, GOSUB_BUSY, LASTNODEKEY};
 
 enum {REM_SIMPLEX, REM_MINUS, REM_PLUS};
 
@@ -418,7 +422,9 @@
 		);
 		char memory[80];
 		char macro[80];
+		char gosub[80];
 		char startupmacro[80];
+		char startupgosub[80];
 		int iobase;
 		char funcchar;
 		char endchar;
@@ -437,6 +443,7 @@
 	char enable;
 	char dtmfbuf[MAXDTMF];
 	char macrobuf[MAXMACRO];
+	char gosubbuf[MAXGOSUB];
 	char rem_dtmfbuf[MAXDTMF];
 	char lastdtmfcommand[MAXDTMF];
 	char cmdnode[50];
@@ -474,6 +481,7 @@
 	char patchcontext[MAXPATCHCONTEXT];
 	int patchdialtime;
 	int macro_longest;
+	int gosub_longest;
 	int phone_longestfunc;
 	int dphone_longestfunc;
 	int link_longestfunc;
@@ -484,6 +492,7 @@
 	time_t disgorgetime;
 	time_t lastthreadrestarttime;
 	long macrotimer;
+	long gosubtimer;
 	char lastnodewhichkeyedusup[MAXNODESTR];
 #ifdef	__RPT_NOTCH
 	struct rptfilter
@@ -784,6 +793,7 @@
 static int function_cop(struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink);
 static int function_remote(struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink);
 static int function_macro(struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink);
+static int function_gosub(struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink);
 /*
 * Function table
 */
@@ -796,6 +806,7 @@
 	{"status", function_status},
 	{"remote", function_remote},
 	{"macro", function_macro}
+	{"gosub", function_gosub}
 } ;
 
 /*
@@ -955,6 +966,7 @@
 	rpt_vars[n].p.politeid = POLITEID;
 	ast_copy_string(rpt_vars[n].p.memory, MEMORY, sizeof(rpt_vars[n].p.memory));
 	ast_copy_string(rpt_vars[n].p.macro, MACRO, sizeof(rpt_vars[n].p.macro));
+	ast_copy_string(rpt_vars[n].p.gosub, GOSUB, sizeof(rpt_vars[n].p.gosub));
 	rpt_vars[n].p.iobase = DEFAULT_IOBASE;
 	ast_copy_string(rpt_vars[n].p.functions, FUNCTIONS, sizeof(rpt_vars[n].p.functions));
 	rpt_vars[n].p.simple = 1;
@@ -1014,8 +1026,12 @@
 			ast_copy_string(rpt_vars[n].p.memory, var->value, sizeof(rpt_vars[n].p.memory));
 		} else if (!strcmp(var->name, "macro")) {
 			ast_copy_string(rpt_vars[n].p.macro, var->value, sizeof(rpt_vars[n].p.macro));
+		} else if (!strcmp(var->name, "gosub")) {
+			ast_copy_string(rpt_vars[n].p.gosub, var->value, sizeof(rpt_vars[n].p.gosub));
 		} else if (!strcmp(var->name, "startup_macro")) {
 			ast_copy_string(rpt_vars[n].p.startupmacro, var->value, sizeof(rpt_vars[n].p.startupmacro));
+		} else if (!strcmp(var->name, "startup_gosub")) {
+			ast_copy_string(rpt_vars[n].p.startupgosub, var->value, sizeof(rpt_vars[n].p.startupgosub));
 		} else if (!strcmp(var->name, "iobase")) {
 			/* do not use atoi() here, we need to be able to have
 			   the input specified in hex or decimal so we use
@@ -1100,6 +1116,12 @@
 	for (vp = ast_variable_browse(cfg, rpt_vars[n].p.macro); vp; vp = vp->next) {
 		if ((j = strlen(vp->name)) > rpt_vars[n].macro_longest)
 			rpt_vars[n].macro_longest = j;
+	}
+
+	rpt_vars[n].gosub_longest = 1;
+	for (vp = ast_variable_browse(cfg, rpt_vars[n].p.gosub); vp; vp = vp->next) {
+		if ((j = strlen(vp->name)) > rpt_vars[n].gosub_longest)
+			rpt_vars[n].gosub_longest = j;
 	}
 	ast_mutex_unlock(&rpt_vars[n].lock);
 }
@@ -1961,10 +1983,20 @@
 		wait_interval(myrpt, DLY_TELEM, mychannel);
 		res = ast_streamfile(mychannel, "rpt/macro_notfound", mychannel->language);
 		break;
+	case GOSUB_NOTFOUND:
+		/* wait a little bit */
+		wait_interval(myrpt, DLY_TELEM, mychannel);
+		res = ast_streamfile(mychannel, "rpt/gosub_notfound", mychannel->language);
+		break;
 	case MACRO_BUSY:
 		/* wait a little bit */
 		wait_interval(myrpt, DLY_TELEM, mychannel);
 		res = ast_streamfile(mychannel, "rpt/macro_busy", mychannel->language);
+		break;
+	case GOSUB_BUSY:
+		/* wait a little bit */
+		wait_interval(myrpt, DLY_TELEM, mychannel);
+		res = ast_streamfile(mychannel, "rpt/gosub_busy", mychannel->language);
 		break;
 	case UNKEY:
 		if (myrpt->patchnoct && myrpt->callmode) { /* If no CT during patch configured, then don't send one */
@@ -3293,6 +3325,54 @@
 	}
 	myrpt->macrotimer = MACROTIME;
 	strncat(myrpt->macrobuf, val, sizeof(myrpt->macrobuf) - 1);
+	rpt_mutex_unlock(&myrpt->lock);
+	return DC_COMPLETE;	
+}
+
+/*
+*  Gosub
+*/
+
+static int function_gosub(struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink)
+{
+
+	const char *val;
+	int	i;
+	struct ast_channel *mychannel;
+
+	if ((!myrpt->remote) && (!myrpt->enable))
+		return DC_ERROR;
+
+	if (debug) 
+		ast_log(LOG_DEBUG, "@@@@ gosub param = %s, digitbuf = %s\n", (param)? param : "(null)", digitbuf);
+	
+	mychannel = myrpt->remchannel;
+
+	if (ast_strlen_zero(digitbuf)) /* needs 1 digit */
+		return DC_INDETERMINATE;
+			
+	for (i = 0; i < digitbuf[i]; i++) {
+		if ((digitbuf[i] < '0') || (digitbuf[i] > '9'))
+			return DC_ERROR;
+	}
+   
+	if (*digitbuf == '0')
+		val = myrpt->p.startupgosub;
+	else
+		val = ast_variable_retrieve(myrpt->cfg, myrpt->p.gosub, digitbuf);
+	/* param was 1 for local buf */
+	if (!val) {
+		rpt_telemetry(myrpt, GOSUB_NOTFOUND, NULL);
+		return DC_COMPLETE;
+	}			
+	rpt_mutex_lock(&myrpt->lock);
+	if ((sizeof(myrpt->gosubbuf) - strlen(myrpt->gosubbuf)) < strlen(val)) {
+		rpt_mutex_unlock(&myrpt->lock);
+		rpt_telemetry(myrpt, GOSUB_BUSY, NULL);
+		return DC_ERROR;
+	}
+	myrpt->gosubtimer = GOSUBTIME;
+	strncat(myrpt->gosubbuf, val, sizeof(myrpt->gosubbuf) - 1);
 	rpt_mutex_unlock(&myrpt->lock);
 	return DC_COMPLETE;	
 }
@@ -5846,6 +5926,9 @@
 	if (myrpt->p.startupmacro) {
 		snprintf(myrpt->macrobuf, sizeof(myrpt->macrobuf), "PPPP%s", myrpt->p.startupmacro);
 	}
+	if (myrpt->p.startupgosub) {
+		snprintf(myrpt->gosubbuf, sizeof(myrpt->gosubbuf), "PPPP%s", myrpt->p.startupgosub);
+	}
 	rpt_mutex_unlock(&myrpt->lock);
 	val = 0;
 	ast_channel_setoption(myrpt->rxchannel, AST_OPTION_TONE_VERIFY, &val, sizeof(char), 0);
@@ -6276,6 +6359,11 @@
 			myrpt->macrotimer -= elap;
 		if (myrpt->macrotimer < 0)
 			myrpt->macrotimer = 0;
+		/* do gosub timers */
+		if (myrpt->gosubtimer)
+			myrpt->gosubtimer -= elap;
+		if (myrpt->gosubtimer < 0)
+			myrpt->gosubtimer = 0;
 		/* Execute scheduler appx. every 2 tenths of a second */
 		if (myrpt->skedtimer <= 0) {
 			myrpt->skedtimer = 200;
@@ -6292,6 +6380,16 @@
 			memmove(myrpt->macrobuf, myrpt->macrobuf + 1, sizeof(myrpt->macrobuf) - 1);
 			if ((c == 'p') || (c == 'P'))
 				myrpt->macrotimer = MACROPTIME;
+			rpt_mutex_unlock(&myrpt->lock);
+			local_dtmf_helper(myrpt, c);
+		} else
+			rpt_mutex_unlock(&myrpt->lock);
+		c = myrpt->gosubbuf[0];
+		if (c && (!myrpt->gosubtimer)) {
+			myrpt->gosubtimer = GOSUBTIME;
+			memmove(myrpt->gosubbuf, myrpt->gosubbuf + 1, sizeof(myrpt->gosubbuf) - 1);
+			if ((c == 'p') || (c == 'P'))
+				myrpt->gosubtimer = GOSUBPTIME;
 			rpt_mutex_unlock(&myrpt->lock);
 			local_dtmf_helper(myrpt, c);
 		} else
@@ -7142,6 +7240,10 @@
 		myrpt->remchannel = chan; /* Save copy of channel */
 		snprintf(myrpt->macrobuf, sizeof(myrpt->macrobuf), "PPPP%s", myrpt->p.startupmacro);
 	}
+	if (myrpt->p.startupgosub) {
+		myrpt->remchannel = chan; /* Save copy of channel */
+		snprintf(myrpt->gosubbuf, sizeof(myrpt->gosubbuf), "PPPP%s", myrpt->p.startupgosub);
+	}
 	myrpt->reload = 0;
 	rpt_mutex_unlock(&myrpt->lock);
 	setrem(myrpt); 
@@ -7193,6 +7295,10 @@
 			myrpt->macrotimer -= elap;
 		if (myrpt->macrotimer < 0)
 			myrpt->macrotimer = 0;
+		if (myrpt->gosubtimer)
+			myrpt->gosubtimer -= elap;
+		if (myrpt->gosubtimer < 0)
+			myrpt->gosubtimer = 0;
 		rpt_mutex_unlock(&myrpt->lock);
 		if (!ms)
 			continue;
@@ -7316,6 +7422,17 @@
 				memmove(myrpt->macrobuf, myrpt->macrobuf + 1, sizeof(myrpt->macrobuf) - 1);
 				if ((c == 'p') || (c == 'P'))
 					myrpt->macrotimer = MACROPTIME;
+				rpt_mutex_unlock(&myrpt->lock);
+				if (handle_remote_dtmf_digit(myrpt, c, &keyed, 0) == -1)
+					break;
+				continue;
+			}
+			c = myrpt->gosubbuf[0];
+			if (c && (!myrpt->gosubtimer)) {
+				myrpt->gosubtimer = GOSUBTIME;
+				memmove(myrpt->gosubbuf, myrpt->gosubbuf + 1, sizeof(myrpt->gosubbuf) - 1);
+				if ((c == 'p') || (c == 'P'))
+					myrpt->gosubtimer = GOSUBPTIME;
 				rpt_mutex_unlock(&myrpt->lock);
 				if (handle_remote_dtmf_digit(myrpt, c, &keyed, 0) == -1)
 					break;



More information about the asterisk-commits mailing list