[Asterisk-cvs] asterisk/apps app_meetme.c,1.124,1.125

kpfleming kpfleming
Tue Nov 8 18:28:31 CST 2005


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

Modified Files:
	app_meetme.c 
Log Message:
issues #3599 and #4252


Index: app_meetme.c
===================================================================
RCS file: /usr/cvsroot/asterisk/apps/app_meetme.c,v
retrieving revision 1.124
retrieving revision 1.125
diff -u -d -r1.124 -r1.125
--- app_meetme.c	8 Nov 2005 21:32:51 -0000	1.124
+++ app_meetme.c	8 Nov 2005 23:19:30 -0000	1.125
@@ -55,17 +55,17 @@
 #include "asterisk/say.h"
 #include "asterisk/utils.h"
 
-static char *tdesc = "MeetMe conference bridge";
+static const char *tdesc = "MeetMe conference bridge";
 
-static char *app = "MeetMe";
-static char *app2 = "MeetMeCount";
-static char *app3 = "MeetMeAdmin";
+static const char *app = "MeetMe";
+static const char *app2 = "MeetMeCount";
+static const char *app3 = "MeetMeAdmin";
 
-static char *synopsis = "MeetMe conference bridge";
-static char *synopsis2 = "MeetMe participant count";
-static char *synopsis3 = "MeetMe conference Administration";
+static const char *synopsis = "MeetMe conference bridge";
+static const char *synopsis2 = "MeetMe participant count";
+static const char *synopsis3 = "MeetMe conference Administration";
 
-static char *descrip =
+static const char *descrip =
 "  MeetMe([confno][,[options][,pin]]): Enters the user into a specified MeetMe conference.\n"
 "If the conference number is omitted, the user will be prompted to enter\n"
 "one. \n"
@@ -102,14 +102,14 @@
 "             digit extension ${MEETME_EXIT_CONTEXT} or the current context\n"
 "             if that variable is not defined.\n";
 
-static char *descrip2 =
+static const char *descrip2 =
 "  MeetMeCount(confno[|var]): Plays back the number of users in the specified\n"
 "MeetMe conference. If var is specified, playback will be skipped and the value\n"
 "will be returned in the variable. Upon app completion, MeetMeCount will hangup the\n"
 "channel, unless priority n+1 exists, in which case priority progress will continue.\n"
 "A ZAPTEL INTERFACE MUST BE INSTALLED FOR CONFERENCING FUNCTIONALITY.\n";
 
-static char *descrip3 = 
+static const char *descrip3 = 
 "  MeetMeAdmin(confno,command[,user]): Run admin command for conference\n"
 "      'e' -- Eject last user that joined\n"
 "      'k' -- Kick one user out of conference\n"
@@ -122,6 +122,8 @@
 "      'N' -- Mute entire conference (except admin)\n"
 "";
 
+#define CONFIG_FILE_NAME "meetme.conf"
+
 STANDARD_LOCAL_USER;
 
 LOCAL_USER_DECL;
@@ -169,8 +171,14 @@
 	struct volume listen;
 };
 
-#define ADMINFLAG_MUTED (1 << 1)	/* User is muted */
-#define ADMINFLAG_KICKME (1 << 2)	/* User is kicked */
+static int audio_buffers;			/* The number of audio buffers to be allocated on pseudo channels
+						   when in a conference
+						*/
+
+#define DEFAULT_AUDIO_BUFFERS 32		/* each buffer is 20ms, so this is 640ms total */
+
+#define ADMINFLAG_MUTED (1 << 1)		/* User is muted */
+#define ADMINFLAG_KICKME (1 << 2)		/* User is kicked */
 #define MEETME_DELAYDETECTTALK 		300
 #define MEETME_DELAYDETECTENDTALK 	1000
 
@@ -706,16 +714,34 @@
 "       Executes a command for the conference or on a conferee\n";
 
 static struct ast_cli_entry cli_conf = {
-	{ "meetme", NULL, NULL }, conf_cmd,
-	"Execute a command on a conference or conferee", conf_usage, complete_confcmd };
+	{"meetme", NULL, NULL }, conf_cmd,
+	"Execute a command on a conference or conferee", conf_usage, complete_confcmd};
 
-static void conf_flush(int fd)
+static void conf_flush(int fd, struct ast_channel *chan)
 {
 	int x;
 
+	/* read any frames that may be waiting on the channel
+	   and throw them away
+	*/
+	if (chan) {
+		struct ast_frame *f;
+
+		/* when no frames are available, this will wait
+		   for 1 millisecond maximum
+		*/
+		while (ast_waitfor(chan, 1)) {
+			f = ast_read(chan);
+			if (f)
+				ast_frfree(f);
+		}
+	}
+
+	/* flush any data sitting in the pseudo channel */
 	x = ZT_FLUSH_ALL;
 	if (ioctl(fd, ZT_FLUSH, &x))
 		ast_log(LOG_WARNING, "Error flushing channel\n");
+
 }
 
 /* Remove the conference from the list and free it.
@@ -960,7 +986,7 @@
 		bi.bufsize = CONF_SIZE/2;
 		bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
 		bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
-		bi.numbufs = 4;
+		bi.numbufs = audio_buffers;
 		if (ioctl(fd, ZT_SET_BUFINFO, &bi)) {
 			ast_log(LOG_WARNING, "Unable to set buffering information: %s\n", strerror(errno));
 			close(fd);
@@ -1042,7 +1068,7 @@
 
 	ast_mutex_unlock(&conflock);
 
-	conf_flush(fd);
+	conf_flush(fd, chan);
 
 	if (confflags & CONFFLAG_AGI) {
 		/* Get name of AGI file to run from $(MEETME_AGI_BACKGROUND)
@@ -1273,8 +1299,15 @@
 						}
 					}
 					if (using_pseudo) {
-						/* Carefully write */
-						careful_write(fd, f->data, f->datalen);
+						/* Absolutely do _not_ use careful_write here...
+						   it is important that we read data from the channel
+						   as fast as it arrives, and feed it into the conference.
+						   The buffering in the pseudo channel will take care of any
+						   timing differences, unless they are so drastic as to lose
+						   audio frames (in which case carefully writing would only
+						   have delayed the audio even further).
+						*/
+						write(fd, f->data, f->datalen);
 					}
 				} else if ((f->frametype == AST_FRAME_DTMF) && (confflags & CONFFLAG_EXIT_CONTEXT)) {
 					char tmp[2];
@@ -1451,7 +1484,8 @@
 						ast_mutex_unlock(&conflock);
 						goto outrun;
 					}
-					conf_flush(fd);
+
+					conf_flush(fd, chan);
 				} else if (option_debug) {
 					ast_log(LOG_DEBUG,
 						"Got unrecognized frame on channel %s, f->frametype=%d,f->subclass=%d\n",
@@ -1597,9 +1631,9 @@
 			}
 		} else {
 			/* Check the config */
-			cfg = ast_config_load("meetme.conf");
+			cfg = ast_config_load(CONFIG_FILE_NAME);
 			if (!cfg) {
-				ast_log(LOG_WARNING, "No meetme.conf file :(\n");
+				ast_log(LOG_WARNING, "No %s file :(\n", CONFIG_FILE_NAME);
 				return NULL;
 			}
 			var = ast_variable_browse(cfg, "rooms");
@@ -1748,28 +1782,24 @@
 		if (retrycnt > 3)
 			allowretry = 0;
 		if (empty) {
-			int i, map[1024];
+			int i, map[1024] = { 0, };
 			struct ast_config *cfg;
 			struct ast_variable *var;
 			int confno_int;
 
-			memset(map, 0, sizeof(map));
-
 			ast_mutex_lock(&conflock);
-			cnf = confs;
-			while (cnf) {
+			for (cnf = confs; cnf; cnf = cnf->next) {
 				if (sscanf(cnf->confno, "%d", &confno_int) == 1) {
 					/* Disqualify in use conference */
 					if (confno_int >= 0 && confno_int < 1024)
 						map[confno_int]++;
 				}
-				cnf = cnf->next;
 			}
 			ast_mutex_unlock(&conflock);
 
 			/* We only need to load the config file for static and empty_no_pin (otherwise we don't care) */
 			if ((empty_no_pin) || (!dynamic)) {
-				cfg = ast_config_load("meetme.conf");
+				cfg = ast_config_load(CONFIG_FILE_NAME);
 				if (cfg) {
 					var = ast_variable_browse(cfg, "rooms");
 					while (var) {
@@ -1820,9 +1850,10 @@
 					ast_config_destroy(cfg);
 				}
 			}
+
 			/* Select first conference number not in use */
 			if (ast_strlen_zero(confno) && dynamic) {
-				for (i=0;i<1024;i++) {
+				for (i = 0; i < sizeof(map) / sizeof(map[0]); i++) {
 					if (!map[i]) {
 						snprintf(confno, sizeof(confno), "%d", i);
 						break;
@@ -1847,6 +1878,7 @@
 				}
 			}
 		}
+
 		while (allowretry && (ast_strlen_zero(confno)) && (++retrycnt < 4)) {
 			/* Prompt user for conference number */
 			res = ast_app_getdata(chan, "conf-getconfno", confno, sizeof(confno) - 1, 0);
@@ -2116,6 +2148,32 @@
 	pthread_exit(0);
 }
 
+static void load_config(void)
+{
+	struct ast_config *cfg;
+	char *val;
+
+	audio_buffers = DEFAULT_AUDIO_BUFFERS;
+
+	if (!(cfg = ast_config_load(CONFIG_FILE_NAME)))
+		return;
+
+	if ((val = ast_variable_retrieve(cfg, "general", "audiobuffers"))) {
+		if ((sscanf(val, "%d", &audio_buffers) != 1)) {
+			ast_log(LOG_WARNING, "audiobuffers setting must be a number, not '%s'\n", val);
+			audio_buffers = DEFAULT_AUDIO_BUFFERS;
+		} else if ((audio_buffers < ZT_DEFAULT_NUM_BUFS) || (audio_buffers > ZT_MAX_NUM_BUFS)) {
+			ast_log(LOG_WARNING, "audiobuffers setting must be between %d and %d\n",
+				ZT_DEFAULT_NUM_BUFS, ZT_MAX_NUM_BUFS);
+			audio_buffers = DEFAULT_AUDIO_BUFFERS;
+		}
+		if (audio_buffers != DEFAULT_AUDIO_BUFFERS)
+			ast_log(LOG_NOTICE, "Audio buffers per channel set to %d\n", audio_buffers);
+	}
+
+	ast_config_destroy(cfg);
+}
+
 int unload_module(void)
 {
 	int res;
@@ -2135,6 +2193,8 @@
 {
 	int res;
 
+	load_config();
+
 	res = ast_cli_register(&cli_show_confs);
 	res |= ast_cli_register(&cli_conf);
 	res |= ast_register_application(app3, admin_exec, synopsis3, descrip3);
@@ -2144,9 +2204,16 @@
 	return res;
 }
 
+int reload(void)
+{
+	load_config();
+
+	return 0;
+}
+
 char *description(void)
 {
-	return tdesc;
+	return (char *) tdesc;
 }
 
 int usecount(void)




More information about the svn-commits mailing list