diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index 6d97c55f81..8a2de89fe9 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -324,6 +324,7 @@ typedef enum { TFLAG_NAT, TFLAG_SIMPLIFY, TFLAG_SIP_HOLD, + TFLAG_SIP_HOLD_INACTIVE, TFLAG_INB_NOMEDIA, TFLAG_LATE_NEGOTIATION, TFLAG_SDP, diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index c6dbbb507d..c83aa8c8bf 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -7549,7 +7549,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) { if ((sofia_test_media_flag(profile, SCMF_DISABLE_HOLD) || ((var = switch_channel_get_variable(channel, "rtp_disable_hold")) && switch_true(var))) - && ((switch_stristr("sendonly", r_sdp) || switch_stristr("0.0.0.0", r_sdp)) || tech_pvt->mparams.hold_laps)) { + && ((switch_stristr("sendonly", r_sdp) || switch_stristr("0.0.0.0", r_sdp) || switch_stristr("inactive", r_sdp)) || tech_pvt->mparams.hold_laps)) { nua_respond(tech_pvt->nh, SIP_200_OK, TAG_END()); if (tech_pvt->mparams.hold_laps) { @@ -7571,7 +7571,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, if (switch_channel_test_flag(channel, CF_PROXY_MODE) && !is_t38 && ((profile->media_options & MEDIA_OPT_MEDIA_ON_HOLD) || media_on_hold)) { - if (switch_stristr("sendonly", r_sdp) || switch_stristr("0.0.0.0", r_sdp)) { + if (switch_stristr("sendonly", r_sdp) || switch_stristr("0.0.0.0", r_sdp) || switch_stristr("inactive", r_sdp)) { tech_pvt->mparams.hold_laps = 1; switch_channel_set_variable(channel, SWITCH_R_SDP_VARIABLE, r_sdp); switch_channel_clear_flag(channel, CF_PROXY_MODE); @@ -7656,12 +7656,12 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Passing SDP to other leg.\n%s\n", r_sdp); if (sofia_test_flag(tech_pvt, TFLAG_SIP_HOLD)) { - if (!switch_stristr("sendonly", r_sdp)) { + if (!switch_stristr("sendonly", r_sdp) && !switch_stristr("inactive", 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)) { + } else if (switch_stristr("sendonly", r_sdp) && !switch_stristr("inactive", r_sdp)) { const char *msg = "hold"; if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)) { @@ -7700,35 +7700,48 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, goto done; } if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) { - switch_core_session_message_t *msg; - - msg = switch_core_session_alloc(other_session, sizeof(*msg)); - if (switch_stristr("sendonly", r_sdp) || switch_stristr("0.0.0.0", r_sdp)) { + if (switch_core_session_compare(session, other_session)) { + switch_core_session_message_t *msg; const char *hold_msg = "hold"; + private_object_t *other_tech_pvt = switch_core_session_get_private(other_session); + + msg = switch_core_session_alloc(other_session, sizeof(*msg)); - msg->message_id = SWITCH_MESSAGE_INDICATE_HOLD; - if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)) { - const char *info = switch_channel_get_variable(channel, "presence_call_info"); + if (switch_stristr("inactive", r_sdp)) { + sofia_set_flag_locked(other_tech_pvt, TFLAG_SIP_HOLD_INACTIVE); + //switch_channel_set_variable(channel, "sofia_hold_inactive", "true"); + } else { + sofia_clear_flag_locked(other_tech_pvt, TFLAG_SIP_HOLD_INACTIVE); + } - if (info) { - if (switch_stristr("private", info)) { - hold_msg = "hold-private"; + if (switch_stristr("sendonly", r_sdp) || switch_stristr("0.0.0.0", r_sdp) || switch_stristr("inactive", r_sdp)) { + + + msg->message_id = SWITCH_MESSAGE_INDICATE_HOLD; + if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)) { + const char *info = switch_channel_get_variable(channel, "presence_call_info"); + + if (info) { + if (switch_stristr("private", info)) { + hold_msg = "hold-private"; + } } } + 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_msg, NULL); + } else { + hold_msg = "unhold"; + msg->message_id = SWITCH_MESSAGE_INDICATE_UNHOLD; + sofia_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD); + switch_channel_clear_flag(channel, CF_LEG_HOLDING); + switch_channel_presence(tech_pvt->channel, "unknown", hold_msg, NULL); } - 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_msg, NULL); - } else { - msg->message_id = SWITCH_MESSAGE_INDICATE_UNHOLD; - 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); - } - msg->from = __FILE__; - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Indicating Hold to other leg.\n%s\n", r_sdp); + msg->from = __FILE__; + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Indicating %s to other leg.\n%s\n", hold_msg, r_sdp); - switch_core_session_queue_message(other_session, msg); + switch_core_session_queue_message(other_session, msg); + } switch_core_session_rwunlock(other_session); } switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0); diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index acbddcaf73..b25f4a1c83 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -748,7 +748,13 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) const char *recover_via = NULL; int require_timer = 1; uint8_t is_t38 = 0; + const char *hold_char = "*"; + if (sofia_test_flag(tech_pvt, TFLAG_SIP_HOLD_INACTIVE) || + switch_true(switch_channel_get_variable_dup(tech_pvt->channel, "sofia_hold_inactive", SWITCH_FALSE, -1))) { + hold_char = "#"; + } + if (switch_channel_test_flag(tech_pvt->channel, CF_RECOVERING)) { const char *recover_contact = switch_channel_get_variable(tech_pvt->channel, "sip_recover_contact"); recover_via = switch_channel_get_variable(tech_pvt->channel, "sip_recover_via"); @@ -1201,7 +1207,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) free(e_dest); } - holdstr = sofia_test_flag(tech_pvt, TFLAG_SIP_HOLD) ? "*" : ""; + holdstr = sofia_test_flag(tech_pvt, TFLAG_SIP_HOLD) ? hold_char : ""; if (!switch_channel_get_variable(channel, "sofia_profile_name")) { switch_channel_set_variable(channel, "sofia_profile_name", tech_pvt->profile->name); diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 98bedcd1cc..982b94e1ee 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -8955,7 +8955,7 @@ SWITCH_DECLARE(void) switch_core_media_patch_sdp(switch_core_session_t *session) if (!(smh->mparams->ndlb & SM_NDLB_NEVER_PATCH_REINVITE)) { if (switch_channel_test_flag(session->channel, CF_ANSWERED) && - (switch_stristr("sendonly", smh->mparams->local_sdp_str) || switch_stristr("0.0.0.0", smh->mparams->local_sdp_str))) { + (switch_stristr("sendonly", smh->mparams->local_sdp_str) || switch_stristr("inactive", smh->mparams->local_sdp_str) || switch_stristr("0.0.0.0", smh->mparams->local_sdp_str))) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Skip patch on hold SDP\n"); return; }