From aba8d7590f5484d2071500a2412845d1ec9a782c Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 24 Nov 2009 18:18:09 +0000 Subject: [PATCH] FSCORE-481 git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@15657 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- src/include/switch_types.h | 1 + src/mod/endpoints/mod_sofia/mod_sofia.c | 38 ++++++++---------------- src/mod/endpoints/mod_sofia/sofia.c | 7 +++++ src/mod/endpoints/mod_sofia/sofia_glue.c | 3 ++ src/switch_ivr_bridge.c | 19 ++++++++++++ 5 files changed, 42 insertions(+), 26 deletions(-) diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 0fb00cfbb0..34d51fac06 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -942,6 +942,7 @@ typedef enum { CF_SIGNAL_BRIDGE_TTL, CF_MEDIA_BRIDGE_TTL, CF_BYPASS_MEDIA_AFTER_BRIDGE, + CF_LEG_HOLDING, /* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */ CF_FLAG_MAX } switch_channel_flag_t; diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 32b010b407..10087a2e92 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -121,10 +121,12 @@ static switch_status_t sofia_on_init(switch_core_session_t *session) static switch_status_t sofia_on_routing(switch_core_session_t *session) { private_object_t *tech_pvt = (private_object_t *) switch_core_session_get_private(session); + switch_channel_t *channel = switch_core_session_get_channel(session); switch_assert(tech_pvt != NULL); if (!sofia_test_flag(tech_pvt, TFLAG_HOLD_LOCK)) { sofia_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD); + switch_channel_clear_flag(channel, CF_LEG_HOLDING); } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s SOFIA ROUTING\n", switch_channel_get_name(switch_core_session_get_channel(session))); @@ -136,10 +138,12 @@ static switch_status_t sofia_on_routing(switch_core_session_t *session) static switch_status_t sofia_on_reset(switch_core_session_t *session) { private_object_t *tech_pvt = (private_object_t *) switch_core_session_get_private(session); + switch_channel_t *channel = switch_core_session_get_channel(session); switch_assert(tech_pvt != NULL); if (!sofia_test_flag(tech_pvt, TFLAG_HOLD_LOCK)) { sofia_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD); + switch_channel_clear_flag(channel, CF_LEG_HOLDING); } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s SOFIA RESET\n", switch_channel_get_name(switch_core_session_get_channel(session))); @@ -151,10 +155,12 @@ static switch_status_t sofia_on_reset(switch_core_session_t *session) static switch_status_t sofia_on_hibernate(switch_core_session_t *session) { private_object_t *tech_pvt = switch_core_session_get_private(session); + switch_channel_t *channel = switch_core_session_get_channel(session); switch_assert(tech_pvt != NULL); if (!sofia_test_flag(tech_pvt, TFLAG_HOLD_LOCK)) { sofia_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD); + switch_channel_clear_flag(channel, CF_LEG_HOLDING); } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s SOFIA HIBERNATE\n", switch_channel_get_name(switch_core_session_get_channel(session))); @@ -165,10 +171,12 @@ static switch_status_t sofia_on_hibernate(switch_core_session_t *session) static switch_status_t sofia_on_execute(switch_core_session_t *session) { private_object_t *tech_pvt = (private_object_t *) switch_core_session_get_private(session); + switch_channel_t *channel = switch_core_session_get_channel(session); switch_assert(tech_pvt != NULL); if (!sofia_test_flag(tech_pvt, TFLAG_HOLD_LOCK)) { sofia_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD); + switch_channel_clear_flag(channel, CF_LEG_HOLDING); } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s SOFIA EXECUTE\n", switch_channel_get_name(switch_core_session_get_channel(session))); @@ -347,32 +355,6 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session) } } - if (sofia_test_flag(tech_pvt, TFLAG_SIP_HOLD) && cause != SWITCH_CAUSE_ATTENDED_TRANSFER) { - const char *buuid; - switch_core_session_t *bsession; - switch_channel_t *bchannel; - const char *lost_ext; - - if (tech_pvt->max_missed_packets) { - switch_rtp_set_max_missed_packets(tech_pvt->rtp_session, tech_pvt->max_missed_packets); - } - switch_channel_presence(tech_pvt->channel, "unknown", "unhold", NULL); - - if ((buuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE))) { - if ((bsession = switch_core_session_locate(buuid))) { - bchannel = switch_core_session_get_channel(bsession); - if (switch_channel_test_flag(bchannel, CF_BROADCAST)) { - if ((lost_ext = switch_channel_get_variable(bchannel, "left_hanging_extension"))) { - switch_ivr_session_transfer(bsession, lost_ext, NULL, NULL); - } - switch_channel_stop_broadcast(bchannel); - } - switch_core_session_rwunlock(bsession); - } - } - sofia_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD); - } - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Channel %s hanging up, cause: %s\n", switch_channel_get_name(channel), switch_channel_cause2str(cause)); @@ -665,6 +647,7 @@ static switch_status_t sofia_read_video_frame(switch_core_session_t *session, sw if (sofia_test_flag(tech_pvt, TFLAG_SIP_HOLD)) { sofia_glue_toggle_hold(tech_pvt, 0); sofia_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD); + switch_channel_clear_flag(channel, CF_LEG_HOLDING); } switch_channel_hangup(tech_pvt->channel, SWITCH_CAUSE_MEDIA_TIMEOUT); } @@ -780,6 +763,7 @@ static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_f if (sofia_test_flag(tech_pvt, TFLAG_SIP_HOLD)) { sofia_glue_toggle_hold(tech_pvt, 0); sofia_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD); + switch_channel_clear_flag(channel, CF_LEG_HOLDING); } switch_channel_hangup(tech_pvt->channel, SWITCH_CAUSE_MEDIA_TIMEOUT); @@ -1446,6 +1430,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi case SWITCH_MESSAGE_INDICATE_HOLD: { sofia_set_flag_locked(tech_pvt, TFLAG_SIP_HOLD); + switch_channel_set_flag(channel, CF_LEG_HOLDING); sofia_glue_do_invite(session); if (!zstr(msg->string_arg)) { char message[256] = ""; @@ -1470,6 +1455,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi case SWITCH_MESSAGE_INDICATE_UNHOLD: { sofia_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD); + switch_channel_clear_flag(channel, CF_LEG_HOLDING); sofia_glue_do_invite(session); } break; diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 2fb3d11d0a..c8aee2fc23 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -3864,6 +3864,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, switch_ivr_uuid_bridge(br_a, br_b); switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "ATTENDED_TRANSFER"); sofia_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD); + switch_channel_clear_flag(channel, CF_LEG_HOLDING); sofia_clear_flag_locked(tech_pvt, TFLAG_HOLD_LOCK); switch_channel_hangup(channel, SWITCH_CAUSE_ATTENDED_TRANSFER); } else { @@ -4007,10 +4008,12 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, if (sofia_test_flag(tech_pvt, TFLAG_SIP_HOLD)) { if (!switch_stristr("sendonly", r_sdp)) { sofia_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD); + switch_channel_clear_flag(channel, CF_LEG_HOLDING); switch_channel_presence(tech_pvt->channel, "unknown", "unhold", NULL); } } else if (switch_stristr("sendonly", r_sdp)) { sofia_set_flag_locked(tech_pvt, TFLAG_SIP_HOLD); + switch_channel_set_flag(channel, CF_LEG_HOLDING); switch_channel_presence(tech_pvt->channel, "unknown", "hold", NULL); } @@ -4530,6 +4533,7 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t sofia_clear_flag_locked(b_tech_pvt, TFLAG_SIP_HOLD); + switch_channel_clear_flag(channel_b, CF_LEG_HOLDING); sofia_clear_flag_locked(tech_pvt, TFLAG_HOLD_LOCK); switch_channel_set_variable(channel_b, SWITCH_HOLDING_UUID_VARIABLE, br_a); @@ -4598,6 +4602,7 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t NUTAG_SUBSTATE(nua_substate_terminated), SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK"), SIPTAG_EVENT_STR(etmp), TAG_END()); sofia_clear_flag_locked(b_tech_pvt, TFLAG_SIP_HOLD); + switch_channel_clear_flag(channel_b, CF_LEG_HOLDING); sofia_clear_flag_locked(tech_pvt, TFLAG_HOLD_LOCK); switch_channel_set_variable(channel_b, "park_timeout", "2"); switch_channel_set_state(channel_b, CS_PARK); @@ -4621,7 +4626,9 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t t_session = switch_core_session_locate(br_b); hup_channel = channel_a; sofia_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD); + switch_channel_clear_flag(tech_pvt->channel, CF_LEG_HOLDING); sofia_clear_flag_locked(h_tech_pvt, TFLAG_SIP_HOLD); + switch_channel_clear_flag(h_tech_pvt->channel, CF_LEG_HOLDING); switch_channel_hangup(channel_b, SWITCH_CAUSE_ATTENDED_TRANSFER); } diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 0af17de290..ab2afd2c56 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -2885,6 +2885,7 @@ void sofia_glue_toggle_hold(private_object_t *tech_pvt, int sendonly) const char *stream; sofia_set_flag_locked(tech_pvt, TFLAG_SIP_HOLD); + switch_channel_set_flag(tech_pvt->channel, CF_LEG_HOLDING); switch_channel_presence(tech_pvt->channel, "unknown", "hold", NULL); if (tech_pvt->max_missed_hold_packets) { @@ -2909,6 +2910,7 @@ void sofia_glue_toggle_hold(private_object_t *tech_pvt, int sendonly) } else { if (sofia_test_flag(tech_pvt, TFLAG_HOLD_LOCK)) { sofia_set_flag(tech_pvt, TFLAG_SIP_HOLD); + switch_channel_set_flag(tech_pvt->channel, CF_LEG_HOLDING); } sofia_clear_flag_locked(tech_pvt, TFLAG_HOLD_LOCK); @@ -2939,6 +2941,7 @@ void sofia_glue_toggle_hold(private_object_t *tech_pvt, int sendonly) } sofia_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD); + switch_channel_clear_flag(tech_pvt->channel, CF_LEG_HOLDING); switch_channel_presence(tech_pvt->channel, "unknown", "unhold", NULL); } } diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index 35f240b4fb..437c6340e2 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -1083,7 +1083,26 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses switch_channel_set_state(peer_channel, CS_EXCHANGE_MEDIA); audio_bridge_thread(NULL, (void *) a_leg); + if (switch_channel_test_flag(caller_channel, CF_LEG_HOLDING)) { + const char *ext = switch_channel_get_variable(caller_channel, "hold_hangup_xfer_exten"); + if (!zstr(ext)) { + switch_channel_set_variable(peer_channel, SWITCH_TRANSFER_AFTER_BRIDGE_VARIABLE, ext); + } + switch_channel_clear_flag(caller_channel, CF_LEG_HOLDING); + } + + if (switch_channel_test_flag(peer_channel, CF_LEG_HOLDING)) { + const char *ext = switch_channel_get_variable(peer_channel, "hold_hangup_xfer_exten"); + if (!zstr(ext)) { + switch_channel_set_variable(caller_channel, SWITCH_TRANSFER_AFTER_BRIDGE_VARIABLE, ext); + } + switch_channel_clear_flag(peer_channel, CF_LEG_HOLDING); + } + switch_channel_clear_flag_recursive(caller_channel, CF_BRIDGE_ORIGINATOR); + + switch_channel_stop_broadcast(peer_channel); + while (switch_channel_get_state(peer_channel) == CS_EXCHANGE_MEDIA) { switch_cond_next();