@ -2180,6 +2180,29 @@ int conf_handle_dtmf(struct ast_bridge_channel *bridge_channel,
return 0 ;
}
static int kick_conference_participant ( struct conference_bridge * bridge , const char * channel )
{
struct conference_bridge_user * participant = NULL ;
SCOPED_AO2LOCK ( bridge_lock , bridge ) ;
AST_LIST_TRAVERSE ( & bridge - > active_list , participant , list ) {
if ( ! strcasecmp ( ast_channel_name ( participant - > chan ) , channel ) ) {
participant - > kicked = 1 ;
ast_bridge_remove ( bridge - > bridge , participant - > chan ) ;
return 0 ;
}
}
AST_LIST_TRAVERSE ( & bridge - > waiting_list , participant , list ) {
if ( ! strcasecmp ( ast_channel_name ( participant - > chan ) , channel ) ) {
participant - > kicked = 1 ;
ast_bridge_remove ( bridge - > bridge , participant - > chan ) ;
return 0 ;
}
}
return - 1 ;
}
static char * complete_confbridge_name ( const char * line , const char * word , int pos , int state )
{
int which = 0 ;
@ -2202,11 +2225,44 @@ static char *complete_confbridge_name(const char *line, const char *word, int po
return res ;
}
static char * complete_confbridge_participant ( const char * bridge_name , const char * line , const char * word , int pos , int state )
{
int which = 0 ;
RAII_VAR ( struct conference_bridge * , bridge , NULL , ao2_cleanup ) ;
struct conference_bridge tmp ;
struct conference_bridge_user * participant ;
char * res = NULL ;
int wordlen = strlen ( word ) ;
ast_copy_string ( tmp . name , bridge_name , sizeof ( tmp . name ) ) ;
bridge = ao2_find ( conference_bridges , & tmp , OBJ_POINTER ) ;
if ( ! bridge ) {
return NULL ;
}
{
SCOPED_AO2LOCK ( bridge_lock , bridge ) ;
AST_LIST_TRAVERSE ( & bridge - > active_list , participant , list ) {
if ( ! strncasecmp ( ast_channel_name ( participant - > chan ) , word , wordlen ) & & + + which > state ) {
res = ast_strdup ( ast_channel_name ( participant - > chan ) ) ;
return res ;
}
}
AST_LIST_TRAVERSE ( & bridge - > waiting_list , participant , list ) {
if ( ! strncasecmp ( ast_channel_name ( participant - > chan ) , word , wordlen ) & & + + which > state ) {
res = ast_strdup ( ast_channel_name ( participant - > chan ) ) ;
return res ;
}
}
}
return NULL ;
}
static char * handle_cli_confbridge_kick ( struct ast_cli_entry * e , int cmd , struct ast_cli_args * a )
{
struct conference_bridge * bridge = NULL ;
struct conference_bridge tmp ;
struct conference_bridge_user * participant = NULL ;
switch ( cmd ) {
case CLI_INIT :
@ -2219,11 +2275,9 @@ static char *handle_cli_confbridge_kick(struct ast_cli_entry *e, int cmd, struct
if ( a - > pos = = 2 ) {
return complete_confbridge_name ( a - > line , a - > word , a - > pos , a - > n ) ;
}
/*
if ( a - > pos = = 3 ) {
return complete_confbridge_ channel( a - > line , a - > word , a - > pos , a - > n ) ;
return complete_confbridge_ participant( a - > argv [ 2 ] , a - > line , a - > word , a - > pos , a - > n ) ;
}
*/
return NULL ;
}
@ -2237,19 +2291,12 @@ static char *handle_cli_confbridge_kick(struct ast_cli_entry *e, int cmd, struct
ast_cli ( a - > fd , " No conference bridge named '%s' found! \n " , a - > argv [ 2 ] ) ;
return CLI_SUCCESS ;
}
ao2_lock ( bridge ) ;
AST_LIST_TRAVERSE ( & bridge - > active_list , participant , list ) {
if ( ! strncmp ( a - > argv [ 3 ] , ast_channel_name ( participant - > chan ) , strlen ( ast_channel_name ( participant - > chan ) ) ) ) {
break ;
}
}
if ( participant ) {
ast_cli ( a - > fd , " Kicking %s from confbridge %s \n " , ast_channel_name ( participant - > chan ) , bridge - > name ) ;
participant - > kicked = 1 ;
ast_bridge_remove ( bridge - > bridge , participant - > chan ) ;
if ( kick_conference_participant ( bridge , a - > argv [ 3 ] ) ) {
ast_cli ( a - > fd , " No participant named '%s' found! \n " , a - > argv [ 3 ] ) ;
return CLI_SUCCESS ;
}
ao2_unlock ( bridge ) ;
ao2_ref ( bridge , - 1 ) ;
ast_cli ( a - > fd , " Participant '%s' kicked out of conference '%s' \n " , a - > argv [ 3 ] , a - > argv [ 2 ] ) ;
return CLI_SUCCESS ;
}
@ -2437,12 +2484,16 @@ static char *handle_cli_confbridge_mute(struct ast_cli_entry *e, int cmd, struct
case CLI_INIT :
e - > command = " confbridge mute " ;
e - > usage =
" Usage: confbridge mute <conference> <channel> \n " ;
" Usage: confbridge mute <conference> <channel> \n "
" Mute a channel in a conference. \n " ;
return NULL ;
case CLI_GENERATE :
if ( a - > pos = = 2 ) {
return complete_confbridge_name ( a - > line , a - > word , a - > pos , a - > n ) ;
}
if ( a - > pos = = 3 ) {
return complete_confbridge_participant ( a - > argv [ 2 ] , a - > line , a - > word , a - > pos , a - > n ) ;
}
return NULL ;
}
if ( a - > argc ! = 4 ) {
@ -2460,12 +2511,16 @@ static char *handle_cli_confbridge_unmute(struct ast_cli_entry *e, int cmd, stru
case CLI_INIT :
e - > command = " confbridge unmute " ;
e - > usage =
" Usage: confbridge unmute <conference> <channel> \n " ;
" Usage: confbridge unmute <conference> <channel> \n "
" Unmute a channel in a conference. \n " ;
return NULL ;
case CLI_GENERATE :
if ( a - > pos = = 2 ) {
return complete_confbridge_name ( a - > line , a - > word , a - > pos , a - > n ) ;
}
if ( a - > pos = = 3 ) {
return complete_confbridge_participant ( a - > argv [ 2 ] , a - > line , a - > word , a - > pos , a - > n ) ;
}
return NULL ;
}
if ( a - > argc ! = 4 ) {
@ -2483,7 +2538,9 @@ static char *handle_cli_confbridge_lock(struct ast_cli_entry *e, int cmd, struct
case CLI_INIT :
e - > command = " confbridge lock " ;
e - > usage =
" Usage: confbridge lock <conference> \n " ;
" Usage: confbridge lock <conference> \n "
" Lock a conference. While locked, no new non-admins \n "
" may join the conference. \n " ;
return NULL ;
case CLI_GENERATE :
if ( a - > pos = = 2 ) {
@ -2508,7 +2565,8 @@ static char *handle_cli_confbridge_unlock(struct ast_cli_entry *e, int cmd, stru
case CLI_INIT :
e - > command = " confbridge unlock " ;
e - > usage =
" Usage: confbridge unlock <conference> \n " ;
" Usage: confbridge unlock <conference> \n "
" Unlock a previously locked conference. \n " ;
return NULL ;
case CLI_GENERATE :
if ( a - > pos = = 2 ) {
@ -2596,7 +2654,8 @@ static char *handle_cli_confbridge_stop_record(struct ast_cli_entry *e, int cmd,
case CLI_INIT :
e - > command = " confbridge record stop " ;
e - > usage =
" Usage: confbridge record stop <conference> \n " ;
" Usage: confbridge record stop <conference> \n "
" Stop a previously started recording. \n " ;
return NULL ;
case CLI_GENERATE :
if ( a - > pos = = 3 ) {
@ -2852,7 +2911,6 @@ static int action_confbridgekick(struct mansession *s, const struct message *m)
{
const char * conference = astman_get_header ( m , " Conference " ) ;
const char * channel = astman_get_header ( m , " Channel " ) ;
struct conference_bridge_user * participant = NULL ;
struct conference_bridge * bridge = NULL ;
struct conference_bridge tmp ;
int found = 0 ;
@ -2865,6 +2923,7 @@ static int action_confbridgekick(struct mansession *s, const struct message *m)
astman_send_error ( s , m , " No active conferences. " ) ;
return 0 ;
}
ast_copy_string ( tmp . name , conference , sizeof ( tmp . name ) ) ;
bridge = ao2_find ( conference_bridges , & tmp , OBJ_POINTER ) ;
if ( ! bridge ) {
@ -2872,16 +2931,7 @@ static int action_confbridgekick(struct mansession *s, const struct message *m)
return 0 ;
}
ao2_lock ( bridge ) ;
AST_LIST_TRAVERSE ( & bridge - > active_list , participant , list ) {
if ( ! strcasecmp ( ast_channel_name ( participant - > chan ) , channel ) ) {
participant - > kicked = 1 ;
ast_bridge_remove ( bridge - > bridge , participant - > chan ) ;
found = 1 ;
break ;
}
}
ao2_unlock ( bridge ) ;
found = ! kick_conference_participant ( bridge , channel ) ;
ao2_ref ( bridge , - 1 ) ;
if ( found ) {
@ -3062,6 +3112,9 @@ static int func_confbridge_info(struct ast_channel *chan, const char *cmd, char
AST_LIST_TRAVERSE ( & bridge - > active_list , participant , list ) {
count + + ;
}
AST_LIST_TRAVERSE ( & bridge - > waiting_list , participant , list ) {
count + + ;
}
} else if ( ! strncasecmp ( args . type , " admins " , 6 ) ) {
AST_LIST_TRAVERSE ( & bridge - > active_list , participant , list ) {
if ( ast_test_flag ( & participant - > u_profile , USER_OPT_ADMIN ) ) {