diff --git a/apps/app_confbridge.c b/apps/app_confbridge.c index ea206bfa0b3736912444c29daa0ff346dda9ef32..dd683d35c62cbbe56f2a453660a57617e94e6677 100644 --- a/apps/app_confbridge.c +++ b/apps/app_confbridge.c @@ -4022,6 +4022,7 @@ static int action_confbridgelist_item(struct mansession *s, const char *id_text, "MarkedUser: %s\r\n" "WaitMarked: %s\r\n" "EndMarked: %s\r\n" + "EndMarkedAny: %s\r\n" "Waiting: %s\r\n" "Muted: %s\r\n" "Talking: %s\r\n" @@ -4034,6 +4035,7 @@ static int action_confbridgelist_item(struct mansession *s, const char *id_text, AST_YESNO(ast_test_flag(&user->u_profile, USER_OPT_MARKEDUSER)), AST_YESNO(ast_test_flag(&user->u_profile, USER_OPT_WAITMARKED)), AST_YESNO(ast_test_flag(&user->u_profile, USER_OPT_ENDMARKED)), + AST_YESNO(ast_test_flag(&user->u_profile, USER_OPT_ENDMARKEDANY)), AST_YESNO(waiting), AST_YESNO(user->muted), AST_YESNO(user->talking), diff --git a/apps/confbridge/conf_config_parser.c b/apps/confbridge/conf_config_parser.c index d04bcf9dcb84fefd6fa2cdb00fe1af2a5a3694b8..aceb3563fe8976f7ed9d97dc247a50c6035ce338 100644 --- a/apps/confbridge/conf_config_parser.c +++ b/apps/confbridge/conf_config_parser.c @@ -120,6 +120,9 @@ <configOption name="end_marked"> <synopsis>Kick the user from the conference when the last marked user leaves</synopsis> </configOption> + <configOption name="end_marked_any"> + <synopsis>Kick the user from the conference when any marked user leaves</synopsis> + </configOption> <configOption name="talk_detection_events"> <synopsis>Set whether or not notifications of when a user begins and ends talking should be sent out as events over AMI</synopsis> </configOption> @@ -1581,9 +1584,12 @@ static char *handle_cli_confbridge_show_user_profile(struct ast_cli_entry *e, in ast_cli(a->fd,"Wait Marked: %s\n", u_profile.flags & USER_OPT_WAITMARKED ? "enabled" : "disabled"); - ast_cli(a->fd,"END Marked: %s\n", + ast_cli(a->fd,"END Marked (All): %s\n", u_profile.flags & USER_OPT_ENDMARKED ? "enabled" : "disabled"); + ast_cli(a->fd,"END Marked (Any): %s\n", + u_profile.flags & USER_OPT_ENDMARKEDANY ? + "enabled" : "disabled"); ast_cli(a->fd,"Drop_silence: %s\n", u_profile.flags & USER_OPT_DROP_SILENCE ? "enabled" : "disabled"); @@ -2407,6 +2413,7 @@ int conf_load_config(void) aco_option_register(&cfg_info, "announce_only_user", ACO_EXACT, user_types, "yes", OPT_BOOLFLAG_T, 0, FLDSET(struct user_profile, flags), USER_OPT_NOONLYPERSON); aco_option_register(&cfg_info, "wait_marked", ACO_EXACT, user_types, "no", OPT_BOOLFLAG_T, 1, FLDSET(struct user_profile, flags), USER_OPT_WAITMARKED); aco_option_register(&cfg_info, "end_marked", ACO_EXACT, user_types, "no", OPT_BOOLFLAG_T, 1, FLDSET(struct user_profile, flags), USER_OPT_ENDMARKED); + aco_option_register(&cfg_info, "end_marked_any", ACO_EXACT, user_types, "no", OPT_BOOLFLAG_T, 1, FLDSET(struct user_profile, flags), USER_OPT_ENDMARKEDANY); aco_option_register(&cfg_info, "talk_detection_events", ACO_EXACT, user_types, "no", OPT_BOOLFLAG_T, 1, FLDSET(struct user_profile, flags), USER_OPT_TALKER_DETECT); aco_option_register(&cfg_info, "dtmf_passthrough", ACO_EXACT, user_types, "no", OPT_BOOLFLAG_T, 1, FLDSET(struct user_profile, flags), USER_OPT_DTMF_PASS); aco_option_register(&cfg_info, "announce_join_leave", ACO_EXACT, user_types, "no", OPT_BOOLFLAG_T, 1, FLDSET(struct user_profile, flags), USER_OPT_ANNOUNCE_JOIN_LEAVE); diff --git a/apps/confbridge/conf_state_multi_marked.c b/apps/confbridge/conf_state_multi_marked.c index 3932edcc20672d3128662d4d3cf1d8ceea36574b..ef3c4b33023a30f1242918e3de035aef30360a6f 100644 --- a/apps/confbridge/conf_state_multi_marked.c +++ b/apps/confbridge/conf_state_multi_marked.c @@ -82,37 +82,39 @@ static void leave_marked(struct confbridge_user *user) conf_remove_user_marked(user->conference, user); - if (user->conference->markedusers == 0) { - AST_LIST_TRAVERSE_SAFE_BEGIN(&user->conference->active_list, user_iter, list) { - /* Kick ENDMARKED cbu_iters */ - if (ast_test_flag(&user_iter->u_profile, USER_OPT_ENDMARKED) && !user_iter->kicked) { - if (ast_test_flag(&user_iter->u_profile, USER_OPT_WAITMARKED) - && !ast_test_flag(&user_iter->u_profile, USER_OPT_MARKEDUSER)) { - AST_LIST_REMOVE_CURRENT(list); - user_iter->conference->activeusers--; - AST_LIST_INSERT_TAIL(&user_iter->conference->waiting_list, user_iter, list); - user_iter->conference->waitingusers++; - } - user_iter->kicked = 1; - pbx_builtin_setvar_helper(user_iter->chan, "CONFBRIDGE_RESULT", "ENDMARKED"); - ast_bridge_remove(user_iter->conference->bridge, user_iter->chan); - } else if (ast_test_flag(&user_iter->u_profile, USER_OPT_WAITMARKED) - && !ast_test_flag(&user_iter->u_profile, USER_OPT_MARKEDUSER)) { - need_prompt = 1; - + /* If all marked users have left, or we're set to kick if any marked user leaves, then boot everyone */ + AST_LIST_TRAVERSE_SAFE_BEGIN(&user->conference->active_list, user_iter, list) { + if (user->conference->markedusers > 0 && !ast_test_flag(&user_iter->u_profile, USER_OPT_ENDMARKEDANY)) { + continue; + } + /* Kick ENDMARKED cbu_iters */ + if ((ast_test_flag(&user_iter->u_profile, USER_OPT_ENDMARKED) || ast_test_flag(&user_iter->u_profile, USER_OPT_ENDMARKEDANY)) && !user_iter->kicked) { + if (ast_test_flag(&user_iter->u_profile, USER_OPT_WAITMARKED) + && (!ast_test_flag(&user_iter->u_profile, USER_OPT_MARKEDUSER) || ast_test_flag(&user_iter->u_profile, USER_OPT_ENDMARKEDANY))) { AST_LIST_REMOVE_CURRENT(list); user_iter->conference->activeusers--; AST_LIST_INSERT_TAIL(&user_iter->conference->waiting_list, user_iter, list); user_iter->conference->waitingusers++; - } else { - /* User is neither wait_marked nor end_marked; however, they - * should still hear the prompt. - */ - need_prompt = 1; } + user_iter->kicked = 1; + pbx_builtin_setvar_helper(user_iter->chan, "CONFBRIDGE_RESULT", "ENDMARKED"); + ast_bridge_remove(user_iter->conference->bridge, user_iter->chan); + } else if (ast_test_flag(&user_iter->u_profile, USER_OPT_WAITMARKED) + && !ast_test_flag(&user_iter->u_profile, USER_OPT_MARKEDUSER)) { + need_prompt = 1; + + AST_LIST_REMOVE_CURRENT(list); + user_iter->conference->activeusers--; + AST_LIST_INSERT_TAIL(&user_iter->conference->waiting_list, user_iter, list); + user_iter->conference->waitingusers++; + } else { + /* User is neither wait_marked nor end_marked nor end_marked_any; however, they + * should still hear the prompt. + */ + need_prompt = 1; } - AST_LIST_TRAVERSE_SAFE_END; } + AST_LIST_TRAVERSE_SAFE_END; switch (user->conference->activeusers) { case 0: diff --git a/apps/confbridge/include/confbridge.h b/apps/confbridge/include/confbridge.h index f90f18588c97c4e5c966c30369b43691a85c73f4..a6fdbb4b2345295c161b141628ce21404c3ac5eb 100644 --- a/apps/confbridge/include/confbridge.h +++ b/apps/confbridge/include/confbridge.h @@ -71,6 +71,7 @@ enum user_profile_flags { USER_OPT_TEXT_MESSAGING = (1 << 19), /*!< Send text messages to the user */ USER_OPT_ANSWER_CHANNEL = (1 << 20), /*!< Sets if the channel should be answered if currently unanswered */ USER_OPT_HEAR_OWN_JOIN_SOUND = (1 << 21), /*!< Set if the caller should hear the join sound */ + USER_OPT_ENDMARKEDANY = (1 << 22), /*!< Set if the user should be kicked after any marked user exits */ }; enum bridge_profile_flags { diff --git a/configs/samples/confbridge.conf.sample b/configs/samples/confbridge.conf.sample index ed4c72b50848c7e7441f21fea8f3c52143dadb33..f582323f10c1a067d37be5dc29797ba435ff5969 100644 --- a/configs/samples/confbridge.conf.sample +++ b/configs/samples/confbridge.conf.sample @@ -58,8 +58,11 @@ type=user ; when a channel enters a empty conference. On by default. ;wait_marked=yes ; Sets if the user must wait for a marked user to enter before ; joining the conference. Off by default. -;end_marked=yes ; This option will kick every user with this option set in their - ; user profile after the last Marked user exists the conference. +;end_marked=yes ; This option will kick every non-marked user with this option set in their + ; user profile after the last marked user exits the conference. +;end_marked_any=no ; This option will kick every user with this option set in + ; their user profile after any marked user exits the conference. + ; Additionally, note that unlike end_marked, this includes marked users. ;dsp_drop_silence=yes ; This option drops what Asterisk detects as silence from ; entering into the bridge. Enabling this option will drastically diff --git a/doc/CHANGES-staging/app_confbridge_marked_any.txt b/doc/CHANGES-staging/app_confbridge_marked_any.txt new file mode 100644 index 0000000000000000000000000000000000000000..cbc1bbffdf20b2a5ee04dc3e667e1e151fdb93b7 --- /dev/null +++ b/doc/CHANGES-staging/app_confbridge_marked_any.txt @@ -0,0 +1,5 @@ +Subject: app_confbridge + +Adds the end_marked_any option which can be used +to kick users from a conference after any +marked user leaves (including marked users).