From 2feae3fc69bdde43002cbf71c025dbae3d87205b Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 2 Jul 2015 15:17:26 -0500 Subject: [PATCH] FS-6833 #comment please test this branch --- src/include/switch_ivr.h | 3 +- src/include/switch_types.h | 5 + .../applications/mod_commands/mod_commands.c | 32 +++ src/mod/endpoints/mod_sofia/mod_sofia.c | 16 +- src/mod/endpoints/mod_sofia/sofia.c | 93 +++++++- src/switch_core_media.c | 7 +- src/switch_ivr.c | 206 ++++++++++++++++++ src/switch_ivr_bridge.c | 5 +- 8 files changed, 360 insertions(+), 7 deletions(-) diff --git a/src/include/switch_ivr.h b/src/include/switch_ivr.h index 7bb00cb06b..999d028eba 100644 --- a/src/include/switch_ivr.h +++ b/src/include/switch_ivr.h @@ -588,7 +588,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_uuid_bridge(const char *originator_uu \return SWITCH_STATUS_SUCCESS if all is well */ SWITCH_DECLARE(switch_status_t) switch_ivr_media(const char *uuid, switch_media_flag_t flags); - +SWITCH_DECLARE(switch_status_t) switch_ivr_3p_media(const char *uuid, switch_media_flag_t flags); /*! \brief Signal a session to request indirect media allowing it to exchange media directly with another device \param uuid the uuid of the session to request @@ -596,6 +596,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_media(const char *uuid, switch_media_ \return SWITCH_STATUS_SUCCESS if all is well */ SWITCH_DECLARE(switch_status_t) switch_ivr_nomedia(const char *uuid, switch_media_flag_t flags); +SWITCH_DECLARE(switch_status_t) switch_ivr_3p_nomedia(const char *uuid, switch_media_flag_t flags); /*! \brief Signal the session with a protocol specific hold message. diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 068df98dad..c6090eaa08 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -1038,7 +1038,9 @@ typedef enum { SWITCH_MESSAGE_INDICATE_TRANSFER, SWITCH_MESSAGE_INDICATE_RINGING, SWITCH_MESSAGE_INDICATE_MEDIA, + SWITCH_MESSAGE_INDICATE_3P_MEDIA, SWITCH_MESSAGE_INDICATE_NOMEDIA, + SWITCH_MESSAGE_INDICATE_3P_NOMEDIA, SWITCH_MESSAGE_INDICATE_HOLD, SWITCH_MESSAGE_INDICATE_UNHOLD, SWITCH_MESSAGE_INDICATE_REDIRECT, @@ -1489,6 +1491,9 @@ typedef enum { CF_VIDEO_MIRROR_INPUT, CF_VIDEO_READ_FILE_ATTACHED, CF_VIDEO_WRITE_FILE_ATTACHED, + CF_3P_MEDIA_REQUESTED, + CF_3P_NOMEDIA_REQUESTED, + CF_3P_NOMEDIA_REQUESTED_BLEG, /* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */ /* IF YOU ADD NEW ONES CHECK IF THEY SHOULD PERSIST OR ZERO THEM IN switch_core_session.c switch_core_session_request_xml() */ CF_FLAG_MAX diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 68e8d2a605..768f170988 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -3404,6 +3404,37 @@ SWITCH_STANDARD_API(uuid_media_function) return SWITCH_STATUS_SUCCESS; } +#define MEDIA_SYNTAX "[off] " +SWITCH_STANDARD_API(uuid_media_3p_function) +{ + char *mycmd = NULL, *argv[4] = { 0 }; + int argc = 0; + switch_status_t status = SWITCH_STATUS_FALSE; + + if (!zstr(cmd) && (mycmd = strdup(cmd))) { + argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + } + + if (zstr(cmd) || argc < 1 || zstr(argv[0])) { + stream->write_function(stream, "-USAGE: %s\n", MEDIA_SYNTAX); + } else { + if (!strcasecmp(argv[0], "off")) { + status = switch_ivr_3p_nomedia(argv[1], SMF_REBRIDGE); + } else { + status = switch_ivr_3p_media(argv[0], SMF_REBRIDGE); + } + } + + if (status == SWITCH_STATUS_SUCCESS) { + stream->write_function(stream, "+OK Success\n"); + } else { + stream->write_function(stream, "-ERR Operation failed\n"); + } + + switch_safe_free(mycmd); + return SWITCH_STATUS_SUCCESS; +} + #define MEDIA_RENEG_SYNTAX "[ ]" SWITCH_STANDARD_API(uuid_media_neg_function) { @@ -6959,6 +6990,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) SWITCH_ADD_API(commands_api_interface, "uuid_limit_release", "Release limit resource", uuid_limit_release_function, LIMIT_RELEASE_SYNTAX); SWITCH_ADD_API(commands_api_interface, "uuid_loglevel", "Set loglevel on session", uuid_loglevel, UUID_LOGLEVEL_SYNTAX); SWITCH_ADD_API(commands_api_interface, "uuid_media", "Reinvite FS in or out of media path", uuid_media_function, MEDIA_SYNTAX); + SWITCH_ADD_API(commands_api_interface, "uuid_media_3p", "Reinvite FS in or out of media path using 3pcc", uuid_media_3p_function, MEDIA_SYNTAX); SWITCH_ADD_API(commands_api_interface, "uuid_media_reneg", "Media negotiation", uuid_media_neg_function, MEDIA_RENEG_SYNTAX); SWITCH_ADD_API(commands_api_interface, "uuid_park", "Park channel", park_function, PARK_SYNTAX); SWITCH_ADD_API(commands_api_interface, "uuid_pause", "Pause media on a channel", pause_function, PAUSE_SYNTAX); diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 29281d0cd6..b2f37b3815 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -969,8 +969,9 @@ static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_f return SWITCH_STATUS_FALSE; } - while (!(switch_core_media_ready(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO) && !switch_channel_test_flag(channel, CF_REQ_MEDIA))) { + while (!(switch_core_media_ready(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO))){// && !switch_channel_test_flag(channel, CF_REQ_MEDIA))) { switch_ivr_parse_all_messages(tech_pvt->session); + if (--sanity && switch_channel_up(channel)) { switch_yield(10000); } else { @@ -1374,7 +1375,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi switch_channel_get_name(channel), msg->string_arg); switch_core_media_set_local_sdp(session, msg->string_arg, SWITCH_TRUE); - if(zstr(tech_pvt->mparams.local_sdp_str)) { + if (zstr(tech_pvt->mparams.local_sdp_str)) { sofia_set_flag(tech_pvt, TFLAG_3PCC_INVITE); } @@ -1447,6 +1448,17 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi } break; + case SWITCH_MESSAGE_INDICATE_3P_NOMEDIA: + { + nua_invite(tech_pvt->nh, NUTAG_MEDIA_ENABLE(0), SIPTAG_PAYLOAD_STR(msg->string_arg), TAG_END()); + } + break; + case SWITCH_MESSAGE_INDICATE_3P_MEDIA: + { + nua_invite(tech_pvt->nh, NUTAG_MEDIA_ENABLE(0), SIPTAG_PAYLOAD_STR(""), TAG_END()); + } + break; + case SWITCH_MESSAGE_INDICATE_MEDIA: { uint32_t send_invite = 1; diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 96d2466e15..35038c4645 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -6929,6 +6929,93 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, } } + if (switch_channel_test_flag(channel, CF_3P_NOMEDIA_REQUESTED)) { + switch_channel_clear_flag(channel, CF_3P_NOMEDIA_REQUESTED); + if (switch_channel_test_flag(channel, CF_3P_NOMEDIA_REQUESTED_BLEG)) { + switch_core_session_t *other_session; + + switch_channel_clear_flag(channel, CF_3P_NOMEDIA_REQUESTED_BLEG); + + if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) { + if (switch_core_session_compare(session, other_session)) { + //switch_channel_t *other_channel = switch_core_session_get_channel(other_session); + private_object_t *other_tech_pvt = switch_core_session_get_private(other_session); + + nua_ack(other_tech_pvt->nh, + NUTAG_MEDIA_ENABLE(0), + TAG_IF(!zstr(other_tech_pvt->user_via), SIPTAG_VIA_STR(other_tech_pvt->user_via)), + SIPTAG_CONTACT_STR(other_tech_pvt->reply_contact), + SIPTAG_PAYLOAD_STR(r_sdp), + TAG_END()); + + + nua_ack(tech_pvt->nh, + TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), + SIPTAG_CONTACT_STR(tech_pvt->reply_contact), + TAG_END()); + + } + switch_core_session_rwunlock(other_session); + } + } else { + switch_channel_set_variable(channel, SWITCH_R_SDP_VARIABLE, r_sdp); + } + + goto done; + + } else if (switch_channel_test_flag(channel, CF_3P_MEDIA_REQUESTED)) { + uint8_t match = 0; + + switch_channel_clear_flag(channel, CF_3P_MEDIA_REQUESTED); + switch_channel_clear_flag(channel, CF_PROXY_MODE); + + switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0); + switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_FALSE); + + if (tech_pvt->mparams.num_codecs) { + match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_REQUEST); + } + + if (!match) { + if (switch_channel_get_state(channel) != CS_NEW) { + nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE, TAG_END()); + } + } else { + switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0); + switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED"); + sofia_set_flag_locked(tech_pvt, TFLAG_READY); + + sofia_set_flag(tech_pvt, TFLAG_SDP); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "RESTABLISH MEDIA SDP:\n%s\n", tech_pvt->mparams.local_sdp_str); + + switch_channel_set_flag(channel, CF_REQ_MEDIA); + switch_channel_set_flag(channel, CF_MEDIA_ACK); + switch_channel_set_flag(channel, CF_MEDIA_SET); + + switch_core_media_activate_rtp(session); + + nua_ack(tech_pvt->nh, + TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), + SIPTAG_CONTACT_STR(tech_pvt->reply_contact), + //SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str), + SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str), + //SOATAG_REUSE_REJECTED(1), + //SOATAG_RTP_SELECT(1), + SOATAG_AUDIO_AUX("cn telephone-event"), + //TAG_IF(sofia_test_pflag(tech_pvt->profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)), + TAG_END()); + + goto done; + } + + switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "NO CODECS"); + switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION); + + goto done; + //ss_state = nua_callstate_ready; + //goto state_process; + } + if (r_sdp && sofia_test_flag(tech_pvt, TFLAG_3PCC_INVITE) && !sofia_test_flag(tech_pvt, TFLAG_SDP)) { sofia_set_flag(tech_pvt, TFLAG_SDP); if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) { @@ -7139,6 +7226,10 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, } goto done; } + + + switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0); + nua_respond(tech_pvt->nh, SIP_200_OK, TAG_END()); goto done; } else if (r_sdp && !sofia_use_soa(tech_pvt)) { @@ -7481,7 +7572,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, int is_ok = 1; if (tech_pvt->mparams.num_codecs) { - match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_REQUEST); + match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_RESPONSE); } if (match) { diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 24395b1292..e09612a0ec 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -9042,7 +9042,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_se switch_rtp_flush(v_engine->rtp_session); } goto end; - + case SWITCH_MESSAGE_INDICATE_3P_MEDIA: case SWITCH_MESSAGE_INDICATE_MEDIA: { @@ -9054,6 +9054,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_se } } break; + + case SWITCH_MESSAGE_INDICATE_3P_NOMEDIA: + switch_channel_set_flag(session->channel, CF_PROXY_MODE); + switch_core_media_set_local_sdp(session, NULL, SWITCH_FALSE); + break; case SWITCH_MESSAGE_INDICATE_NOMEDIA: { const char *uuid; diff --git a/src/switch_ivr.c b/src/switch_ivr.c index 1bf876c441..3e514d1e61 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -1548,6 +1548,114 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_unhold_uuid(const char *uuid) return SWITCH_STATUS_SUCCESS; } +SWITCH_DECLARE(switch_status_t) switch_ivr_3p_media(const char *uuid, switch_media_flag_t flags) +{ + const char *other_uuid = NULL; + switch_channel_t *channel, *other_channel = NULL; + switch_core_session_t *session, *other_session; + switch_core_session_message_t msg = { 0 }; + switch_status_t status = SWITCH_STATUS_GENERR; + uint8_t swap = 0; + //switch_frame_t *read_frame = NULL; + + msg.message_id = SWITCH_MESSAGE_INDICATE_3P_MEDIA; + msg.from = __FILE__; + + if ((session = switch_core_session_locate(uuid))) { + channel = switch_core_session_get_channel(session); + + if (switch_channel_test_flag(channel, CF_MEDIA_TRANS)) { + switch_core_session_rwunlock(session); + return SWITCH_STATUS_INUSE; + } + + switch_channel_set_flag(channel, CF_MEDIA_TRANS); + + if ((flags & SMF_REBRIDGE) && !switch_channel_test_flag(channel, CF_BRIDGE_ORIGINATOR)) { + swap = 1; + } + + if (switch_channel_test_flag(channel, CF_PROXY_MODE)) { + status = SWITCH_STATUS_SUCCESS; + + /* If we had early media in bypass mode before, it is no longer relevant */ + if (switch_channel_test_flag(channel, CF_EARLY_MEDIA)) { + switch_core_session_message_t msg2 = { 0 }; + + msg2.message_id = SWITCH_MESSAGE_INDICATE_CLEAR_PROGRESS; + msg2.from = __FILE__; + switch_core_session_receive_message(session, &msg2); + } + + if ((flags & SMF_REPLYONLY_A)) { + msg.numeric_arg = 1; + } + + switch_channel_set_flag(channel, CF_3P_MEDIA_REQUESTED); + + if (switch_core_session_receive_message(session, &msg) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't re-establsh media on %s\n", switch_channel_get_name(channel)); + switch_channel_clear_flag(channel, CF_3P_MEDIA_REQUESTED); + switch_core_session_rwunlock(session); + return SWITCH_STATUS_GENERR; + } + + if ((flags & SMF_REPLYONLY_B)) { + msg.numeric_arg = 1; + } else { + msg.numeric_arg = 0; + } + + if ((flags & SMF_IMMEDIATE)) { + switch_channel_wait_for_flag(channel, CF_REQ_MEDIA, SWITCH_FALSE, 250, NULL); + switch_yield(250000); + } else { + switch_channel_wait_for_flag(channel, CF_REQ_MEDIA, SWITCH_FALSE, 10000, NULL); + switch_channel_wait_for_flag(channel, CF_MEDIA_ACK, SWITCH_TRUE, 10000, NULL); + switch_channel_wait_for_flag(channel, CF_MEDIA_SET, SWITCH_TRUE, 10000, NULL); + //switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); + } + + if ((flags & SMF_REBRIDGE) + && (other_uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BRIDGE_VARIABLE)) + && (other_session = switch_core_session_locate(other_uuid))) { + + other_channel = switch_core_session_get_channel(other_session); + switch_assert(other_channel != NULL); + + switch_channel_set_flag(other_channel, CF_3P_MEDIA_REQUESTED); + switch_channel_set_variable(other_channel, "rtp_secure_media", "optional"); + + switch_core_session_receive_message(other_session, &msg); + switch_channel_wait_for_flag(other_channel, CF_REQ_MEDIA, SWITCH_FALSE, 10000, NULL); + switch_channel_wait_for_flag(other_channel, CF_MEDIA_ACK, SWITCH_TRUE, 10000, NULL); + switch_channel_wait_for_flag(other_channel, CF_MEDIA_SET, SWITCH_TRUE, 10000, NULL); + //switch_core_session_read_frame(other_session, &read_frame, SWITCH_IO_FLAG_NONE, 0); + switch_channel_clear_state_handler(other_channel, NULL); + switch_core_session_rwunlock(other_session); + } + if (other_channel) { + switch_channel_clear_state_handler(channel, NULL); + } + } + + switch_channel_clear_flag(channel, CF_MEDIA_TRANS); + switch_core_session_rwunlock(session); + + if (other_channel) { + if (swap) { + switch_ivr_uuid_bridge(other_uuid, uuid); + } else { + switch_ivr_uuid_bridge(uuid, other_uuid); + } + switch_channel_wait_for_flag(channel, CF_BRIDGED, SWITCH_TRUE, 1000, NULL); + switch_channel_wait_for_flag(other_channel, CF_BRIDGED, SWITCH_TRUE, 1000, NULL); + } + } + + return status; +} + SWITCH_DECLARE(switch_status_t) switch_ivr_media(const char *uuid, switch_media_flag_t flags) { const char *other_uuid = NULL; @@ -1648,6 +1756,104 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_media(const char *uuid, switch_media_ return status; } +SWITCH_DECLARE(switch_status_t) switch_ivr_3p_nomedia(const char *uuid, switch_media_flag_t flags) +{ + const char *other_uuid; + switch_channel_t *channel, *other_channel = NULL; + switch_core_session_t *session, *other_session = NULL; + switch_core_session_message_t msg = { 0 }; + switch_status_t status = SWITCH_STATUS_GENERR; + uint8_t swap = 0; + + msg.message_id = SWITCH_MESSAGE_INDICATE_3P_NOMEDIA; + msg.from = __FILE__; + + if ((session = switch_core_session_locate(uuid))) { + status = SWITCH_STATUS_SUCCESS; + channel = switch_core_session_get_channel(session); + + if (switch_channel_test_flag(channel, CF_MEDIA_TRANS)) { + switch_core_session_rwunlock(session); + return SWITCH_STATUS_INUSE; + } + + switch_channel_set_flag(channel, CF_MEDIA_TRANS); + + if ((flags & SMF_REBRIDGE) && !switch_channel_test_flag(channel, CF_BRIDGE_ORIGINATOR)) { + swap = 1; + } + + if ((flags & SMF_FORCE) || !switch_channel_test_flag(channel, CF_PROXY_MODE)) { + if ((flags & SMF_REBRIDGE) && (other_uuid = switch_channel_get_variable(channel, SWITCH_BRIDGE_VARIABLE)) && + (other_session = switch_core_session_locate(other_uuid))) { + other_channel = switch_core_session_get_channel(other_session); + + switch_channel_set_flag(channel, CF_REDIRECT); + switch_channel_set_flag(channel, CF_RESET); + + switch_channel_set_flag(other_channel, CF_RESET); + switch_channel_set_flag(other_channel, CF_REDIRECT); + + switch_channel_set_flag(channel, CF_3P_NOMEDIA_REQUESTED); + switch_core_session_receive_message(session, &msg); + + if (!switch_core_session_in_thread(session)) { + switch_channel_set_state(channel, CS_PARK); + } + switch_channel_set_state(other_channel, CS_PARK); + if (switch_core_session_in_thread(session)) { + switch_yield(100000); + } else { + switch_channel_wait_for_state(other_channel, channel, CS_PARK); + } + + msg.string_arg = switch_channel_get_variable(channel, SWITCH_R_SDP_VARIABLE); + switch_channel_set_flag(other_channel, CF_3P_NOMEDIA_REQUESTED); + switch_channel_set_flag(other_channel, CF_3P_NOMEDIA_REQUESTED_BLEG); + + switch_core_session_receive_message(other_session, &msg); + switch_channel_wait_for_flag(other_channel, CF_REQ_MEDIA, SWITCH_FALSE, 10000, NULL); + switch_channel_wait_for_flag(other_channel, CF_MEDIA_SET, SWITCH_TRUE, 10000, NULL); + } + + if (other_channel) { + if (!switch_core_session_in_thread(session)) { + switch_channel_wait_for_state(channel, NULL, CS_PARK); + switch_channel_wait_for_flag(channel, CF_REQ_MEDIA, SWITCH_FALSE, 10000, NULL); + switch_channel_wait_for_flag(channel, CF_MEDIA_ACK, SWITCH_TRUE, 10000, NULL); + switch_channel_wait_for_flag(channel, CF_MEDIA_SET, SWITCH_TRUE, 10000, NULL); + } + + if (swap) { + switch_ivr_signal_bridge(other_session, session); + } else { + switch_ivr_signal_bridge(session, other_session); + } + + if (switch_core_session_in_thread(session)) { + switch_yield(100000); + } else { + switch_channel_wait_for_state(other_channel, channel, CS_HIBERNATE); + } + + if (!switch_core_session_in_thread(session)) { + switch_channel_wait_for_state(channel, other_channel, CS_HIBERNATE); + } + switch_core_session_rwunlock(other_session); + } + } + + switch_channel_clear_flag(channel, CF_MEDIA_TRANS); + switch_core_session_rwunlock(session); + } + + + + return status; +} + + + SWITCH_DECLARE(switch_status_t) switch_ivr_nomedia(const char *uuid, switch_media_flag_t flags) { const char *other_uuid; diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index ccf0f9c5bd..ecad0171ae 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -1762,7 +1762,8 @@ static void cleanup_proxy_mode_a(switch_core_session_t *session) switch_channel_t *channel = switch_core_session_get_channel(session); int done = 0; - if (switch_channel_test_flag(channel, CF_PROXY_MODE)) { + if (!switch_channel_test_flag(channel, CF_3P_MEDIA_REQUESTED) && + switch_channel_test_flag(channel, CF_PROXY_MODE) && !switch_channel_test_flag(channel, CF_3P_NOMEDIA_REQUESTED)) { if (switch_core_session_get_partner(session, &sbsession) == SWITCH_STATUS_SUCCESS) { switch_channel_t *sbchannel = switch_core_session_get_channel(sbsession); @@ -1844,7 +1845,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_uuid_bridge(const char *originator_uu if (switch_channel_direction(originatee_channel) == SWITCH_CALL_DIRECTION_OUTBOUND && switch_channel_test_flag(originatee_channel, CF_DIALPLAN)) { switch_channel_clear_flag(originatee_channel, CF_DIALPLAN); } - + cleanup_proxy_mode_a(originator_session); cleanup_proxy_mode_a(originatee_session);