From 57f5932f010799a2858098374793f52f00dc1fd9 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 30 Dec 2016 17:36:29 -0600 Subject: [PATCH] FS-9206: [mod_sofia] proxy media with enable-3pcc=proxy does not properly pass audio after 3pcc re-invite #resolve --- src/mod/endpoints/mod_sofia/mod_sofia.c | 41 ++++++++---- src/mod/endpoints/mod_sofia/sofia.c | 72 +++++++++++++++------ src/switch_core_media.c | 84 ++++++++++++++++--------- 3 files changed, 138 insertions(+), 59 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 82d1ecc3b4..12f086e709 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -668,17 +668,36 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session) b_sdp = switch_channel_get_variable(channel, SWITCH_B_SDP_VARIABLE); switch_core_media_set_local_sdp(session, b_sdp, SWITCH_TRUE); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "3PCC-PROXY nomedia - sending ack, SDP:\n%s\n", tech_pvt->mparams.local_sdp_str); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, + "3PCC-PROXY nomedia - sending ack, SDP:\n%s\n", tech_pvt->mparams.local_sdp_str); + + if (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MEDIA)) { + switch_core_media_patch_sdp(tech_pvt->session); + switch_core_media_proxy_remote_addr(tech_pvt->session, NULL); + } + + if (sofia_use_soa(tech_pvt)) { + 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), + 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()); + } else { + nua_ack(tech_pvt->nh, + NUTAG_MEDIA_ENABLE(0), + TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), + SIPTAG_CONTACT_STR(tech_pvt->reply_contact), + TAG_IF(tech_pvt->mparams.local_sdp_str, SIPTAG_CONTENT_TYPE_STR("application/sdp")), + TAG_IF(tech_pvt->mparams.local_sdp_str, SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str)), + SOATAG_AUDIO_AUX("cn telephone-event"), + 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), - SOATAG_USER_SDP_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()); sofia_clear_flag(tech_pvt, TFLAG_3PCC_INVITE); // all done sofia_set_flag_locked(tech_pvt, TFLAG_ANS); sofia_set_flag_locked(tech_pvt, TFLAG_SDP); @@ -2220,7 +2239,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi while (switch_channel_ready(channel) && !sofia_test_flag(tech_pvt, TFLAG_3PCC_HAS_ACK)) { switch_ivr_parse_all_events(session); - switch_cond_next(); + switch_yield(10000); } /* Regain lock on sofia */ diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index ce76e54bcb..33f4036053 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -1689,6 +1689,16 @@ static void our_sofia_event_callback(nua_event_t event, switch_core_recovery_track(session); sofia_set_flag(tech_pvt, TFLAG_GOT_ACK); + if (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MEDIA) && r_sdp) { + if (sofia_test_pflag(tech_pvt->profile, PFLAG_3PCC_PROXY)) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "3PCC-PROXY, Got my ACK\n"); + sofia_set_flag(tech_pvt, TFLAG_3PCC_HAS_ACK); + sofia_clear_flag(tech_pvt, TFLAG_PASS_ACK); + } + + } + + if (sofia_test_flag(tech_pvt, TFLAG_PASS_ACK)) { switch_core_session_t *other_session; @@ -7431,15 +7441,27 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, private_object_t *other_tech_pvt = switch_core_session_get_private(other_session); sofia_glue_clear_soa(other_session, SWITCH_TRUE); - - 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_CONTENT_TYPE_STR("application/sdp"), - SIPTAG_PAYLOAD_STR(r_sdp), - TAG_END()); - + + if (sofia_use_soa(other_tech_pvt)) { + nua_ack(other_tech_pvt->nh, + TAG_IF(!zstr(other_tech_pvt->user_via), SIPTAG_VIA_STR(other_tech_pvt->user_via)), + SIPTAG_CONTACT_STR(other_tech_pvt->reply_contact), + SOATAG_USER_SDP_STR(r_sdp), + SOATAG_REUSE_REJECTED(1), + SOATAG_RTP_SELECT(1), + SOATAG_AUDIO_AUX("cn telephone-event"), + TAG_IF(sofia_test_pflag(other_tech_pvt->profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)), + TAG_END()); + } else { + 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), + TAG_IF(r_sdp, SIPTAG_CONTENT_TYPE_STR("application/sdp")), + TAG_IF(r_sdp, SIPTAG_PAYLOAD_STR(r_sdp)), + SOATAG_AUDIO_AUX("cn telephone-event"), + TAG_END()); + } nua_ack(tech_pvt->nh, TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), @@ -7486,17 +7508,27 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, 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), - TAG_IF(tech_pvt->mparams.local_sdp_str, SIPTAG_CONTENT_TYPE_STR("application/sdp")), - TAG_IF(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()); + + if (sofia_use_soa(tech_pvt)) { + 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), + 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()); + } else { + nua_ack(tech_pvt->nh, + NUTAG_MEDIA_ENABLE(0), + TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), + SIPTAG_CONTACT_STR(tech_pvt->reply_contact), + TAG_IF(tech_pvt->mparams.local_sdp_str, SIPTAG_CONTENT_TYPE_STR("application/sdp")), + TAG_IF(tech_pvt->mparams.local_sdp_str, SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str)), + SOATAG_AUDIO_AUX("cn telephone-event"), + TAG_END()); + } switch_channel_clear_flag(channel, CF_3P_MEDIA_REQUESTED); goto done; diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 413ec7d215..df179c8dd2 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -472,7 +472,7 @@ static void switch_core_media_find_zrtp_hash(switch_core_session_t *session, sdp audio_engine = &session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO]; video_engine = &session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO]; - text_engine = &session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO]; + text_engine = &session->media_handle->engines[SWITCH_MEDIA_TYPE_TEXT]; switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG1, "Looking for zrtp-hash\n"); @@ -1836,7 +1836,7 @@ SWITCH_DECLARE(switch_status_t) switch_media_handle_create(switch_media_handle_t session->media_handle->engines[SWITCH_MEDIA_TYPE_TEXT].payload_map = switch_core_alloc(session->pool, sizeof(payload_map_t)); - session->media_handle->engines[SWITCH_MEDIA_TYPE_TEXT].cur_payload_map = session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].payload_map; + session->media_handle->engines[SWITCH_MEDIA_TYPE_TEXT].cur_payload_map = session->media_handle->engines[SWITCH_MEDIA_TYPE_TEXT].payload_map; session->media_handle->engines[SWITCH_MEDIA_TYPE_TEXT].cur_payload_map->current = 1; switch_channel_set_flag(session->channel, CF_DTLS_OK); @@ -6862,33 +6862,39 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_proxy_remote_addr(switch_core_ } } - p = port_ptr; - x = 0; - while (x < sizeof(rp) - 1 && p && *p && (*p >= '0' && *p <= '9')) { - rp[x++] = *p; - p++; - if (p >= pe) { - goto end; + if (port_ptr) { + p = port_ptr; + x = 0; + while (x < sizeof(rp) - 1 && p && *p && (*p >= '0' && *p <= '9')) { + rp[x++] = *p; + p++; + if (p >= pe) { + goto end; + } } } - p = vid_port_ptr; - x = 0; - while (x < sizeof(rvp) - 1 && p && *p && (*p >= '0' && *p <= '9')) { - rvp[x++] = *p; - p++; - if (p >= pe) { - goto end; + if (vid_port_ptr) { + p = vid_port_ptr; + x = 0; + while (x < sizeof(rvp) - 1 && p && *p && (*p >= '0' && *p <= '9')) { + rvp[x++] = *p; + p++; + if (p >= pe) { + goto end; + } } } - p = text_port_ptr; - x = 0; - while (x < sizeof(rtp) - 1 && p && *p && (*p >= '0' && *p <= '9')) { - rtp[x++] = *p; - p++; - if (p >= pe) { - goto end; + if (text_port_ptr) { + p = text_port_ptr; + x = 0; + while (x < sizeof(rtp) - 1 && p && *p && (*p >= '0' && *p <= '9')) { + rtp[x++] = *p; + p++; + if (p >= pe) { + goto end; + } } } @@ -6914,7 +6920,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_proxy_remote_addr(switch_core_ switch_channel_set_flag(session->channel, CF_TEXT_POSSIBLE); } - if (v_engine->cur_payload_map->remote_sdp_ip && v_engine->cur_payload_map->remote_sdp_port) { + if (v_engine->cur_payload_map && v_engine->cur_payload_map->remote_sdp_ip && v_engine->cur_payload_map->remote_sdp_port) { if (!strcmp(v_engine->cur_payload_map->remote_sdp_ip, rip) && atoi(rvp) == v_engine->cur_payload_map->remote_sdp_port) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Remote video address:port [%s:%d] has not changed.\n", v_engine->cur_payload_map->remote_sdp_ip, v_engine->cur_payload_map->remote_sdp_port); @@ -6952,7 +6958,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_proxy_remote_addr(switch_core_ } } - if (t_engine->cur_payload_map->remote_sdp_ip && t_engine->cur_payload_map->remote_sdp_port) { + if (t_engine->cur_payload_map && t_engine->cur_payload_map->remote_sdp_ip && t_engine->cur_payload_map->remote_sdp_port) { if (!strcmp(t_engine->cur_payload_map->remote_sdp_ip, rip) && atoi(rvp) == t_engine->cur_payload_map->remote_sdp_port) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Remote text address:port [%s:%d] has not changed.\n", t_engine->cur_payload_map->remote_sdp_ip, t_engine->cur_payload_map->remote_sdp_port); @@ -11082,13 +11088,13 @@ SWITCH_DECLARE(void) switch_core_media_patch_sdp(switch_core_session_t *session) } has_video++; - } else if (!strncmp("m=text ", p, 8) && *(p + 8) != '0') { + } else if (!strncmp("m=text ", p, 8) && *(p + 8) != '0') { if (!has_text) { switch_core_media_choose_port(session, SWITCH_MEDIA_TYPE_TEXT, 1); clear_pmaps(t_engine); pmap = switch_core_media_add_payload_map(session, SWITCH_MEDIA_TYPE_TEXT, - "PROXY-VID", + "PROXY-TXT", NULL, NULL, SDP_TYPE_RESPONSE, @@ -12552,7 +12558,7 @@ SWITCH_DECLARE(void) switch_core_session_stop_media(switch_core_session_t *sessi //? SWITCH_DECLARE(void) switch_core_media_check_outgoing_proxy(switch_core_session_t *session, switch_core_session_t *o_session) { - switch_rtp_engine_t *a_engine, *v_engine; + switch_rtp_engine_t *a_engine, *v_engine, *t_engine; switch_media_handle_t *smh; const char *r_sdp = NULL; payload_map_t *pmap; @@ -12571,6 +12577,7 @@ SWITCH_DECLARE(void) switch_core_media_check_outgoing_proxy(switch_core_session_ a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO]; v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO]; + t_engine = &smh->engines[SWITCH_MEDIA_TYPE_TEXT]; switch_channel_set_flag(session->channel, CF_PROXY_MEDIA); @@ -12610,6 +12617,27 @@ SWITCH_DECLARE(void) switch_core_media_check_outgoing_proxy(switch_core_session_ switch_channel_set_flag(session->channel, CF_VIDEO); switch_channel_set_flag(session->channel, CF_VIDEO_POSSIBLE); } + + + if (switch_stristr("m=text", r_sdp)) { + switch_core_media_choose_port(session, SWITCH_MEDIA_TYPE_VIDEO, 1); + pmap = switch_core_media_add_payload_map(session, + SWITCH_MEDIA_TYPE_AUDIO, + "PROXY-TXT", + NULL, + NULL, + SDP_TYPE_RESPONSE, + 0, + 1000, + 1000, + 1, + SWITCH_TRUE); + + t_engine->cur_payload_map = pmap; + + switch_channel_set_flag(session->channel, CF_HAS_TEXT); + switch_channel_set_flag(session->channel, CF_TEXT_POSSIBLE); + } }