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)

_______________________________________________
Asterisk-Cvs mailing list
[email protected]
http://lists.digium.com/mailman/listinfo/asterisk-cvs

Reply via email to