From 84a383fe0fcc0ff93b70c21380c4b0702c55e6f9 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 29 Sep 2010 14:14:41 -0500 Subject: [PATCH] improve video support for new polycom phones --- src/include/switch_rtp.h | 1 + src/mod/endpoints/mod_sofia/mod_sofia.c | 14 +- src/mod/endpoints/mod_sofia/mod_sofia.h | 3 + src/mod/endpoints/mod_sofia/sofia.c | 35 +++- src/mod/endpoints/mod_sofia/sofia_glue.c | 241 +++++++++++++++++++++-- src/switch_rtp.c | 14 +- 6 files changed, 284 insertions(+), 24 deletions(-) diff --git a/src/include/switch_rtp.h b/src/include/switch_rtp.h index 7e6028a68b..7269a2b8d9 100644 --- a/src/include/switch_rtp.h +++ b/src/include/switch_rtp.h @@ -449,6 +449,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_stun_ping(switch_rtp_t *rtp_ SWITCH_DECLARE(void) switch_rtp_intentional_bugs(switch_rtp_t *rtp_session, switch_rtp_bug_flag_t bugs); SWITCH_DECLARE(switch_rtp_stats_t *) switch_rtp_get_stats(switch_rtp_t *rtp_session, switch_memory_pool_t *pool); +SWITCH_DECLARE(switch_byte_t) switch_rtp_check_auto_adj(switch_rtp_t *rtp_session); /*! \} diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index e4c4a51865..c2fece8a20 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -1482,12 +1482,11 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi switch (msg->message_id) { case SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ: { - const char *pl = - "\r\n" - " \r\n" - " \r\n" - " \r\n" - " \r\n" " \r\n" " \r\n" " \r\n" " \r\n"; + const char *pl = ""; + + if (!zstr(msg->string_arg)) { + pl = msg->string_arg; + } nua_info(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("application/media_control+xml"), SIPTAG_PAYLOAD_STR(pl), TAG_END()); @@ -2104,6 +2103,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi break; case SWITCH_MESSAGE_INDICATE_ANSWER: status = sofia_answer_channel(session); + if (switch_channel_test_flag(tech_pvt->channel, CF_VIDEO)) { + sofia_glue_build_vid_refresh_message(session, NULL); + } break; case SWITCH_MESSAGE_INDICATE_PROGRESS: { diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index 4e0c4fda1c..58eef2918c 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -1013,3 +1013,6 @@ void sofia_glue_tech_simplify(private_object_t *tech_pvt); switch_console_callback_match_t *sofia_reg_find_reg_url_multi(sofia_profile_t *profile, const char *user, const char *host); switch_bool_t sofia_glue_profile_exists(const char *key); void sofia_glue_global_siptrace(switch_bool_t on); +void sofia_glue_proxy_codec(switch_core_session_t *session, const char *r_sdp); +switch_status_t sofia_glue_sdp_map(const char *r_sdp, switch_event_t **fmtp, switch_event_t **pt); +void sofia_glue_build_vid_refresh_message(switch_core_session_t *session, const char *pl); diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 470a8658ce..a3554ec861 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -3933,6 +3933,23 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status } } +#if 0 + if (status == 200 && switch_channel_test_flag(channel, CF_PROXY_MEDIA) && + sip->sip_payload && sip->sip_payload->pl_data && !strcasecmp(tech_pvt->iananame, "PROXY")) { + switch_core_session_t *other_session; + + sofia_glue_proxy_codec(session, sip->sip_payload->pl_data); + + if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) { + if (switch_core_session_compare(session, other_session)) { + sofia_glue_proxy_codec(other_session, sip->sip_payload->pl_data); + } + switch_core_session_rwunlock(other_session); + } + } +#endif + + if ((status == 180 || status == 183 || status == 200)) { const char *x_freeswitch_support; @@ -4494,6 +4511,8 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, } } + + state_process: switch ((enum nua_callstate) ss_state) { @@ -4972,6 +4991,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, sofia_set_flag_locked(tech_pvt, TFLAG_ANS); sofia_set_flag(tech_pvt, TFLAG_SDP); switch_channel_mark_answered(channel); + if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) { if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE)) && (other_session = switch_core_session_locate(uuid))) { @@ -4992,6 +5012,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, sofia_set_flag_locked(tech_pvt, TFLAG_ANS); sofia_set_flag_locked(tech_pvt, TFLAG_SDP); switch_channel_mark_answered(channel); + if (switch_channel_test_flag(channel, CF_PROXY_MEDIA)) { if (sofia_glue_activate_rtp(tech_pvt, 0) != SWITCH_STATUS_SUCCESS) { goto done; @@ -5097,6 +5118,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, } done: + if ((enum nua_callstate) ss_state == nua_callstate_ready && channel && session && tech_pvt) { sofia_glue_tech_simplify(tech_pvt); @@ -5248,7 +5270,6 @@ nua_handle_t *sofia_global_nua_handle_by_replaces(sip_replaces_t *replaces) } - void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, switch_core_session_t *session, sip_t const *sip, tagi_t tags[]) { /* Incoming refer */ @@ -5821,7 +5842,17 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t if (sip && sip->sip_content_type && sip->sip_content_type->c_type && sip->sip_content_type->c_subtype && sip->sip_payload && sip->sip_payload->pl_data) { - if (!strncasecmp(sip->sip_content_type->c_type, "application", 11) && !strcasecmp(sip->sip_content_type->c_subtype, "dtmf-relay")) { + if (!strncasecmp(sip->sip_content_type->c_type, "application", 11) && !strcasecmp(sip->sip_content_type->c_subtype, "media_control+xml")) { + switch_core_session_t *other_session; + + if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) { + sofia_glue_build_vid_refresh_message(other_session, sip->sip_payload->pl_data); + switch_core_session_rwunlock(other_session); + } else { + sofia_glue_build_vid_refresh_message(session, sip->sip_payload->pl_data); + } + + } else if (!strncasecmp(sip->sip_content_type->c_type, "application", 11) && !strcasecmp(sip->sip_content_type->c_subtype, "dtmf-relay")) { /* Try and find signal information in the payload */ if ((signal_ptr = switch_stristr("Signal=", sip->sip_payload->pl_data))) { int tmp; diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 508fa54aac..9301348eb5 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -202,6 +202,13 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, uint32 const char *username = tech_pvt->profile->username; const char *fmtp_out = tech_pvt->fmtp_out; const char *fmtp_out_var = switch_channel_get_variable(tech_pvt->channel, "sip_force_audio_fmtp"); + switch_event_t *map = NULL, *ptmap = NULL; + const char *b_sdp = NULL; + + if ((b_sdp = switch_channel_get_variable(tech_pvt->channel, SWITCH_B_SDP_VARIABLE))) { + sofia_glue_sdp_map(b_sdp, &map, &ptmap); + } + if (fmtp_out_var) { fmtp_out = fmtp_out_var; @@ -330,7 +337,8 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, uint32 int already_did[128] = { 0 }; for (i = 0; i < tech_pvt->num_codecs; i++) { const switch_codec_implementation_t *imp = tech_pvt->codecs[i]; - + char *fmtp = imp->fmtp; + if (imp->codec_type != SWITCH_CODEC_TYPE_AUDIO) { continue; } @@ -345,9 +353,14 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, uint32 rate = imp->samples_per_second; + if (map) { + fmtp = switch_event_get_header(map, imp->iananame); + } + + switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=rtpmap:%d %s/%d\n", imp->ianacode, imp->iananame, rate); if (imp->fmtp) { - switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=fmtp:%d %s\n", imp->ianacode, imp->fmtp); + switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=fmtp:%d %s\n", imp->ianacode, fmtp); } } } @@ -479,38 +492,87 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, uint32 int i; int already_did[128] = { 0 }; +#if 0 + switch_event_t *event; + char *buf; + int level = SWITCH_LOG_INFO; + + if (switch_event_create_plain(&event, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) { + switch_channel_event_set_data(switch_core_session_get_channel(tech_pvt->session), event); + switch_event_serialize(event, &buf, SWITCH_FALSE); + switch_assert(buf); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), level, "CHANNEL_DATA:\n%s\n", buf); + switch_event_destroy(&event); + free(buf); + } +#endif + for (i = 0; i < tech_pvt->num_codecs; i++) { const switch_codec_implementation_t *imp = tech_pvt->codecs[i]; + char *fmtp = NULL; + uint32_t ianacode = imp->ianacode; +#if 0 + const char *str; + + + if ((str = switch_event_get_header(ptmap, imp->iananame))) { + int tmp = atoi(str); + if (tmp > 0) { + ianacode = tmp; + } + } +#endif if (imp->codec_type != SWITCH_CODEC_TYPE_VIDEO) { continue; } - if (imp->ianacode < 128) { - if (already_did[imp->ianacode]) { + if (ianacode < 128) { + if (already_did[ianacode]) { continue; } - already_did[imp->ianacode] = 1; + already_did[ianacode] = 1; } if (!rate) { rate = imp->samples_per_second; } - - switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=rtpmap:%d %s/%d\n", imp->ianacode, imp->iananame, + + + switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=rtpmap:%d %s/%d\n", ianacode, imp->iananame, imp->samples_per_second); - if (imp->fmtp) { - switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=fmtp:%d %s\n", imp->ianacode, imp->fmtp); + + if (!zstr(ov_fmtp)) { + fmtp = (char *) ov_fmtp; } else { - if (pass_fmtp) { - switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=fmtp:%d %s\n", imp->ianacode, pass_fmtp); + + if (map) { + fmtp = switch_event_get_header(map, imp->iananame); } + + if (zstr(fmtp)) fmtp = imp->fmtp; + + if (zstr(fmtp)) fmtp = (char *) pass_fmtp; + } + + if (!zstr(fmtp) && strcasecmp(fmtp, "_blank_")) { + switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=fmtp:%d %s\n", imp->ianacode, fmtp); } } + } } } + + if (map) { + switch_event_destroy(&map); + } + + if (ptmap) { + switch_event_destroy(&ptmap); + } + sofia_glue_tech_set_local_sdp(tech_pvt, buf, SWITCH_TRUE); } @@ -2514,9 +2576,10 @@ switch_status_t sofia_glue_tech_set_codec(private_object_t *tech_pvt, int force) if (switch_rtp_ready(tech_pvt->rtp_session)) { switch_assert(tech_pvt->read_codec.implementation); - + if (switch_rtp_change_interval(tech_pvt->rtp_session, - tech_pvt->read_impl.microseconds_per_packet, tech_pvt->read_impl.samples_per_packet) != SWITCH_STATUS_SUCCESS) { + tech_pvt->read_impl.microseconds_per_packet, + tech_pvt->read_impl.samples_per_packet) != SWITCH_STATUS_SUCCESS) { switch_channel_hangup(tech_pvt->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); switch_goto_status(SWITCH_STATUS_FALSE, end); } @@ -2776,6 +2839,10 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f tech_pvt->local_sdp_audio_port, tech_pvt->remote_sdp_audio_ip, tech_pvt->remote_sdp_audio_port, tech_pvt->agreed_pt, tech_pvt->read_impl.microseconds_per_packet / 1000); + + if (switch_rtp_ready(tech_pvt->rtp_session)) { + switch_rtp_set_default_payload(tech_pvt->rtp_session, tech_pvt->agreed_pt); + } } switch_snprintf(tmp, sizeof(tmp), "%d", tech_pvt->local_sdp_audio_port); @@ -2828,6 +2895,10 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f tech_pvt->remote_sdp_audio_ip, tech_pvt->remote_sdp_audio_port, tech_pvt->agreed_pt, tech_pvt->read_impl.microseconds_per_packet / 1000); + if (switch_rtp_ready(tech_pvt->rtp_session)) { + switch_rtp_set_default_payload(tech_pvt->rtp_session, tech_pvt->agreed_pt); + } + } else { timer_name = tech_pvt->profile->timer_name; @@ -3018,13 +3089,14 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f sofia_glue_check_video_codecs(tech_pvt); if (sofia_test_flag(tech_pvt, TFLAG_VIDEO) && tech_pvt->video_rm_encoding && tech_pvt->remote_sdp_video_port) { - + /******************************************************************************************/ if (tech_pvt->video_rtp_session && sofia_test_flag(tech_pvt, TFLAG_REINVITE)) { //const char *ip = switch_channel_get_variable(tech_pvt->channel, SWITCH_LOCAL_MEDIA_IP_VARIABLE); //const char *port = switch_channel_get_variable(tech_pvt->channel, SWITCH_LOCAL_MEDIA_PORT_VARIABLE); char *remote_host = switch_rtp_get_remote_host(tech_pvt->video_rtp_session); switch_port_t remote_port = switch_rtp_get_remote_port(tech_pvt->video_rtp_session); + if (remote_host && remote_port && !strcmp(remote_host, tech_pvt->remote_sdp_video_ip) && remote_port == tech_pvt->remote_sdp_video_port) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Video params are unchanged for %s.\n", @@ -3042,8 +3114,12 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f "VIDEO RTP [%s] %s port %d -> %s port %d codec: %u ms: %d\n", switch_channel_get_name(tech_pvt->channel), tech_pvt->local_sdp_audio_ip, tech_pvt->local_sdp_video_port, tech_pvt->remote_sdp_video_ip, tech_pvt->remote_sdp_video_port, tech_pvt->video_agreed_pt, tech_pvt->read_impl.microseconds_per_packet / 1000); - } + if (switch_rtp_ready(tech_pvt->video_rtp_session)) { + switch_rtp_set_default_payload(tech_pvt->video_rtp_session, tech_pvt->video_agreed_pt); + } + } + switch_snprintf(tmp, sizeof(tmp), "%d", tech_pvt->local_sdp_video_port); switch_channel_set_variable(tech_pvt->channel, SWITCH_LOCAL_VIDEO_IP_VARIABLE, tech_pvt->adv_sdp_audio_ip); switch_channel_set_variable(tech_pvt->channel, SWITCH_LOCAL_VIDEO_PORT_VARIABLE, tmp); @@ -3070,6 +3146,7 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f /* Reactivate the NAT buster flag. */ switch_rtp_set_flag(tech_pvt->video_rtp_session, SWITCH_RTP_FLAG_AUTOADJ); } + } goto video_up; } @@ -3095,6 +3172,9 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f tech_pvt->remote_sdp_video_ip, tech_pvt->remote_sdp_video_port, tech_pvt->video_agreed_pt, tech_pvt->read_impl.microseconds_per_packet / 1000); + if (switch_rtp_ready(tech_pvt->video_rtp_session)) { + switch_rtp_set_default_payload(tech_pvt->video_rtp_session, tech_pvt->video_agreed_pt); + } } else { timer_name = tech_pvt->profile->timer_name; @@ -3145,6 +3225,11 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f tech_pvt->remote_sdp_video_port, tech_pvt->video_agreed_pt, 0, switch_rtp_ready(tech_pvt->video_rtp_session) ? "SUCCESS" : err); + + if (switch_rtp_ready(tech_pvt->video_rtp_session)) { + switch_rtp_set_default_payload(tech_pvt->video_rtp_session, tech_pvt->video_agreed_pt); + } + if (switch_rtp_ready(tech_pvt->video_rtp_session)) { const char *ssrc; switch_channel_set_flag(tech_pvt->channel, CF_VIDEO); @@ -3574,6 +3659,115 @@ static switch_t38_options_t *tech_process_udptl(private_object_t *tech_pvt, sdp_ return t38_options; } + +switch_status_t sofia_glue_sdp_map(const char *r_sdp, switch_event_t **fmtp, switch_event_t **pt) +{ + sdp_media_t *m; + sdp_parser_t *parser = NULL; + sdp_session_t *sdp; + + if (!(parser = sdp_parse(NULL, r_sdp, (int) strlen(r_sdp), 0))) { + return SWITCH_STATUS_FALSE; + } + + if (!(sdp = sdp_session(parser))) { + sdp_parser_free(parser); + return SWITCH_STATUS_FALSE; + } + + switch_event_create(&(*fmtp), SWITCH_EVENT_REQUEST_PARAMS); + switch_event_create(&(*pt), SWITCH_EVENT_REQUEST_PARAMS); + + for (m = sdp->sdp_media; m; m = m->m_next) { + if (m->m_proto == sdp_proto_rtp) { + sdp_rtpmap_t *map; + + for (map = m->m_rtpmaps; map; map = map->rm_next) { + if (map->rm_encoding) { + char buf[25] = ""; + switch_snprintf(buf, sizeof(buf), "%d", map->rm_pt); + switch_event_add_header_string(*pt, SWITCH_STACK_BOTTOM, map->rm_encoding, buf); + + if (map->rm_fmtp) { + switch_event_add_header_string(*fmtp, SWITCH_STACK_BOTTOM, map->rm_encoding, map->rm_fmtp); + } + } + } + } + } + + sdp_parser_free(parser); + + return SWITCH_STATUS_SUCCESS; + +} + + +void sofia_glue_proxy_codec(switch_core_session_t *session, const char *r_sdp) +{ + sdp_media_t *m; + sdp_parser_t *parser = NULL; + sdp_session_t *sdp; + private_object_t *tech_pvt = switch_core_session_get_private(session); + sdp_attribute_t *attr; + int ptime = 0, dptime = 0, dmaxptime = 0, maxptime = 0; + + if (!(parser = sdp_parse(NULL, r_sdp, (int) strlen(r_sdp), 0))) { + return; + } + + if (!(sdp = sdp_session(parser))) { + sdp_parser_free(parser); + return; + } + + switch_assert(tech_pvt != NULL); + + + for (attr = sdp->sdp_attributes; attr; attr = attr->a_next) { + if (zstr(attr->a_name)) { + continue; + } + + if (!strcasecmp(attr->a_name, "ptime")) { + dptime = atoi(attr->a_value); + } else if (!strcasecmp(attr->a_name, "maxptime")) { + dmaxptime = atoi(attr->a_value); + } + } + + + for (m = sdp->sdp_media; m; m = m->m_next) { + + ptime = dptime; + maxptime = dmaxptime; + + if (m->m_proto == sdp_proto_rtp) { + sdp_rtpmap_t *map; + for (attr = m->m_attributes; attr; attr = attr->a_next) { + if (!strcasecmp(attr->a_name, "ptime") && attr->a_value) { + ptime = atoi(attr->a_value); + } else if (!strcasecmp(attr->a_name, "maxptime") && attr->a_value) { + maxptime = atoi(attr->a_value); + } + } + + for (map = m->m_rtpmaps; map; map = map->rm_next) { + tech_pvt->iananame = switch_core_session_strdup(tech_pvt->session, map->rm_encoding); + tech_pvt->rm_rate = map->rm_rate; + tech_pvt->codec_ms = ptime; + sofia_glue_tech_set_codec(tech_pvt, 0); + break; + } + + break; + } + } + + sdp_parser_free(parser); + +} + switch_t38_options_t *sofia_glue_extract_t38_options(switch_core_session_t *session, const char *r_sdp) { sdp_media_t *m; @@ -5585,6 +5779,23 @@ void sofia_glue_tech_simplify(private_object_t *tech_pvt) } +void sofia_glue_build_vid_refresh_message(switch_core_session_t *session, const char *pl) +{ + switch_core_session_message_t *msg; + msg = switch_core_session_alloc(session, sizeof(*msg)); + MESSAGE_STAMP_FFL(msg); + msg->message_id = SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ; + if (pl) { + msg->string_arg = switch_core_session_strdup(session, pl); + } + msg->from = __FILE__; + + switch_core_session_queue_message(session, msg); +} + + + + /* For Emacs: * Local Variables: diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 4e734c3c8d..66fc4cc7f3 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -239,6 +239,7 @@ struct switch_rtp { #endif switch_time_t send_time; + switch_byte_t auto_adj_used; }; struct switch_rtcp_senderinfo { @@ -1623,6 +1624,10 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t * SWITCH_DECLARE(switch_status_t) switch_rtp_activate_rtcp(switch_rtp_t *rtp_session, int send_rate, switch_port_t remote_port) { const char *err = NULL; + + if (!rtp_session->ms_per_packet) { + return SWITCH_STATUS_FALSE; + } switch_set_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP); @@ -2531,13 +2536,14 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ switch_channel_set_variable(channel, "remote_media_port", adj_port); switch_channel_set_variable(channel, "rtp_auto_adjust", "true"); } - + rtp_session->auto_adj_used = 1; switch_rtp_set_remote_address(rtp_session, tx_host, switch_sockaddr_get_port(rtp_session->from_addr), 0, SWITCH_FALSE, &err); switch_clear_flag_locked(rtp_session, SWITCH_RTP_FLAG_AUTOADJ); } } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Correct ip/port confirmed.\n"); switch_clear_flag_locked(rtp_session, SWITCH_RTP_FLAG_AUTOADJ); + rtp_session->auto_adj_used = 0; } } @@ -2877,6 +2883,12 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ return ret; } + +SWITCH_DECLARE(switch_byte_t) switch_rtp_check_auto_adj(switch_rtp_t *rtp_session) +{ + return rtp_session->auto_adj_used; +} + SWITCH_DECLARE(switch_size_t) switch_rtp_has_dtmf(switch_rtp_t *rtp_session) { switch_size_t has = 0;