From 86c523fbb1db503a760713b451b197a701de7290 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 21 Nov 2008 00:09:11 +0000 Subject: [PATCH] code reworking do make current git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@10487 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- src/include/private/switch_core_pvt.h | 2 + src/include/switch_types.h | 9 +-- src/switch_channel.c | 1 - src/switch_core_codec.c | 10 +++ src/switch_core_io.c | 14 ++++- src/switch_core_session.c | 3 + src/switch_core_state_machine.c | 4 +- src/switch_ivr_bridge.c | 89 +++++++++++++++------------ src/switch_ivr_originate.c | 12 +++- 9 files changed, 93 insertions(+), 51 deletions(-) diff --git a/src/include/private/switch_core_pvt.h b/src/include/private/switch_core_pvt.h index 3cc1e9ff66..040a6ecb60 100644 --- a/src/include/private/switch_core_pvt.h +++ b/src/include/private/switch_core_pvt.h @@ -118,6 +118,8 @@ struct switch_core_session { switch_mutex_t *mutex; switch_mutex_t *resample_mutex; + switch_mutex_t *codec_read_mutex; + switch_mutex_t *codec_write_mutex; switch_thread_cond_t *cond; switch_thread_rwlock_t *rwlock; diff --git a/src/include/switch_types.h b/src/include/switch_types.h index f3eaedd6bc..068b79a3a1 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -732,7 +732,7 @@ CF_EARLY_MEDIA = (1 << 2) - Channel is ready for audio before answer CF_ORIGINATOR = (1 << 3) - Channel is an originator CF_TRANSFER = (1 << 4) - Channel is being transfered CF_ACCEPT_CNG = (1 << 5) - Channel will accept CNG frames -CF_WAIT_FOR_ME = (1 << 6) - Channel wants you to wait +CF_REDIRECT = (1 << 6) - Channel is being redirected CF_BRIDGED = (1 << 7) - Channel in a bridge CF_HOLD = (1 << 8) - Channel is on hold CF_SERVICE = (1 << 9) - Channel has a service thread @@ -763,7 +763,7 @@ typedef enum { CF_ORIGINATOR = (1 << 3), CF_TRANSFER = (1 << 4), CF_ACCEPT_CNG = (1 << 5), - CF_WAIT_FOR_ME = (1 << 6), + CF_REDIRECT = (1 << 6), CF_BRIDGED = (1 << 7), CF_HOLD = (1 << 8), CF_SERVICE = (1 << 9), @@ -787,12 +787,13 @@ typedef enum { CF_PROXY_MEDIA = (1 << 27), CF_INNER_BRIDGE = (1 << 28), CF_REQ_MEDIA = (1 << 29), - CF_VERBOSE_EVENTS = (1 << 30), - CF_MASTER = (1 << 31) + CF_VERBOSE_EVENTS = (1 << 30) } switch_channel_flag_enum_t; + typedef uint32_t switch_channel_flag_t; + /*! \enum switch_frame_flag_t \brief Frame Flags diff --git a/src/switch_channel.c b/src/switch_channel.c index 82a3d5be32..90383b4fe4 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -841,7 +841,6 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_running_state( switch_clear_flag(channel, CF_TAGGED); if (channel->state >= CS_ROUTING) { - switch_clear_flag(channel, CF_TRANSFER); switch_channel_presence(channel, "unknown", (char *) state_names[state], NULL); } diff --git a/src/switch_core_codec.c b/src/switch_core_codec.c index d1709049fd..5fee015971 100644 --- a/src/switch_core_codec.c +++ b/src/switch_core_codec.c @@ -46,6 +46,7 @@ SWITCH_DECLARE(void) switch_core_session_unset_read_codec(switch_core_session_t { switch_mutex_t *mutex = NULL; + switch_mutex_lock(session->codec_read_mutex); if (session->read_codec) mutex = session->read_codec->mutex; if (mutex) switch_mutex_lock(mutex); session->real_read_codec = session->read_codec = NULL; @@ -54,16 +55,19 @@ SWITCH_DECLARE(void) switch_core_session_unset_read_codec(switch_core_session_t session->enc_read_frame.codec = session->read_codec; session->enc_write_frame.codec = session->read_codec; if (mutex) switch_mutex_unlock(mutex); + switch_mutex_unlock(session->codec_read_mutex); } SWITCH_DECLARE(void) switch_core_session_unset_write_codec(switch_core_session_t *session) { switch_mutex_t *mutex = NULL; + switch_mutex_lock(session->codec_write_mutex); if (session->write_codec) mutex = session->write_codec->mutex; if (mutex) switch_mutex_lock(mutex); session->real_write_codec = session->write_codec = NULL; if (mutex) switch_mutex_unlock(mutex); + switch_mutex_unlock(session->codec_write_mutex); } @@ -74,6 +78,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_set_read_codec(switch_core_s char tmp[30]; switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_mutex_lock(session->codec_read_mutex); + if (codec && !codec->implementation) { codec = NULL; } @@ -128,6 +134,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_set_read_codec(switch_core_s end: + switch_mutex_unlock(session->codec_read_mutex); return status; } @@ -192,6 +199,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_set_write_codec(switch_core_ char tmp[30]; switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_mutex_lock(session->codec_write_mutex); + if (!codec || !codec->implementation) { if (session->real_write_codec) { session->write_codec = session->real_write_codec; @@ -241,6 +250,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_set_write_codec(switch_core_ } end: + switch_mutex_unlock(session->codec_write_mutex); return status; } diff --git a/src/switch_core_io.c b/src/switch_core_io.c index 52b8c31011..1573b174d2 100644 --- a/src/switch_core_io.c +++ b/src/switch_core_io.c @@ -110,10 +110,15 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi switch_assert(session != NULL); if (!(session->read_codec && session->read_codec->implementation)) { + if (switch_channel_test_flag(session->channel, CF_PROXY_MODE) || switch_channel_get_state(session->channel) == CS_HIBERNATE) { + *frame = &runtime.dummy_cng_frame; + return SWITCH_STATUS_SUCCESS; + } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s has no read codec.\n", switch_channel_get_name(session->channel)); return SWITCH_STATUS_FALSE; } + switch_mutex_lock(session->codec_read_mutex); switch_mutex_lock(session->read_codec->mutex); top: @@ -521,7 +526,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi } switch_mutex_unlock(session->read_codec->mutex); - + switch_mutex_unlock(session->codec_read_mutex); + return status; } @@ -588,7 +594,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess } switch_mutex_lock(session->write_codec->mutex); switch_mutex_lock(frame->codec->mutex); - + switch_mutex_lock(session->codec_write_mutex); + if ((session->write_codec && frame->codec && session->write_codec->implementation != frame->codec->implementation)) { need_codec = TRUE; if (session->write_codec->implementation->codec_id == frame->codec->implementation->codec_id) { @@ -977,7 +984,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess switch_mutex_unlock(session->write_codec->mutex); switch_mutex_unlock(frame->codec->mutex); - + switch_mutex_unlock(session->codec_write_mutex); + return status; } diff --git a/src/switch_core_session.c b/src/switch_core_session.c index 6e3cba450b..7d91dcbdca 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -747,6 +747,7 @@ SWITCH_DECLARE(void) switch_core_session_reset(switch_core_session_t *session, s switch_channel_t *channel = switch_core_session_get_channel(session); switch_size_t has; + switch_core_session_set_read_codec(session, NULL); /* clear resamplers */ @@ -1102,6 +1103,8 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request_uuid(switch_ switch_mutex_init(&session->mutex, SWITCH_MUTEX_NESTED, session->pool); switch_mutex_init(&session->resample_mutex, SWITCH_MUTEX_NESTED, session->pool); + switch_mutex_init(&session->codec_read_mutex, SWITCH_MUTEX_NESTED, session->pool); + switch_mutex_init(&session->codec_write_mutex, SWITCH_MUTEX_NESTED, session->pool); switch_thread_rwlock_create(&session->bug_rwlock, session->pool); switch_thread_cond_create(&session->cond, session->pool); switch_thread_rwlock_create(&session->rwlock, session->pool); diff --git a/src/switch_core_state_machine.c b/src/switch_core_state_machine.c index 109d93bc0c..9403a3b9ed 100644 --- a/src/switch_core_state_machine.c +++ b/src/switch_core_state_machine.c @@ -165,7 +165,7 @@ static void switch_core_standard_on_execute(switch_core_session_t *session) } if (switch_channel_get_state(session->channel) == CS_EXECUTE) { - switch_channel_hangup(session->channel, SWITCH_CAUSE_NORMAL_CLEARING); + switch_channel_hangup(session->channel, SWITCH_CAUSE_NORMAL_CLEARING); } } @@ -185,7 +185,6 @@ static void switch_core_standard_on_park(switch_core_session_t *session) { switch_assert(session != NULL); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s Standard PARK\n", switch_channel_get_name(session->channel)); - switch_channel_clear_flag(session->channel, CF_TRANSFER); switch_core_session_reset(session, SWITCH_TRUE); switch_ivr_park(session, NULL); } @@ -373,6 +372,7 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session) int do_extra_handlers = 1; switch_channel_set_running_state(session->channel, state); + switch_channel_clear_flag(session->channel, CF_TRANSFER); switch (state) { case CS_NEW: /* Just created, Waiting for first instructions */ diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index aad1df9a06..486dbe2a73 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -140,7 +140,8 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj) switch_channel_wait_for_flag(chan_b, CF_BRIDGED, SWITCH_TRUE, 10000, chan_a); if (!switch_channel_test_flag(chan_b, CF_BRIDGED)) { - if (!(switch_channel_test_flag(chan_b, CF_TRANSFER) || switch_channel_get_state(chan_b) == CS_RESET)) { + if (!(switch_channel_test_flag(chan_b, CF_TRANSFER) || switch_channel_test_flag(chan_b, CF_REDIRECT) + || switch_channel_get_state(chan_b) == CS_RESET)) { switch_channel_hangup(chan_b, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); } goto end_of_bridge_loop; @@ -208,11 +209,11 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj) goto end_of_bridge_loop; } - if (switch_channel_test_flag(chan_a, CF_TRANSFER)) { + if (switch_channel_test_flag(chan_a, CF_TRANSFER) || switch_channel_test_flag(chan_a, CF_REDIRECT)) { data->clean_exit = 1; } - if (data->clean_exit || switch_channel_test_flag(chan_b, CF_TRANSFER)) { + if (data->clean_exit || switch_channel_test_flag(chan_b, CF_TRANSFER) || switch_channel_test_flag(chan_b, CF_REDIRECT)) { switch_channel_clear_flag(chan_a, CF_HOLD); switch_channel_clear_flag(chan_a, CF_SUSPEND); goto end_of_bridge_loop; @@ -352,8 +353,6 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj) if (switch_core_session_write_frame(session_b, read_frame, SWITCH_IO_FLAG_NONE, stream_id) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s ending bridge by request from write function\n", switch_channel_get_name(chan_b)); - - goto end_of_bridge_loop; } } @@ -467,7 +466,7 @@ static switch_status_t audio_bridge_on_exchange_media(switch_core_session_t *ses switch_ivr_park_session(session); } - if (!switch_channel_test_flag(channel, CF_TRANSFER) && bd && !bd->clean_exit && state != CS_PARK && + if (!switch_channel_test_flag(channel, CF_TRANSFER) && !switch_channel_test_flag(channel, CF_REDIRECT) && bd && !bd->clean_exit && state != CS_PARK && state != CS_ROUTING && !switch_channel_test_flag(channel, CF_INNER_BRIDGE)) { switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); } @@ -485,6 +484,9 @@ static switch_status_t audio_bridge_on_exchange_media(switch_core_session_t *ses } } + if (switch_channel_get_state(channel) < CS_HANGUP) { + switch_channel_set_state(channel, CS_RESET); + } return SWITCH_STATUS_FALSE; } @@ -526,33 +528,38 @@ static switch_status_t uuid_bridge_on_reset(switch_core_session_t *session) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CUSTOM RESET\n", switch_channel_get_name(channel)); - switch_channel_clear_flag(channel, CF_TRANSFER); + switch_channel_clear_flag(channel, CF_REDIRECT); + switch_channel_clear_flag(channel, CF_ORIGINATING); - if (switch_channel_test_flag(channel, (uint32_t)CF_MASTER)) { + if (switch_channel_test_flag(channel, CF_ORIGINATOR)) { switch_channel_set_state(channel, CS_SOFT_EXECUTE); } return SWITCH_STATUS_SUCCESS; } +static switch_status_t uuid_bridge_on_hibernate(switch_core_session_t *session) +{ + switch_channel_set_state(switch_core_session_get_channel(session), CS_RESET); + return SWITCH_STATUS_FALSE; +} + static switch_status_t uuid_bridge_on_soft_execute(switch_core_session_t *session) { switch_channel_t *channel = switch_core_session_get_channel(session); switch_core_session_t *other_session; const char *other_uuid = NULL; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CUSTOM TRANSMIT\n", switch_channel_get_name(channel)); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CUSTOM SOFT_EXECUTE\n", switch_channel_get_name(channel)); switch_channel_clear_state_handler(channel, NULL); - switch_channel_clear_flag(channel, CF_TRANSFER); - - if (!switch_channel_test_flag(channel, (uint32_t)CF_MASTER)) { + if (!switch_channel_test_flag(channel, CF_ORIGINATOR)) { return SWITCH_STATUS_SUCCESS; } - switch_channel_clear_flag(channel, (uint32_t)CF_MASTER); - + switch_channel_clear_flag(channel, CF_ORIGINATOR); + if ((other_uuid = switch_channel_get_variable(channel, SWITCH_UUID_BRIDGE)) && (other_session = switch_core_session_locate(other_uuid))) { switch_channel_t *other_channel = switch_core_session_get_channel(other_session); switch_event_t *event; @@ -575,8 +582,6 @@ static switch_status_t uuid_bridge_on_soft_execute(switch_core_session_t *sessio switch_channel_wait_for_state(channel, other_channel, CS_SOFT_EXECUTE); - switch_channel_clear_flag(channel, CF_TRANSFER); - switch_channel_clear_flag(other_channel, CF_TRANSFER); switch_core_session_reset(session, SWITCH_TRUE); @@ -618,7 +623,7 @@ static switch_status_t uuid_bridge_on_soft_execute(switch_core_session_t *sessio switch_ivr_multi_threaded_bridge(session, other_session, NULL, NULL, NULL); state = switch_channel_get_state(channel); - if (!switch_channel_test_flag(channel, CF_TRANSFER) && state < CS_HANGUP && state != CS_ROUTING && state != CS_PARK) { + if (!switch_channel_test_flag(channel, CF_TRANSFER) && !switch_channel_test_flag(channel, CF_REDIRECT) && state < CS_HANGUP && state != CS_ROUTING && state != CS_PARK) { switch_channel_set_state(channel, CS_EXECUTE); } switch_core_session_rwunlock(other_session); @@ -638,8 +643,8 @@ static const switch_state_handler_table_t uuid_bridge_state_handlers = { /*.on_hangup */ NULL, /*.on_exchange_media */ NULL, /*.on_soft_execute */ uuid_bridge_on_soft_execute, - /*.on_consume_media */ NULL, - /*.on_hibernate */ NULL, + /*.on_consume_media */ uuid_bridge_on_hibernate, + /*.on_hibernate */ uuid_bridge_on_hibernate, /*.on_reset */ uuid_bridge_on_reset }; @@ -649,7 +654,6 @@ static switch_status_t signal_bridge_on_hibernate(switch_core_session_t *session channel = switch_core_session_get_channel(session); switch_assert(channel != NULL); - switch_channel_clear_flag(channel, CF_TRANSFER); switch_channel_set_variable(channel, SWITCH_BRIDGE_VARIABLE, switch_channel_get_variable(channel, SWITCH_SIGNAL_BRIDGE_VARIABLE)); @@ -785,8 +789,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses int inner_bridge = switch_channel_test_flag(caller_channel, CF_INNER_BRIDGE); switch_channel_set_flag(caller_channel, CF_ORIGINATOR); - switch_channel_clear_flag(caller_channel, CF_TRANSFER); - switch_channel_clear_flag(peer_channel, CF_TRANSFER); b_leg->session = peer_session; switch_copy_string(b_leg->b_uuid, switch_core_session_get_uuid(session), sizeof(b_leg->b_uuid)); @@ -830,7 +832,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses if ((status = switch_ivr_wait_for_answer(session, peer_session)) != SWITCH_STATUS_SUCCESS) { switch_channel_state_t w_state = switch_channel_get_state(caller_channel); switch_channel_hangup(peer_channel, SWITCH_CAUSE_ALLOTTED_TIMEOUT); - if (w_state < CS_HANGUP && w_state != CS_ROUTING && w_state != CS_PARK && !switch_channel_test_flag(caller_channel, CF_TRANSFER) && + if (w_state < CS_HANGUP && w_state != CS_ROUTING && w_state != CS_PARK && + !switch_channel_test_flag(caller_channel, CF_REDIRECT) && !switch_channel_test_flag(caller_channel, CF_TRANSFER) && w_state != CS_EXECUTE) { const char *ext = switch_channel_get_variable(peer_channel, "original_destination_number"); if (!ext) { @@ -911,10 +914,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses switch_channel_clear_flag(caller_channel, CF_ORIGINATOR); - if (!switch_channel_test_flag(peer_channel, CF_TRANSFER) && switch_channel_get_state(peer_channel) == CS_EXCHANGE_MEDIA) { - switch_channel_set_state(peer_channel, CS_RESET); - } - while (switch_channel_get_state(peer_channel) == CS_EXCHANGE_MEDIA) { switch_cond_next(); } @@ -943,8 +942,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses } state = switch_channel_get_state(caller_channel); - - if (!switch_channel_test_flag(caller_channel, CF_TRANSFER) && !a_leg->clean_exit && !inner_bridge) { + + if (!switch_channel_test_flag(caller_channel, CF_TRANSFER) && !switch_channel_test_flag(caller_channel, CF_REDIRECT) + && !a_leg->clean_exit && !inner_bridge) { if ((state != CS_EXECUTE && state != CS_SOFT_EXECUTE && state != CS_PARK && state != CS_ROUTING) || (switch_channel_test_flag(peer_channel, CF_ANSWERED) && state < CS_HANGUP)) { if (switch_true(switch_channel_get_variable(caller_channel, SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE))) { @@ -955,6 +955,11 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses } } + if (switch_channel_test_flag(caller_channel, CF_REDIRECT)) { + switch_channel_set_state(caller_channel, CS_RESET); + } + + return status; } @@ -992,6 +997,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_uuid_bridge(const char *originator_uu switch_status_t status = SWITCH_STATUS_FALSE; switch_caller_profile_t *cp, *originator_cp, *originatee_cp; char *p; + switch_channel_state_t state; if ((originator_session = switch_core_session_locate(originator_uuid))) { if ((originatee_session = switch_core_session_locate(originatee_uuid))) { @@ -1033,14 +1039,11 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_uuid_bridge(const char *originator_uu * originatee_session will fall asleep and originator_session will bridge to it */ - switch_channel_clear_state_handler(originator_channel, NULL); - switch_channel_clear_state_handler(originatee_channel, NULL); - switch_channel_set_flag(originator_channel, (uint32_t)CF_MASTER); - switch_channel_clear_flag(originatee_channel, (uint32_t)CF_MASTER); - switch_channel_add_state_handler(originator_channel, &uuid_bridge_state_handlers); - switch_channel_add_state_handler(originatee_channel, &uuid_bridge_state_handlers); - switch_channel_set_variable(originator_channel, SWITCH_UUID_BRIDGE, switch_core_session_get_uuid(originatee_session)); + switch_channel_set_flag(originator_channel, CF_REDIRECT); + switch_channel_set_flag(originatee_channel, CF_REDIRECT); + + switch_channel_set_variable(originator_channel, SWITCH_UUID_BRIDGE, switch_core_session_get_uuid(originatee_session)); switch_channel_set_variable(originator_channel, SWITCH_BRIDGE_CHANNEL_VARIABLE, switch_channel_get_name(originatee_channel)); switch_channel_set_variable(originator_channel, SWITCH_BRIDGE_UUID_VARIABLE, switch_core_session_get_uuid(originatee_session)); switch_channel_set_variable(originator_channel, SWITCH_SIGNAL_BOND_VARIABLE, switch_core_session_get_uuid(originatee_session)); @@ -1089,13 +1092,23 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_uuid_bridge(const char *originator_uu switch_channel_set_flag(originator_channel, CF_TRANSFER); switch_channel_set_flag(originatee_channel, CF_TRANSFER); + switch_channel_clear_flag(originator_channel, CF_ORIGINATING); switch_channel_clear_flag(originatee_channel, CF_ORIGINATING); /* change the states and let the chips fall where they may */ - switch_channel_set_state(originator_channel, CS_RESET); - switch_channel_set_state(originatee_channel, CS_RESET); + switch_channel_clear_state_handler(originator_channel, NULL); + switch_channel_clear_state_handler(originatee_channel, NULL); + switch_channel_set_state_flag(originator_channel, CF_ORIGINATOR); + switch_channel_clear_flag(originatee_channel, CF_ORIGINATOR); + switch_channel_add_state_handler(originator_channel, &uuid_bridge_state_handlers); + switch_channel_add_state_handler(originatee_channel, &uuid_bridge_state_handlers); + state = switch_channel_get_state(originator_channel); + switch_channel_set_state(originator_channel, state == CS_HIBERNATE ? CS_CONSUME_MEDIA : CS_HIBERNATE); + state = switch_channel_get_state(originatee_channel); + switch_channel_set_state(originatee_channel, state == CS_HIBERNATE ? CS_CONSUME_MEDIA : CS_HIBERNATE); + status = SWITCH_STATUS_SUCCESS; /* release the read locks we have on the channels */ diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index 44f845428b..187f366eea 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -231,7 +231,9 @@ static uint8_t check_channel_status(switch_channel_t **peer_channels, state = switch_channel_get_state(peer_channels[i]); if (state >= CS_HANGUP || state == CS_RESET || switch_channel_test_flag(peer_channels[i], CF_TRANSFER) || - switch_channel_test_flag(peer_channels[i], CF_BRIDGED) || !switch_channel_test_flag(peer_channels[i], CF_ORIGINATING) + switch_channel_test_flag(peer_channels[i], CF_REDIRECT) || + switch_channel_test_flag(peer_channels[i], CF_BRIDGED) || + !switch_channel_test_flag(peer_channels[i], CF_ORIGINATING) ) { (*hups)++; } else if ((switch_channel_test_flag(peer_channels[i], CF_ANSWERED) || @@ -1453,8 +1455,11 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess continue; } - if (switch_channel_test_flag(peer_channels[i], CF_TRANSFER) || switch_channel_test_flag(peer_channels[i], CF_BRIDGED) || - switch_channel_get_state(peer_channels[i]) == CS_RESET || !switch_channel_test_flag(peer_channels[i], CF_ORIGINATING) + if (switch_channel_test_flag(peer_channels[i], CF_TRANSFER) + || switch_channel_test_flag(peer_channels[i], CF_REDIRECT) + || switch_channel_test_flag(peer_channels[i], CF_BRIDGED) || + switch_channel_get_state(peer_channels[i]) == CS_RESET || + !switch_channel_test_flag(peer_channels[i], CF_ORIGINATING) ) { continue; } @@ -1652,6 +1657,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess } } else if ((state=switch_channel_get_state(peer_channels[i])) < CS_HANGUP && switch_channel_test_flag(peer_channels[i], CF_ORIGINATING)) { if (!(state == CS_RESET || switch_channel_test_flag(peer_channels[i], CF_TRANSFER) || + switch_channel_test_flag(peer_channels[i], CF_REDIRECT) || switch_channel_test_flag(peer_channels[i], CF_BRIDGED))) { switch_channel_hangup(peer_channels[i], *cause); }