app_meetme: Use new prompts for administrator menu
authorJonathan Rose <jrose@digium.com>
Tue, 22 Jan 2013 19:29:50 +0000 (19:29 +0000)
committerJonathan Rose <jrose@digium.com>
Tue, 22 Jan 2013 19:29:50 +0000 (19:29 +0000)
The old prompts for the administrator menu were inadequate. They didn't mention
that the menu had additional options through the 8 key and pressing the 8 key
wouldn't reveal what those options were. This patch fixes all of that while
also organizing code pertaining to each individual menu type which was
previously all stored in one gigantic function along with many of the basic
conference functions.

(closes issue AST-996)
Reported by: John Bigelow
Review: http://reviewboard.digium.internal/r/360/
........

Merged revisions 379885 from http://svn.asterisk.org/svn/asterisk/branches/1.8
........

Merged revisions 379892 from http://svn.asterisk.org/svn/asterisk/branches/11

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@379912 65c4cc65-6c06-0410-ace0-fbb531ad65f3

apps/app_meetme.c
sounds/Makefile

index e63a4b3..9fb0e06 100644 (file)
@@ -2375,6 +2375,428 @@ static int user_set_muted_cb(void *obj, void *check_admin_arg, int flags)
        return 0;
 }
 
+enum menu_modes {
+       MENU_DISABLED = 0,
+       MENU_NORMAL,
+       MENU_ADMIN,
+       MENU_ADMIN_EXTENDED,
+};
+
+/*! \internal
+ * \brief Processes menu options for the standard menu (accessible through the 's' option for app_meetme)
+ *
+ * \param menu_mode a pointer to the currently active menu_mode.
+ * \param dtmf a pointer to the dtmf value currently being processed against the menu.
+ * \param conf the active conference for which the user has called the menu from.
+ * \param confflags flags used by conf for various options
+ * \param chan ast_channel belonging to the user who called the menu
+ * \param user which meetme conference user invoked the menu
+ */
+static void meetme_menu_normal(enum menu_modes *menu_mode, int *dtmf, struct ast_conference *conf, struct ast_flags64 *confflags, struct ast_channel *chan, struct ast_conf_user *user)
+{
+       switch (*dtmf) {
+       case '1': /* Un/Mute */
+               *menu_mode = MENU_DISABLED;
+
+               /* user can only toggle the self-muted state */
+               user->adminflags ^= ADMINFLAG_SELFMUTED;
+
+               /* they can't override the admin mute state */
+               if (ast_test_flag64(confflags, CONFFLAG_MONITOR) || (user->adminflags & (ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED))) {
+                       if (!ast_streamfile(chan, "conf-muted", ast_channel_language(chan))) {
+                               ast_waitstream(chan, "");
+                       }
+               } else {
+                       if (!ast_streamfile(chan, "conf-unmuted", ast_channel_language(chan))) {
+                               ast_waitstream(chan, "");
+                       }
+               }
+               break;
+
+       case '2':
+               *menu_mode = MENU_DISABLED;
+               if (user->adminflags & (ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED)) {
+                       user->adminflags |= ADMINFLAG_T_REQUEST;
+               }
+
+               if (user->adminflags & ADMINFLAG_T_REQUEST) {
+                       if (!ast_streamfile(chan, "beep", ast_channel_language(chan))) {
+                               ast_waitstream(chan, "");
+                       }
+               }
+               break;
+
+       case '4':
+               tweak_listen_volume(user, VOL_DOWN);
+               break;
+       case '5':
+               /* Extend RT conference */
+               if (rt_schedule) {
+                       rt_extend_conf(conf->confno);
+               }
+               *menu_mode = MENU_DISABLED;
+               break;
+
+       case '6':
+               tweak_listen_volume(user, VOL_UP);
+               break;
+
+       case '7':
+               tweak_talk_volume(user, VOL_DOWN);
+               break;
+
+       case '8':
+               *menu_mode = MENU_DISABLED;
+               break;
+
+       case '9':
+               tweak_talk_volume(user, VOL_UP);
+               break;
+
+       default:
+               *menu_mode = MENU_DISABLED;
+               if (!ast_streamfile(chan, "conf-errormenu", ast_channel_language(chan))) {
+                       ast_waitstream(chan, "");
+               }
+               break;
+       }
+}
+
+/*! \internal
+ * \brief Processes menu options for the adminstrator menu (accessible through the 's' option for app_meetme)
+ *
+ * \param menu_mode a pointer to the currently active menu_mode.
+ * \param dtmf a pointer to the dtmf value currently being processed against the menu.
+ * \param conf the active conference for which the user has called the menu from.
+ * \param confflags flags used by conf for various options
+ * \param chan ast_channel belonging to the user who called the menu
+ * \param user which meetme conference user invoked the menu
+ */
+static void meetme_menu_admin(enum menu_modes *menu_mode, int *dtmf, struct ast_conference *conf, struct ast_flags64 *confflags, struct ast_channel *chan, struct ast_conf_user *user)
+{
+       switch(*dtmf) {
+       case '1': /* Un/Mute */
+               *menu_mode = MENU_DISABLED;
+               /* for admin, change both admin and use flags */
+               if (user->adminflags & (ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED)) {
+                       user->adminflags &= ~(ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED);
+               } else {
+                       user->adminflags |= (ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED);
+               }
+
+               if (ast_test_flag64(confflags, CONFFLAG_MONITOR) || (user->adminflags & (ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED))) {
+                       if (!ast_streamfile(chan, "conf-muted", ast_channel_language(chan))) {
+                               ast_waitstream(chan, "");
+                       }
+               } else {
+                       if (!ast_streamfile(chan, "conf-unmuted", ast_channel_language(chan))) {
+                               ast_waitstream(chan, "");
+                       }
+               }
+               break;
+
+       case '2': /* Un/Lock the Conference */
+               *menu_mode = MENU_DISABLED;
+               if (conf->locked) {
+                       conf->locked = 0;
+                       if (!ast_streamfile(chan, "conf-unlockednow", ast_channel_language(chan))) {
+                               ast_waitstream(chan, "");
+                       }
+               } else {
+                       conf->locked = 1;
+                       if (!ast_streamfile(chan, "conf-lockednow", ast_channel_language(chan))) {
+                               ast_waitstream(chan, "");
+                       }
+               }
+               break;
+
+       case '3': /* Eject last user */
+       {
+               struct ast_conf_user *usr = NULL;
+               int max_no = 0;
+               ao2_callback(conf->usercontainer, OBJ_NODATA, user_max_cmp, &max_no);
+               *menu_mode = MENU_DISABLED;
+               usr = ao2_find(conf->usercontainer, &max_no, 0);
+               if ((ast_channel_name(usr->chan) == ast_channel_name(chan)) || ast_test_flag64(&usr->userflags, CONFFLAG_ADMIN)) {
+                       if (!ast_streamfile(chan, "conf-errormenu", ast_channel_language(chan))) {
+                               ast_waitstream(chan, "");
+                       }
+               } else {
+                       usr->adminflags |= ADMINFLAG_KICKME;
+               }
+               ao2_ref(usr, -1);
+               ast_stopstream(chan);
+               break;
+       }
+
+       case '4':
+               tweak_listen_volume(user, VOL_DOWN);
+               break;
+
+       case '5':
+               /* Extend RT conference */
+               if (rt_schedule) {
+                       if (!rt_extend_conf(conf->confno)) {
+                               if (!ast_streamfile(chan, "conf-extended", ast_channel_language(chan))) {
+                                       ast_waitstream(chan, "");
+                               }
+                       } else {
+                               if (!ast_streamfile(chan, "conf-nonextended", ast_channel_language(chan))) {
+                                       ast_waitstream(chan, "");
+                               }
+                       }
+                       ast_stopstream(chan);
+               }
+               *menu_mode = MENU_DISABLED;
+               break;
+
+       case '6':
+               tweak_listen_volume(user, VOL_UP);
+               break;
+
+       case '7':
+               tweak_talk_volume(user, VOL_DOWN);
+               break;
+
+       case '8':
+               if (!ast_streamfile(chan, "conf-adminmenu-menu8", ast_channel_language(chan))) {
+                       /* If the user provides DTMF while playing the sound, we want to drop right into the extended menu function with new DTMF once we get out of here. */
+                       *dtmf = ast_waitstream(chan, AST_DIGIT_ANY);
+                       ast_stopstream(chan);
+               }
+               *menu_mode = MENU_ADMIN_EXTENDED;
+               break;
+
+       case '9':
+               tweak_talk_volume(user, VOL_UP);
+               break;
+       default:
+               menu_mode = MENU_DISABLED;
+               /* Play an error message! */
+               if (!ast_streamfile(chan, "conf-errormenu", ast_channel_language(chan))) {
+                       ast_waitstream(chan, "");
+               }
+               break;
+       }
+
+}
+
+/*! \internal
+ * \brief Processes menu options for the extended administrator menu (accessible through option 8 on the administrator menu)
+ *
+ * \param menu_mode a pointer to the currently active menu_mode.
+ * \param dtmf a pointer to the dtmf value currently being processed against the menu.
+ * \param conf the active conference for which the user has called the menu from.
+ * \param confflags flags used by conf for various options
+ * \param chan ast_channel belonging to the user who called the menu
+ * \param user which meetme conference user invoked the menu
+ * \param recordingtmp character buffer which may hold the name of the conference recording file
+ * \param dahdic dahdi configuration info used by the main conference loop
+ */
+static void meetme_menu_admin_extended(enum menu_modes *menu_mode, int *dtmf, struct ast_conference *conf, struct ast_flags64 *confflags, struct ast_channel *chan, struct ast_conf_user *user, char *recordingtmp, struct dahdi_confinfo *dahdic, struct ast_format_cap *cap_slin)
+{
+       int keepplaying;
+       int playednamerec;
+       int res;
+       struct ao2_iterator user_iter;
+       struct ast_conf_user *usr = NULL;
+
+       switch(*dtmf) {
+       case '1': /* *81 Roll call */
+               keepplaying = 1;
+               playednamerec = 0;
+               if (conf->users == 1) {
+                       if (keepplaying && !ast_streamfile(chan, "conf-onlyperson", ast_channel_language(chan))) {
+                               res = ast_waitstream(chan, AST_DIGIT_ANY);
+                               ast_stopstream(chan);
+                               if (res > 0) {
+                                       keepplaying = 0;
+                               }
+                       }
+               } else if (conf->users == 2) {
+                       if (keepplaying && !ast_streamfile(chan, "conf-onlyone", ast_channel_language(chan))) {
+                               res = ast_waitstream(chan, AST_DIGIT_ANY);
+                               ast_stopstream(chan);
+                               if (res > 0) {
+                                       keepplaying = 0;
+                               }
+                       }
+               } else {
+                       if (keepplaying && !ast_streamfile(chan, "conf-thereare", ast_channel_language(chan))) {
+                               res = ast_waitstream(chan, AST_DIGIT_ANY);
+                               ast_stopstream(chan);
+                               if (res > 0) {
+                                       keepplaying = 0;
+                               }
+                       }
+                       if (keepplaying) {
+                               res = ast_say_number(chan, conf->users - 1, AST_DIGIT_ANY, ast_channel_language(chan), (char *) NULL);
+                               ast_stopstream(chan);
+                               if (res > 0) {
+                                       keepplaying = 0;
+                               }
+                       }
+                       if (keepplaying && !ast_streamfile(chan, "conf-otherinparty", ast_channel_language(chan))) {
+                               res = ast_waitstream(chan, AST_DIGIT_ANY);
+                               ast_stopstream(chan);
+                               if (res > 0) {
+                                       keepplaying = 0;
+                               }
+                       }
+               }
+               user_iter = ao2_iterator_init(conf->usercontainer, 0);
+               while((usr = ao2_iterator_next(&user_iter))) {
+                       if (ast_fileexists(usr->namerecloc, NULL, NULL)) {
+                               if (keepplaying && !ast_streamfile(chan, usr->namerecloc, ast_channel_language(chan))) {
+                                       res = ast_waitstream(chan, AST_DIGIT_ANY);
+                                       ast_stopstream(chan);
+                                       if (res > 0) {
+                                               keepplaying = 0;
+                                       }
+                               }
+                               playednamerec = 1;
+                       }
+                       ao2_ref(usr, -1);
+               }
+               ao2_iterator_destroy(&user_iter);
+               if (keepplaying && playednamerec && !ast_streamfile(chan, "conf-roll-callcomplete", ast_channel_language(chan))) {
+                       res = ast_waitstream(chan, AST_DIGIT_ANY);
+                       ast_stopstream(chan);
+                       if (res > 0) {
+                               keepplaying = 0;
+                       }
+               }
+
+               *menu_mode = MENU_DISABLED;
+               break;
+
+       case '2': /* *82 Eject all non-admins */
+               if (conf->users == 1) {
+                       if(!ast_streamfile(chan, "conf-errormenu", ast_channel_language(chan))) {
+                               ast_waitstream(chan, "");
+                       }
+               } else {
+                       ao2_callback(conf->usercontainer, OBJ_NODATA, user_set_kickme_cb, &conf);
+               }
+               ast_stopstream(chan);
+               *menu_mode = MENU_DISABLED;
+               break;
+
+       case '3': /* *83 (Admin) mute/unmute all non-admins */
+               if(conf->gmuted) {
+                       conf->gmuted = 0;
+                       ao2_callback(conf->usercontainer, OBJ_NODATA, user_set_unmuted_cb, &conf);
+                       if (!ast_streamfile(chan, "conf-now-unmuted", ast_channel_language(chan))) {
+                               ast_waitstream(chan, "");
+                       }
+               } else {
+                       conf->gmuted = 1;
+                       ao2_callback(conf->usercontainer, OBJ_NODATA, user_set_muted_cb, &conf);
+                       if (!ast_streamfile(chan, "conf-now-muted", ast_channel_language(chan))) {
+                               ast_waitstream(chan, "");
+                       }
+               }
+               ast_stopstream(chan);
+               *menu_mode = MENU_DISABLED;
+               break;
+
+       case '4': /* *84 Record conference */
+               if (conf->recording != MEETME_RECORD_ACTIVE) {
+                       ast_set_flag64(confflags, CONFFLAG_RECORDCONF);
+                       if (!conf->recordingfilename) {
+                               const char *var;
+                               ast_channel_lock(chan);
+                               if ((var = pbx_builtin_getvar_helper(chan, "MEETME_RECORDINGFILE"))) {
+                                       conf->recordingfilename = ast_strdup(var);
+                               }
+                               if ((var = pbx_builtin_getvar_helper(chan, "MEETME_RECORDINGFORMAT"))) {
+                                       conf->recordingformat = ast_strdup(var);
+                               }
+                               ast_channel_unlock(chan);
+                               if (!conf->recordingfilename) {
+                                       snprintf(recordingtmp, sizeof(recordingtmp), "meetme-conf-rec-%s-%s", conf->confno, ast_channel_uniqueid(chan));
+                                       conf->recordingfilename = ast_strdup(recordingtmp);
+                               }
+                               if (!conf->recordingformat) {
+                                       conf->recordingformat = ast_strdup("wav");
+                               }
+                               ast_verb(4, "Starting recording of MeetMe Conference %s into file %s.%s.\n",
+                               conf->confno, conf->recordingfilename, conf->recordingformat);
+                       }
+
+                       ast_mutex_lock(&conf->recordthreadlock);
+                       if ((conf->recordthread == AST_PTHREADT_NULL) && ast_test_flag64(confflags, CONFFLAG_RECORDCONF) && ((conf->lchan = ast_request("DAHDI", cap_slin, chan, "pseudo", NULL)))) {
+                               ast_set_read_format_by_id(conf->lchan, AST_FORMAT_SLINEAR);
+                               ast_set_write_format_by_id(conf->lchan, AST_FORMAT_SLINEAR);
+                               dahdic->chan = 0;
+                               dahdic->confno = conf->dahdiconf;
+                               dahdic->confmode = DAHDI_CONF_CONFANN | DAHDI_CONF_CONFANNMON;
+                               if (ioctl(ast_channel_fd(conf->lchan, 0), DAHDI_SETCONF, dahdic)) {
+                                       ast_log(LOG_WARNING, "Error starting listen channel\n");
+                                       ast_hangup(conf->lchan);
+                                       conf->lchan = NULL;
+                               } else {
+                                       ast_pthread_create_detached_background(&conf->recordthread, NULL, recordthread, conf);
+                               }
+                       }
+                       ast_mutex_unlock(&conf->recordthreadlock);
+                       if (!ast_streamfile(chan, "conf-now-recording", ast_channel_language(chan))) {
+                               ast_waitstream(chan, "");
+                       }
+               }
+
+               ast_stopstream(chan);
+               *menu_mode = MENU_DISABLED;
+               break;
+
+       case '8': /* *88 Exit the menu and return to the conference... without an error message */
+               ast_stopstream(chan);
+               *menu_mode = MENU_DISABLED;
+               break;
+
+       default:
+               if (!ast_streamfile(chan, "conf-errormenu", ast_channel_language(chan))) {
+                       ast_waitstream(chan, "");
+               }
+               ast_stopstream(chan);
+               *menu_mode = MENU_DISABLED;
+               break;
+       }
+}
+
+/*! \internal
+ * \brief Processes menu options for the various menu types (accessible through the 's' option for app_meetme)
+ *
+ * \param menu_mode a pointer to the currently active menu_mode.
+ * \param dtmf a pointer to the dtmf value currently being processed against the menu.
+ * \param conf the active conference for which the user has called the menu from.
+ * \param confflags flags used by conf for various options
+ * \param chan ast_channel belonging to the user who called the menu
+ * \param user which meetme conference user invoked the menu
+ * \param recordingtmp character buffer which may hold the name of the conference recording file
+ * \param dahdic dahdi configuration info used by the main conference loop
+ */
+
+static void meetme_menu(enum menu_modes *menu_mode, int *dtmf, struct ast_conference *conf, struct ast_flags64 *confflags, struct ast_channel *chan, struct ast_conf_user *user, char *recordingtmp, struct dahdi_confinfo *dahdic, struct ast_format_cap *cap_slin)
+{
+       switch (*menu_mode) {
+       case MENU_DISABLED:
+               break;
+       case MENU_NORMAL:
+               meetme_menu_normal(menu_mode, dtmf, conf, confflags, chan, user);
+               break;
+       case MENU_ADMIN:
+               meetme_menu_admin(menu_mode, dtmf, conf, confflags, chan, user);
+               /* Admin Menu is capable of branching into another menu, in which case it will reset dtmf and change the menu mode. */
+               if (*menu_mode != MENU_ADMIN_EXTENDED || (*dtmf <= 0)) {
+                       break;
+               }
+       case MENU_ADMIN_EXTENDED:
+               meetme_menu_admin_extended(menu_mode, dtmf, conf, confflags, chan, user, recordingtmp, dahdic, cap_slin);
+               break;
+       }
+}
+
 static int conf_run(struct ast_channel *chan, struct ast_conference *conf, struct ast_flags64 *confflags, char *optargs[])
 {
        struct ast_conf_user *user = NULL;
@@ -2395,8 +2817,7 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, struc
        int currentmarked = 0;
        int ret = -1;
        int x;
-       int menu_active = 0;
-       int menu8_active = 0;
+       enum menu_modes menu_mode = MENU_DISABLED;
        int talkreq_manager = 0;
        int using_pseudo = 0;
        int duration = 20;
@@ -2412,7 +2833,7 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, struc
        char exitcontext[AST_MAX_CONTEXT] = "";
        char recordingtmp[AST_MAX_EXTENSION] = "";
        char members[10] = "";
-       int dtmf, opt_waitmarked_timeout = 0;
+       int dtmf = 0, opt_waitmarked_timeout = 0;
        time_t timeout = 0;
        struct dahdi_bufferinfo bi;
        char __buf[CONF_SIZE + AST_FRIENDLY_OFFSET];
@@ -2994,7 +3415,8 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, struc
                        /*  Set CONFMUTE mode on DAHDI channel to mute DTMF tones when the menu is enabled */
                        x = 1;
                        ast_channel_setoption(chan, AST_OPTION_TONE_VERIFY, &x, sizeof(char), 0);
-               }       
+               }
+
                for (;;) {
                        int menu_was_active = 0;
 
@@ -3157,11 +3579,11 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, struc
                        /* if we have just exited from the menu, and the user had a channel-driver
                           volume adjustment, restore it
                        */
-                       if (!menu_active && menu_was_active && user->listen.desired && !user->listen.actual) {
+                       if (!menu_mode && menu_was_active && user->listen.desired && !user->listen.actual) {
                                set_talk_volume(user, user->listen.desired);
                        }
 
-                       menu_was_active = menu_active;
+                       menu_was_active = menu_mode;
 
                        currentmarked = conf->markedusers;
                        if (!ast_test_flag64(confflags, CONFFLAG_QUIET) &&
@@ -3471,7 +3893,7 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, struc
                                                        careful_write(fd, f->data.ptr, f->datalen, 0);
                                                }
                                        }
-                               } else if (((f->frametype == AST_FRAME_DTMF) && (f->subclass.integer == '*') && ast_test_flag64(confflags, CONFFLAG_STARMENU)) || ((f->frametype == AST_FRAME_DTMF) && menu_active)) {
+                               } else if (((f->frametype == AST_FRAME_DTMF) && (f->subclass.integer == '*') && ast_test_flag64(confflags, CONFFLAG_STARMENU)) || ((f->frametype == AST_FRAME_DTMF) && menu_mode)) {
                                        if (ast_test_flag64(confflags, CONFFLAG_PASS_DTMF)) {
                                                conf_queue_dtmf(conf, user, f);
                                        }
@@ -3485,345 +3907,37 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, struc
                                        /* if we are entering the menu, and the user has a channel-driver
                                           volume adjustment, clear it
                                        */
-                                       if (!menu_active && user->talk.desired && !user->talk.actual) {
+                                       if (!menu_mode && user->talk.desired && !user->talk.actual) {
                                                set_talk_volume(user, 0);
                                        }
 
                                        if (musiconhold) {
                                                ast_moh_stop(chan);
-                                       }
-                                       if (menu8_active) {
-                                               /* *8 Submenu */
-                                               dtmf = f->subclass.integer;
-                                               if (dtmf > 0) {
-                                                       int keepplaying;
-                                                       int playednamerec;
-                                                       struct ao2_iterator user_iter;
-                                                       struct ast_conf_user *usr = NULL;
-                                                       switch(dtmf) {
-                                                       case '1': /* *81 Roll call */
-                                                               keepplaying = 1;
-                                                               playednamerec = 0;
-                                                               if (conf->users == 1) {
-                                                                       if (keepplaying && !ast_streamfile(chan, "conf-onlyperson", ast_channel_language(chan))) {
-                                                                               res = ast_waitstream(chan, AST_DIGIT_ANY);
-                                                                               ast_stopstream(chan);
-                                                                               if (res > 0)
-                                                                                       keepplaying = 0;
-                                                                       }
-                                                               } else if (conf->users == 2) {
-                                                                       if (keepplaying && !ast_streamfile(chan, "conf-onlyone", ast_channel_language(chan))) {
-                                                                               res = ast_waitstream(chan, AST_DIGIT_ANY);
-                                                                               ast_stopstream(chan);
-                                                                               if (res > 0)
-                                                                                       keepplaying = 0;
-                                                                       }
-                                                               } else {
-                                                                       if (keepplaying && !ast_streamfile(chan, "conf-thereare", ast_channel_language(chan))) {
-                                                                               res = ast_waitstream(chan, AST_DIGIT_ANY);
-                                                                               ast_stopstream(chan);
-                                                                               if (res > 0)
-                                                                                       keepplaying = 0;
-                                                                       }
-                                                                       if (keepplaying) {
-                                                                               res = ast_say_number(chan, conf->users - 1, AST_DIGIT_ANY, ast_channel_language(chan), (char *) NULL);
-                                                                               if (res > 0)
-                                                                                       keepplaying = 0;
-                                                                       }
-                                                                       if (keepplaying && !ast_streamfile(chan, "conf-otherinparty", ast_channel_language(chan))) {
-                                                                               res = ast_waitstream(chan, AST_DIGIT_ANY);
-                                                                               ast_stopstream(chan);
-                                                                               if (res > 0)
-                                                                                       keepplaying = 0;
-                                                                       }
-                                                               }
-                                                               user_iter = ao2_iterator_init(conf->usercontainer, 0);
-                                                               while((usr = ao2_iterator_next(&user_iter))) {
-                                                                       if (ast_fileexists(usr->namerecloc, NULL, NULL)) {
-                                                                               if (keepplaying && !ast_streamfile(chan, usr->namerecloc, ast_channel_language(chan))) {
-                                                                                       res = ast_waitstream(chan, AST_DIGIT_ANY);
-                                                                                       ast_stopstream(chan);
-                                                                                       if (res > 0)
-                                                                                               keepplaying = 0;
-                                                                               }
-                                                                               playednamerec = 1;
-                                                                       }
-                                                                       ao2_ref(usr, -1);
-                                                               }
-                                                               ao2_iterator_destroy(&user_iter);
-                                                               if (keepplaying && playednamerec && !ast_streamfile(chan, "conf-roll-callcomplete", ast_channel_language(chan))) {
-                                                                       res = ast_waitstream(chan, AST_DIGIT_ANY);
-                                                                       ast_stopstream(chan);
-                                                                       if (res > 0)
-                                                                               keepplaying = 0;
-                                                               }
-                                                               break;
-                                                       case '2': /* *82 Eject all non-admins */
-                                                               if (conf->users == 1) {
-                                                                       if(!ast_streamfile(chan, "conf-errormenu", ast_channel_language(chan)))
-                                                                               ast_waitstream(chan, "");
-                                                               } else {
-                                                                       ao2_callback(conf->usercontainer, OBJ_NODATA, user_set_kickme_cb, &conf);
-                                                               }
-                                                               ast_stopstream(chan);
-                                                               break;
-                                                       case '3': /* *83 (Admin) mute/unmute all non-admins */
-                                                               if(conf->gmuted) {
-                                                                       conf->gmuted = 0;
-                                                                       ao2_callback(conf->usercontainer, OBJ_NODATA, user_set_unmuted_cb, &conf);
-                                                                       if (!ast_streamfile(chan, "conf-now-unmuted", ast_channel_language(chan)))
-                                                                               ast_waitstream(chan, "");
-                                                               } else {
-                                                                       conf->gmuted = 1;
-                                                                       ao2_callback(conf->usercontainer, OBJ_NODATA, user_set_muted_cb, &conf);
-                                                                       if (!ast_streamfile(chan, "conf-now-muted", ast_channel_language(chan)))
-                                                                               ast_waitstream(chan, "");
-                                                               }
-                                                               ast_stopstream(chan);
-                                                               break;
-                                                       case '4': /* *84 Record conference */
-                                                               if (conf->recording != MEETME_RECORD_ACTIVE) {
-                                                                       ast_set_flag64(confflags, CONFFLAG_RECORDCONF);
-
-                                                                       if (!conf->recordingfilename) {
-                                                                               const char *var;
-                                                                               ast_channel_lock(chan);
-                                                                               if ((var = pbx_builtin_getvar_helper(chan, "MEETME_RECORDINGFILE"))) {
-                                                                                       conf->recordingfilename = ast_strdup(var);
-                                                                               }
-                                                                               if ((var = pbx_builtin_getvar_helper(chan, "MEETME_RECORDINGFORMAT"))) {
-                                                                                       conf->recordingformat = ast_strdup(var);
-                                                                               }
-                                                                               ast_channel_unlock(chan);
-                                                                               if (!conf->recordingfilename) {
-                                                                                       snprintf(recordingtmp, sizeof(recordingtmp), "meetme-conf-rec-%s-%s", conf->confno, ast_channel_uniqueid(chan));
-                                                                                       conf->recordingfilename = ast_strdup(recordingtmp);
-                                                                               }
-                                                                               if (!conf->recordingformat) {
-                                                                                       conf->recordingformat = ast_strdup("wav");
-                                                                               }
-                                                                               ast_verb(4, "Starting recording of MeetMe Conference %s into file %s.%s.\n",
-                                                                                       conf->confno, conf->recordingfilename, conf->recordingformat);
-                                                                       }
-
-                                                                       ast_mutex_lock(&conf->recordthreadlock);
-                                                                       if ((conf->recordthread == AST_PTHREADT_NULL) && ast_test_flag64(confflags, CONFFLAG_RECORDCONF) && ((conf->lchan = ast_request("DAHDI", cap_slin, chan, "pseudo", NULL)))) {
-                                                                               ast_set_read_format_by_id(conf->lchan, AST_FORMAT_SLINEAR);
-                                                                               ast_set_write_format_by_id(conf->lchan, AST_FORMAT_SLINEAR);
-                                                                               dahdic.chan = 0;
-                                                                               dahdic.confno = conf->dahdiconf;
-                                                                               dahdic.confmode = DAHDI_CONF_CONFANN | DAHDI_CONF_CONFANNMON;
-                                                                               if (ioctl(ast_channel_fd(conf->lchan, 0), DAHDI_SETCONF, &dahdic)) {
-                                                                                       ast_log(LOG_WARNING, "Error starting listen channel\n");
-                                                                                       ast_hangup(conf->lchan);
-                                                                                       conf->lchan = NULL;
-                                                                               } else {
-                                                                                       ast_pthread_create_detached_background(&conf->recordthread, NULL, recordthread, conf);
-                                                                               }
-                                                                       }
-                                                                       ast_mutex_unlock(&conf->recordthreadlock);
-
-                                                                       if (!ast_streamfile(chan, "conf-now-recording", ast_channel_language(chan)))
-                                                                               ast_waitstream(chan, "");
-
-                                                               }
-
-                                                               ast_stopstream(chan);
-                                                               break;
-                                                       default:
-                                                               if (!ast_streamfile(chan, "conf-errormenu", ast_channel_language(chan)))
-                                                                       ast_waitstream(chan, "");
-                                                               ast_stopstream(chan);
-                                                               break;
-                                                       }
-                                               }
-
-                                               menu8_active = 0;
-                                               menu_active = 0;
-                                       } else if (ast_test_flag64(confflags, CONFFLAG_ADMIN)) {
-                                               /* Admin menu */
-                                               if (!menu_active) {
-                                                       menu_active = 1;
-                                                       /* Record this sound! */
-                                                       if (!ast_streamfile(chan, "conf-adminmenu-162", ast_channel_language(chan))) {
-                                                               dtmf = ast_waitstream(chan, AST_DIGIT_ANY);
-                                                               ast_stopstream(chan);
-                                                       } else {
-                                                               dtmf = 0;
-                                                       }
+                                       } else if (!menu_mode) {
+                                               char *menu_to_play;
+                                               if (ast_test_flag64(confflags, CONFFLAG_ADMIN)) {
+                                                       menu_mode = MENU_ADMIN;
+                                                       menu_to_play = "conf-adminmenu-18";
                                                } else {
-                                                       dtmf = f->subclass.integer;
+                                                       menu_mode = MENU_NORMAL;
+                                                       menu_to_play = "conf-usermenu-162";
                                                }
-                                               if (dtmf > 0) {
-                                                       switch(dtmf) {
-                                                       case '1': /* Un/Mute */
-                                                               menu_active = 0;
-
-                                                               /* for admin, change both admin and use flags */
-                                                               if (user->adminflags & (ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED)) {
-                                                                       user->adminflags &= ~(ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED);
-                                                               } else {
-                                                                       user->adminflags |= (ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED);
-                                                               }
 
-                                                               if (ast_test_flag64(confflags, CONFFLAG_MONITOR) || (user->adminflags & (ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED))) {
-                                                                       if (!ast_streamfile(chan, "conf-muted", ast_channel_language(chan))) {
-                                                                               ast_waitstream(chan, "");
-                                                                       }
-                                                               } else {
-                                                                       if (!ast_streamfile(chan, "conf-unmuted", ast_channel_language(chan))) {
-                                                                               ast_waitstream(chan, "");
-                                                                       }
-                                                               }
-                                                               break;
-                                                       case '2': /* Un/Lock the Conference */
-                                                               menu_active = 0;
-                                                               if (conf->locked) {
-                                                                       conf->locked = 0;
-                                                                       if (!ast_streamfile(chan, "conf-unlockednow", ast_channel_language(chan))) {
-                                                                               ast_waitstream(chan, "");
-                                                                       }
-                                                               } else {
-                                                                       conf->locked = 1;
-                                                                       if (!ast_streamfile(chan, "conf-lockednow", ast_channel_language(chan))) {
-                                                                               ast_waitstream(chan, "");
-                                                                       }
-                                                               }
-                                                               break;
-                                                       case '3': /* Eject last user */
-                                                       {
-                                                               struct ast_conf_user *usr = NULL;
-                                                               int max_no = 0;
-                                                               ao2_callback(conf->usercontainer, OBJ_NODATA, user_max_cmp, &max_no);
-                                                               menu_active = 0;
-                                                               usr = ao2_find(conf->usercontainer, &max_no, 0);
-                                                               if ((ast_channel_name(usr->chan) == ast_channel_name(chan)) || ast_test_flag64(&usr->userflags, CONFFLAG_ADMIN)) {
-                                                                       if (!ast_streamfile(chan, "conf-errormenu", ast_channel_language(chan))) {
-                                                                               ast_waitstream(chan, "");
-                                                                       }
-                                                               } else {
-                                                                       usr->adminflags |= ADMINFLAG_KICKME;
-                                                               }
-                                                               ao2_ref(usr, -1);
-                                                               ast_stopstream(chan);
-                                                               break;  
-                                                       }
-                                                       case '4':
-                                                               tweak_listen_volume(user, VOL_DOWN);
-                                                               break;
-                                                       case '5':
-                                                               /* Extend RT conference */
-                                                               if (rt_schedule) {
-                                                                       if (!rt_extend_conf(conf->confno)) {
-                                                                               if (!ast_streamfile(chan, "conf-extended", ast_channel_language(chan))) {
-                                                                                       ast_waitstream(chan, "");
-                                                                               }
-                                                                       } else {
-                                                                               if (!ast_streamfile(chan, "conf-nonextended", ast_channel_language(chan))) {
-                                                                                       ast_waitstream(chan, "");
-                                                                               }
-                                                                       }
-                                                                       ast_stopstream(chan);
-                                                               }
-                                                               menu_active = 0;
-                                                               break;
-                                                       case '6':
-                                                               tweak_listen_volume(user, VOL_UP);
-                                                               break;
-                                                       case '7':
-                                                               tweak_talk_volume(user, VOL_DOWN);
-                                                               break;
-                                                       case '8':
-                                                               menu8_active = 1;
-                                                               break;
-                                                       case '9':
-                                                               tweak_talk_volume(user, VOL_UP);
-                                                               break;
-                                                       default:
-                                                               menu_active = 0;
-                                                               /* Play an error message! */
-                                                               if (!ast_streamfile(chan, "conf-errormenu", ast_channel_language(chan))) {
-                                                                       ast_waitstream(chan, "");
-                                                               }
-                                                               break;
-                                                       }
-                                               }
-                                       } else {
-                                               /* User menu */
-                                               if (!menu_active) {
-                                                       menu_active = 1;
-                                                       if (!ast_streamfile(chan, "conf-usermenu-162", ast_channel_language(chan))) {
-                                                               dtmf = ast_waitstream(chan, AST_DIGIT_ANY);
-                                                               ast_stopstream(chan);
-                                                       } else {
-                                                               dtmf = 0;
-                                                       }
+                                               if (!ast_streamfile(chan, menu_to_play, ast_channel_language(chan))) {
+                                                       dtmf = ast_waitstream(chan, AST_DIGIT_ANY);
+                                                       ast_stopstream(chan);
                                                } else {
-                                                       dtmf = f->subclass.integer;
-                                               }
-                                               if (dtmf > 0) {
-                                                       switch (dtmf) {
-                                                       case '1': /* Un/Mute */
-                                                               menu_active = 0;
-
-                                                               /* user can only toggle the self-muted state */
-                                                               user->adminflags ^= ADMINFLAG_SELFMUTED;
-
-                                                               /* they can't override the admin mute state */
-                                                               if (ast_test_flag64(confflags, CONFFLAG_MONITOR) || (user->adminflags & (ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED))) {
-                                                                       if (!ast_streamfile(chan, "conf-muted", ast_channel_language(chan))) {
-                                                                               ast_waitstream(chan, "");
-                                                                       }
-                                                               } else {
-                                                                       if (!ast_streamfile(chan, "conf-unmuted", ast_channel_language(chan))) {
-                                                                               ast_waitstream(chan, "");
-                                                                       }
-                                                               }
-                                                               break;
-                                                       case '2':
-                                                               menu_active = 0;
-                                                               if (user->adminflags & (ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED)) {
-                                                                       user->adminflags |= ADMINFLAG_T_REQUEST;
-                                                               }
-                                                                       
-                                                               if (user->adminflags & ADMINFLAG_T_REQUEST) {
-                                                                       if (!ast_streamfile(chan, "beep", ast_channel_language(chan))) {
-                                                                               ast_waitstream(chan, "");
-                                                                       }
-                                                               }
-                                                               break;
-                                                       case '4':
-                                                               tweak_listen_volume(user, VOL_DOWN);
-                                                               break;
-                                                       case '5':
-                                                               /* Extend RT conference */
-                                                               if (rt_schedule) {
-                                                                       rt_extend_conf(conf->confno);
-                                                               }
-                                                               menu_active = 0;
-                                                               break;
-                                                       case '6':
-                                                               tweak_listen_volume(user, VOL_UP);
-                                                               break;
-                                                       case '7':
-                                                               tweak_talk_volume(user, VOL_DOWN);
-                                                               break;
-                                                       case '8':
-                                                               menu_active = 0;
-                                                               break;
-                                                       case '9':
-                                                               tweak_talk_volume(user, VOL_UP);
-                                                               break;
-                                                       default:
-                                                               menu_active = 0;
-                                                               if (!ast_streamfile(chan, "conf-errormenu", ast_channel_language(chan))) {
-                                                                       ast_waitstream(chan, "");
-                                                               }
-                                                               break;
-                                                       }
+                                                       dtmf = 0;
                                                }
+                                       } else {
+                                               dtmf = f->subclass.integer;
+                                       }
+
+                                       if (dtmf > 0) {
+                                               meetme_menu(&menu_mode, &dtmf, conf, confflags, chan, user, recordingtmp, &dahdic, cap_slin);
                                        }
-                                       if (musiconhold && !menu_active) {
+
+                                       if (musiconhold && !menu_mode) {
                                                conf_start_moh(chan, optargs[OPT_ARG_MOH_CLASS]);
                                        }
 
index 4f753eb..bc8ad58 100644 (file)
@@ -19,8 +19,8 @@ CMD_PREFIX?=@
 SOUNDS_DIR:=$(DESTDIR)$(ASTDATADIR)/sounds
 SOUNDS_CACHE_DIR?=
 MOH_DIR:=$(DESTDIR)$(ASTDATADIR)/moh
-CORE_SOUNDS_VERSION:=1.4.22
-EXTRA_SOUNDS_VERSION:=1.4.12
+CORE_SOUNDS_VERSION:=1.4.23
+EXTRA_SOUNDS_VERSION:=1.4.13
 MOH_VERSION:=2.03
 SOUNDS_URL:=http://downloads.asterisk.org/pub/telephony/sounds/releases
 MCS:=$(subst -EN-,-en-,$(MENUSELECT_CORE_SOUNDS))