diff --git a/src/include/switch_channel.h b/src/include/switch_channel.h index f21d36d63a..775bf91e92 100644 --- a/src/include/switch_channel.h +++ b/src/include/switch_channel.h @@ -558,6 +558,7 @@ SWITCH_DECLARE(switch_call_direction_t) switch_channel_direction(switch_channel_ SWITCH_DECLARE(switch_core_session_t *) switch_channel_get_session(switch_channel_t *channel); SWITCH_DECLARE(char *) switch_channel_get_flag_string(switch_channel_t *channel); SWITCH_DECLARE(char *) switch_channel_get_cap_string(switch_channel_t *channel); +SWITCH_DECLARE(int) switch_channel_state_change_pending(switch_channel_t *channel); /** @} */ diff --git a/src/switch_channel.c b/src/switch_channel.c index b97829d6ef..2b34c6bd72 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -1260,6 +1260,11 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_get_running_state(switch_c return state; } +SWITCH_DECLARE(int) switch_channel_state_change_pending(switch_channel_t *channel) +{ + return channel->running_state != channel->state; +} + SWITCH_DECLARE(int) switch_channel_test_ready(switch_channel_t *channel, switch_bool_t check_ready, switch_bool_t check_media) { int ret = 0; @@ -1270,6 +1275,7 @@ SWITCH_DECLARE(int) switch_channel_test_ready(switch_channel_t *channel, switch_ ret = ((switch_channel_test_flag(channel, CF_ANSWERED) || switch_channel_test_flag(channel, CF_EARLY_MEDIA)) && !switch_channel_test_flag(channel, CF_PROXY_MODE) && switch_core_session_get_read_codec(channel->session) && switch_core_session_get_write_codec(channel->session)); + if (!ret) return ret; @@ -1281,7 +1287,8 @@ SWITCH_DECLARE(int) switch_channel_test_ready(switch_channel_t *channel, switch_ ret = 0; if (!channel->hangup_cause && channel->state > CS_ROUTING && channel->state < CS_HANGUP && channel->state != CS_RESET && - !switch_channel_test_flag(channel, CF_TRANSFER) && !switch_channel_test_flag(channel, CF_NOT_READY)) { + !switch_channel_test_flag(channel, CF_TRANSFER) && !switch_channel_test_flag(channel, CF_NOT_READY) && + !switch_channel_state_change_pending(channel)) { ret++; } diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index 66486f45c0..9d58ae6d88 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -287,6 +287,16 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj) switch_event_t *event; loop_count++; + if (switch_channel_test_flag(chan_a, CF_TRANSFER)) { + data->clean_exit = 1; + } + + if (data->clean_exit || switch_channel_test_flag(chan_b, CF_TRANSFER)) { + switch_channel_clear_flag(chan_a, CF_HOLD); + switch_channel_clear_flag(chan_a, CF_SUSPEND); + goto end_of_bridge_loop; + } + if (!switch_channel_test_flag(chan_b, CF_BRIDGED)) { goto end_of_bridge_loop; } @@ -298,17 +308,7 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj) if ((b_state = switch_channel_down(chan_b))) { goto end_of_bridge_loop; } - - if (switch_channel_test_flag(chan_a, CF_TRANSFER)) { - data->clean_exit = 1; - } - - if (data->clean_exit || switch_channel_test_flag(chan_b, CF_TRANSFER)) { - switch_channel_clear_flag(chan_a, CF_HOLD); - switch_channel_clear_flag(chan_a, CF_SUSPEND); - goto end_of_bridge_loop; - } - + if (loop_count > DEFAULT_LEAD_FRAMES && switch_channel_media_ack(chan_a) && switch_core_session_private_event_count(session_a)) { switch_channel_set_flag(chan_b, CF_SUSPEND); msg.string_arg = data->b_uuid; diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index 2783125dcd..0930f2a797 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -1810,8 +1810,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess switch_ivr_media(switch_core_session_get_uuid(session), SMF_NONE); } } - - if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE) && switch_channel_media_ready(caller_channel)) { + + if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE) && switch_channel_test_flag(caller_channel, CF_ANSWERED)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Channel is already up, delaying proxy mode 'till both legs are answered.\n"); switch_channel_set_variable(caller_channel, "bypass_media_after_bridge", "true");