[Asterisk-cvs] asterisk/apps app_read.c,1.7,1.8 app_record.c,1.18,1.19

markster at lists.digium.com markster at lists.digium.com
Wed Jun 30 12:18:37 CDT 2004


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

Modified Files:
	app_read.c app_record.c 
Log Message:
Read/Record updates (bug #1947)


Index: app_read.c
===================================================================
RCS file: /usr/cvsroot/asterisk/apps/app_read.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- app_read.c	22 Jun 2004 19:32:52 -0000	1.7
+++ app_read.c	30 Jun 2004 16:04:28 -0000	1.8
@@ -31,13 +31,17 @@
 static char *synopsis = "Read a variable";
 
 static char *descrip = 
-"  Read(variable[|filename][|maxdigits]):  Reads a #-terminated string of digits from\n"
-"the user, optionally playing a given filename first.  Returns -1 on hangup or\n"
-"error and 0 otherwise.\n"
-"  maxdigits   -- maximum acceptable number of digits. Stops reading after maxdigits\n"
-"                 have been entered (without requiring the user press the '#' key).\n"
-"                 Defaults to 0 - no limit - wait for the user press the '#' key.\n"
-"                 Any value below 0 means the same. Max accepted value is 255.\n";	
+"  Read(variable[|filename][|maxdigits][|option])\n\n"
+"Reads a #-terminated string of digits from the user in to the given variable,\n"
+"optionally playing a given filename first.\n"
+"  maxdigits  -- maximum acceptable number of digits. Stops reading after\n"
+"                maxdigits have been entered (without requiring the user to\n"
+"                press the '#' key).\n"
+"                Defaults to 0 - no limit - wait for the user press the '#' key.\n"
+"                Any value below 0 means the same. Max accepted value is 255.\n"
+"  option     -- may be 'skip' to return immediately if the line is not up,\n"
+"                or 'noanswer' to read digits even if the line is not up.\n\n"
+"Returns -1 on hangup or error and 0 otherwise.\n";
 
 STANDARD_LOCAL_USER;
 
@@ -48,21 +52,29 @@
 	int res = 0;
 	struct localuser *u;
 	char tmp[256];
+	char argdata[256] = "";
 	char *varname;
 	char *filename;
 	char *stringp;
 	char *maxdigitstr;
+	char *options;
+	int option_skip = 0;
+	int option_noanswer = 0;
 	int maxdigits=255;
 	if (!data || ast_strlen_zero((char *)data)) {
 		ast_log(LOG_WARNING, "Read requires an argument (variable)\n");
 		return -1;
 	}
-	strncpy(tmp, (char *)data, sizeof(tmp)-1);
-	stringp=(char *)calloc(1,strlen(tmp)+1);
-	snprintf(stringp,strlen(tmp)+1,"%s",tmp);
+	strncpy(argdata, (char *)data, sizeof(argdata)-1);
+	stringp=argdata;
 	varname = strsep(&stringp, "|");
 	filename = strsep(&stringp, "|");
 	maxdigitstr = strsep(&stringp,"|");
+	options = strsep(&stringp, "|");
+	if (options && !strcasecmp(options, "skip"))
+		option_skip = 1;
+	if (options && !strcasecmp(options, "noanswer"))
+		option_noanswer = 1;
 	if (!(filename) || ast_strlen_zero(filename)) 
 		filename = NULL;
 	if (maxdigitstr) {
@@ -78,10 +90,16 @@
 	}
 	LOCAL_USER_ADD(u);
 	if (chan->_state != AST_STATE_UP) {
-		/* Answer if the line isn't up. */
-		res = ast_answer(chan);
+		if (option_skip) {
+			/* At the user's option, skip if the line is not up */
+			pbx_builtin_setvar_helper(chan, varname, "\0");
+			LOCAL_USER_REMOVE(u);
+			return 0;
+		} else if (!option_noanswer) {
+			/* Otherwise answer unless we're supposed to read while on-hook */
+			res = ast_answer(chan);
+		}
 	}
-	strncpy(tmp, (char *)varname, sizeof(tmp)-1);
 	if (!res) {
 		ast_stopstream(chan);
 		res = ast_app_getdata(chan, filename, tmp, maxdigits, 0);

Index: app_record.c
===================================================================
RCS file: /usr/cvsroot/asterisk/apps/app_record.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- app_record.c	22 Jun 2004 19:32:52 -0000	1.18
+++ app_record.c	30 Jun 2004 16:04:28 -0000	1.19
@@ -29,10 +29,15 @@
 static char *synopsis = "Record to a file";
 
 static char *descrip = 
-"  Record(filename:format|silence): Records from the channel into a given\n"
-"filename. If the file exists it will be overwritten. \n"
+"  Record(filename:format|silence[|maxduration][|option])\n\n"
+"Records from the channel into a given filename. If the file exists it will\n"
+"be overwritten.\n"
 "- 'format' is the format of the file type to be recorded (wav, gsm, etc).\n"
-"- 'silence' is the number of seconds of silence to allow before returning.\n\n"
+"- 'silence' is the number of seconds of silence to allow before returning.\n"
+"- 'maxduration' is the maximum recording duration in seconds. If missing\n"
+"or 0 there is no maximum.\n"
+"- 'option' may be 'skip' to return immediately if the line is not up,\n"
+"or 'noanswer' to attempt to record even if the line is not up.\n\n"
 "If filename contains '%d', these characters will be replaced with a number\n"
 "incremented by one each time the file is recorded. \n\n"
 "Formats: g723, g729, gsm, h263, ulaw, alaw, vox, wav, WAV\n\n"
@@ -65,7 +70,13 @@
 	int silence = 0;		/* amount of silence to allow */
 	int gotsilence = 0;		/* did we timeout for silence? */
 	char silencestr[5];
-	int k = 0;
+	char durationstr[8];
+	int maxduration = 0;		/* max duration of recording */
+	int gottimeout = 0;		/* did we timeout for maxduration exceeded? */
+	time_t timeout = 0;
+	char option[16];
+	int option_skip = 0;
+	int option_noanswer = 0;
 	int rfmt = 0;
 
 	vdata = data; /* explained above */
@@ -80,50 +91,90 @@
 		if ((vdata[i] == '%') && (vdata[i+1] == 'd')) {
 			percentflag = 1;                      /* the wildcard is used */
 		}
-		
-		if (i == strlen(vdata) ) {
-			ast_log(LOG_WARNING, "No extension found\n");
-			return -1;
-		}
-		fil[i] = vdata[i];
+		if (j < sizeof(fil) - 1)
+			fil[j++] = vdata[i];
 	}
-	fil[i++] = '\0';
+	fil[j] = '\0';
 
-	for (; j < 10 && i < strlen(data) && (vdata[i] != '|'); i++, j++)
-		ext[j] = vdata[i];
+	if (vdata[i] != ':') {
+		ast_log(LOG_WARNING, "No extension found\n");
+		return -1;
+	}
+	i++;
+
+	j = 0;
+	for (; vdata[i] && (vdata[i] != '|'); i++)
+		if (j < sizeof(ext) - 1)
+			ext[j++] = vdata[i];
 	ext[j] = '\0';
 
-	if (vdata[i] && (vdata[i] == '|')) i++;
-	for (; vdata[i] && (vdata[i] != '|') && (k < 3) && i < strlen(data); i++, k++)
-		silencestr[k] = vdata[i];
-	silencestr[k] = '\0';
+	if (vdata[i] == '|')
+		i++;
 
-	if (silencestr) {
+	j = 0;
+	for (; vdata[i] && (vdata[i] != '|'); i++)
+		if (j < sizeof(silencestr) - 1)
+			silencestr[j++] = vdata[i];
+	silencestr[j] = '\0';
+
+	if (j > 0) {
 		silence = atoi(silencestr);
 		if (silence > 0)
 			silence *= 1000;
 	}
 
+	if (vdata[i] == '|')
+		i++;
+
+	j = 0;
+	for (; vdata[i] && (vdata[i] != '|'); i++)
+		if (j < sizeof(durationstr) - 1)
+			durationstr[j++] = vdata[i];
+	durationstr[j] = '\0';
+
+	if (j > 0)
+		maxduration = atoi(durationstr);
+
+	if (vdata[i] == '|')
+		i++;
+
+	j = 0;
+	for (; vdata[i] && (vdata[i] != '|'); i++)
+		if (j < sizeof(option) - 1)
+			option[j++] = vdata[i];
+	option[j] = '\0';
+
+	if (!strcasecmp(option, "skip"))
+		option_skip = 1;
+	if (!strcasecmp(option, "noanswer"))
+		option_noanswer = 1;
+
 	/* done parsing */
-	
+
 	
 	/* these are to allow the use of the %d in the config file for a wild card of sort to
 	  create a new file with the inputed name scheme */
 	if (percentflag) {
 		do {
-			snprintf(tmp, 256, fil, count);
+			snprintf(tmp, sizeof(tmp)-1, fil, count);
 			count++;
 		} while ( ast_fileexists(tmp, ext, chan->language) != -1 );
 		pbx_builtin_setvar_helper(chan, "RECORDED_FILE", tmp);
 	} else
-		strncpy(tmp, fil, 256-1);
+		strncpy(tmp, fil, sizeof(tmp)-1);
 	/* end of routine mentioned */
 
 	LOCAL_USER_ADD(u);
 
 	if (chan->_state != AST_STATE_UP) {
-		res = ast_answer(chan); /* Shouldn't need this, but checking to see if channel is already answered
-					 * Theoretically asterisk should already have answered before running the app */
+		if (option_skip) {
+			/* At the user's option, skip if the line is not up */
+			LOCAL_USER_REMOVE(u);
+			return 0;
+		} else if (!option_noanswer) {
+			/* Otherwise answer unless we're supposed to record while on-hook */
+			res = ast_answer(chan);
+		}
 	}
 	
 	if (!res) {
@@ -157,7 +208,15 @@
 		s = ast_writefile( tmp, ext, NULL, O_CREAT|O_TRUNC|O_WRONLY , 0, 0644);
 	
 		if (s) {
+			if (maxduration > 0)
+				timeout = time(NULL) + (time_t)maxduration;
+
 			while (ast_waitfor(chan, -1) > -1) {
+				if (maxduration > 0 && time(NULL) > timeout) {
+					gottimeout = 1;
+					break;
+				}
+
 				f = ast_read(chan);
 				if (!f) {
 					res = -1;
@@ -210,7 +269,7 @@
 			if (gotsilence) {
 				ast_stream_rewind(s, silence-1000);
 				ast_truncstream(s);
-			} else {
+			} else if (!gottimeout) {
 				/* Strip off the last 1/4 second of it */
 				ast_stream_rewind(s, 250);
 				ast_truncstream(s);




More information about the svn-commits mailing list