From d421818c3d7b30e1854d2f7628e51617ad23fbdf Mon Sep 17 00:00:00 2001 From: Mark Michelson Date: Mon, 9 Dec 2013 17:29:48 +0000 Subject: [PATCH] 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 | 4 +++ apps/app_confbridge.c | 30 +++++++++++++++++++++++ apps/confbridge/conf_state_multi_marked.c | 2 ++ 3 files changed, 36 insertions(+) diff --git a/CHANGES b/CHANGES index 91cd210bb4..ac63077dc7 100644 --- a/CHANGES +++ b/CHANGES @@ -21,6 +21,10 @@ ConfBridge menus, bridge settings, and user settings that have been applied by the 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 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 diff --git a/apps/app_confbridge.c b/apps/app_confbridge.c index 8347bc6edd..9688f2f460 100644 --- a/apps/app_confbridge.c +++ b/apps/app_confbridge.c @@ -109,6 +109,16 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") Enters the user into a specified conference bridge. The user can exit the conference by hangup or DTMF menu option. + This application sets the following channel variable upon completion: + + + The channel encountered an error and could not enter the conference. + The channel exited the conference by hanging up. + The channel was kicked from the conference. + The channel left the conference as a result of the last marked user leaving. + The channel pressed a DTMF sequence to exit the conference. + + ConfBridge @@ -1564,11 +1574,13 @@ static int confbridge_exec(struct ast_channel *chan, const char *data) } if (ast_bridge_features_init(&user.features)) { + pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED"); res = -1; goto confbridge_cleanup; } 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); res = -1; 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; } 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 ? b_profile_name : DEFAULT_BRIDGE_PROFILE); res = -1; @@ -1595,6 +1608,7 @@ static int confbridge_exec(struct ast_channel *chan, const char *data) u_profile_name = args.u_profile_name; } 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 ? u_profile_name : DEFAULT_USER_PROFILE); res = -1; @@ -1607,6 +1621,7 @@ static int confbridge_exec(struct ast_channel *chan, const char *data) * prompted for requardless of quiet setting. */ if (!ast_strlen_zero(user.u_profile.pin)) { if (conf_get_pin(chan, &user)) { + pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED"); res = -1; /* invalid PIN */ 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)) { + pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED"); ast_log(LOG_WARNING, "Conference menu profile %s does not exist\n", menu_profile_name ? menu_profile_name : DEFAULT_MENU_PROFILE); 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 */ if (!conf_name) { + pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED"); res = -1; goto confbridge_cleanup; } if (ast_bridge_talk_detector_hook(&user.features, conf_handle_talker_cb, conf_name, conf_handle_talker_destructor, AST_BRIDGE_HOOK_REMOVE_ON_PULL)) { + pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED"); ast_free(conf_name); res = -1; 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 */ if (!(conference = join_conference_bridge(args.conf_name, &user))) { + pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED"); res = -1; goto confbridge_cleanup; } @@ -1731,6 +1750,11 @@ static int confbridge_exec(struct ast_channel *chan, const char *data) &user.features, &user.tech_args, 0); + + if (!user.kicked && ast_check_hangup(chan)) { + pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "HANGUP"); + } + send_leave_event(user.chan, conference); /* 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) { last_user->kicked = 1; + pbx_builtin_setvar_helper(last_user->chan, "CONFBRIDGE_RESULT", "KICKED"); ast_bridge_remove(conference->bridge, last_user->chan); ao2_unlock(conference); } @@ -2104,6 +2129,7 @@ static int execute_menu_entry(struct confbridge_conference *conference, res |= action_kick_last(conference, bridge_channel, user); break; case MENU_ACTION_LEAVE: + pbx_builtin_setvar_helper(bridge_channel->chan, "CONFBRIDGE_RESULT", "DTMF"); ao2_lock(conference); ast_bridge_remove(conference->bridge, bridge_channel->chan); 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) { if (!strcasecmp(ast_channel_name(user->chan), channel)) { user->kicked = 1; + pbx_builtin_setvar_helper(user->chan, "CONFBRIDGE_RESULT", "KICKED"); ast_bridge_remove(conference->bridge, user->chan); return 0; } else if (!strcasecmp("all", channel)) { user->kicked = 1; + pbx_builtin_setvar_helper(user->chan, "CONFBRIDGE_RESULT", "KICKED"); ast_bridge_remove(conference->bridge, user->chan); res = 0; } @@ -2163,10 +2191,12 @@ static int kick_conference_participant(struct confbridge_conference *conference, AST_LIST_TRAVERSE(&conference->waiting_list, user, list) { if (!strcasecmp(ast_channel_name(user->chan), channel)) { user->kicked = 1; + pbx_builtin_setvar_helper(user->chan, "CONFBRIDGE_RESULT", "KICKED"); ast_bridge_remove(conference->bridge, user->chan); return 0; } else if (!strcasecmp("all", channel)) { user->kicked = 1; + pbx_builtin_setvar_helper(user->chan, "CONFBRIDGE_RESULT", "KICKED"); ast_bridge_remove(conference->bridge, user->chan); res = 0; } diff --git a/apps/confbridge/conf_state_multi_marked.c b/apps/confbridge/conf_state_multi_marked.c index a469cf737d..525cc4d5f7 100644 --- a/apps/confbridge/conf_state_multi_marked.c +++ b/apps/confbridge/conf_state_multi_marked.c @@ -38,6 +38,7 @@ #include "include/confbridge.h" #include "asterisk/musiconhold.h" #include "include/conf_state.h" +#include "asterisk/pbx.h" static void join_active(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->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)) {