[Asterisk-cvs] asterisk file.c,1.70,1.71 pbx.c,1.258,1.259

kpfleming at lists.digium.com kpfleming at lists.digium.com
Mon Jul 11 21:25:51 CDT 2005


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

Modified Files:
	file.c pbx.c 
Log Message:
add 'exit context' and 'only stop on match' options to Background app (bug #4511)


Index: file.c
===================================================================
RCS file: /usr/cvsroot/asterisk/file.c,v
retrieving revision 1.70
retrieving revision 1.71
diff -u -d -r1.70 -r1.71
--- file.c	5 Jul 2005 14:37:24 -0000	1.70
+++ file.c	12 Jul 2005 01:34:05 -0000	1.71
@@ -37,6 +37,7 @@
 #include "asterisk/utils.h"
 #include "asterisk/lock.h"
 #include "asterisk/app.h"
+#include "asterisk/pbx.h"
 
 struct ast_format {
 	/* Name of format */
@@ -1140,6 +1141,67 @@
 	return (c->_softhangup ? -1 : 0);
 }
 
+int ast_waitstream_exten(struct ast_channel *c, const char *context)
+{
+	/* Waitstream, with return in the case of a valid 1 digit extension */
+	/* in the current or specified context being pressed */
+	/* XXX Maybe I should just front-end ast_waitstream_full ? XXX */
+	int res;
+	struct ast_frame *fr;
+	char exten[AST_MAX_EXTENSION] = "";
+
+	if (!context) context = c->context;
+	while(c->stream) {
+		res = ast_sched_wait(c->sched);
+		if ((res < 0) && !c->timingfunc) {
+			ast_stopstream(c);
+			break;
+		}
+		if (res < 0)
+			res = 1000;
+		res = ast_waitfor(c, res);
+		if (res < 0) {
+			ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno));
+			return res;
+		} else if (res > 0) {
+			fr = ast_read(c);
+			if (!fr) {
+#if 0
+				ast_log(LOG_DEBUG, "Got hung up\n");
+#endif
+				return -1;
+			}
+			
+			switch(fr->frametype) {
+			case AST_FRAME_DTMF:
+				res = fr->subclass;
+				snprintf(exten, sizeof(exten), "%c", res);
+				if (ast_exists_extension(c, context, exten, 1, c->cid.cid_num)) {
+					ast_frfree(fr);
+					return res;
+				}
+				break;
+			case AST_FRAME_CONTROL:
+				switch(fr->subclass) {
+				case AST_CONTROL_HANGUP:
+					ast_frfree(fr);
+					return -1;
+				case AST_CONTROL_RINGING:
+				case AST_CONTROL_ANSWER:
+					/* Unimportant */
+					break;
+				default:
+					ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass);
+				}
+			}
+			/* Ignore */
+			ast_frfree(fr);
+		}
+		ast_sched_runq(c->sched);
+	}
+	return (c->_softhangup ? -1 : 0);
+}
+
 static int show_file_formats(int fd, int argc, char *argv[])
 {
 #define FORMAT "%-10s %-10s %-20s\n"

Index: pbx.c
===================================================================
RCS file: /usr/cvsroot/asterisk/pbx.c,v
retrieving revision 1.258
retrieving revision 1.259
diff -u -d -r1.258 -r1.259
--- pbx.c	10 Jul 2005 23:49:57 -0000	1.258
+++ pbx.c	12 Jul 2005 01:34:05 -0000	1.259
@@ -72,10 +72,14 @@
 
 #define BACKGROUND_SKIP		(1 << 0)
 #define BACKGROUND_NOANSWER	(1 << 1)
+#define BACKGROUND_MATCHEXTEN	(1 << 2)
+#define BACKGROUND_PLAYBACK	(1 << 3)
 
 AST_DECLARE_OPTIONS(background_opts,{
 	['s'] = { BACKGROUND_SKIP },
 	['n'] = { BACKGROUND_NOANSWER },
+	['m'] = { BACKGROUND_MATCHEXTEN },
+	['p'] = { BACKGROUND_PLAYBACK },
 });
 
 #define WAITEXTEN_MOH		(1 << 0)
@@ -243,19 +247,23 @@
 
 	{ "BackGround", pbx_builtin_background,
 	"Play a file while awaiting extension",
-	"  Background(filename1[&filename2...][|options[|langoverride]]): Plays\n"
-	"given files, while simultaneously waiting for the user to begin typing\n"
+	"  Background(filename1[&filename2...][|options[|langoverride][|context]]):\n"
+	"Plays given files, while simultaneously waiting for the user to begin typing\n"
 	"an extension. The timeouts do not count until the last BackGround\n"
 	"application has ended. Options may also be included following a pipe \n"
 	"symbol. The 'langoverride' may be a language to use for playing the prompt\n"
-	"which differs from the current language of the channel. Returns -1 if \n"
-	"the channel was hung up, or if the file does not exist. Returns 0 otherwise.\n\n"
+	"which differs from the current language of the channel.  The optional\n"
+	"'context' can be used to specify an optional context to exit into.\n"
+	"Returns -1 if thhe channel was hung up, or if the file does not exist./n"
+	"Returns 0 otherwise.\n\n"
 	"  Options:\n"
 	"    's' - causes the playback of the message to be skipped\n"
 	"          if the channel is not in the 'up' state (i.e. it\n"
 	"          hasn't been answered yet.) If this happens, the\n"
 	"          application will return immediately.\n"
 	"    'n' - don't answer the channel before playing the files\n"
+	"    'm' - only break if a digit hit matches a one digit\n"
+	"		 extension in the destination context\n"
 	},
 
 	{ "Busy", pbx_builtin_busy,
@@ -5440,11 +5448,12 @@
 	int res = 0;
 	int argc;
 	char *args;
-	char *argv[3];
+	char *argv[4];
 	char *options = NULL; 
 	char *filename = NULL;
 	char *front = NULL, *back = NULL;
 	char *lang = NULL;
+	char *context = NULL;
 	struct ast_flags flags = {0};
 
 	args = ast_strdupa(data);
@@ -5456,6 +5465,8 @@
 				options = argv[1];
 			if (argc > 2)
 				lang = argv[2];
+			if (argc > 3)
+				context = argv[3];
 		} else {
 			ast_log(LOG_WARNING, "Background requires an argument (filename)\n");
 		}
@@ -5464,6 +5475,9 @@
 	if (!lang)
 		lang = chan->language;
 
+	if (!context)
+		context = chan->context;
+
 	if (options) {
 		if (!strcasecmp(options, "skip"))
 			flags.flags = BACKGROUND_SKIP;
@@ -5494,7 +5508,15 @@
 			}
 			res = ast_streamfile(chan, front, lang);
 			if (!res) {
-				res = ast_waitstream(chan, AST_DIGIT_ANY);
+				if (ast_test_flag(&flags, BACKGROUND_PLAYBACK)) {
+					res = ast_waitstream(chan, "");
+				} else {
+					if (ast_test_flag(&flags, BACKGROUND_MATCHEXTEN)) {
+						res = ast_waitstream_exten(chan, context);
+					} else {
+						res = ast_waitstream(chan, AST_DIGIT_ANY);
+					}
+				}
 				ast_stopstream(chan);
 			} else {
 				ast_log(LOG_WARNING, "ast_streamfile failed on %s for %s\n", chan->name, (char*)data);
@@ -5504,7 +5526,14 @@
 			front = back;
 		}
 	}
-	return res;
+	if (context != chan->context && res) {
+		snprintf(chan->exten, sizeof(chan->exten), "%c", res);
+		ast_copy_string(chan->context, context, sizeof(chan->context));
+		chan->priority = 0;
+		return 0;
+	} else {
+		return res;
+	}
 }
 
 static int pbx_builtin_atimeout(struct ast_channel *chan, void *data)




More information about the svn-commits mailing list