Index: apps/app_confbridge.c =================================================================== --- apps/app_confbridge.c (revision 359977) +++ apps/app_confbridge.c (working copy) @@ -1061,14 +1061,8 @@ /* If there are still users in the conference bridge we may need to do things (such as start MOH on them) */ if (conference_bridge->users) { + struct conference_bridge_user *other_participant = NULL; if (ast_test_flag(&conference_bridge_user->u_profile, USER_OPT_MARKEDUSER) && !conference_bridge->markedusers) { - struct conference_bridge_user *other_participant = NULL; - - /* Start out with muting everyone */ - AST_LIST_TRAVERSE(&conference_bridge->users_list, other_participant, list) { - other_participant->features.mute = 1; - } - + /* Start out with muting everyone with WAITMARKED */ + AST_LIST_TRAVERSE(&conference_bridge->users_list, other_participant, list) { + if (ast_test_flag(&other_participant->u_profile, USER_OPT_WAITMARKED)) { + other_participant->features.mute = 1; + } + } + /* Play back the audio prompt saying the leader has left the conference */ if (!ast_test_flag(&conference_bridge_user->u_profile, USER_OPT_QUIET)) { ao2_unlock(conference_bridge); @@ -1079,25 +1073,39 @@ ao2_lock(conference_bridge); } - /* Now on to starting MOH or kick if needed */ + /* Now on kicking participants, if needed */ AST_LIST_TRAVERSE(&conference_bridge->users_list, other_participant, list) { if (ast_test_flag(&other_participant->u_profile, USER_OPT_ENDMARKED)) { other_participant->kicked = 1; ast_bridge_remove(conference_bridge->bridge, other_participant->chan); - } else if (ast_test_flag(&other_participant->u_profile, USER_OPT_MUSICONHOLD) && !ast_bridge_suspend(conference_bridge->bridge, other_participant->chan)) { - ast_moh_start(other_participant->chan, other_participant->u_profile.moh_class, NULL); - other_participant->playing_moh = 1; - ast_bridge_unsuspend(conference_bridge->bridge, other_participant->chan); } } - } else if (conference_bridge->users == 1) { - /* Of course if there is one other person in here we may need to start up MOH on them */ - struct conference_bridge_user *first_participant = AST_LIST_FIRST(&conference_bridge->users_list); - - if (ast_test_flag(&first_participant->u_profile, USER_OPT_MUSICONHOLD) && !ast_bridge_suspend(conference_bridge->bridge, first_participant->chan)) { - ast_moh_start(first_participant->chan, first_participant->u_profile.moh_class, NULL); - first_participant->playing_moh = 1; - ast_bridge_unsuspend(conference_bridge->bridge, first_participant->chan); + } + + /* For anyone left, MoH may need to be turned on, so gather statistics */ + int nonwaiting_participants = 0; /* The number of participants not blocking on the presence of a marked user */ + if (!conference_bridge->markedusers) { /* Only count them if there are no marked users */ + AST_LIST_TRAVERSE(&conference_bridge->users_list, other_participant, list) { + if (!other_participant->kicked && !ast_test_flag(&other_participant->u_profile, USER_OPT_WAITMARKED)) { + nonwaiting_participants += 1; + } + } + } + /* Enable MoH for anyone who should hear it */ + AST_LIST_TRAVERSE(&conference_bridge->users_list, other_participant, list) { + if (!other_participant->kicked && ast_test_flag(&other_participant->u_profile, USER_OPT_MUSICONHOLD)) { + if (conference_bridge->users > 1) { /* If there's only one user, hold music can't be skipped */ + if (!ast_test_flag(&other_participant->u_profile, USER_OPT_WAITMARKED) && (conference_bridge->markedusers || nonwaiting_participants >= 2)) { + continue; /* All conditions needed to enable speech are satisfied */ + } else if (ast_test_flag(&other_participant->u_profile, USER_OPT_WAITMARKED) && conference_bridge->markedusers) { + continue; /* Waiting for marked user and one's already here */ + } + } + if (!ast_bridge_suspend(conference_bridge->bridge, other_participant->chan)) { + ast_moh_start(other_participant->chan, other_participant->u_profile.moh_class, NULL); + other_participant->playing_moh = 1; + ast_bridge_unsuspend(conference_bridge->bridge, other_participant->chan); + } } } } else {