mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-03 11:11:05 +00:00
Merge topic 'ASTERISK-20987' into 13
* changes: app_confbridge: Add ability to get the muted conference state. app_confbridge.c: Update CONFBRIDGE and CONFBRIDGE_INFO documentation. app_confbridge: Make non-admin users join a muted conference muted.
This commit is contained in:
12
CHANGES
12
CHANGES
@@ -12,6 +12,17 @@
|
|||||||
--- Functionality changes from Asterisk 13.7.0 to Asterisk 13.8.0 ------------
|
--- 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
|
res_pjproject
|
||||||
------------------
|
------------------
|
||||||
* This module is the successor of res_pjsip_log_forwarder. As well as
|
* This module is the successor of res_pjsip_log_forwarder. As well as
|
||||||
@@ -22,7 +33,6 @@ res_pjproject
|
|||||||
|
|
||||||
res_pjsip
|
res_pjsip
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
* Added new global option (regcontext) to pjsip. When set, Asterisk will
|
* Added new global option (regcontext) to pjsip. When set, Asterisk will
|
||||||
dynamically create and destroy a NoOp priority 1 extension
|
dynamically create and destroy a NoOp priority 1 extension
|
||||||
for a given endpoint who registers or unregisters with us.
|
for a given endpoint who registers or unregisters with us.
|
||||||
|
@@ -130,32 +130,51 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
|||||||
</application>
|
</application>
|
||||||
<function name="CONFBRIDGE" language="en_US">
|
<function name="CONFBRIDGE" language="en_US">
|
||||||
<synopsis>
|
<synopsis>
|
||||||
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.
|
||||||
</synopsis>
|
</synopsis>
|
||||||
<syntax>
|
<syntax>
|
||||||
<parameter name="type" required="true">
|
<parameter name="type" required="true">
|
||||||
<para>Type refers to which type of profile the option belongs too. Type can be <literal>bridge</literal>, <literal>user</literal>, or
|
<para>To what type of conference profile the option applies.</para>
|
||||||
<literal>menu</literal>.</para>
|
<enumlist>
|
||||||
|
<enum name="bridge"></enum>
|
||||||
|
<enum name="menu"></enum>
|
||||||
|
<enum name="user"></enum>
|
||||||
|
</enumlist>
|
||||||
</parameter>
|
</parameter>
|
||||||
<parameter name="option" required="true">
|
<parameter name="option" required="true">
|
||||||
<para>Option refers to <filename>confbridge.conf</filename> option that is being set dynamically on this channel, or
|
<para>Option refers to a <filename>confbridge.conf</filename> option
|
||||||
<literal>clear</literal> to remove already applied options from the channel.</para>
|
that is being set dynamically on this channel, or <literal>clear</literal>
|
||||||
|
to remove already applied profile options from the channel.</para>
|
||||||
</parameter>
|
</parameter>
|
||||||
</syntax>
|
</syntax>
|
||||||
<description>
|
<description>
|
||||||
|
<para>A custom profile uses the default profile type settings defined in
|
||||||
|
<filename>confbridge.conf</filename> as defaults if the profile template
|
||||||
|
is not explicitly specified first.</para>
|
||||||
|
<para>For <literal>bridge</literal> profiles the default template is <literal>default_bridge</literal>.</para>
|
||||||
|
<para>For <literal>menu</literal> profiles the default template is <literal>default_menu</literal>.</para>
|
||||||
|
<para>For <literal>user</literal> profiles the default template is <literal>default_user</literal>.</para>
|
||||||
<para>---- Example 1 ----</para>
|
<para>---- Example 1 ----</para>
|
||||||
<para>In this example the custom set user profile on this channel will automatically be used by the ConfBridge app.</para>
|
<para>In this example the custom user profile set on the channel will
|
||||||
|
automatically be used by the ConfBridge application.</para>
|
||||||
<para>exten => 1,1,Answer()</para>
|
<para>exten => 1,1,Answer()</para>
|
||||||
<para>exten => 1,n,Set(CONFBRIDGE(user,announce_join_leave)=yes)</para>
|
<para>; In this example the effect of the following line is</para>
|
||||||
<para>exten => 1,n,Set(CONFBRIDGE(user,startmuted)=yes)</para>
|
<para>; implied:</para>
|
||||||
<para>exten => 1,n,ConfBridge(1) </para>
|
<para>; same => n,Set(CONFBRIDGE(user,template)=default_user)</para>
|
||||||
|
<para>same => n,Set(CONFBRIDGE(user,announce_join_leave)=yes)</para>
|
||||||
|
<para>same => n,Set(CONFBRIDGE(user,startmuted)=yes)</para>
|
||||||
|
<para>same => n,ConfBridge(1) </para>
|
||||||
<para>---- Example 2 ----</para>
|
<para>---- Example 2 ----</para>
|
||||||
<para>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.</para>
|
<para>This example shows how to use a predefined user profile in
|
||||||
|
<filename>confbridge.conf</filename> as a template for a dynamic profile.
|
||||||
|
Here we make an admin/marked user out of the <literal>my_user</literal>
|
||||||
|
profile that you define in <filename>confbridge.conf</filename>.</para>
|
||||||
<para>exten => 1,1,Answer()</para>
|
<para>exten => 1,1,Answer()</para>
|
||||||
<para>exten => 1,n,Set(CONFBRIDGE(user,template)=default_user)</para>
|
<para>same => n,Set(CONFBRIDGE(user,template)=my_user)</para>
|
||||||
<para>exten => 1,n,Set(CONFBRIDGE(user,admin)=yes)</para>
|
<para>same => n,Set(CONFBRIDGE(user,admin)=yes)</para>
|
||||||
<para>exten => 1,n,Set(CONFBRIDGE(user,marked)=yes)</para>
|
<para>same => n,Set(CONFBRIDGE(user,marked)=yes)</para>
|
||||||
<para>exten => 1,n,ConfBridge(1)</para>
|
<para>same => n,ConfBridge(1)</para>
|
||||||
</description>
|
</description>
|
||||||
</function>
|
</function>
|
||||||
<function name="CONFBRIDGE_INFO" language="en_US">
|
<function name="CONFBRIDGE_INFO" language="en_US">
|
||||||
@@ -164,14 +183,32 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
|||||||
</synopsis>
|
</synopsis>
|
||||||
<syntax>
|
<syntax>
|
||||||
<parameter name="type" required="true">
|
<parameter name="type" required="true">
|
||||||
<para>Type can be <literal>parties</literal>, <literal>admins</literal>, <literal>marked</literal>, or <literal>locked</literal>.</para>
|
<para>What conference information is requested.</para>
|
||||||
|
<enumlist>
|
||||||
|
<enum name="admins">
|
||||||
|
<para>Get the number of admin users in the conference.</para>
|
||||||
|
</enum>
|
||||||
|
<enum name="locked">
|
||||||
|
<para>Determine if the conference is locked. (0 or 1)</para>
|
||||||
|
</enum>
|
||||||
|
<enum name="marked">
|
||||||
|
<para>Get the number of marked users in the conference.</para>
|
||||||
|
</enum>
|
||||||
|
<enum name="muted">
|
||||||
|
<para>Determine if the conference is muted. (0 or 1)</para>
|
||||||
|
</enum>
|
||||||
|
<enum name="parties">
|
||||||
|
<para>Get the number of users in the conference.</para>
|
||||||
|
</enum>
|
||||||
|
</enumlist>
|
||||||
</parameter>
|
</parameter>
|
||||||
<parameter name="conf" required="true">
|
<parameter name="conf" required="true">
|
||||||
<para>Conf refers to the name of the conference being referenced.</para>
|
<para>The name of the conference being referenced.</para>
|
||||||
</parameter>
|
</parameter>
|
||||||
</syntax>
|
</syntax>
|
||||||
<description>
|
<description>
|
||||||
<para>This function returns a non-negative integer for valid conference identifiers (0 or 1 for <literal>locked</literal>) and "" for invalid conference identifiers.</para>
|
<para>This function returns a non-negative integer for valid conference
|
||||||
|
names and an empty string for invalid conference names.</para>
|
||||||
</description>
|
</description>
|
||||||
</function>
|
</function>
|
||||||
<manager name="ConfbridgeList" language="en_US">
|
<manager name="ConfbridgeList" language="en_US">
|
||||||
@@ -1310,6 +1347,13 @@ static struct confbridge_conference *join_conference_bridge(const char *conferen
|
|||||||
|
|
||||||
ao2_lock(conference);
|
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
|
* Suspend any MOH until the user actually joins the bridge of
|
||||||
* the conference. This way any pre-join file playback does not
|
* 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 */
|
/* Look for a conference bridge matching the provided name */
|
||||||
if (!(conference = join_conference_bridge(args.conf_name, &user))) {
|
if (!(conference = join_conference_bridge(args.conf_name, &user))) {
|
||||||
pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
|
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) {
|
if (a->argc == 2) {
|
||||||
struct ao2_iterator iter;
|
struct ao2_iterator iter;
|
||||||
|
|
||||||
ast_cli(a->fd, "Conference Bridge Name Users Marked Locked?\n");
|
ast_cli(a->fd, "Conference Bridge Name Users Marked Locked Muted\n");
|
||||||
ast_cli(a->fd, "================================ ====== ====== ========\n");
|
ast_cli(a->fd, "================================ ====== ====== ====== =====\n");
|
||||||
iter = ao2_iterator_init(conference_bridges, 0);
|
iter = ao2_iterator_init(conference_bridges, 0);
|
||||||
while ((conference = ao2_iterator_next(&iter))) {
|
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_ref(conference, -1);
|
||||||
}
|
}
|
||||||
ao2_iterator_destroy(&iter);
|
ao2_iterator_destroy(&iter);
|
||||||
@@ -2942,12 +2985,14 @@ static int action_confbridgelistrooms(struct mansession *s, const struct message
|
|||||||
"Parties: %u\r\n"
|
"Parties: %u\r\n"
|
||||||
"Marked: %u\r\n"
|
"Marked: %u\r\n"
|
||||||
"Locked: %s\r\n"
|
"Locked: %s\r\n"
|
||||||
|
"Muted: %s\r\n"
|
||||||
"\r\n",
|
"\r\n",
|
||||||
id_text,
|
id_text,
|
||||||
conference->name,
|
conference->name,
|
||||||
conference->activeusers + conference->waitingusers,
|
conference->activeusers + conference->waitingusers,
|
||||||
conference->markedusers,
|
conference->markedusers,
|
||||||
conference->locked ? "Yes" : "No");
|
AST_YESNO(conference->locked),
|
||||||
|
AST_YESNO(conference->muted));
|
||||||
ao2_unlock(conference);
|
ao2_unlock(conference);
|
||||||
|
|
||||||
ao2_ref(conference, -1);
|
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 */
|
/* get the correct count for the type requested */
|
||||||
ao2_lock(conference);
|
ao2_lock(conference);
|
||||||
if (!strncasecmp(args.type, "parties", 7)) {
|
if (!strcasecmp(args.type, "parties")) {
|
||||||
AST_LIST_TRAVERSE(&conference->active_list, user, list) {
|
AST_LIST_TRAVERSE(&conference->active_list, user, list) {
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
AST_LIST_TRAVERSE(&conference->waiting_list, user, list) {
|
AST_LIST_TRAVERSE(&conference->waiting_list, user, list) {
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
} else if (!strncasecmp(args.type, "admins", 6)) {
|
} else if (!strcasecmp(args.type, "admins")) {
|
||||||
AST_LIST_TRAVERSE(&conference->active_list, user, list) {
|
AST_LIST_TRAVERSE(&conference->active_list, user, list) {
|
||||||
if (ast_test_flag(&user->u_profile, USER_OPT_ADMIN)) {
|
if (ast_test_flag(&user->u_profile, USER_OPT_ADMIN)) {
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (!strncasecmp(args.type, "marked", 6)) {
|
} else if (!strcasecmp(args.type, "marked")) {
|
||||||
AST_LIST_TRAVERSE(&conference->active_list, user, list) {
|
AST_LIST_TRAVERSE(&conference->active_list, user, list) {
|
||||||
if (ast_test_flag(&user->u_profile, USER_OPT_MARKEDUSER)) {
|
if (ast_test_flag(&user->u_profile, USER_OPT_MARKEDUSER)) {
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (!strncasecmp(args.type, "locked", 6)) {
|
} else if (!strcasecmp(args.type, "locked")) {
|
||||||
count = conference->locked;
|
count = conference->locked;
|
||||||
|
} else if (!strcasecmp(args.type, "muted")) {
|
||||||
|
count = conference->muted;
|
||||||
} else {
|
} else {
|
||||||
ast_log(LOG_ERROR, "Invalid keyword '%s' passed to CONFBRIDGE_INFO. Should be one of: "
|
ast_log(LOG_ERROR, "Invalid keyword '%s' passed to CONFBRIDGE_INFO.\n", args.type);
|
||||||
"parties, admins, marked, or locked.\n", args.type);
|
|
||||||
}
|
}
|
||||||
snprintf(buf, len, "%d", count);
|
snprintf(buf, len, "%d", count);
|
||||||
ao2_unlock(conference);
|
ao2_unlock(conference);
|
||||||
|
@@ -334,10 +334,12 @@ type=bridge
|
|||||||
; upon release of the video src.
|
; upon release of the video src.
|
||||||
|
|
||||||
; admin_toggle_mute_participants ; This action allows an administrator to toggle the mute
|
; admin_toggle_mute_participants ; This action allows an administrator to toggle the mute
|
||||||
; state for all non-admins within a conference. All
|
; state for all non-admins within a conference.
|
||||||
; admin users are unaffected by this option. Note that all
|
; Subsequent non-admins joining a muted conference will
|
||||||
; users, regardless of their admin status, are notified
|
; start muted. All admin users are unaffected by this
|
||||||
; that the conference is muted.
|
; 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
|
; participant_count ; This action plays back the number of participants currently
|
||||||
; in a conference
|
; in a conference
|
||||||
|
Reference in New Issue
Block a user