[svn-commits] branch oej/test-this-branch r26052 - in /team/oej/test-this-branch: ./ apps/ ...

svn-commits at lists.digium.com svn-commits at lists.digium.com
Tue May 9 06:44:33 MST 2006


Author: oej
Date: Tue May  9 08:44:33 2006
New Revision: 26052

URL: http://svn.digium.com/view/asterisk?rev=26052&view=rev
Log:
Updating to trunk, resetting automerge

Modified:
    team/oej/test-this-branch/   (props changed)
    team/oej/test-this-branch/app.c
    team/oej/test-this-branch/apps/app_chanspy.c
    team/oej/test-this-branch/apps/app_exec.c
    team/oej/test-this-branch/apps/app_macro.c
    team/oej/test-this-branch/apps/app_meetme.c
    team/oej/test-this-branch/apps/app_senddtmf.c
    team/oej/test-this-branch/apps/app_verbose.c
    team/oej/test-this-branch/build_tools/make_version
    team/oej/test-this-branch/build_tools/menuselect.c
    team/oej/test-this-branch/build_tools/menuselect.h
    team/oej/test-this-branch/channel.c
    team/oej/test-this-branch/channels/chan_iax2.c
    team/oej/test-this-branch/channels/chan_misdn.c
    team/oej/test-this-branch/channels/chan_sip.c
    team/oej/test-this-branch/channels/chan_zap.c
    team/oej/test-this-branch/channels/misdn/chan_misdn_config.h
    team/oej/test-this-branch/channels/misdn/isdn_lib.c
    team/oej/test-this-branch/channels/misdn/isdn_lib.h
    team/oej/test-this-branch/channels/misdn_config.c
    team/oej/test-this-branch/loader.c
    team/oej/test-this-branch/manager.c
    team/oej/test-this-branch/pbx/ael/ael.tab.c
    team/oej/test-this-branch/pbx/ael/ael.y
    team/oej/test-this-branch/pbx/pbx_dundi.c
    team/oej/test-this-branch/utils.c

Propchange: team/oej/test-this-branch/
------------------------------------------------------------------------------
    automerge = http://edvina.net/training/

Modified: team/oej/test-this-branch/app.c
URL: http://svn.digium.com/view/asterisk/team/oej/test-this-branch/app.c?rev=26052&r1=26051&r2=26052&view=diff
==============================================================================
--- team/oej/test-this-branch/app.c (original)
+++ team/oej/test-this-branch/app.c Tue May  9 08:44:33 2006
@@ -535,22 +535,37 @@
 static int global_silence_threshold = 128;
 static int global_maxsilence = 0;
 
-int ast_play_and_record(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, int silencethreshold, int maxsilence, const char *path)
-{
-	int d;
+/*! Optionally play a sound file or a beep, then record audio and video from the channel.
+ * @param chan Channel to playback to/record from.
+ * @param playfile Filename of sound to play before recording begins.
+ * @param recordfile Filename to record to.
+ * @param maxtime Maximum length of recording (in milliseconds).
+ * @param fmt Format(s) to record message in. Multiple formats may be specified by separating them with a '|'.
+ * @param duration Where to store actual length of the recorded message (in milliseconds).
+ * @param beep Whether to play a beep before starting to record.
+ * @param silencethreshold 
+ * @param maxsilence Length of silence that will end a recording (in milliseconds).
+ * @param path Optional filesystem path to unlock.
+ * @param prepend If true, prepend the recorded audio to an existing file.
+ * @param acceptdtmf DTMF digits that will end the recording.
+ * @param canceldtmf DTMF digits that will cancel the recording.
+ */
+
+static int __ast_play_and_record(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, int beep, int silencethreshold, int maxsilence, const char *path, int prepend, const char *acceptdtmf, const char *canceldtmf)
+{
+	int d = 0;
 	char *fmts;
 	char comment[256];
-	int x, fmtcnt=1, res=-1,outmsg=0;
-	struct ast_frame *f;
+	int x, fmtcnt = 1, res = -1, outmsg = 0;
 	struct ast_filestream *others[MAX_OTHER_FORMATS];
 	char *sfmt[MAX_OTHER_FORMATS];
-	char *stringp=NULL;
+	char *stringp = NULL;
 	time_t start, end;
-	struct ast_dsp *sildet=NULL;   	/* silence detector dsp */
+	struct ast_dsp *sildet = NULL;   /* silence detector dsp */
 	int totalsilence = 0;
-	int dspsilence = 0;
-	int rfmt=0;
+	int rfmt = 0;
 	struct ast_silence_generator *silgen = NULL;
+	char prependfile[80];
 
 	if (silencethreshold < 0)
 		silencethreshold = global_silence_threshold;
@@ -565,19 +580,25 @@
 	}
 
 	ast_log(LOG_DEBUG,"play_and_record: %s, %s, '%s'\n", playfile ? playfile : "<None>", recordfile, fmt);
-	snprintf(comment,sizeof(comment),"Playing %s, Recording to: %s on %s\n", playfile ? playfile : "<None>", recordfile, chan->name);
-
-	if (playfile) {
-		d = ast_play_and_wait(chan, playfile);
+	snprintf(comment, sizeof(comment), "Playing %s, Recording to: %s on %s\n", playfile ? playfile : "<None>", recordfile, chan->name);
+
+	if (playfile || beep) {
+		if (!beep)
+			d = ast_play_and_wait(chan, playfile);
 		if (d > -1)
 			d = ast_stream_and_wait(chan, "beep", chan->language, "");
 		if (d < 0)
 			return -1;
 	}
 
+	if (prepend) {
+		ast_copy_string(prependfile, recordfile, sizeof(prependfile));	
+		strncat(prependfile, "-prepend", sizeof(prependfile) - strlen(prependfile) - 1);
+	}
+
 	fmts = ast_strdupa(fmt);
 
-	stringp=fmts;
+	stringp = fmts;
 	strsep(&stringp, "|");
 	ast_log(LOG_DEBUG,"Recording Formats: sfmts=%s\n", fmts);
 	sfmt[0] = ast_strdupa(fmts);
@@ -591,10 +612,11 @@
 	}
 
 	time(&start);
-	end=start;  /* pre-initialize end to be same as start in case we never get into loop */
-	for (x=0;x<fmtcnt;x++) {
-		others[x] = ast_writefile(recordfile, sfmt[x], comment, O_TRUNC, 0, 0700);
-		ast_verbose( VERBOSE_PREFIX_3 "x=%d, open writing:  %s format: %s, %p\n", x, recordfile, sfmt[x], others[x]);
+	end = start;  /* pre-initialize end to be same as start in case we never get into loop */
+	for (x = 0; x < fmtcnt; x++) {
+		others[x] = ast_writefile(prepend ? prependfile : recordfile, sfmt[x], comment, O_TRUNC, 0, 0700);
+		if (option_verbose > 2)
+			ast_verbose(VERBOSE_PREFIX_3 "x=%d, open writing:  %s format: %s, %p\n", x, prepend ? prependfile : recordfile, sfmt[x], others[x]);
 
 		if (!others[x]) {
 			break;
@@ -620,17 +642,19 @@
 		}
 	}
 
-	/* Request a video update */
-	ast_indicate(chan, AST_CONTROL_VIDUPDATE);
-
-	if (ast_opt_transmit_silence)
-		silgen = ast_channel_start_silence_generator(chan);
+	if (!prepend) {
+		/* Request a video update */
+		ast_indicate(chan, AST_CONTROL_VIDUPDATE);
+
+		if (ast_opt_transmit_silence)
+			silgen = ast_channel_start_silence_generator(chan);
+	}
 
 	if (x == fmtcnt) {
-	/* Loop forever, writing the packets we read to the writer(s), until
-	   we read a # or get a hangup */
-		f = NULL;
-		for(;;) {
+		/* Loop forever, writing the packets we read to the writer(s), until
+		   we read a digit or get a hangup */
+		struct ast_frame *f;
+		for (;;) {
 		 	res = ast_waitfor(chan, 2000);
 			if (!res) {
 				ast_log(LOG_DEBUG, "One waitfor failed, trying another\n");
@@ -651,13 +675,15 @@
 				break;
 			if (f->frametype == AST_FRAME_VOICE) {
 				/* write each format */
-				for (x=0;x<fmtcnt;x++) {
+				for (x = 0; x < fmtcnt; x++) {
+					if (prepend && !others[x])
+						break;
 					res = ast_writestream(others[x], f);
 				}
 
 				/* Silence Detection */
 				if (maxsilence > 0) {
-					dspsilence = 0;
+					int dspsilence = 0;
 					ast_dsp_silence(sildet, f, &dspsilence);
 					if (dspsilence)
 						totalsilence = dspsilence;
@@ -668,37 +694,40 @@
 						/* Ended happily with silence */
 						if (option_verbose > 2)
 							ast_verbose( VERBOSE_PREFIX_3 "Recording automatically stopped after a silence of %d seconds\n", totalsilence/1000);
-						ast_frfree(f);
 						res = 'S';
-						outmsg=2;
+						outmsg = 2;
 						break;
 					}
 				}
 				/* Exit on any error */
 				if (res) {
 					ast_log(LOG_WARNING, "Error writing frame\n");
-					ast_frfree(f);
 					break;
 				}
 			} else if (f->frametype == AST_FRAME_VIDEO) {
 				/* Write only once */
 				ast_writestream(others[0], f);
 			} else if (f->frametype == AST_FRAME_DTMF) {
-				if (f->subclass == '#') {
-					if (option_verbose > 2)
-						ast_verbose( VERBOSE_PREFIX_3 "User ended message by pressing %c\n", f->subclass);
-					res = '#';
+				if (prepend) {
+				/* stop recording with any digit */
+					if (option_verbose > 2) 
+						ast_verbose(VERBOSE_PREFIX_3 "User ended message by pressing %c\n", f->subclass);
+					res = 't';
 					outmsg = 2;
-					ast_frfree(f);
 					break;
 				}
-				if (f->subclass == '0') {
-				/* Check for a '0' during message recording also, in case caller wants operator */
+				if (strchr(acceptdtmf, f->subclass)) {
 					if (option_verbose > 2)
-						ast_verbose(VERBOSE_PREFIX_3 "User cancelled by pressing %c\n", f->subclass);
-					res = '0';
+						ast_verbose(VERBOSE_PREFIX_3 "User ended message by pressing %c\n", f->subclass);
+					res = f->subclass;
+					outmsg = 2;
+					break;
+				}
+				if (strchr(canceldtmf, f->subclass)) {
+					if (option_verbose > 2)
+						ast_verbose(VERBOSE_PREFIX_3 "User cancelled message by pressing %c\n", f->subclass);
+					res = f->subclass;
 					outmsg = 0;
-					ast_frfree(f);
 					break;
 				}
 			}
@@ -706,276 +735,95 @@
 				time(&end);
 				if (maxtime < (end - start)) {
 					if (option_verbose > 2)
-						ast_verbose( VERBOSE_PREFIX_3 "Took too long, cutting it short...\n");
+						ast_verbose(VERBOSE_PREFIX_3 "Took too long, cutting it short...\n");
+					res = 't';
 					outmsg = 2;
-					res = 't';
-					ast_frfree(f);
 					break;
 				}
 			}
 			ast_frfree(f);
 		}
-		if (end == start) time(&end);
 		if (!f) {
 			if (option_verbose > 2)
-				ast_verbose( VERBOSE_PREFIX_3 "User hung up\n");
+				ast_verbose(VERBOSE_PREFIX_3 "User hung up\n");
 			res = -1;
-			outmsg=1;
-		}
+			outmsg = 1;
+		} else {
+			ast_frfree(f);
+		}
+		if (end == start) time(&end);
 	} else {
 		ast_log(LOG_WARNING, "Error creating writestream '%s', format '%s'\n", recordfile, sfmt[x]);
 	}
 
-	if (silgen)
-		ast_channel_stop_silence_generator(chan, silgen);
-
+	if (!prepend) {
+		if (silgen)
+			ast_channel_stop_silence_generator(chan, silgen);
+	}
 	*duration = end - start;
 
-	for (x=0;x<fmtcnt;x++) {
-		if (!others[x])
-			break;
-		if (res > 0)
-			ast_stream_rewind(others[x], totalsilence ? totalsilence-200 : 200);
-		ast_truncstream(others[x]);
-		ast_closestream(others[x]);
-	}
-	if (rfmt && ast_set_read_format(chan, rfmt)) {
-		ast_log(LOG_WARNING, "Unable to restore format %s to channel '%s'\n", ast_getformatname(rfmt), chan->name);
-	}
-	if (outmsg > 1) {
-		/* Let them know recording is stopped */
-		ast_stream_and_wait(chan, "auth-thankyou", chan->language, "");
-	}
-	if (sildet)
-		ast_dsp_free(sildet);
-	return res;
-}
-
-int ast_play_and_prepend(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int *duration, int beep, int silencethreshold, int maxsilence)
-{
-	int d = 0;
-	char *fmts;
-	char comment[256];
-	int x, fmtcnt=1, res=-1,outmsg=0;
-	struct ast_frame *f;
-	struct ast_filestream *others[MAX_OTHER_FORMATS];
-	struct ast_filestream *realfiles[MAX_OTHER_FORMATS];
-	char *sfmt[MAX_OTHER_FORMATS];
-	char *stringp=NULL;
-	time_t start, end;
-	struct ast_dsp *sildet;   	/* silence detector dsp */
-	int totalsilence = 0;
-	int dspsilence = 0;
-	int rfmt=0;	
-	char prependfile[80];
-	
-	if (silencethreshold < 0)
-		silencethreshold = global_silence_threshold;
-
-	if (maxsilence < 0)
-		maxsilence = global_maxsilence;
-
-	/* barf if no pointer passed to store duration in */
-	if (duration == NULL) {
-		ast_log(LOG_WARNING, "Error play_and_prepend called without duration pointer\n");
-		return -1;
-	}
-
-	ast_log(LOG_DEBUG,"play_and_prepend: %s, %s, '%s'\n", playfile ? playfile : "<None>", recordfile, fmt);
-	snprintf(comment,sizeof(comment),"Playing %s, Recording to: %s on %s\n", playfile ? playfile : "<None>", recordfile, chan->name);
-
-	if (playfile || beep) {	
-		if (!beep)
-			d = ast_play_and_wait(chan, playfile);
-		if (d > -1)
-			d = ast_stream_and_wait(chan, "beep",chan->language, "");
-		if (d < 0)
-			return -1;
-	}
-	ast_copy_string(prependfile, recordfile, sizeof(prependfile));	
-	strncat(prependfile, "-prepend", sizeof(prependfile) - strlen(prependfile) - 1);
-			
-	fmts = ast_strdupa(fmt);
-	
-	stringp=fmts;
-	strsep(&stringp, "|");
-	ast_log(LOG_DEBUG,"Recording Formats: sfmts=%s\n", fmts);	
-	sfmt[0] = ast_strdupa(fmts);
-	
-	while((fmt = strsep(&stringp, "|"))) {
-		if (fmtcnt > MAX_OTHER_FORMATS - 1) {
-			ast_log(LOG_WARNING, "Please increase MAX_OTHER_FORMATS in app.c\n");
-			break;
-		}
-		sfmt[fmtcnt++] = ast_strdupa(fmt);
-	}
-
-	time(&start);
-	end=start;  /* pre-initialize end to be same as start in case we never get into loop */
-	for (x=0;x<fmtcnt;x++) {
-		others[x] = ast_writefile(prependfile, sfmt[x], comment, O_TRUNC, 0, 0700);
-		ast_verbose( VERBOSE_PREFIX_3 "x=%d, open writing:  %s format: %s, %p\n", x, prependfile, sfmt[x], others[x]);
-		if (!others[x]) {
-			break;
-		}
-	}
-	
-	sildet = ast_dsp_new(); /* Create the silence detector */
-	if (!sildet) {
-		ast_log(LOG_WARNING, "Unable to create silence detector :(\n");
-		return -1;
-	}
-	ast_dsp_set_threshold(sildet, silencethreshold);
-
-	if (maxsilence > 0) {
-		rfmt = chan->readformat;
-		res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
-		if (res < 0) {
-			ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n");
-			ast_dsp_free(sildet);
-			return -1;
-		}
-	}
-						
-	if (x == fmtcnt) {
-	/* Loop forever, writing the packets we read to the writer(s), until
-	   we read a # or get a hangup */
-		f = NULL;
-		for(;;) {
-		 	res = ast_waitfor(chan, 2000);
-			if (!res) {
-				ast_log(LOG_DEBUG, "One waitfor failed, trying another\n");
-				/* Try one more time in case of masq */
-			 	res = ast_waitfor(chan, 2000);
-				if (!res) {
-					ast_log(LOG_WARNING, "No audio available on %s??\n", chan->name);
-					res = -1;
-				}
-			}
-			
-			if (res < 0) {
-				f = NULL;
+	if (!prepend) {
+		for (x = 0; x < fmtcnt; x++) {
+			if (!others[x])
 				break;
-			}
-			f = ast_read(chan);
-			if (!f)
-				break;
-			if (f->frametype == AST_FRAME_VOICE) {
-				/* write each format */
-				for (x=0;x<fmtcnt;x++) {
-					if (!others[x])
-						break;
-					res = ast_writestream(others[x], f);
-				}
-				
-				/* Silence Detection */
-				if (maxsilence > 0) {
-					dspsilence = 0;
-					ast_dsp_silence(sildet, f, &dspsilence);
-					if (dspsilence)
-						totalsilence = dspsilence;
-					else
-						totalsilence = 0;
-					
-					if (totalsilence > maxsilence) {
-					/* Ended happily with silence */
-					if (option_verbose > 2) 
-						ast_verbose( VERBOSE_PREFIX_3 "Recording automatically stopped after a silence of %d seconds\n", totalsilence/1000);
-					ast_frfree(f);
-					res = 'S';
-					outmsg=2;
-					break;
-					}
-				}
-				/* Exit on any error */
-				if (res) {
-					ast_log(LOG_WARNING, "Error writing frame\n");
-					ast_frfree(f);
-					break;
-				}
-			} else if (f->frametype == AST_FRAME_VIDEO) {
-				/* Write only once */
-				ast_writestream(others[0], f);
-			} else if (f->frametype == AST_FRAME_DTMF) {
-				/* stop recording with any digit */
-				if (option_verbose > 2) 
-					ast_verbose( VERBOSE_PREFIX_3 "User ended message by pressing %c\n", f->subclass);
-				res = 't';
-				outmsg = 2;
-				ast_frfree(f);
-				break;
-			}
-			if (maxtime) {
-				time(&end);
-				if (maxtime < (end - start)) {
-					if (option_verbose > 2)
-						ast_verbose( VERBOSE_PREFIX_3 "Took too long, cutting it short...\n");
-					res = 't';
-					outmsg=2;
-					ast_frfree(f);
-					break;
-				}
-			}
-			ast_frfree(f);
-		}
-		if (end == start) time(&end);
-		if (!f) {
-			if (option_verbose > 2) 
-				ast_verbose( VERBOSE_PREFIX_3 "User hung up\n");
-			res = -1;
-			outmsg=1;
-#if 0
-			/* delete all the prepend files */
-			for (x=0;x<fmtcnt;x++) {
-				if (!others[x])
-					break;
-				ast_closestream(others[x]);
-				ast_filedelete(prependfile, sfmt[x]);
-			}
-#endif
-		}
-	} else {
-		ast_log(LOG_WARNING, "Error creating writestream '%s', format '%s'\n", prependfile, sfmt[x]); 
-	}
-	ast_dsp_free(sildet);
-	*duration = end - start;
-#if 0
-	if (outmsg > 1) {
-#else
-	if (outmsg) {
-#endif
+			if (res > 0)
+				ast_stream_rewind(others[x], totalsilence ? totalsilence-200 : 200);
+			ast_truncstream(others[x]);
+			ast_closestream(others[x]);
+		}
+	}
+
+	if (prepend && outmsg) {
+		struct ast_filestream *realfiles[MAX_OTHER_FORMATS];
 		struct ast_frame *fr;
-		for (x=0;x<fmtcnt;x++) {
+
+		for (x = 0; x < fmtcnt; x++) {
 			snprintf(comment, sizeof(comment), "Opening the real file %s.%s\n", recordfile, sfmt[x]);
 			realfiles[x] = ast_readfile(recordfile, sfmt[x], comment, O_RDONLY, 0, 0);
 			if (!others[x] || !realfiles[x])
 				break;
-			if (totalsilence)
-				ast_stream_rewind(others[x], totalsilence-200);
-			else
-				ast_stream_rewind(others[x], 200);
+			ast_stream_rewind(others[x], totalsilence ? totalsilence-200 : 200);
 			ast_truncstream(others[x]);
 			/* add the original file too */
 			while ((fr = ast_readframe(realfiles[x]))) {
-				ast_writestream(others[x],fr);
+				ast_writestream(others[x], fr);
+				ast_frfree(fr);
 			}
 			ast_closestream(others[x]);
 			ast_closestream(realfiles[x]);
 			ast_filerename(prependfile, recordfile, sfmt[x]);
-#if 0
-			ast_verbose("Recording Format: sfmts=%s, prependfile %s, recordfile %s\n", sfmt[x],prependfile,recordfile);
-#endif
+			if (option_verbose > 3)
+				ast_verbose(VERBOSE_PREFIX_4 "Recording Format: sfmts=%s, prependfile %s, recordfile %s\n", sfmt[x], prependfile, recordfile);
 			ast_filedelete(prependfile, sfmt[x]);
 		}
 	}
 	if (rfmt && ast_set_read_format(chan, rfmt)) {
 		ast_log(LOG_WARNING, "Unable to restore format %s to channel '%s'\n", ast_getformatname(rfmt), chan->name);
 	}
-	if (outmsg > 1) {
-		/* Let them know it worked */
+	if (outmsg == 2) {
 		ast_stream_and_wait(chan, "auth-thankyou", chan->language, "");
-	}	
+	}
+	if (sildet)
+		ast_dsp_free(sildet);
 	return res;
+}
+
+static char default_acceptdtmf[] = "#";
+static char default_canceldtmf[] = "";
+
+int ast_play_and_record_full(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, int silencethreshold, int maxsilence, const char *path, const char *acceptdtmf, const char *canceldtmf)
+{
+	return __ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, 0, silencethreshold, maxsilence, path, 0, S_OR(acceptdtmf, default_acceptdtmf), S_OR(canceldtmf, default_canceldtmf));
+}
+
+int ast_play_and_record(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, int silencethreshold, int maxsilence, const char *path)
+{
+	return __ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, 0, silencethreshold, maxsilence, path, 0, default_acceptdtmf, default_canceldtmf);
+}
+
+int ast_play_and_prepend(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int *duration, int beep, int silencethreshold, int maxsilence)
+{
+	return __ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, beep, silencethreshold, maxsilence, NULL, 1, default_acceptdtmf, default_canceldtmf);
 }
 
 /* Channel group core functions */

Modified: team/oej/test-this-branch/apps/app_chanspy.c
URL: http://svn.digium.com/view/asterisk/team/oej/test-this-branch/apps/app_chanspy.c?rev=26052&r1=26051&r2=26052&view=diff
==============================================================================
--- team/oej/test-this-branch/apps/app_chanspy.c (original)
+++ team/oej/test-this-branch/apps/app_chanspy.c Tue May  9 08:44:33 2006
@@ -73,7 +73,7 @@
 "  Options:\n"
 "    b - Only spy on channels involved in a bridged call.\n"
 "    g(grp) - Match only channels where their ${SPYGROUP} variable is set to\n"
-"             'grp'.\n"
+"             contain 'grp' in an optional : delimited list.\n"
 "    q - Don't play a beep when beginning to spy on a channel.\n"
 "    r[(basename)] - Record the session to the monitor spool directory. An\n"
 "                    optional base for the filename may be specified. The\n"
@@ -414,7 +414,7 @@
 			spec = NULL;
 		}
 	}
-	
+
 	if (options) {
 		char *opts[OPT_ARG_ARRAY_SIZE];
 		ast_app_parse_options(chanspy_opts, &flags, opts, options);
@@ -471,18 +471,34 @@
 			if (peer != chan) {
 				const char *group = NULL;
 				int igrp = 1;
-
+				char *groups[25] = {0};
+				int num_groups = 0;
+				char *dup_group;
+				
 				if (peer == prev && !chosen) {
 					break;
 				}
 				chosen = 0;
-				group = pbx_builtin_getvar_helper(peer, "SPYGROUP");
+
 				if (mygroup) {
-					if (!group || strcmp(mygroup, group)) {
-						igrp = 0;
+					int x;
+
+					if ((group = pbx_builtin_getvar_helper(peer, "SPYGROUP"))) {
+						dup_group = ast_strdupa(group);
+						num_groups = ast_app_separate_args(dup_group, ':', groups, sizeof(groups) / sizeof(groups[0]));
 					}
+
+					igrp = 0;
+					if (num_groups) {
+						for (x = 0; x < num_groups; x++) {
+							if (!strcmp(mygroup, groups[x])) {
+								igrp = 1;
+								break;
+							}
+						}
+					} 
 				}
-				
+
 				if (igrp && (!spec || ((strlen(spec) <= strlen(peer->name) &&
 							!strncasecmp(peer->name, spec, strlen(spec)))))) {
 					if (peer && (!bronly || ast_bridged_channel(peer)) &&

Modified: team/oej/test-this-branch/apps/app_exec.c
URL: http://svn.digium.com/view/asterisk/team/oej/test-this-branch/apps/app_exec.c?rev=26052&r1=26051&r2=26052&view=diff
==============================================================================
--- team/oej/test-this-branch/apps/app_exec.c (original)
+++ team/oej/test-this-branch/apps/app_exec.c Tue May  9 08:44:33 2006
@@ -83,6 +83,14 @@
 "    NOAPP     if the application was not found or was not specified\n"
 "    NOMEMORY  if there was not enough memory to execute.\n";
 
+static char *app_execif = "ExecIf";
+static char *execif_synopsis = "Executes dialplan application, conditionally";
+static char *execif_descrip = 
+"Usage:  ExecIF (<expr>|<app>|<data>)\n"
+"If <expr> is true, execute and return the result of <app>(<data>).\n"
+"If <expr> is true, but <app> is not found, then the application\n"
+"will return a non-zero value.\n";
+
 LOCAL_USER_DECL;
 
 static int exec_exec(struct ast_channel *chan, void *data)
@@ -160,12 +168,54 @@
 	return 0;
 }
 
+static int execif_exec(struct ast_channel *chan, void *data) {
+	int res=0;
+	struct localuser *u;
+	char *myapp = NULL;
+	char *mydata = NULL;
+	char *expr = NULL;
+	struct ast_app *app = NULL;
+
+	LOCAL_USER_ADD(u);
+
+	if (!(expr = ast_strdupa(data))) {
+		LOCAL_USER_REMOVE(u);
+		return -1;
+	}
+
+	if ((myapp = strchr(expr,'|'))) {
+		*myapp = '\0';
+		myapp++;
+		if ((mydata = strchr(myapp,'|'))) {
+			*mydata = '\0';
+			mydata++;
+		} else
+			mydata = "";
+
+		if (pbx_checkcondition(expr)) { 
+			if ((app = pbx_findapp(myapp))) {
+				res = pbx_exec(chan, app, mydata);
+			} else {
+				ast_log(LOG_WARNING, "Count not find application! (%s)\n", myapp);
+				res = -1;
+			}
+		}
+	} else {
+		ast_log(LOG_ERROR,"Invalid Syntax.\n");
+		res = -1;
+	}
+		
+	LOCAL_USER_REMOVE(u);
+	return res;
+}
+
 static int unload_module(void *mod)
 {
 	int res;
 
 	res = ast_unregister_application(app_exec);
 	res |= ast_unregister_application(app_tryexec);
+	res |= ast_unregister_application(app_execif);
 
 	STANDARD_HANGUP_LOCALUSERS;
 
@@ -176,6 +226,7 @@
 {
 	int res = ast_register_application(app_exec, exec_exec, exec_synopsis, exec_descrip);
 	res |= ast_register_application(app_tryexec, tryexec_exec, tryexec_synopsis, tryexec_descrip);
+	res |= ast_register_application(app_execif, execif_exec, execif_synopsis, execif_descrip);
 	return res;
 }
 

Modified: team/oej/test-this-branch/apps/app_macro.c
URL: http://svn.digium.com/view/asterisk/team/oej/test-this-branch/apps/app_macro.c?rev=26052&r1=26051&r2=26052&view=diff
==============================================================================
--- team/oej/test-this-branch/apps/app_macro.c (original)
+++ team/oej/test-this-branch/apps/app_macro.c Tue May  9 08:44:33 2006
@@ -326,7 +326,7 @@
 			*label_b = '\0';
 			label_b++;
 		}
-		if (ast_true(expr))
+		if (pbx_checkcondition(expr))
 			macro_exec(chan, label_a);
 		else if (label_b) 
 			macro_exec(chan, label_b);

Modified: team/oej/test-this-branch/apps/app_meetme.c
URL: http://svn.digium.com/view/asterisk/team/oej/test-this-branch/apps/app_meetme.c?rev=26052&r1=26051&r2=26052&view=diff
==============================================================================
--- team/oej/test-this-branch/apps/app_meetme.c (original)
+++ team/oej/test-this-branch/apps/app_meetme.c Tue May  9 08:44:33 2006
@@ -1,4 +1,3 @@
-
 /*
  * Asterisk -- An open source telephony toolkit.
  *
@@ -2171,9 +2170,12 @@
 								break;
 							} else {
 								/* Pin invalid */
-								res = ast_streamfile(chan, "conf-invalidpin", chan->language);
-								if (!res)
-									ast_waitstream(chan, AST_DIGIT_ANY);
+								if (!ast_streamfile(chan, "conf-invalidpin", chan->language))
+									res = ast_waitstream(chan, AST_DIGIT_ANY);
+								else {
+									ast_log(LOG_WARNING, "Couldn't play invalid pin msg!\n");
+									break;
+								}
 								if (res < 0) {
 									AST_LIST_LOCK(&confs);
 									cnf->refcount--;

Modified: team/oej/test-this-branch/apps/app_senddtmf.c
URL: http://svn.digium.com/view/asterisk/team/oej/test-this-branch/apps/app_senddtmf.c?rev=26052&r1=26051&r2=26052&view=diff
==============================================================================
--- team/oej/test-this-branch/apps/app_senddtmf.c (original)
+++ team/oej/test-this-branch/apps/app_senddtmf.c Tue May  9 08:44:33 2006
@@ -84,7 +84,7 @@
 		timeout = atoi(to);
 	}
 		
-	if(timeout <= 0)
+	if (timeout <= 0)
 		timeout = 250;
 
 	res = ast_dtmf_stream(chan,NULL,digits,timeout);
@@ -95,29 +95,33 @@
 }
 
 static char mandescr_playdtmf[] =
-	"Description: Plays a DTMF digit on the specified channel.\n"
-	"Variables: (all are required)\n"
-	"Channel: Channel name to send digit to\n"
-	"Digit: The dtmf digit to play\n";
+"Description: Plays a dtmf digit on the specified channel.\n"
+"Variables: (all are required)\n"
+"	Channel: Channel name to send digit to\n"
+"	Digit: The dtmf digit to play\n";
 
 static int manager_play_dtmf(struct mansession *s, struct message *m)
 {
-	char *channel, *digit;
-
-	channel = astman_get_header(m, "Channel");
-	digit = astman_get_header(m, "Digit");
+	char *channel = astman_get_header(m, "Channel");
+	char *digit = astman_get_header(m, "Digit");
 	struct ast_channel *chan = ast_get_channel_by_name_locked(channel);
-	if (chan == NULL) {
-		astman_send_error(s, m, "No such channel");
+	
+	if (!chan) {
+		astman_send_error(s, m, "Channel not specified");
+		ast_mutex_unlock(&chan->lock);
 		return 0;
 	}
-	if (digit == NULL) {
+	if (!digit) {
 		astman_send_error(s, m, "No digit specified");
+		ast_mutex_unlock(&chan->lock);
 		return 0;
 	}
+
 	ast_senddigit(chan, *digit);
+
 	ast_mutex_unlock(&chan->lock);
-	astman_send_ack(s, m, "DTMF successfully sent");
+	astman_send_ack(s, m, "DTMF successfully queued");
+	
 	return 0;
 }
 
@@ -126,7 +130,7 @@
 	int res;
 
 	res = ast_unregister_application(app);
-	res |= ast_manager_unregister("playDTMF");
+	res |= ast_manager_unregister("PlayDTMF");
 
 	STANDARD_HANGUP_LOCALUSERS;
 
@@ -135,8 +139,12 @@
 
 static int load_module(void *mod)
 {
-	ast_manager_register2( "playDTMF", EVENT_FLAG_AGENT, manager_play_dtmf, "Play DTMF signal on a specific channel.", mandescr_playdtmf);
-	return ast_register_application(app, senddtmf_exec, synopsis, descrip);
+	int res;
+
+	res = ast_manager_register2( "PlayDTMF", EVENT_FLAG_CALL, manager_play_dtmf, "Play DTMF signal on a specific channel.", mandescr_playdtmf );
+	res |= ast_register_application(app, senddtmf_exec, synopsis, descrip);
+
+	return res;
 }
 
 static const char *description(void)

Modified: team/oej/test-this-branch/apps/app_verbose.c
URL: http://svn.digium.com/view/asterisk/team/oej/test-this-branch/apps/app_verbose.c?rev=26052&r1=26051&r2=26052&view=diff
==============================================================================
--- team/oej/test-this-branch/apps/app_verbose.c (original)
+++ team/oej/test-this-branch/apps/app_verbose.c Tue May  9 08:44:33 2006
@@ -66,7 +66,7 @@
 
 	if (data) {
 		if ((vtext = ast_strdupa(data))) {
-			char *tmp = strsep(&vtext, "|,");
+			char *tmp = strsep(&vtext, "|");
 			if (vtext) {
 				if (sscanf(tmp, "%d", &vsize) != 1) {
 					vsize = 0;

Modified: team/oej/test-this-branch/build_tools/make_version
URL: http://svn.digium.com/view/asterisk/team/oej/test-this-branch/build_tools/make_version?rev=26052&r1=26051&r2=26052&view=diff
==============================================================================
--- team/oej/test-this-branch/build_tools/make_version (original)
+++ team/oej/test-this-branch/build_tools/make_version Tue May  9 08:44:33 2006
@@ -3,7 +3,7 @@
 if [ -f ${1}/.version ]; then
 	cat ${1}.version
 elif [ -f ${1}/.svnrevision ]; then
-	echo SVN-`cat ${1}/.svnbranch`-r`cat ${1}.svnrevision`
+	echo SVN-`cat ${1}/.svnbranch`-r`cat ${1}/.svnrevision`
 elif [ -d .svn ]; then
     PARTS=`LANG=C svn info ${1} | grep URL | awk '{print $2;}' | sed -e s:^.*/svn/asterisk/:: | sed -e 's:/: :g'`
     BRANCH=0

Modified: team/oej/test-this-branch/build_tools/menuselect.c
URL: http://svn.digium.com/view/asterisk/team/oej/test-this-branch/build_tools/menuselect.c?rev=26052&r1=26051&r2=26052&view=diff
==============================================================================
--- team/oej/test-this-branch/build_tools/menuselect.c (original)
+++ team/oej/test-this-branch/build_tools/menuselect.c Tue May  9 08:44:33 2006
@@ -72,46 +72,34 @@
 };
 
 /*! The list of trees from makeopts.xml files */
-AST_LIST_HEAD_NOLOCK_STATIC(trees, tree);
-
-const char * const makeopts_files[] = {
+static AST_LIST_HEAD_NOLOCK_STATIC(trees, tree);
+
+static const char * const makeopts_files[] = {
 	"makeopts.xml"
 };
 
-char *output_makeopts = OUTPUT_MAKEOPTS_DEFAULT;
+static char *output_makeopts = OUTPUT_MAKEOPTS_DEFAULT;
 
 /*! This is set to 1 if menuselect.makeopts pre-existed the execution of this app */
-int existing_config = 0;
+static int existing_config = 0;
 
 /*! This is set when the --check-deps argument is provided. */
-int check_deps = 0;
+static int check_deps = 0;
 
 /*! Force a clean of the source tree */
-int force_clean = 0;
-
-int add_category(struct category *cat);
-int add_member(struct member *mem, struct category *cat);
-int parse_makeopts_xml(const char *makeopts_xml);
-int process_deps(void);
-int build_member_list(void);
-void mark_as_present(const char *member, const char *category);
-int parse_existing_config(const char *infile);
-int generate_makeopts_file(void);
-void free_member_list(void);
-void free_trees(void);
-
-/*! \brief a wrapper for calloc() that generates an error message if the allocation fails */
-static inline void *my_calloc(size_t num, size_t len)
-{
-	void *tmp;
-
-	tmp = calloc(num, len);
-	
-	if (!tmp)
-		fprintf(stderr, "Memory allocation error!\n");
-
-	return tmp;
-}
+static int force_clean = 0;
+
+static int add_category(struct category *cat);
+static int add_member(struct member *mem, struct category *cat);
+static int parse_makeopts_xml(const char *makeopts_xml);
+static int process_deps(void);
+static int build_member_list(void);
+static void mark_as_present(const char *member, const char *category);
+static void process_prev_failed_deps(char *buf);
+static int parse_existing_config(const char *infile);
+static int generate_makeopts_file(void);
+static void free_member_list(void);
+static void free_trees(void);
 
 /*! \brief return a pointer to the first non-whitespace character */
 static inline char *skip_blanks(char *str)
@@ -126,7 +114,7 @@
 }
 
 /*! \brief Add a category to the category list, ensuring that there are no duplicates */
-int add_category(struct category *cat)
+static int add_category(struct category *cat)
 {
 	struct category *tmp;
 
@@ -142,7 +130,7 @@
 }
 
 /*! \brief Add a member to the member list of a category, ensuring that there are no duplicates */
-int add_member(struct member *mem, struct category *cat)
+static int add_member(struct member *mem, struct category *cat)
 {
 	struct member *tmp;
 
@@ -158,7 +146,7 @@
 }
 
 /*! \brief Parse an input makeopts file */
-int parse_makeopts_xml(const char *makeopts_xml)
+static int parse_makeopts_xml(const char *makeopts_xml)
 {
 	FILE *f;
 	struct category *cat;
@@ -177,7 +165,7 @@
 		return -1;
 	}
 
-	if (!(tree = my_calloc(1, sizeof(*tree)))) {
+	if (!(tree = calloc(1, sizeof(*tree)))) {
 		fclose(f);
 		return -1;
 	}
@@ -195,7 +183,7 @@
 	     cur;
 	     cur = mxmlFindElement(cur, menu, "category", NULL, NULL, MXML_DESCEND))
 	{
-		if (!(cat = my_calloc(1, sizeof(*cat))))
+		if (!(cat = calloc(1, sizeof(*cat))))
 			return -1;
 
 		cat->name = mxmlElementGetAttr(cur, "name");
@@ -214,29 +202,23 @@
 		     cur2;
 		     cur2 = mxmlFindElement(cur2, cur, "member", NULL, NULL, MXML_DESCEND))
 		{
-			if (!(mem = my_calloc(1, sizeof(*mem))))
+			if (!(mem = calloc(1, sizeof(*mem))))
 				return -1;
 			
+			mem->name = mxmlElementGetAttr(cur2, "name");
+		
 			if (!cat->positive_output)
-				mem->enabled = 1; /* Enabled by default */
-
-			mem->name = mxmlElementGetAttr(cur2, "name");
-			
+				mem->enabled = 1;
+	
 			cur3 = mxmlFindElement(cur2, cur2, "defaultenabled", NULL, NULL, MXML_DESCEND);
-			if (cur3 && cur3->child) {
-				if (!strcasecmp("no", cur3->child->value.opaque))
-					mem->enabled = 0;
-				else if (!strcasecmp("yes", cur3->child->value.opaque))
-					mem->enabled = 1;
-				else
-					fprintf(stderr, "Invalid value '%s' for <defaultenabled> !\n", cur3->child->value.opaque);
-			}
+			if (cur3 && cur3->child)
+				mem->defaultenabled = cur3->child->value.opaque;
 			
 			for (cur3 = mxmlFindElement(cur2, cur2, "depend", NULL, NULL, MXML_DESCEND);
 			     cur3 && cur3->child;
 			     cur3 = mxmlFindElement(cur3, cur2, "depend", NULL, NULL, MXML_DESCEND))
 			{
-				if (!(dep = my_calloc(1, sizeof(*dep))))
+				if (!(dep = calloc(1, sizeof(*dep))))
 					return -1;
 				if (!strlen_zero(cur3->child->value.opaque)) {
 					dep->name = cur3->child->value.opaque;
@@ -249,7 +231,7 @@
 			     cur3 && cur3->child;
 			     cur3 = mxmlFindElement(cur3, cur2, "conflict", NULL, NULL, MXML_DESCEND))
 			{
-				if (!(cnf = my_calloc(1, sizeof(*cnf))))
+				if (!(cnf = calloc(1, sizeof(*cnf))))
 					return -1;
 				if (!strlen_zero(cur3->child->value.opaque)) {
 					cnf->name = cur3->child->value.opaque;
@@ -269,7 +251,7 @@
 }
 
 /*! \brief Process dependencies against the input dependencies file */
-int process_deps(void)
+static int process_deps(void)
 {
 	struct category *cat;
 	struct member *mem;
@@ -297,7 +279,7 @@
 		strsep(&p, "=");
 		if (!p)
 			continue;
-		if (!(dep_file = my_calloc(1, sizeof(*dep_file))))
+		if (!(dep_file = calloc(1, sizeof(*dep_file))))
 			break;
 		strncpy(dep_file->name, buf, sizeof(dep_file->name) - 1);
 		dep_file->met = atoi(p);
@@ -321,20 +303,6 @@
 				if (mem->depsfailed)
 					break; /* This dependency is not met, so we can stop now */
 			}
-			if (mem->depsfailed) {
-				if (check_deps && existing_config && mem->enabled) {
-					/* Config already existed, but this module was not disabled.
-					 * However, according to our current list of dependencies that
-					 * have been met, this can not be built. */
-					res = -1;
-					fprintf(stderr, "\nThe existing menuselect.makeopts did not specify that %s should not be built\n", mem->name);
-					fprintf(stderr, "However, menuselect-deps indicates that dependencies for this module have not\n");
-					fprintf(stderr, "been met.  So, either remove the existing menuselect.makeopts file, or run\n");
-					fprintf(stderr, "'make menuselect' to generate a file that is correct.\n\n");
-					goto deps_file_free;
-				}
-				mem->enabled = 0; /* Automatically disable it if dependencies not met */
-			}
 		}
 	}
 
@@ -353,24 +321,8 @@
 				if (mem->conflictsfailed)
 					break; /* This conflict was found, so we can stop now */
 			}
-			if (mem->conflictsfailed) {
-				if (check_deps && existing_config && mem->enabled) {
-					/* Config already existed, but this module was not disabled.
-					 * However, according to our current list of conflicts that
-					 * exist, this can not be built. */
-					res = -1;
-					fprintf(stderr, "\nThe existing menuselect.makeopts did not specify that %s should not be built\n", mem->name);
-					fprintf(stderr, "However, menuselect-deps indicates that conflicts for this module exist.\n");
-					fprintf(stderr, "So, either remove the existing menuselect.makeopts file, or run\n");
-					fprintf(stderr, "'make menuselect' to generate a file that is correct.\n\n");
-					goto deps_file_free;
-				}
-				mem->enabled = 0; /* Automatically disable it if conflicts exist */
-			}
-		}
-	}
-
-deps_file_free:
+		}
+	}
 
 	/* Free the dependency list we built from the file */
 	while ((dep_file = AST_LIST_REMOVE_HEAD(&deps_file, list)))
@@ -380,7 +332,7 @@
 }
 
 /*! \brief Iterate through all of the input makeopts files and call the parse function on them */
-int build_member_list(void)
+static int build_member_list(void)
 {
 	int i;
 	int res = -1;
@@ -396,7 +348,7 @@
 }
 
 /*! \brief Given the string representation of a member and category, mark it as present in a given input file */
-void mark_as_present(const char *member, const char *category)
+static void mark_as_present(const char *member, const char *category)
 {
 	struct category *cat;
 	struct member *mem;
@@ -437,8 +389,45 @@
 	}
 }
 
+/*! \brief Process a previously failed dependency
+ *
+ * If a module was previously disabled because of a failed dependency
+ * or a conflict, and not because the user selected it to be that way,
+ * then it needs to be re-enabled by default if the problem is no longer present.
+ */
+static void process_prev_failed_deps(char *buf)
+{
+	const char *cat_name, *mem_name;
+	struct category *cat;
+	struct member *mem;
+
+	cat_name = strsep(&buf, "=");
+	mem_name = strsep(&buf, "\n");
+
+	if (!cat_name || !mem_name)
+		return;
+
+	AST_LIST_TRAVERSE(&categories, cat, list) {
+		if (strcasecmp(cat->name, cat_name))
+			continue;
+		AST_LIST_TRAVERSE(&cat->members, mem, list) {
+			if (strcasecmp(mem->name, mem_name))
+				continue;
+
+			if (!mem->depsfailed && !mem->conflictsfailed)
+				mem->enabled = 1;			
+	
+			break;
+		}
+		break;	
+	}
+
+	if (!cat || !mem)
+		fprintf(stderr, "Unable to find '%s' in category '%s'\n", mem_name, cat_name);
+}
+
 /*! \brief Parse an existing output makeopts file and enable members previously selected */
-int parse_existing_config(const char *infile)
+static int parse_existing_config(const char *infile)
 {
 	FILE *f;
 	char buf[2048];
@@ -474,13 +463,18 @@
 			fprintf(stderr, "Invalid string in '%s' at line '%d'!\n", output_makeopts, lineno);
 			continue;
 		}
-
+		
 		parse = skip_blanks(parse);
+	
+		if (!strcasecmp(category, "MENUSELECT_DEPSFAILED")) {
+			process_prev_failed_deps(parse);
+			continue;
+		}
+	
 		while ((member = strsep(&parse, " \n"))) {
 			member = skip_blanks(member);
 			if (strlen_zero(member))
 				continue;
-
 			mark_as_present(member, category);
 		}
 	}
@@ -491,7 +485,7 @@
 }
 
 /*! \brief Create the output makeopts file that results from the user's selections */
-int generate_makeopts_file(void)
+static int generate_makeopts_file(void)
 {
 	FILE *f;
 	struct category *cat;
@@ -513,6 +507,14 @@
 		fprintf(f, "\n");
 	}
 
+	/* Output which members were disabled because of failed dependencies or conflicts */
+	AST_LIST_TRAVERSE(&categories, cat, list) {
+		AST_LIST_TRAVERSE(&cat->members, mem, list) {
+			if (mem->depsfailed || mem->conflictsfailed)
+				fprintf(f, "MENUSELECT_DEPSFAILED=%s=%s\n", cat->name, mem->name);
+		}
+	}
+
 	fclose(f);
 
 	return 0;
@@ -520,7 +522,7 @@
 
 #ifdef MENUSELECT_DEBUG

[... 4475 lines stripped ...]


More information about the svn-commits mailing list