FSCORE-481

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@15657 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2009-11-24 18:18:09 +00:00
parent cf8d26bef3
commit aba8d7590f
5 changed files with 42 additions and 26 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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();