From 3026e639fe0b8cfec9a37f2ce99aee7779b9e736 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 17 Jun 2010 10:23:37 -0500 Subject: [PATCH] MODENDP-312 --- src/include/switch_types.h | 6 +- .../mod_spandsp/mod_spandsp_fax.c | 12 +--- src/mod/endpoints/mod_sofia/mod_sofia.c | 46 ++++++++++++--- src/mod/endpoints/mod_sofia/sofia_glue.c | 20 +++---- src/switch_rtp.c | 58 +++++++++++++++---- 5 files changed, 101 insertions(+), 41 deletions(-) diff --git a/src/include/switch_types.h b/src/include/switch_types.h index fb4b423bfd..96e10f9c50 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -754,8 +754,10 @@ typedef struct { uint32_t T38FaxMaxDatagram; const char *T38FaxUdpEC; const char *T38VendorInfo; - const char *ip; - uint32_t port; + const char *remote_ip; + uint32_t remote_port; + const char *local_ip; + uint32_t local_port; } switch_t38_options_t; /*! diff --git a/src/mod/applications/mod_spandsp/mod_spandsp_fax.c b/src/mod/applications/mod_spandsp/mod_spandsp_fax.c index feaf3cc820..05ad60805b 100644 --- a/src/mod/applications/mod_spandsp/mod_spandsp_fax.c +++ b/src/mod/applications/mod_spandsp/mod_spandsp_fax.c @@ -741,15 +741,12 @@ static t38_mode_t negotiate_t38(pvt_t *pvt) switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "T38FaxMaxDatagram = %d\n", t38_options->T38FaxMaxDatagram); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "T38FaxUdpEC = '%s'\n", t38_options->T38FaxUdpEC); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "T38VendorInfo = '%s'\n", switch_str_nil(t38_options->T38VendorInfo)); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "ip = '%s'\n", t38_options->ip ? t38_options->ip : "Not specified"); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "port = %d\n", t38_options->port); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "ip = '%s'\n", + t38_options->remote_ip ? t38_options->remote_ip : "Not specified"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "port = %d\n", t38_options->remote_port); /* Time to practice our negotiating skills, by editing the t38_options */ - /* use default IP/PORT */ - t38_options->ip = NULL; - t38_options->port = 0; - if (t38_options->T38FaxVersion > 3) { t38_options->T38FaxVersion = 3; } @@ -835,9 +832,6 @@ static t38_mode_t request_t38(pvt_t *pvt) t38_options->T38FaxUdpEC = "t38UDPRedundancy"; t38_options->T38VendorInfo = "0 0 0"; - /* use default IP/PORT */ - t38_options->ip = NULL; - t38_options->port = 0; switch_channel_set_private(channel, "t38_options", t38_options); pvt->t38_mode = T38_MODE_REQUESTED; diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 21733bd2e6..fe10dfce1c 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -1195,6 +1195,39 @@ static switch_status_t sofia_kill_channel(switch_core_session_t *session, int si return SWITCH_STATUS_SUCCESS; } + +static void start_udptl(private_object_t *tech_pvt, switch_t38_options_t *t38_options) +{ + + if (switch_rtp_ready(tech_pvt->rtp_session)) { + char *remote_host = switch_rtp_get_remote_host(tech_pvt->rtp_session); + switch_port_t remote_port = switch_rtp_get_remote_port(tech_pvt->rtp_session); + const char *err, *val; + + switch_rtp_udptl_mode(tech_pvt->rtp_session); + + if (remote_host && remote_port && !strcmp(remote_host, t38_options->remote_ip) && remote_port == t38_options->remote_port) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Remote address:port [%s:%d] has not changed.\n", + t38_options->remote_ip, t38_options->remote_port); + return; + } + + if (switch_rtp_set_remote_address(tech_pvt->rtp_session, t38_options->remote_ip, + t38_options->remote_port, 0, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "IMAGE UDPTL REPORTS ERROR: [%s]\n", err); + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "IMAGE UDPTL CHANGING DEST TO: [%s:%d]\n", + t38_options->remote_ip, t38_options->remote_port); + if (!sofia_test_pflag(tech_pvt->profile, PFLAG_DISABLE_RTP_AUTOADJ) && + !((val = switch_channel_get_variable(tech_pvt->channel, "disable_udptl_auto_adjust")) && switch_true(val))) { + /* Reactivate the NAT buster flag. */ + switch_rtp_set_flag(tech_pvt->rtp_session, SWITCH_RTP_FLAG_AUTOADJ); + } + } + } +} + + static switch_status_t sofia_send_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf) { private_object_t *tech_pvt; @@ -1528,12 +1561,10 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE, TAG_END()); goto end_lock; } + + start_udptl(tech_pvt, t38_options); - if (switch_rtp_ready(tech_pvt->rtp_session)) { - switch_rtp_udptl_mode(tech_pvt->rtp_session); - } } - break; case SWITCH_MESSAGE_INDICATE_T38_DESCRIPTION: { switch_t38_options_t *t38_options = switch_channel_get_private(tech_pvt->channel, "t38_options"); @@ -1543,13 +1574,10 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi goto end_lock; } - if (switch_rtp_ready(tech_pvt->rtp_session)) { - switch_rtp_udptl_mode(tech_pvt->rtp_session); - } + start_udptl(tech_pvt, t38_options); - sofia_glue_set_image_sdp(tech_pvt, t38_options, msg->numeric_arg); - + if (!sofia_test_flag(tech_pvt, TFLAG_BYE)) { char *extra_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_RESPONSE_HEADER_PREFIX); if (sofia_use_soa(tech_pvt)) { diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 884e5025b8..93cf586901 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -40,8 +40,8 @@ void sofia_glue_set_image_sdp(private_object_t *tech_pvt, switch_t38_options_t *t38_options, int insist) { char buf[2048]; - const char *ip = t38_options->ip; - uint32_t port = t38_options->port; + const char *ip = t38_options->local_ip; + uint32_t port = t38_options->local_port; const char *family = "IP4"; const char *username = tech_pvt->profile->username; @@ -3409,13 +3409,13 @@ void sofia_glue_copy_t38_options(switch_t38_options_t *t38_options, switch_core_ local_t38_options->T38FaxFillBitRemoval = t38_options->T38FaxFillBitRemoval; local_t38_options->T38FaxTranscodingMMR = t38_options->T38FaxTranscodingMMR; local_t38_options->T38FaxTranscodingJBIG = t38_options->T38FaxTranscodingJBIG; - local_t38_options->T38FaxRateManagement = t38_options->T38FaxRateManagement; + local_t38_options->T38FaxRateManagement = switch_core_session_strdup(session, t38_options->T38FaxRateManagement); local_t38_options->T38FaxMaxBuffer = t38_options->T38FaxMaxBuffer; local_t38_options->T38FaxMaxDatagram = t38_options->T38FaxMaxDatagram; - local_t38_options->T38FaxUdpEC = t38_options->T38FaxUdpEC; - local_t38_options->T38VendorInfo = t38_options->T38VendorInfo; - local_t38_options->ip = NULL; - local_t38_options->port = 0; + local_t38_options->T38FaxUdpEC = switch_core_session_strdup(session, t38_options->T38FaxUdpEC); + local_t38_options->T38VendorInfo = switch_core_session_strdup(session, t38_options->T38VendorInfo); + local_t38_options->remote_ip = switch_core_session_strdup(session, t38_options->remote_ip); + local_t38_options->remote_port = t38_options->remote_port; switch_channel_set_private(channel, "t38_options", local_t38_options); @@ -3430,12 +3430,12 @@ static switch_t38_options_t *tech_process_udptl(private_object_t *tech_pvt, sdp_ t38_options = switch_core_session_alloc(tech_pvt->session, sizeof(switch_t38_options_t)); } - t38_options->port = m->m_port; + t38_options->remote_port = m->m_port; if (m->m_connections) { - t38_options->ip = switch_core_session_strdup(tech_pvt->session, m->m_connections->c_address); + t38_options->remote_ip = switch_core_session_strdup(tech_pvt->session, m->m_connections->c_address); } else if (sdp && sdp->sdp_connection) { - t38_options->ip = switch_core_session_strdup(tech_pvt->session, sdp->sdp_connection->c_address); + t38_options->remote_ip = switch_core_session_strdup(tech_pvt->session, sdp->sdp_connection->c_address); } for (attr = m->m_attributes; attr; attr = attr->a_next) { diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 0efbf24e97..a9a408a27a 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -1024,9 +1024,21 @@ SWITCH_DECLARE(switch_port_t) switch_rtp_get_remote_port(switch_rtp_t *rtp_sessi return rtp_session->remote_port; } +static void ping_socket(switch_rtp_t *rtp_session) +{ + uint32_t o = UINT_MAX; + switch_size_t len = sizeof(o); + switch_socket_sendto(rtp_session->sock_input, rtp_session->local_addr, 0, (void *) &o, &len); + + if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP) && rtp_session->rtcp_sock_input) { + switch_socket_sendto(rtp_session->rtcp_sock_input, rtp_session->rtcp_local_addr, 0, (void *) &o, &len); + } +} SWITCH_DECLARE(switch_status_t) switch_rtp_udptl_mode(switch_rtp_t *rtp_session) { + switch_socket_t *sock; + READ_INC(rtp_session); WRITE_INC(rtp_session); @@ -1035,6 +1047,29 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_udptl_mode(switch_rtp_t *rtp_session) memset(&rtp_session->timer, 0, sizeof(rtp_session->timer)); } + switch_clear_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP); + + if (rtp_session->rtcp_sock_input) { + ping_socket(rtp_session); + switch_socket_shutdown(rtp_session->rtcp_sock_input, SWITCH_SHUTDOWN_READWRITE); + } + + if (rtp_session->rtcp_sock_output && rtp_session->rtcp_sock_output != rtp_session->rtcp_sock_input) { + switch_socket_shutdown(rtp_session->rtcp_sock_output, SWITCH_SHUTDOWN_READWRITE); + } + + if ((sock = rtp_session->rtcp_sock_input)) { + rtp_session->rtcp_sock_input = NULL; + switch_socket_close(sock); + + if (rtp_session->rtcp_sock_output && rtp_session->rtcp_sock_output != sock) { + if ((sock = rtp_session->rtcp_sock_output)) { + rtp_session->rtcp_sock_output = NULL; + switch_socket_close(sock); + } + } + } + switch_set_flag_locked(rtp_session, SWITCH_RTP_FLAG_UDPTL); switch_set_flag_locked(rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA); switch_socket_opt_set(rtp_session->sock_input, SWITCH_SO_NONBLOCK, FALSE); @@ -1619,17 +1654,6 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_ice(switch_rtp_t *rtp_sessio return SWITCH_STATUS_SUCCESS; } -static void ping_socket(switch_rtp_t *rtp_session) -{ - uint32_t o = UINT_MAX; - switch_size_t len = sizeof(o); - switch_socket_sendto(rtp_session->sock_input, rtp_session->local_addr, 0, (void *) &o, &len); - - if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP) && rtp_session->rtcp_sock_input) { - switch_socket_sendto(rtp_session->rtcp_sock_input, rtp_session->rtcp_local_addr, 0, (void *) &o, &len); - } -} - SWITCH_DECLARE(void) switch_rtp_break(switch_rtp_t *rtp_session) { if (!switch_rtp_ready(rtp_session)) { @@ -1739,6 +1763,18 @@ SWITCH_DECLARE(void) switch_rtp_destroy(switch_rtp_t **rtp_session) switch_socket_close(sock); } + if ((sock = (*rtp_session)->rtcp_sock_input)) { + (*rtp_session)->rtcp_sock_input = NULL; + switch_socket_close(sock); + + if ((*rtp_session)->rtcp_sock_output && (*rtp_session)->rtcp_sock_output != sock) { + if ((sock = (*rtp_session)->rtcp_sock_output)) { + (*rtp_session)->rtcp_sock_output = NULL; + switch_socket_close(sock); + } + } + } + if (switch_test_flag((*rtp_session), SWITCH_RTP_FLAG_VAD)) { switch_rtp_disable_vad(*rtp_session); }