diff --git a/CHANGES b/CHANGES
index 4a5ae2cf30..84ecff5001 100644
--- a/CHANGES
+++ b/CHANGES
@@ -12,6 +12,17 @@
--- Functionality changes from Asterisk 13.7.0 to Asterisk 13.8.0 ------------
------------------------------------------------------------------------------
+app_confbridge
+------------------
+ * Added CONFBRIDGE_INFO(muted,) for querying the muted conference state.
+
+ * Added Muted header to AMI ConfbridgeListRooms action response list events
+ to indicate the muted conference state.
+
+ * Added Muted column to CLI "confbridge list" output to indicate the muted
+ conference state and made the locked column a yes/no value instead of a
+ locked/unlocked value.
+
res_pjproject
------------------
* This module is the successor of res_pjsip_log_forwarder. As well as
@@ -22,7 +33,6 @@ res_pjproject
res_pjsip
------------------
-
* Added new global option (regcontext) to pjsip. When set, Asterisk will
dynamically create and destroy a NoOp priority 1 extension
for a given endpoint who registers or unregisters with us.
diff --git a/apps/app_confbridge.c b/apps/app_confbridge.c
index 5976d39db4..ad2a511bfa 100644
--- a/apps/app_confbridge.c
+++ b/apps/app_confbridge.c
@@ -130,32 +130,51 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
- Set a custom dynamic bridge, user, or menu profile on a channel for the ConfBridge application using the same options defined in confbridge.conf.
+ Set a custom dynamic bridge, user, or menu profile on a channel for the
+ ConfBridge application using the same options available in confbridge.conf.
- Type refers to which type of profile the option belongs too. Type can be bridge, user, or
- menu.
+ To what type of conference profile the option applies.
+
+
+
+
+
- Option refers to confbridge.conf option that is being set dynamically on this channel, or
- clear to remove already applied options from the channel.
+ Option refers to a confbridge.conf option
+ that is being set dynamically on this channel, or clear
+ to remove already applied profile options from the channel.
+ A custom profile uses the default profile type settings defined in
+ confbridge.conf as defaults if the profile template
+ is not explicitly specified first.
+ For bridge profiles the default template is default_bridge.
+ For menu profiles the default template is default_menu.
+ For user profiles the default template is default_user.
---- Example 1 ----
- In this example the custom set user profile on this channel will automatically be used by the ConfBridge app.
- exten => 1,1,Answer()
- exten => 1,n,Set(CONFBRIDGE(user,announce_join_leave)=yes)
- exten => 1,n,Set(CONFBRIDGE(user,startmuted)=yes)
- exten => 1,n,ConfBridge(1)
+ In this example the custom user profile set on the channel will
+ automatically be used by the ConfBridge application.
+ exten => 1,1,Answer()
+ ; In this example the effect of the following line is
+ ; implied:
+ ; same => n,Set(CONFBRIDGE(user,template)=default_user)
+ same => n,Set(CONFBRIDGE(user,announce_join_leave)=yes)
+ same => n,Set(CONFBRIDGE(user,startmuted)=yes)
+ same => n,ConfBridge(1)
---- Example 2 ----
- This example shows how to use a predefined user or bridge profile in confbridge.conf as a template for a dynamic profile. Here we make a admin/marked user out of the default_user profile that is already defined in confbridge.conf.
- exten => 1,1,Answer()
- exten => 1,n,Set(CONFBRIDGE(user,template)=default_user)
- exten => 1,n,Set(CONFBRIDGE(user,admin)=yes)
- exten => 1,n,Set(CONFBRIDGE(user,marked)=yes)
- exten => 1,n,ConfBridge(1)
+ This example shows how to use a predefined user profile in
+ confbridge.conf as a template for a dynamic profile.
+ Here we make an admin/marked user out of the my_user
+ profile that you define in confbridge.conf.
+ exten => 1,1,Answer()
+ same => n,Set(CONFBRIDGE(user,template)=my_user)
+ same => n,Set(CONFBRIDGE(user,admin)=yes)
+ same => n,Set(CONFBRIDGE(user,marked)=yes)
+ same => n,ConfBridge(1)
@@ -164,14 +183,32 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
- Type can be parties, admins, marked, or locked.
+ What conference information is requested.
+
+
+ Get the number of admin users in the conference.
+
+
+ Determine if the conference is locked. (0 or 1)
+
+
+ Get the number of marked users in the conference.
+
+
+ Determine if the conference is muted. (0 or 1)
+
+
+ Get the number of users in the conference.
+
+
- Conf refers to the name of the conference being referenced.
+ The name of the conference being referenced.
- This function returns a non-negative integer for valid conference identifiers (0 or 1 for locked) and "" for invalid conference identifiers.
+ This function returns a non-negative integer for valid conference
+ names and an empty string for invalid conference names.
@@ -1310,6 +1347,13 @@ static struct confbridge_conference *join_conference_bridge(const char *conferen
ao2_lock(conference);
+ /* Determine if the new user should join the conference muted. */
+ if (ast_test_flag(&user->u_profile, USER_OPT_STARTMUTED)
+ || (!ast_test_flag(&user->u_profile, USER_OPT_ADMIN) && conference->muted)) {
+ /* Set user level mute request. */
+ user->muted = 1;
+ }
+
/*
* Suspend any MOH until the user actually joins the bridge of
* the conference. This way any pre-join file playback does not
@@ -1727,12 +1771,6 @@ static int confbridge_exec(struct ast_channel *chan, const char *data)
}
}
- /* If the caller should be joined already muted, set the flag before we join. */
- if (ast_test_flag(&user.u_profile, USER_OPT_STARTMUTED)) {
- /* Set user level mute request. */
- user.muted = 1;
- }
-
/* Look for a conference bridge matching the provided name */
if (!(conference = join_conference_bridge(args.conf_name, &user))) {
pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
@@ -2448,11 +2486,16 @@ static char *handle_cli_confbridge_list(struct ast_cli_entry *e, int cmd, struct
if (a->argc == 2) {
struct ao2_iterator iter;
- ast_cli(a->fd, "Conference Bridge Name Users Marked Locked?\n");
- ast_cli(a->fd, "================================ ====== ====== ========\n");
+ ast_cli(a->fd, "Conference Bridge Name Users Marked Locked Muted\n");
+ ast_cli(a->fd, "================================ ====== ====== ====== =====\n");
iter = ao2_iterator_init(conference_bridges, 0);
while ((conference = ao2_iterator_next(&iter))) {
- ast_cli(a->fd, "%-32s %6u %6u %s\n", conference->name, conference->activeusers + conference->waitingusers, conference->markedusers, (conference->locked ? "locked" : "unlocked"));
+ ast_cli(a->fd, "%-32s %6u %6u %-6s %s\n",
+ conference->name,
+ conference->activeusers + conference->waitingusers,
+ conference->markedusers,
+ AST_CLI_YESNO(conference->locked),
+ AST_CLI_YESNO(conference->muted));
ao2_ref(conference, -1);
}
ao2_iterator_destroy(&iter);
@@ -2942,12 +2985,14 @@ static int action_confbridgelistrooms(struct mansession *s, const struct message
"Parties: %u\r\n"
"Marked: %u\r\n"
"Locked: %s\r\n"
+ "Muted: %s\r\n"
"\r\n",
id_text,
conference->name,
conference->activeusers + conference->waitingusers,
conference->markedusers,
- conference->locked ? "Yes" : "No");
+ AST_YESNO(conference->locked),
+ AST_YESNO(conference->muted));
ao2_unlock(conference);
ao2_ref(conference, -1);
@@ -3218,30 +3263,31 @@ static int func_confbridge_info(struct ast_channel *chan, const char *cmd, char
/* get the correct count for the type requested */
ao2_lock(conference);
- if (!strncasecmp(args.type, "parties", 7)) {
+ if (!strcasecmp(args.type, "parties")) {
AST_LIST_TRAVERSE(&conference->active_list, user, list) {
count++;
}
AST_LIST_TRAVERSE(&conference->waiting_list, user, list) {
count++;
}
- } else if (!strncasecmp(args.type, "admins", 6)) {
+ } else if (!strcasecmp(args.type, "admins")) {
AST_LIST_TRAVERSE(&conference->active_list, user, list) {
if (ast_test_flag(&user->u_profile, USER_OPT_ADMIN)) {
count++;
}
}
- } else if (!strncasecmp(args.type, "marked", 6)) {
+ } else if (!strcasecmp(args.type, "marked")) {
AST_LIST_TRAVERSE(&conference->active_list, user, list) {
if (ast_test_flag(&user->u_profile, USER_OPT_MARKEDUSER)) {
count++;
}
}
- } else if (!strncasecmp(args.type, "locked", 6)) {
+ } else if (!strcasecmp(args.type, "locked")) {
count = conference->locked;
+ } else if (!strcasecmp(args.type, "muted")) {
+ count = conference->muted;
} else {
- ast_log(LOG_ERROR, "Invalid keyword '%s' passed to CONFBRIDGE_INFO. Should be one of: "
- "parties, admins, marked, or locked.\n", args.type);
+ ast_log(LOG_ERROR, "Invalid keyword '%s' passed to CONFBRIDGE_INFO.\n", args.type);
}
snprintf(buf, len, "%d", count);
ao2_unlock(conference);
diff --git a/configs/samples/confbridge.conf.sample b/configs/samples/confbridge.conf.sample
index 0419001eb8..d0bdd6fd9b 100644
--- a/configs/samples/confbridge.conf.sample
+++ b/configs/samples/confbridge.conf.sample
@@ -334,10 +334,12 @@ type=bridge
; upon release of the video src.
; admin_toggle_mute_participants ; This action allows an administrator to toggle the mute
- ; state for all non-admins within a conference. All
- ; admin users are unaffected by this option. Note that all
- ; users, regardless of their admin status, are notified
- ; that the conference is muted.
+ ; state for all non-admins within a conference.
+ ; Subsequent non-admins joining a muted conference will
+ ; start muted. All admin users are unaffected by this
+ ; option. Note that all users, regardless of their admin
+ ; status, are notified that the conference is muted when
+ ; the state is toggled.
; participant_count ; This action plays back the number of participants currently
; in a conference