Index: apps/app_confbridge.c =================================================================== --- apps/app_confbridge.c (revision 359978) +++ apps/app_confbridge.c (working copy) @@ -711,19 +711,51 @@ } ao2_unlock(conference_bridge); } /*! + * \brief Turns off MoH for a marked user when participants join + * + * \param conference_bridge Conference bridge being used + * + * \return Returns 0 on success or no-op, -1 on failure + */ +static int turn_off_marked_moh(struct conference_bridge *conference_bridge) +{ + /* Deal with the case where a marked user has hold-music while the conference is empty, + * triggered by the departure and subsequent joining of other users. */ + struct conference_bridge_user *first_participant = AST_LIST_FIRST(&conference_bridge->users_list); + if (conference_bridge->users == 2) { + /* Temporarily suspend the above participant from the bridge, if it's a marked user who can + * be on hold, so we can turn off MoH if needed. */ + if (ast_test_flag(&first_participant->u_profile, USER_OPT_MARKEDUSER) && ast_test_flag(&first_participant->u_profile, USER_OPT_MUSICONHOLD)) { + if (first_participant->playing_moh) { + if (!ast_bridge_suspend(conference_bridge->bridge, first_participant->chan)) { + first_participant->playing_moh = 0; + ast_moh_stop(first_participant->chan); + ast_bridge_unsuspend(conference_bridge->bridge, first_participant->chan); + } else { + return -1; + } + } + } + } + return 0; +} + +/*! * \brief Perform post-joining marked specific actions * * \param conference_bridge Conference bridge being joined * \param conference_bridge_user Conference bridge user joining * * \return Returns 0 on success, -1 if the user hung up */ static int post_join_marked(struct conference_bridge *conference_bridge, struct conference_bridge_user *conference_bridge_user) { + turn_off_marked_moh(conference_bridge); + if (ast_test_flag(&conference_bridge_user->u_profile, USER_OPT_MARKEDUSER)) { struct conference_bridge_user *other_conference_bridge_user = NULL; /* If we are not the first user to join, then the users are already * in the conference so we do not need to update them. */ @@ -734,11 +766,15 @@ /* Iterate through every participant stopping MOH on them if need be */ AST_LIST_TRAVERSE(&conference_bridge->users_list, other_conference_bridge_user, list) { if (other_conference_bridge_user == conference_bridge_user) { continue; } - if (other_conference_bridge_user->playing_moh && !ast_bridge_suspend(conference_bridge->bridge, other_conference_bridge_user->chan)) { + if ( + other_conference_bridge_user->playing_moh && + ast_test_flag(&other_conference_bridge_user->u_profile, USER_OPT_MUSICONHOLD) && + !ast_bridge_suspend(conference_bridge->bridge, other_conference_bridge_user->chan) + ) { other_conference_bridge_user->playing_moh = 0; ast_moh_stop(other_conference_bridge_user->chan); ast_bridge_unsuspend(conference_bridge->bridge, other_conference_bridge_user->chan); } } @@ -777,19 +813,25 @@ conf_get_sound(CONF_SOUND_WAIT_FOR_LEADER, conference_bridge_user->b_profile.sounds))) { /* user hungup while the sound was playing */ return -1; } } - /* Start music on hold if needed */ - /* We need to recheck the markedusers value here. play_prompt_to_channel unlocks the conference bridge, potentially - * allowing a marked user to enter while the prompt was playing - */ - if (!conference_bridge->markedusers && ast_test_flag(&conference_bridge_user->u_profile, USER_OPT_MUSICONHOLD)) { + } + + /* Start music on hold if needed: MoH is enabled, the user waits for a marked user, and there are no marked users or the marked user is alone */ + /* We need to recheck the markedusers value here. play_prompt_to_channel unlocks the conference bridge, potentially + * allowing a marked user to enter while the prompt was playing + */ + if (ast_test_flag(&conference_bridge_user->u_profile, USER_OPT_MUSICONHOLD) && + ((ast_test_flag(&conference_bridge_user->u_profile, USER_OPT_WAITMARKED) && !conference_bridge->markedusers) || conference_bridge->users == 1) + ) { + if (!conference_bridge_user->playing_moh) { ast_moh_start(conference_bridge_user->chan, conference_bridge_user->u_profile.moh_class, NULL); conference_bridge_user->playing_moh = 1; } } + return 0; } /*! * \brief Perform post-joining non-marked specific actions @@ -819,10 +861,12 @@ if (conference_bridge->users == 1 && ast_test_flag(&conference_bridge_user->u_profile, USER_OPT_MUSICONHOLD)) { ast_moh_start(conference_bridge_user->chan, conference_bridge_user->u_profile.moh_class, NULL); conference_bridge_user->playing_moh = 1; } return 0; + }else{ + turn_off_marked_moh(conference_bridge); } /* Announce number of users if need be */ if (ast_test_flag(&conference_bridge_user->u_profile, USER_OPT_ANNOUNCEUSERCOUNT)) { ao2_unlock(conference_bridge);