diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 0f9a512734..728dc93f17 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -580,7 +580,8 @@ typedef enum { CS_HIBERNATE, CS_RESET, CS_HANGUP, - CS_DONE + CS_DONE, + CS_NONE } switch_channel_state_t; diff --git a/src/switch_channel.c b/src/switch_channel.c index 7119d0b174..4c4c971733 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -288,6 +288,7 @@ SWITCH_DECLARE(switch_status_t) switch_channel_init(switch_channel_t *channel, s channel->state = state; channel->flags = flags; channel->session = session; + channel->running_state = CS_NONE; return SWITCH_STATUS_SUCCESS; } @@ -592,7 +593,13 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_running_state( channel->name, state_names[channel->state]); channel->running_state = channel->state; + if (channel->state_flags) { + channel->flags |= channel->state_flags; + channel->state_flags = 0; + } + if (channel->state >= CS_RING) { + switch_clear_flag(channel, CF_TRANSFER); switch_channel_presence(channel, "unknown", (char *) state_names[channel->state]); } @@ -770,7 +777,6 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_state(switch_c break; case CS_RING: - switch_clear_flag(channel, CF_TRANSFER); switch (state) { case CS_LOOPBACK: case CS_EXECUTE: @@ -842,12 +848,6 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_state(switch_c } done: - if (channel->state_flags) { - channel->flags |= channel->state_flags; - channel->state_flags = 0; - - } - switch_mutex_unlock(channel->flag_mutex); return channel->state; } diff --git a/src/switch_core_state_machine.c b/src/switch_core_state_machine.c index 2b7e65edf4..3492c327a9 100644 --- a/src/switch_core_state_machine.c +++ b/src/switch_core_state_machine.c @@ -330,7 +330,7 @@ void switch_core_state_machine_init(switch_memory_pool_t *pool) SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session) { - switch_channel_state_t state = CS_NEW, laststate = CS_HANGUP, midstate = CS_DONE, endstate; + switch_channel_state_t state = CS_NEW, midstate = CS_DONE, endstate; const switch_endpoint_interface_t *endpoint_interface; const switch_state_handler_table_t *driver_state_handler = NULL; const switch_state_handler_table_t *application_state_handler = NULL; @@ -395,7 +395,7 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session) switch_channel_clear_flag(session->channel, CF_REPEAT_STATE); exception = 1; } - if (state != laststate || state == CS_HANGUP || exception) { + if (state != switch_channel_get_running_state(session->channel) || state == CS_HANGUP || exception) { int index = 0; int proceed = 1; @@ -437,20 +437,22 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session) case CS_HIBERNATE: /* sleep */ STATE_MACRO(hibernate, "HIBERNATE"); break; + case CS_NONE: + abort(); + break; } if (midstate == CS_DONE) { break; } - laststate = midstate; } endstate = switch_channel_get_state(session->channel); - - if (midstate == endstate) { + + if (endstate == switch_channel_get_running_state(session->channel)) { if (endstate == CS_NEW) { switch_yield(1000); } else { diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index 8d38b00ab8..045dc6b2f8 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -447,6 +447,8 @@ static switch_status_t signal_bridge_on_hangup(switch_core_session_t *session) switch_channel_set_variable(channel, SWITCH_BRIDGE_VARIABLE, NULL); switch_channel_set_variable(other_channel, SWITCH_BRIDGE_VARIABLE, NULL); + assert (!switch_channel_test_flag(other_channel, CF_TRANSFER)); + if (!switch_channel_test_flag(other_channel, CF_TRANSFER)) { if (switch_channel_test_flag(other_channel, CF_ANSWERED) && switch_channel_get_state(other_channel) < CS_HANGUP && @@ -455,7 +457,7 @@ static switch_status_t signal_bridge_on_hangup(switch_core_session_t *session) } else { switch_channel_set_state(other_channel, CS_EXECUTE); } - } + } switch_core_session_rwunlock(other_session); }