[Asterisk-code-review] confbridge: Separate user muting from system muting overrides. (asterisk[certified/11.6])
Richard Mudgett
asteriskteam at digium.com
Wed Jan 27 17:24:25 CST 2016
Richard Mudgett has uploaded a new change for review.
https://gerrit.asterisk.org/2118
Change subject: confbridge: Separate user muting from system muting overrides.
......................................................................
confbridge: Separate user muting from system muting overrides.
The system overrides the user muting requests when MOH is playing or a
waitmarked user is waiting for a marked user to join. System muting
overrides interfere with what the user may wish the muting to be when the
system override ends.
* User muting requests are now independent of the system muting overrides.
The effective muting is now the logical or of the user request and system
override.
* Added a Muted column to the CLI "confbridge list <conference>" command.
* Added a Muted header to the AMI ConfbridgeList action ConfbridgeList
event.
(closes issue AST-1102)
Reported by: John Bigelow
Review: https://reviewboard.asterisk.org/r/2960/
Cherry-picked to support ASTERISK-20987
Change-Id: Iec7bd77736847af6a5f70b8d279f85c6e2082ee2
---
M apps/app_confbridge.c
M apps/confbridge/conf_state.c
M apps/confbridge/conf_state_inactive.c
M apps/confbridge/conf_state_multi.c
M apps/confbridge/conf_state_multi_marked.c
M apps/confbridge/conf_state_single.c
M apps/confbridge/conf_state_single_marked.c
M apps/confbridge/include/confbridge.h
8 files changed, 113 insertions(+), 43 deletions(-)
git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/18/2118/1
diff --git a/apps/app_confbridge.c b/apps/app_confbridge.c
index b08af53..ef27a2e 100644
--- a/apps/app_confbridge.c
+++ b/apps/app_confbridge.c
@@ -960,6 +960,32 @@
return 0;
}
+void conf_update_user_mute(struct conference_bridge_user *user)
+{
+ int mute_user;
+ int mute_system;
+ int mute_effective;
+
+ /* User level mute request. */
+ mute_user = user->muted;
+
+ /* System level mute request. */
+ mute_system = user->playing_moh
+ /*
+ * Do not allow waitmarked users to talk to anyone unless there
+ * is a marked user present.
+ */
+ || (!user->conference_bridge->markedusers
+ && ast_test_flag(&user->u_profile, USER_OPT_WAITMARKED));
+
+ mute_effective = mute_user || mute_system;
+
+ ast_debug(1, "User %s is %s: user:%d system:%d.\n",
+ ast_channel_name(user->chan), mute_effective ? "muted" : "unmuted",
+ mute_user, mute_system);
+ user->features.mute = mute_effective;
+}
+
void conf_moh_stop(struct conference_bridge_user *user)
{
user->playing_moh = 0;
@@ -1105,9 +1131,7 @@
if (ast_test_flag(&first_participant->u_profile, USER_OPT_MUSICONHOLD)) {
conf_moh_stop(first_participant);
}
- if (!ast_test_flag(&first_participant->u_profile, USER_OPT_STARTMUTED)) {
- first_participant->features.mute = 0;
- }
+ conf_update_user_mute(first_participant);
}
void conf_ended(struct conference_bridge *conference_bridge)
@@ -1652,7 +1676,8 @@
/* If the caller should be joined already muted, make it so */
if (ast_test_flag(&conference_bridge_user.u_profile, USER_OPT_STARTMUTED)) {
- conference_bridge_user.features.mute = 1;
+ /* Set user level mute request. */
+ conference_bridge_user.muted = 1;
}
if (ast_test_flag(&conference_bridge_user.u_profile, USER_OPT_DROP_SILENCE)) {
@@ -1769,12 +1794,23 @@
struct conference_bridge_user *conference_bridge_user,
struct ast_channel *chan)
{
- /* Mute or unmute yourself, note we only allow manipulation if they aren't waiting for a marked user or if marked users exist */
- if (!ast_test_flag(&conference_bridge_user->u_profile, USER_OPT_WAITMARKED) || conference_bridge->markedusers) {
- conference_bridge_user->features.mute = (!conference_bridge_user->features.mute ? 1 : 0);
- ast_test_suite_event_notify("CONF_MUTE", "Message: participant %s %s\r\nConference: %s\r\nChannel: %s", ast_channel_name(chan), conference_bridge_user->features.mute ? "muted" : "unmuted", conference_bridge_user->b_profile.name, ast_channel_name(chan));
- }
- return ast_stream_and_wait(chan, (conference_bridge_user->features.mute ?
+ int mute;
+
+ /* Toggle user level mute request. */
+ mute = !conference_bridge_user->muted;
+ conference_bridge_user->muted = mute;
+
+ conf_update_user_mute(conference_bridge_user);
+ ast_test_suite_event_notify("CONF_MUTE",
+ "Message: participant %s %s\r\n"
+ "Conference: %s\r\n"
+ "Channel: %s",
+ ast_channel_name(chan),
+ mute ? "muted" : "unmuted",
+ conference_bridge_user->b_profile.name,
+ ast_channel_name(chan));
+
+ return ast_stream_and_wait(chan, (mute ?
conf_get_sound(CONF_SOUND_MUTED, conference_bridge_user->b_profile.sounds) :
conf_get_sound(CONF_SOUND_UNMUTED, conference_bridge_user->b_profile.sounds)),
"");
@@ -1784,21 +1820,26 @@
{
struct conference_bridge_user *participant = NULL;
const char *sound_to_play;
+ int mute;
ao2_lock(conference_bridge);
- /* If already muted, then unmute */
- conference_bridge->muted = conference_bridge->muted ? 0 : 1;
- sound_to_play = conf_get_sound((conference_bridge->muted ? CONF_SOUND_PARTICIPANTS_MUTED : CONF_SOUND_PARTICIPANTS_UNMUTED),
- conference_bridge_user->b_profile.sounds);
+ /* Toggle bridge level mute request. */
+ mute = !conference_bridge->muted;
+ conference_bridge->muted = mute;
AST_LIST_TRAVERSE(&conference_bridge->active_list, participant, list) {
if (!ast_test_flag(&participant->u_profile, USER_OPT_ADMIN)) {
- participant->features.mute = conference_bridge->muted;
+ /* Set user level to bridge level mute request. */
+ participant->muted = mute;
+ conf_update_user_mute(participant);
}
}
ao2_unlock(conference_bridge);
+
+ sound_to_play = conf_get_sound((mute ? CONF_SOUND_PARTICIPANTS_MUTED : CONF_SOUND_PARTICIPANTS_UNMUTED),
+ conference_bridge_user->b_profile.sounds);
/* The host needs to hear it seperately, as they don't get the audio from play_sound_helper */
ast_stream_and_wait(conference_bridge_user->chan, sound_to_play, "");
@@ -2219,12 +2260,14 @@
static void handle_cli_confbridge_list_item(struct ast_cli_args *a, struct conference_bridge_user *participant)
{
- ast_cli(a->fd, "%-29s ", ast_channel_name(participant->chan));
- ast_cli(a->fd, "%-17s", participant->u_profile.name);
- ast_cli(a->fd, "%-17s", participant->b_profile.name);
- ast_cli(a->fd, "%-17s", participant->menu_name);
- ast_cli(a->fd, "%-17s", S_COR(ast_channel_caller(participant->chan)->id.number.valid, ast_channel_caller(participant->chan)->id.number.str, "<unknown>"));
- ast_cli(a->fd, "\n");
+ ast_cli(a->fd, "%-30s %-16s %-16s %-16s %-16s %s\n",
+ ast_channel_name(participant->chan),
+ participant->u_profile.name,
+ participant->b_profile.name,
+ participant->menu_name,
+ S_COR(ast_channel_caller(participant->chan)->id.number.valid,
+ ast_channel_caller(participant->chan)->id.number.str, "<unknown>"),
+ AST_CLI_YESNO(participant->muted));
}
static char *handle_cli_confbridge_list(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
@@ -2267,8 +2310,8 @@
ast_cli(a->fd, "No conference bridge named '%s' found!\n", a->argv[2]);
return CLI_SUCCESS;
}
- ast_cli(a->fd, "Channel User Profile Bridge Profile Menu CallerID\n");
- ast_cli(a->fd, "============================= ================ ================ ================ ================\n");
+ ast_cli(a->fd, "Channel User Profile Bridge Profile Menu CallerID Muted\n");
+ ast_cli(a->fd, "============================== ================ ================ ================ ================ =====\n");
ao2_lock(bridge);
AST_LIST_TRAVERSE(&bridge->active_list, participant, list) {
handle_cli_confbridge_list_item(a, participant);
@@ -2335,8 +2378,18 @@
}
}
if (participant) {
- participant->features.mute = mute;
- ast_test_suite_event_notify("CONF_MUTE", "Message: participant %s %s\r\nConference: %s\r\nChannel: %s", ast_channel_name(participant->chan), participant->features.mute ? "muted" : "unmuted", bridge->b_profile.name, ast_channel_name(participant->chan));
+ /* Set user level mute request. */
+ participant->muted = mute ? 1 : 0;
+
+ conf_update_user_mute(participant);
+ ast_test_suite_event_notify("CONF_MUTE",
+ "Message: participant %s %s\r\n"
+ "Conference: %s\r\n"
+ "Channel: %s",
+ ast_channel_name(participant->chan),
+ mute ? "muted" : "unmuted",
+ bridge->b_profile.name,
+ ast_channel_name(participant->chan));
} else {
res = -2;;
}
@@ -2596,6 +2649,7 @@
"Channel: %s\r\n"
"Admin: %s\r\n"
"MarkedUser: %s\r\n"
+ "Muted: %s\r\n"
"\r\n",
id_text,
bridge->name,
@@ -2603,7 +2657,8 @@
S_COR(ast_channel_caller(participant->chan)->id.name.valid, ast_channel_caller(participant->chan)->id.name.str, "<no name>"),
ast_channel_name(participant->chan),
ast_test_flag(&participant->u_profile, USER_OPT_ADMIN) ? "Yes" : "No",
- ast_test_flag(&participant->u_profile, USER_OPT_MARKEDUSER) ? "Yes" : "No");
+ ast_test_flag(&participant->u_profile, USER_OPT_MARKEDUSER) ? "Yes" : "No",
+ participant->muted ? "Yes" : "No");
}
static int action_confbridgelist(struct mansession *s, const struct message *m)
@@ -3051,11 +3106,11 @@
{
struct conference_bridge_user *only_participant = AST_LIST_FIRST(&conference_bridge->active_list);
- /* Turn on MOH/mute if the single participant is set up for it */
+ /* Turn on MOH if the single participant is set up for it */
if (ast_test_flag(&only_participant->u_profile, USER_OPT_MUSICONHOLD)) {
- only_participant->features.mute = 1;
conf_moh_start(only_participant);
}
+ conf_update_user_mute(only_participant);
}
void conf_remove_user_waiting(struct conference_bridge *conference_bridge, struct conference_bridge_user *cbu)
diff --git a/apps/confbridge/conf_state.c b/apps/confbridge/conf_state.c
index ea5ab10..5b3893f 100644
--- a/apps/confbridge/conf_state.c
+++ b/apps/confbridge/conf_state.c
@@ -57,12 +57,11 @@
*/
static void conf_mute_moh_inactive_waitmarked(struct conference_bridge_user *user)
{
- /* Be sure we are muted so we can't talk to anybody else waiting */
- user->features.mute = 1;
/* Start music on hold if needed */
if (ast_test_flag(&user->u_profile, USER_OPT_MUSICONHOLD)) {
conf_moh_start(user);
}
+ conf_update_user_mute(user);
}
void conf_default_join_waitmarked(struct conference_bridge_user *cbu)
diff --git a/apps/confbridge/conf_state_inactive.c b/apps/confbridge/conf_state_inactive.c
index 80210fc..31cc6f1 100644
--- a/apps/confbridge/conf_state_inactive.c
+++ b/apps/confbridge/conf_state_inactive.c
@@ -61,7 +61,7 @@
static void join_marked(struct conference_bridge_user *cbu)
{
conf_add_user_marked(cbu->conference_bridge, cbu);
- conf_handle_second_active(cbu->conference_bridge);
+ conf_update_user_mute(cbu);
conf_change_state(cbu, CONF_STATE_MULTI_MARKED);
}
diff --git a/apps/confbridge/conf_state_multi.c b/apps/confbridge/conf_state_multi.c
index 5dcd8f4..689db8a 100644
--- a/apps/confbridge/conf_state_multi.c
+++ b/apps/confbridge/conf_state_multi.c
@@ -54,11 +54,13 @@
static void join_unmarked(struct conference_bridge_user *cbu)
{
conf_add_user_active(cbu->conference_bridge, cbu);
+ conf_update_user_mute(cbu);
}
static void join_marked(struct conference_bridge_user *cbu)
{
conf_add_user_marked(cbu->conference_bridge, cbu);
+ conf_update_user_mute(cbu);
conf_change_state(cbu, CONF_STATE_MULTI_MARKED);
}
diff --git a/apps/confbridge/conf_state_multi_marked.c b/apps/confbridge/conf_state_multi_marked.c
index ff4b38d..6089ac6 100644
--- a/apps/confbridge/conf_state_multi_marked.c
+++ b/apps/confbridge/conf_state_multi_marked.c
@@ -60,11 +60,13 @@
static void join_active(struct conference_bridge_user *cbu)
{
conf_add_user_active(cbu->conference_bridge, cbu);
+ conf_update_user_mute(cbu);
}
static void join_marked(struct conference_bridge_user *cbu)
{
conf_add_user_marked(cbu->conference_bridge, cbu);
+ conf_update_user_mute(cbu);
}
static void leave_active(struct conference_bridge_user *cbu)
@@ -88,8 +90,8 @@
AST_LIST_TRAVERSE_SAFE_BEGIN(&cbu->conference_bridge->active_list, cbu_iter, list) {
/* Kick ENDMARKED cbu_iters */
if (ast_test_flag(&cbu_iter->u_profile, USER_OPT_ENDMARKED) && !cbu_iter->kicked) {
- if (ast_test_flag(&cbu_iter->u_profile, USER_OPT_WAITMARKED) &&
- !ast_test_flag(&cbu_iter->u_profile, USER_OPT_MARKEDUSER)) {
+ if (ast_test_flag(&cbu_iter->u_profile, USER_OPT_WAITMARKED)
+ && !ast_test_flag(&cbu_iter->u_profile, USER_OPT_MARKEDUSER)) {
AST_LIST_REMOVE_CURRENT(list);
cbu_iter->conference_bridge->activeusers--;
AST_LIST_INSERT_TAIL(&cbu_iter->conference_bridge->waiting_list, cbu_iter, list);
@@ -97,17 +99,18 @@
}
cbu_iter->kicked = 1;
ast_bridge_remove(cbu_iter->conference_bridge->bridge, cbu_iter->chan);
- } else if (ast_test_flag(&cbu_iter->u_profile, USER_OPT_WAITMARKED) &&
- !ast_test_flag(&cbu_iter->u_profile, USER_OPT_MARKEDUSER)) {
+ } else if (ast_test_flag(&cbu_iter->u_profile, USER_OPT_WAITMARKED)
+ && !ast_test_flag(&cbu_iter->u_profile, USER_OPT_MARKEDUSER)) {
AST_LIST_REMOVE_CURRENT(list);
cbu_iter->conference_bridge->activeusers--;
AST_LIST_INSERT_TAIL(&cbu_iter->conference_bridge->waiting_list, cbu_iter, list);
cbu_iter->conference_bridge->waitingusers++;
- /* Handle muting/moh of cbu_iter if necessary */
+
+ /* Handle moh of cbu_iter if necessary */
if (ast_test_flag(&cbu_iter->u_profile, USER_OPT_MUSICONHOLD)) {
- cbu_iter->features.mute = 1;
conf_moh_start(cbu_iter);
}
+ conf_update_user_mute(cbu_iter);
}
}
AST_LIST_TRAVERSE_SAFE_END;
@@ -175,7 +178,7 @@
conf_handle_first_marked_common(cbu);
}
- /* Move all waiting users to active, stopping MOH and umuting if necessary */
+ /* Move all waiting users to active, stopping MOH and unmuting if necessary */
AST_LIST_TRAVERSE_SAFE_BEGIN(&cbu->conference_bridge->waiting_list, cbu_iter, list) {
AST_LIST_REMOVE_CURRENT(list);
cbu->conference_bridge->waitingusers--;
@@ -184,10 +187,7 @@
if (cbu_iter->playing_moh) {
conf_moh_stop(cbu_iter);
}
- /* only unmute them if they are not supposed to start muted */
- if (!ast_test_flag(&cbu_iter->u_profile, USER_OPT_STARTMUTED)) {
- cbu_iter->features.mute = 0;
- }
+ conf_update_user_mute(cbu_iter);
}
AST_LIST_TRAVERSE_SAFE_END;
}
diff --git a/apps/confbridge/conf_state_single.c b/apps/confbridge/conf_state_single.c
index 806ed63..4dd8d56 100644
--- a/apps/confbridge/conf_state_single.c
+++ b/apps/confbridge/conf_state_single.c
@@ -55,6 +55,7 @@
{
conf_add_user_active(cbu->conference_bridge, cbu);
conf_handle_second_active(cbu->conference_bridge);
+ conf_update_user_mute(cbu);
conf_change_state(cbu, CONF_STATE_MULTI);
}
@@ -63,6 +64,7 @@
{
conf_add_user_marked(cbu->conference_bridge, cbu);
conf_handle_second_active(cbu->conference_bridge);
+ conf_update_user_mute(cbu);
conf_change_state(cbu, CONF_STATE_MULTI_MARKED);
}
diff --git a/apps/confbridge/conf_state_single_marked.c b/apps/confbridge/conf_state_single_marked.c
index a7ac578..3a64a74 100644
--- a/apps/confbridge/conf_state_single_marked.c
+++ b/apps/confbridge/conf_state_single_marked.c
@@ -54,6 +54,7 @@
{
conf_add_user_active(cbu->conference_bridge, cbu);
conf_handle_second_active(cbu->conference_bridge);
+ conf_update_user_mute(cbu);
conf_change_state(cbu, CONF_STATE_MULTI_MARKED);
}
@@ -62,6 +63,7 @@
{
conf_add_user_marked(cbu->conference_bridge, cbu);
conf_handle_second_active(cbu->conference_bridge);
+ conf_update_user_mute(cbu);
conf_change_state(cbu, CONF_STATE_MULTI_MARKED);
}
diff --git a/apps/confbridge/include/confbridge.h b/apps/confbridge/include/confbridge.h
index f9fc93d..50e223e 100644
--- a/apps/confbridge/include/confbridge.h
+++ b/apps/confbridge/include/confbridge.h
@@ -210,7 +210,7 @@
unsigned int markedusers; /*!< Number of marked users present */
unsigned int waitingusers; /*!< Number of waiting users present */
unsigned int locked:1; /*!< Is this conference bridge locked? */
- unsigned int muted:1; /*!< Is this conference bridge muted? */
+ unsigned int muted:1; /*!< Is this conference bridge muted? */
unsigned int record_state:2; /*!< Whether recording is started, stopped, or should exit */
struct ast_channel *playback_chan; /*!< Channel used for playback into the conference bridge */
struct ast_channel *record_chan; /*!< Channel used for recording the conference */
@@ -238,6 +238,7 @@
struct ast_bridge_features features; /*!< Bridge features structure */
struct ast_bridge_tech_optimizations tech_args; /*!< Bridge technology optimizations for talk detection */
unsigned int suspended_moh; /*!< Count of active suspended MOH actions. */
+ unsigned int muted:1; /*!< Has the user requested to be muted? */
unsigned int kicked:1; /*!< User has been kicked from the conference */
unsigned int playing_moh:1; /*!< MOH is currently being played to the user */
AST_LIST_HEAD_NOLOCK(, post_join_action) post_join_list; /*!< List of sounds to play after joining */;
@@ -364,6 +365,15 @@
void conf_ended(struct conference_bridge *conference_bridge);
/*!
+ * \brief Update the actual mute status of the user and set it on the bridge.
+ *
+ * \param user User to update the mute status.
+ *
+ * \return Nothing
+ */
+void conf_update_user_mute(struct conference_bridge_user *user);
+
+/*!
* \brief Stop MOH for the conference user.
*
* \param user Conference user to stop MOH on.
--
To view, visit https://gerrit.asterisk.org/2118
To unsubscribe, visit https://gerrit.asterisk.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Iec7bd77736847af6a5f70b8d279f85c6e2082ee2
Gerrit-PatchSet: 1
Gerrit-Project: asterisk
Gerrit-Branch: certified/11.6
Gerrit-Owner: Richard Mudgett <rmudgett at digium.com>
More information about the asterisk-code-review
mailing list