Add a CONFBRIDGE_RESULT channel variable to discern why a channel left a ConfBridge.

Review: https://reviewboard.asterisk.org/r/3009



git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@403526 65c4cc65-6c06-0410-ace0-fbb531ad65f3
changes/97/197/1
Mark Michelson 12 years ago
parent 5730410861
commit d421818c3d

@ -21,6 +21,10 @@ ConfBridge
menus, bridge settings, and user settings that have been applied by the menus, bridge settings, and user settings that have been applied by the
CONFBRIDGE dialplan function. CONFBRIDGE dialplan function.
* The ConfBridge dialplan application now sets a channel variable,
CONFBRIGE_RESULT, upon exiting. This variable can be used to determine
how a channel exited the conference.
* Added conference user option 'announce_join_leave_review'. This option * Added conference user option 'announce_join_leave_review'. This option
implies 'announce_join_leave' with the added effect that the user will implies 'announce_join_leave' with the added effect that the user will
be asked if they want to confirm or re-record the recording of their be asked if they want to confirm or re-record the recording of their

@ -109,6 +109,16 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
<description> <description>
<para>Enters the user into a specified conference bridge. The user can <para>Enters the user into a specified conference bridge. The user can
exit the conference by hangup or DTMF menu option.</para> exit the conference by hangup or DTMF menu option.</para>
<para>This application sets the following channel variable upon completion:</para>
<variablelist>
<variable name="CONFBRIDGE_RESULT">
<value name="FAILED">The channel encountered an error and could not enter the conference.</value>
<value name="HANGUP">The channel exited the conference by hanging up.</value>
<value name="KICKED">The channel was kicked from the conference.</value>
<value name="ENDMARKED">The channel left the conference as a result of the last marked user leaving.</value>
<value name="DTMF">The channel pressed a DTMF sequence to exit the conference.</value>
</variable>
</variablelist>
</description> </description>
<see-also> <see-also>
<ref type="application">ConfBridge</ref> <ref type="application">ConfBridge</ref>
@ -1564,11 +1574,13 @@ static int confbridge_exec(struct ast_channel *chan, const char *data)
} }
if (ast_bridge_features_init(&user.features)) { if (ast_bridge_features_init(&user.features)) {
pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
res = -1; res = -1;
goto confbridge_cleanup; goto confbridge_cleanup;
} }
if (ast_strlen_zero(data)) { if (ast_strlen_zero(data)) {
pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
ast_log(LOG_WARNING, "%s requires an argument (conference name[,options])\n", app); ast_log(LOG_WARNING, "%s requires an argument (conference name[,options])\n", app);
res = -1; res = -1;
goto confbridge_cleanup; goto confbridge_cleanup;
@ -1584,6 +1596,7 @@ static int confbridge_exec(struct ast_channel *chan, const char *data)
b_profile_name = args.b_profile_name; b_profile_name = args.b_profile_name;
} }
if (!conf_find_bridge_profile(chan, b_profile_name, &user.b_profile)) { if (!conf_find_bridge_profile(chan, b_profile_name, &user.b_profile)) {
pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
ast_log(LOG_WARNING, "Conference bridge profile %s does not exist\n", b_profile_name ? ast_log(LOG_WARNING, "Conference bridge profile %s does not exist\n", b_profile_name ?
b_profile_name : DEFAULT_BRIDGE_PROFILE); b_profile_name : DEFAULT_BRIDGE_PROFILE);
res = -1; res = -1;
@ -1595,6 +1608,7 @@ static int confbridge_exec(struct ast_channel *chan, const char *data)
u_profile_name = args.u_profile_name; u_profile_name = args.u_profile_name;
} }
if (!conf_find_user_profile(chan, u_profile_name, &user.u_profile)) { if (!conf_find_user_profile(chan, u_profile_name, &user.u_profile)) {
pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
ast_log(LOG_WARNING, "Conference user profile %s does not exist\n", u_profile_name ? ast_log(LOG_WARNING, "Conference user profile %s does not exist\n", u_profile_name ?
u_profile_name : DEFAULT_USER_PROFILE); u_profile_name : DEFAULT_USER_PROFILE);
res = -1; res = -1;
@ -1607,6 +1621,7 @@ static int confbridge_exec(struct ast_channel *chan, const char *data)
* prompted for requardless of quiet setting. */ * prompted for requardless of quiet setting. */
if (!ast_strlen_zero(user.u_profile.pin)) { if (!ast_strlen_zero(user.u_profile.pin)) {
if (conf_get_pin(chan, &user)) { if (conf_get_pin(chan, &user)) {
pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
res = -1; /* invalid PIN */ res = -1; /* invalid PIN */
goto confbridge_cleanup; goto confbridge_cleanup;
} }
@ -1625,6 +1640,7 @@ static int confbridge_exec(struct ast_channel *chan, const char *data)
} }
if (conf_set_menu_to_user(chan, &user, menu_profile_name)) { if (conf_set_menu_to_user(chan, &user, menu_profile_name)) {
pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
ast_log(LOG_WARNING, "Conference menu profile %s does not exist\n", menu_profile_name ? ast_log(LOG_WARNING, "Conference menu profile %s does not exist\n", menu_profile_name ?
menu_profile_name : DEFAULT_MENU_PROFILE); menu_profile_name : DEFAULT_MENU_PROFILE);
res = -1; res = -1;
@ -1651,11 +1667,13 @@ static int confbridge_exec(struct ast_channel *chan, const char *data)
char *conf_name = ast_strdup(args.conf_name); /* this is freed during feature cleanup */ char *conf_name = ast_strdup(args.conf_name); /* this is freed during feature cleanup */
if (!conf_name) { if (!conf_name) {
pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
res = -1; res = -1;
goto confbridge_cleanup; goto confbridge_cleanup;
} }
if (ast_bridge_talk_detector_hook(&user.features, conf_handle_talker_cb, if (ast_bridge_talk_detector_hook(&user.features, conf_handle_talker_cb,
conf_name, conf_handle_talker_destructor, AST_BRIDGE_HOOK_REMOVE_ON_PULL)) { conf_name, conf_handle_talker_destructor, AST_BRIDGE_HOOK_REMOVE_ON_PULL)) {
pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
ast_free(conf_name); ast_free(conf_name);
res = -1; res = -1;
goto confbridge_cleanup; goto confbridge_cleanup;
@ -1664,6 +1682,7 @@ static int confbridge_exec(struct ast_channel *chan, const char *data)
/* 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");
res = -1; res = -1;
goto confbridge_cleanup; goto confbridge_cleanup;
} }
@ -1731,6 +1750,11 @@ static int confbridge_exec(struct ast_channel *chan, const char *data)
&user.features, &user.features,
&user.tech_args, &user.tech_args,
0); 0);
if (!user.kicked && ast_check_hangup(chan)) {
pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "HANGUP");
}
send_leave_event(user.chan, conference); send_leave_event(user.chan, conference);
/* if we're shutting down, don't attempt to do further processing */ /* if we're shutting down, don't attempt to do further processing */
@ -1967,6 +1991,7 @@ static int action_kick_last(struct confbridge_conference *conference,
""); "");
} else if (last_user) { } else if (last_user) {
last_user->kicked = 1; last_user->kicked = 1;
pbx_builtin_setvar_helper(last_user->chan, "CONFBRIDGE_RESULT", "KICKED");
ast_bridge_remove(conference->bridge, last_user->chan); ast_bridge_remove(conference->bridge, last_user->chan);
ao2_unlock(conference); ao2_unlock(conference);
} }
@ -2104,6 +2129,7 @@ static int execute_menu_entry(struct confbridge_conference *conference,
res |= action_kick_last(conference, bridge_channel, user); res |= action_kick_last(conference, bridge_channel, user);
break; break;
case MENU_ACTION_LEAVE: case MENU_ACTION_LEAVE:
pbx_builtin_setvar_helper(bridge_channel->chan, "CONFBRIDGE_RESULT", "DTMF");
ao2_lock(conference); ao2_lock(conference);
ast_bridge_remove(conference->bridge, bridge_channel->chan); ast_bridge_remove(conference->bridge, bridge_channel->chan);
ast_test_suite_event_notify("CONF_MENU_LEAVE", ast_test_suite_event_notify("CONF_MENU_LEAVE",
@ -2152,10 +2178,12 @@ static int kick_conference_participant(struct confbridge_conference *conference,
AST_LIST_TRAVERSE(&conference->active_list, user, list) { AST_LIST_TRAVERSE(&conference->active_list, user, list) {
if (!strcasecmp(ast_channel_name(user->chan), channel)) { if (!strcasecmp(ast_channel_name(user->chan), channel)) {
user->kicked = 1; user->kicked = 1;
pbx_builtin_setvar_helper(user->chan, "CONFBRIDGE_RESULT", "KICKED");
ast_bridge_remove(conference->bridge, user->chan); ast_bridge_remove(conference->bridge, user->chan);
return 0; return 0;
} else if (!strcasecmp("all", channel)) { } else if (!strcasecmp("all", channel)) {
user->kicked = 1; user->kicked = 1;
pbx_builtin_setvar_helper(user->chan, "CONFBRIDGE_RESULT", "KICKED");
ast_bridge_remove(conference->bridge, user->chan); ast_bridge_remove(conference->bridge, user->chan);
res = 0; res = 0;
} }
@ -2163,10 +2191,12 @@ static int kick_conference_participant(struct confbridge_conference *conference,
AST_LIST_TRAVERSE(&conference->waiting_list, user, list) { AST_LIST_TRAVERSE(&conference->waiting_list, user, list) {
if (!strcasecmp(ast_channel_name(user->chan), channel)) { if (!strcasecmp(ast_channel_name(user->chan), channel)) {
user->kicked = 1; user->kicked = 1;
pbx_builtin_setvar_helper(user->chan, "CONFBRIDGE_RESULT", "KICKED");
ast_bridge_remove(conference->bridge, user->chan); ast_bridge_remove(conference->bridge, user->chan);
return 0; return 0;
} else if (!strcasecmp("all", channel)) { } else if (!strcasecmp("all", channel)) {
user->kicked = 1; user->kicked = 1;
pbx_builtin_setvar_helper(user->chan, "CONFBRIDGE_RESULT", "KICKED");
ast_bridge_remove(conference->bridge, user->chan); ast_bridge_remove(conference->bridge, user->chan);
res = 0; res = 0;
} }

@ -38,6 +38,7 @@
#include "include/confbridge.h" #include "include/confbridge.h"
#include "asterisk/musiconhold.h" #include "asterisk/musiconhold.h"
#include "include/conf_state.h" #include "include/conf_state.h"
#include "asterisk/pbx.h"
static void join_active(struct confbridge_user *user); static void join_active(struct confbridge_user *user);
static void join_marked(struct confbridge_user *user); static void join_marked(struct confbridge_user *user);
@ -105,6 +106,7 @@ static void leave_marked(struct confbridge_user *user)
user_iter->conference->waitingusers++; user_iter->conference->waitingusers++;
} }
user_iter->kicked = 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); ast_bridge_remove(user_iter->conference->bridge, user_iter->chan);
} else if (ast_test_flag(&user_iter->u_profile, USER_OPT_WAITMARKED) } else 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_MARKEDUSER)) {

Loading…
Cancel
Save