]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
add manual_rtp_bugs to profile and chan var and 3 new RTP bugs SEND_LINEAR_TIMESTAMPS...
authorAnthony Minessale <anthm@freeswitch.org>
Wed, 10 Nov 2010 22:55:56 +0000 (16:55 -0600)
committerAnthony Minessale <anthm@freeswitch.org>
Wed, 10 Nov 2010 22:58:36 +0000 (16:58 -0600)
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....

src/include/switch_types.h
src/mod/endpoints/mod_sofia/mod_sofia.h
src/mod/endpoints/mod_sofia/sofia.c
src/mod/endpoints/mod_sofia/sofia_glue.c
src/switch_rtp.c

index 272d435068cb707587750773acf913e96e61f08e..c01638089fc6420cfa838d19277e9441527bcff1 100644 (file)
@@ -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;
 
index 6978e34ffc40f1ea49b29c7bbca5685d7bb614ac..750fb60c15a37246b14e2daa17adfb849eda16fd 100644 (file)
@@ -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);
index 7cb4c5b528e2e92c2d4b2d0ffaa92ad644d292e6..e5672061bdae38145d5c15df8321988dec198ef6 100644 (file)
@@ -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")) {
index fbd270d41be5c9d2a4c63b45a536f15add77c58b..6e9aacb1262bb290ec9e1c0e46bc63c96419a9ea 100644 (file)
@@ -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;
+       }
+}
+
 
 
 
index 1792de08b37df27f5d8d8b97c0d820621da6086a..f0eead3c422fc732b8231565a469a8859d4448fb 100644 (file)
@@ -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;