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;
/*!
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;
}
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;
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;
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");
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)) {
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;
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);
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) {
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);
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);
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)) {
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);
}