conf_state_multi_marked.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 2012, Terry Wilson
00005  *
00006  * Terry Wilson <twilson@digium.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  *
00018  * Please follow coding guidelines
00019  * http://svn.digium.com/view/asterisk/trunk/doc/CODING-GUIDELINES
00020  */
00021 
00022 /*! \file
00023  *
00024  * \brief Confbridge state handling for the MULTI_MARKED state
00025  *
00026  * \author\verbatim Terry Wilson <twilson@digium.com> \endverbatim
00027  *
00028  * \ingroup applications
00029  */
00030 
00031 /*** MODULEINFO
00032    <support_level>core</support_level>
00033  ***/
00034 
00035 #include "asterisk.h"
00036 #include "asterisk/utils.h"
00037 #include "asterisk/linkedlists.h"
00038 #include "include/confbridge.h"
00039 #include "asterisk/musiconhold.h"
00040 #include "include/conf_state.h"
00041 #include "asterisk/pbx.h"
00042 
00043 static void join_active(struct confbridge_user *user);
00044 static void join_marked(struct confbridge_user *user);
00045 static void leave_active(struct confbridge_user *user);
00046 static void leave_marked(struct confbridge_user *user);
00047 static void transition_to_marked(struct confbridge_user *user);
00048 
00049 static struct confbridge_state STATE_MULTI_MARKED = {
00050    .name = "MULTI_MARKED",
00051    .join_unmarked = join_active,
00052    .join_waitmarked = join_active,
00053    .join_marked = join_marked,
00054    .leave_unmarked = leave_active,
00055    .leave_waitmarked = leave_active,
00056    .leave_marked = leave_marked,
00057    .entry = transition_to_marked,
00058 };
00059 struct confbridge_state *CONF_STATE_MULTI_MARKED = &STATE_MULTI_MARKED;
00060 
00061 static void join_active(struct confbridge_user *user)
00062 {
00063    conf_add_user_active(user->conference, user);
00064    conf_update_user_mute(user);
00065 }
00066 
00067 static void join_marked(struct confbridge_user *user)
00068 {
00069    conf_add_user_marked(user->conference, user);
00070    conf_update_user_mute(user);
00071 }
00072 
00073 static void leave_active(struct confbridge_user *user)
00074 {
00075    conf_remove_user_active(user->conference, user);
00076    if (user->conference->activeusers == 1) {
00077       conf_change_state(user, CONF_STATE_SINGLE_MARKED);
00078    }
00079 }
00080 
00081 static void leave_marked(struct confbridge_user *user)
00082 {
00083    struct confbridge_user *user_iter;
00084    int need_prompt = 0;
00085 
00086    conf_remove_user_marked(user->conference, user);
00087 
00088    if (user->conference->markedusers == 0) {
00089       AST_LIST_TRAVERSE_SAFE_BEGIN(&user->conference->active_list, user_iter, list) {
00090          /* Kick ENDMARKED cbu_iters */
00091          if (ast_test_flag(&user_iter->u_profile, USER_OPT_ENDMARKED) && !user_iter->kicked) {
00092             if (ast_test_flag(&user_iter->u_profile, USER_OPT_WAITMARKED)
00093                && !ast_test_flag(&user_iter->u_profile, USER_OPT_MARKEDUSER)) {
00094                AST_LIST_REMOVE_CURRENT(list);
00095                user_iter->conference->activeusers--;
00096                AST_LIST_INSERT_TAIL(&user_iter->conference->waiting_list, user_iter, list);
00097                user_iter->conference->waitingusers++;
00098             }
00099             user_iter->kicked = 1;
00100             pbx_builtin_setvar_helper(user_iter->chan, "CONFBRIDGE_RESULT", "ENDMARKED");
00101             ast_bridge_remove(user_iter->conference->bridge, user_iter->chan);
00102          } else if (ast_test_flag(&user_iter->u_profile, USER_OPT_WAITMARKED)
00103             && !ast_test_flag(&user_iter->u_profile, USER_OPT_MARKEDUSER)) {
00104             need_prompt = 1;
00105 
00106             AST_LIST_REMOVE_CURRENT(list);
00107             user_iter->conference->activeusers--;
00108             AST_LIST_INSERT_TAIL(&user_iter->conference->waiting_list, user_iter, list);
00109             user_iter->conference->waitingusers++;
00110          } else {
00111             /* User is neither wait_marked nor end_marked; however, they
00112              * should still hear the prompt.
00113              */
00114             need_prompt = 1;
00115          }
00116       }
00117       AST_LIST_TRAVERSE_SAFE_END;
00118    }
00119 
00120    switch (user->conference->activeusers) {
00121    case 0:
00122       /* Implies markedusers == 0 */
00123       switch (user->conference->waitingusers) {
00124       case 0:
00125          conf_change_state(user, CONF_STATE_EMPTY);
00126          break;
00127       default:
00128          conf_change_state(user, CONF_STATE_INACTIVE);
00129          break;
00130       }
00131       break;
00132    case 1:
00133       switch (user->conference->markedusers) {
00134       case 0:
00135          conf_change_state(user, CONF_STATE_SINGLE);
00136          break;
00137       case 1:
00138          /* XXX I seem to remember doing this for a reason, but right now it escapes me
00139           * how we could possibly ever have a waiting user while we have a marked user */
00140          switch (user->conference->waitingusers) {
00141          case 0:
00142             conf_change_state(user, CONF_STATE_SINGLE_MARKED);
00143             break;
00144          case 1:
00145             break; /* Stay in marked */
00146          }
00147          break;
00148       }
00149       break;
00150    default:
00151       switch (user->conference->markedusers) {
00152       case 0:
00153          conf_change_state(user, CONF_STATE_MULTI);
00154          break;
00155       default:
00156          break; /* Stay in marked */
00157       }
00158    }
00159 
00160    if (need_prompt) {
00161       /* Play back the audio prompt saying the leader has left the conference */
00162       if (!ast_test_flag(&user->u_profile, USER_OPT_QUIET)) {
00163          ao2_unlock(user->conference);
00164          ast_autoservice_start(user->chan);
00165          play_sound_file(user->conference,
00166             conf_get_sound(CONF_SOUND_LEADER_HAS_LEFT, user->b_profile.sounds));
00167          ast_autoservice_stop(user->chan);
00168          ao2_lock(user->conference);
00169       }
00170 
00171       AST_LIST_TRAVERSE(&user->conference->waiting_list, user_iter, list) {
00172          if (user_iter->kicked) {
00173             continue;
00174          }
00175 
00176          if (ast_test_flag(&user_iter->u_profile, USER_OPT_MUSICONHOLD)) {
00177             conf_moh_start(user_iter);
00178          }
00179 
00180          conf_update_user_mute(user_iter);
00181       }
00182    }
00183 }
00184 
00185 static int post_join_play_begin(struct confbridge_user *cbu)
00186 {
00187    int res;
00188 
00189    ast_autoservice_start(cbu->chan);
00190    res = play_sound_file(cbu->conference,
00191       conf_get_sound(CONF_SOUND_BEGIN, cbu->b_profile.sounds));
00192    ast_autoservice_stop(cbu->chan);
00193    return res;
00194 }
00195 
00196 static void transition_to_marked(struct confbridge_user *user)
00197 {
00198    struct confbridge_user *user_iter;
00199    int waitmarked_moved = 0;
00200 
00201    /* Move all waiting users to active, stopping MOH and unmuting if necessary */
00202    AST_LIST_TRAVERSE_SAFE_BEGIN(&user->conference->waiting_list, user_iter, list) {
00203       AST_LIST_REMOVE_CURRENT(list);
00204       user->conference->waitingusers--;
00205       AST_LIST_INSERT_TAIL(&user->conference->active_list, user_iter, list);
00206       user->conference->activeusers++;
00207       if (user_iter->playing_moh) {
00208          conf_moh_stop(user_iter);
00209       }
00210       conf_update_user_mute(user_iter);
00211       waitmarked_moved++;
00212    }
00213    AST_LIST_TRAVERSE_SAFE_END;
00214 
00215    /* Play the audio file stating that the conference is beginning */
00216    if (user->conference->markedusers == 1
00217       && ast_test_flag(&user->u_profile, USER_OPT_MARKEDUSER)
00218       && !ast_test_flag(&user->u_profile, USER_OPT_QUIET)
00219       && waitmarked_moved) {
00220       conf_add_post_join_action(user, post_join_play_begin);
00221    }
00222 }

Generated on Thu Apr 16 06:27:31 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6