@ -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_ activ e & & menu_was_active & & user - > listen . desired & & ! user - > listen . actual ) {
if ( ! menu_ mod e & & menu_was_active & & user - > listen . desired & & ! user - > listen . actual ) {
set_talk_volume ( user , user - > listen . desired ) ;
}
menu_was_active = menu_ activ e;
menu_was_active = menu_ mod e;
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_ activ e) ) {
} else if ( ( ( f - > frametype = = AST_FRAME_DTMF ) & & ( f - > subclass . integer = = ' * ' ) & & ast_test_flag64 ( confflags , CONFFLAG_STARMENU ) ) | | ( ( f - > frametype = = AST_FRAME_DTMF ) & & menu_ mod e) ) {
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_ activ e & & user - > talk . desired & & ! user - > talk . actual ) {
if ( ! menu_ mod e & & 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 ] ) ;
}