1
0
mirror of https://github.com/signalwire/freeswitch.git synced 2025-04-19 09:47:23 +00:00

add manual_rtp_bugs to profile and chan var and 3 new RTP bugs SEND_LINEAR_TIMESTAMPS|START_SEQ_AT_ZERO|NEVER_SEND_MARKER

RTP_BUG_SEND_LINEAR_TIMESTAMPS = (1 << 3),

	  Our friends at Sonus get real mad when the timestamps are not in perfect sequence even during periods of silence.
	  With this flag, we will only increment the timestamp when write packets even if they are eons apart.

	RTP_BUG_START_SEQ_AT_ZERO = (1 << 4),

	  Our friends at Sonus also get real mad if the sequence number does not start at 0.
	  Typically, we set this to a random starting value for your saftey.
	  This is a security risk you take upon yourself when you enable this flag.

	RTP_BUG_NEVER_SEND_MARKER = (1 << 5),

	  Our friends at Sonus are on a roll, They also get easily dumbfounded by marker bits.
	  This flag will never send any. Sheesh....
This commit is contained in:
Anthony Minessale 2010-11-10 16:55:56 -06:00
parent ca8c23361b
commit b278dd2379
5 changed files with 112 additions and 44 deletions

@ -596,7 +596,7 @@ typedef enum {
*/
RTP_BUG_IGNORE_MARK_BIT = (1 << 2)
RTP_BUG_IGNORE_MARK_BIT = (1 << 2),
/*
A Huawei SBC has been discovered that sends the mark bit on every single RTP packet.
@ -606,6 +606,34 @@ typedef enum {
*/
RTP_BUG_SEND_LINEAR_TIMESTAMPS = (1 << 3),
/*
Our friends at Sonus get real mad when the timestamps are not in perfect sequence even during periods of silence.
With this flag, we will only increment the timestamp when write packets even if they are eons apart.
*/
RTP_BUG_START_SEQ_AT_ZERO = (1 << 4),
/*
Our friends at Sonus also get real mad if the sequence number does not start at 0.
Typically, we set this to a random starting value for your saftey.
This is a security risk you take upon yourself when you enable this flag.
*/
RTP_BUG_NEVER_SEND_MARKER = (1 << 5),
/*
Our friends at Sonus are on a roll, They also get easily dumbfounded by marker bits.
This flag will never send any. Sheesh....
*/
} switch_rtp_bug_flag_t;

@ -558,6 +558,7 @@ struct sofia_profile {
char *user_agent_filter;
uint32_t max_registrations_perext;
switch_rtp_bug_flag_t auto_rtp_bugs;
switch_rtp_bug_flag_t manual_rtp_bugs;
uint32_t ib_calls;
uint32_t ob_calls;
uint32_t ib_failed_calls;
@ -1035,3 +1036,4 @@ 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);
void sofia_glue_check_dtmf_type(private_object_t *tech_pvt);
void sofia_glue_parse_rtp_bugs(uint32_t *flag_pole, const char *str);

@ -2220,39 +2220,6 @@ static void parse_domain_tag(sofia_profile_t *profile, switch_xml_t x_domain_tag
}
}
static void parse_rtp_bugs(sofia_profile_t *profile, const char *str)
{
if (switch_stristr("clear", str)) {
profile->auto_rtp_bugs = 0;
}
if (switch_stristr("CISCO_SKIP_MARK_BIT_2833", str)) {
profile->auto_rtp_bugs |= RTP_BUG_CISCO_SKIP_MARK_BIT_2833;
}
if (switch_stristr("~CISCO_SKIP_MARK_BIT_2833", str)) {
profile->auto_rtp_bugs &= ~RTP_BUG_CISCO_SKIP_MARK_BIT_2833;
}
if (switch_stristr("SONUS_SEND_INVALID_TIMESTAMP_2833", str)) {
profile->auto_rtp_bugs |= RTP_BUG_SONUS_SEND_INVALID_TIMESTAMP_2833;
}
if (switch_stristr("~SONUS_SEND_INVALID_TIMESTAMP_2833", str)) {
profile->auto_rtp_bugs &= ~RTP_BUG_SONUS_SEND_INVALID_TIMESTAMP_2833;
}
if (switch_stristr("IGNORE_MARK_BIT", str)) {
profile->auto_rtp_bugs |= RTP_BUG_IGNORE_MARK_BIT;
}
if (switch_stristr("~IGNORE_MARK_BIT", str)) {
profile->auto_rtp_bugs &= ~RTP_BUG_IGNORE_MARK_BIT;
}
}
switch_status_t reconfig_sofia(sofia_profile_t *profile)
{
switch_xml_t cfg, xml = NULL, xprofile, profiles, gateways_tag, domain_tag, domains_tag, aliases_tag, alias_tag, settings, param;
@ -2382,7 +2349,9 @@ switch_status_t reconfig_sofia(sofia_profile_t *profile)
sofia_clear_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER);
}
} else if (!strcasecmp(var, "auto-rtp-bugs")) {
parse_rtp_bugs(profile, val);
sofia_glue_parse_rtp_bugs(&profile->auto_rtp_bugs, val);
} else if (!strcasecmp(var, "manual-rtp-bugs")) {
sofia_glue_parse_rtp_bugs(&profile->manual_rtp_bugs, val);
} else if (!strcasecmp(var, "user-agent-string")) {
profile->user_agent = switch_core_strdup(profile->pool, val);
} else if (!strcasecmp(var, "auto-restart")) {
@ -3103,7 +3072,9 @@ switch_status_t config_sofia(int reload, char *profile_name)
profile->rport_level = 2;
}
} else if (!strcasecmp(var, "auto-rtp-bugs")) {
parse_rtp_bugs(profile, val);
sofia_glue_parse_rtp_bugs(&profile->auto_rtp_bugs, val);
} else if (!strcasecmp(var, "manual-rtp-bugs")) {
sofia_glue_parse_rtp_bugs(&profile->manual_rtp_bugs, val);
} else if (!strcasecmp(var, "dbname")) {
profile->dbname = switch_core_strdup(profile->pool, val);
} else if (!strcasecmp(var, "presence-hosts")) {

@ -3106,7 +3106,11 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f
tech_pvt->rtp_bugs |= RTP_BUG_IGNORE_MARK_BIT;
}
switch_rtp_intentional_bugs(tech_pvt->rtp_session, tech_pvt->rtp_bugs);
if ((val = switch_channel_get_variable(tech_pvt->channel, "rtp_manual_rtp_bugs"))) {
sofia_glue_parse_rtp_bugs(&tech_pvt->rtp_bugs, val);
}
switch_rtp_intentional_bugs(tech_pvt->rtp_session, tech_pvt->rtp_bugs | tech_pvt->profile->manual_rtp_bugs);
if ((vad_in && inb) || (vad_out && !inb)) {
switch_rtp_enable_vad(tech_pvt->rtp_session, tech_pvt->session, &tech_pvt->read_codec, SWITCH_VAD_FLAG_TALKING);
@ -5990,6 +5994,62 @@ void sofia_glue_build_vid_refresh_message(switch_core_session_t *session, const
}
void sofia_glue_parse_rtp_bugs(uint32_t *flag_pole, const char *str)
{
if (switch_stristr("clear", str)) {
*flag_pole = 0;
}
if (switch_stristr("CISCO_SKIP_MARK_BIT_2833", str)) {
*flag_pole |= RTP_BUG_CISCO_SKIP_MARK_BIT_2833;
}
if (switch_stristr("~CISCO_SKIP_MARK_BIT_2833", str)) {
*flag_pole &= ~RTP_BUG_CISCO_SKIP_MARK_BIT_2833;
}
if (switch_stristr("SONUS_SEND_INVALID_TIMESTAMP_2833", str)) {
*flag_pole |= RTP_BUG_SONUS_SEND_INVALID_TIMESTAMP_2833;
}
if (switch_stristr("~SONUS_SEND_INVALID_TIMESTAMP_2833", str)) {
*flag_pole &= ~RTP_BUG_SONUS_SEND_INVALID_TIMESTAMP_2833;
}
if (switch_stristr("IGNORE_MARK_BIT", str)) {
*flag_pole |= RTP_BUG_IGNORE_MARK_BIT;
}
if (switch_stristr("~IGNORE_MARK_BIT", str)) {
*flag_pole &= ~RTP_BUG_IGNORE_MARK_BIT;
}
if (switch_stristr("SEND_LINEAR_TIMESTAMPS", str)) {
*flag_pole |= RTP_BUG_SEND_LINEAR_TIMESTAMPS;
}
if (switch_stristr("~SEND_LINEAR_TIMESTAMPS", str)) {
*flag_pole &= ~RTP_BUG_SEND_LINEAR_TIMESTAMPS;
}
if (switch_stristr("START_SEQ_AT_ZERO", str)) {
*flag_pole |= RTP_BUG_START_SEQ_AT_ZERO;
}
if (switch_stristr("~START_SEQ_AT_ZERO", str)) {
*flag_pole &= ~RTP_BUG_START_SEQ_AT_ZERO;
}
if (switch_stristr("NEVER_SEND_MARKER", str)) {
*flag_pole |= RTP_BUG_NEVER_SEND_MARKER;
}
if (switch_stristr("~NEVER_SEND_MARKER", str)) {
*flag_pole &= ~RTP_BUG_NEVER_SEND_MARKER;
}
}

@ -1366,7 +1366,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_create(switch_rtp_t **new_rtp_session
if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP)) {
switch_sockaddr_info_get(&rtp_session->rtcp_from_addr, NULL, SWITCH_UNSPEC, 0, 0, pool);
}
rtp_session->seq = (uint16_t) rand();
rtp_session->seq = (rtp_session->rtp_bugs & RTP_BUG_START_SEQ_AT_ZERO) ? 0 : (uint16_t) rand();
rtp_session->ssrc = (uint32_t) ((intptr_t) rtp_session + (uint32_t) switch_epoch_time_now(NULL));
rtp_session->send_msg.header.ssrc = htonl(rtp_session->ssrc);
@ -3179,10 +3179,15 @@ static int rtp_common_write(switch_rtp_t *rtp_session,
send_msg = &rtp_session->send_msg;
send_msg->header.pt = payload;
if (timestamp) {
if (rtp_session->rtp_bugs & RTP_BUG_SEND_LINEAR_TIMESTAMPS) {
rtp_session->ts += rtp_session->samples_per_interval;
if (rtp_session->ts <= rtp_session->last_write_ts && rtp_session->ts > 0) {
rtp_session->ts = rtp_session->last_write_ts + rtp_session->samples_per_interval;
}
} else if (timestamp) {
rtp_session->ts = (uint32_t) timestamp;
/* Send marker bit if timestamp is lower/same as before (resetted/new timer) */
if (rtp_session->ts <= rtp_session->last_write_ts) {
if (rtp_session->ts <= rtp_session->last_write_ts && !(rtp_session->rtp_bugs & RTP_BUG_NEVER_SEND_MARKER)) {
m++;
}
} else if (rtp_session->timer.timer_interface) {
@ -3216,8 +3221,8 @@ static int rtp_common_write(switch_rtp_t *rtp_session,
rtp_session->cn = 0;
m++;
}
send_msg->header.m = m ? 1 : 0;
send_msg->header.m = (m && !(rtp_session->rtp_bugs & RTP_BUG_NEVER_SEND_MARKER)) ? 1 : 0;
memcpy(send_msg->body, data, datalen);
bytes = datalen + rtp_header_len;
@ -3287,7 +3292,9 @@ static int rtp_common_write(switch_rtp_t *rtp_session,
if (diff >= rtp_session->vad_data.diff_level || ++rtp_session->vad_data.hangunder_hits >= rtp_session->vad_data.hangunder) {
switch_set_flag(&rtp_session->vad_data, SWITCH_VAD_FLAG_TALKING);
send_msg->header.m = 1;
if (!(rtp_session->rtp_bugs & RTP_BUG_NEVER_SEND_MARKER)) {
send_msg->header.m = 1;
}
rtp_session->vad_data.hangover_hits = rtp_session->vad_data.hangunder_hits = rtp_session->vad_data.cng_count = 0;
if (switch_test_flag(&rtp_session->vad_data, SWITCH_VAD_FLAG_EVENTS_TALK)) {
switch_event_t *event;
@ -3755,7 +3762,7 @@ SWITCH_DECLARE(int) switch_rtp_write_manual(switch_rtp_t *rtp_session,
rtp_session->write_msg.header.seq = htons(++rtp_session->seq);
rtp_session->write_msg.header.ts = htonl(ts);
rtp_session->write_msg.header.pt = payload;
rtp_session->write_msg.header.m = m ? 1 : 0;
rtp_session->write_msg.header.m = (m && !(rtp_session->rtp_bugs & RTP_BUG_NEVER_SEND_MARKER)) ? 1 : 0;
memcpy(rtp_session->write_msg.body, data, datalen);
bytes = rtp_header_len + datalen;