mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-29 18:19:30 +00:00
confbridge: Fix MOH on simultaneous user entry to a new conference.
When two users entered a new conference simultaneously, one of the callers hears MOH. This happened if two unmarked users entered simultaneously and also if a waitmarked and a marked user entered simultaneously. * Created a confbridge internal MOH API to eliminate the inlined MOH handling code. Note that the conference mixing bridge needs to be locked when actually starting/stopping MOH because there is a small window between the conference join unsuspend MOH and actually joining the mixing bridge. * Created the concept of suspended MOH so it can be interrupted while conference join announcements to the user and DTMF features can operate. * Suspend any MOH until the user is about to actually join the mixing bridge of the conference. This way any pre-join file playback does not need to worry about MOH. * Made post-join actions only play deferred entry announcement files. Changing the user/conference state during that time is not protected or controlled by the state machine. (closes issue ASTERISK-20606) Reported by: Eugenia Belova Tested by: rmudgett Review: https://reviewboard.asterisk.org/r/2232/ ........ Merged revisions 377992 from http://svn.asterisk.org/svn/asterisk/branches/10 ........ Merged revisions 377993 from http://svn.asterisk.org/svn/asterisk/branches/11 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@378002 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -47,9 +47,28 @@ void conf_invalid_event_fn(struct conference_bridge_user *cbu)
|
||||
ast_log(LOG_ERROR, "Invalid event for confbridge user '%s'\n", cbu->u_profile.name);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Mute the user and play MOH if the user requires it.
|
||||
*
|
||||
* \param user Conference user to mute and optionally start MOH on.
|
||||
*
|
||||
* \return Nothing
|
||||
*/
|
||||
static void conf_mute_moh_inactive_waitmarked(struct conference_bridge_user *user)
|
||||
{
|
||||
/* Be sure we are muted so we can't talk to anybody else waiting */
|
||||
user->features.mute = 1;
|
||||
/* Start music on hold if needed */
|
||||
if (ast_test_flag(&user->u_profile, USER_OPT_MUSICONHOLD)) {
|
||||
conf_moh_start(user);
|
||||
}
|
||||
}
|
||||
|
||||
void conf_default_join_waitmarked(struct conference_bridge_user *cbu)
|
||||
{
|
||||
conf_add_user_waiting(cbu->conference_bridge, cbu);
|
||||
conf_mute_moh_inactive_waitmarked(cbu);
|
||||
conf_add_post_join_action(cbu, conf_handle_inactive_waitmarked);
|
||||
}
|
||||
|
||||
|
@@ -107,12 +107,8 @@ static void leave_marked(struct conference_bridge_user *cbu)
|
||||
cbu_iter->conference_bridge->waitingusers++;
|
||||
/* Handle muting/moh of cbu_iter if necessary */
|
||||
if (ast_test_flag(&cbu_iter->u_profile, USER_OPT_MUSICONHOLD)) {
|
||||
cbu_iter->features.mute = 1;
|
||||
if (!ast_bridge_suspend(cbu_iter->conference_bridge->bridge, cbu_iter->chan)) {
|
||||
ast_moh_start(cbu_iter->chan, cbu_iter->u_profile.moh_class, NULL);
|
||||
cbu_iter->playing_moh = 1;
|
||||
ast_bridge_unsuspend(cbu_iter->conference_bridge->bridge, cbu_iter->chan);
|
||||
}
|
||||
cbu_iter->features.mute = 1;
|
||||
conf_moh_start(cbu_iter);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -173,10 +169,8 @@ static void transition_to_marked(struct conference_bridge_user *cbu)
|
||||
cbu->conference_bridge->waitingusers--;
|
||||
AST_LIST_INSERT_TAIL(&cbu->conference_bridge->active_list, cbu_iter, list);
|
||||
cbu->conference_bridge->activeusers++;
|
||||
if (cbu_iter->playing_moh && !ast_bridge_suspend(cbu->conference_bridge->bridge, cbu_iter->chan)) {
|
||||
cbu_iter->playing_moh = 0;
|
||||
ast_moh_stop(cbu_iter->chan);
|
||||
ast_bridge_unsuspend(cbu->conference_bridge->bridge, cbu_iter->chan);
|
||||
if (cbu_iter->playing_moh) {
|
||||
conf_moh_stop(cbu_iter);
|
||||
}
|
||||
/* only unmute them if they are not supposed to start muted */
|
||||
if (!ast_test_flag(&cbu_iter->u_profile, USER_OPT_STARTMUTED)) {
|
||||
|
@@ -236,6 +236,7 @@ struct conference_bridge_user {
|
||||
struct ast_channel *chan; /*!< Asterisk channel participating */
|
||||
struct ast_bridge_features features; /*!< Bridge features structure */
|
||||
struct ast_bridge_tech_optimizations tech_args; /*!< Bridge technology optimizations for talk detection */
|
||||
unsigned int suspended_moh; /*!< Count of active suspended MOH actions. */
|
||||
unsigned int kicked:1; /*!< User has been kicked from the conference */
|
||||
unsigned int playing_moh:1; /*!< MOH is currently being played to the user */
|
||||
AST_LIST_HEAD_NOLOCK(, post_join_action) post_join_list; /*!< List of sounds to play after joining */;
|
||||
@@ -358,6 +359,24 @@ int play_sound_file(struct conference_bridge *conference_bridge, const char *fil
|
||||
*/
|
||||
void conf_ended(struct conference_bridge *conference_bridge);
|
||||
|
||||
/*!
|
||||
* \brief Stop MOH for the conference user.
|
||||
*
|
||||
* \param user Conference user to stop MOH on.
|
||||
*
|
||||
* \return Nothing
|
||||
*/
|
||||
void conf_moh_stop(struct conference_bridge_user *user);
|
||||
|
||||
/*!
|
||||
* \brief Start MOH for the conference user.
|
||||
*
|
||||
* \param user Conference user to start MOH on.
|
||||
*
|
||||
* \return Nothing
|
||||
*/
|
||||
void conf_moh_start(struct conference_bridge_user *user);
|
||||
|
||||
/*! \brief Attempt to mute/play MOH to the only user in the conference if they require it
|
||||
* \param conference_bridge A conference bridge containing a single user
|
||||
*/
|
||||
|
Reference in New Issue
Block a user