<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[Freeswitch-trunk][17339] </title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<div id="header">FreeSWITCH Subversion</div>
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://fisheye.freeswitch.org/changelog/FreeSWITCH?cs=17339">17339</a></dd>
<dt>Author</dt> <dd>brian</dd>
<dt>Date</dt> <dd>2010-04-20 11:08:39 -0500 (Tue, 20 Apr 2010)</dd>
</dl>

<h3>Log Message</h3>
<pre><a href="http://jira.freeswitch.org/browse/FSRTP-14">FSRTP-14</a></pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#freeswitchtrunksrcincludeswitchh">freeswitch/trunk/src/include/switch.h</a></li>
<li><a href="#freeswitchtrunksrcincludeswitch_rtph">freeswitch/trunk/src/include/switch_rtp.h</a></li>
<li><a href="#freeswitchtrunksrcincludeswitch_typesh">freeswitch/trunk/src/include/switch_types.h</a></li>
<li><a href="#freeswitchtrunksrcmodendpointsmod_sofiamod_sofiac">freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c</a></li>
<li><a href="#freeswitchtrunksrcmodendpointsmod_sofiamod_sofiah">freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.h</a></li>
<li><a href="#freeswitchtrunksrcmodendpointsmod_sofiasofiac">freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c</a></li>
<li><a href="#freeswitchtrunksrcmodendpointsmod_sofiasofia_gluec">freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_glue.c</a></li>
<li><a href="#freeswitchtrunksrcswitch_eventc">freeswitch/trunk/src/switch_event.c</a></li>
<li><a href="#freeswitchtrunksrcswitch_rtpc">freeswitch/trunk/src/switch_rtp.c</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#freeswitchtrunksrcincludeswitch_rtcp_frameh">freeswitch/trunk/src/include/switch_rtcp_frame.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="freeswitchtrunksrcincludeswitchh"></a>
<div class="modfile"><h4>Modified: freeswitch/trunk/src/include/switch.h (17338 => 17339)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/trunk/src/include/switch.h        2010-04-19 19:42:41 UTC (rev 17338)
+++ freeswitch/trunk/src/include/switch.h        2010-04-20 16:08:39 UTC (rev 17339)
</span><span class="lines">@@ -116,6 +116,7 @@
</span><span class="cx"> #include &quot;switch_utils.h&quot;
</span><span class="cx"> #include &quot;switch_caller.h&quot;
</span><span class="cx"> #include &quot;switch_frame.h&quot;
</span><ins>+#include &quot;switch_rtcp_frame.h&quot;
</ins><span class="cx"> #include &quot;switch_module_interfaces.h&quot;
</span><span class="cx"> #include &quot;switch_channel.h&quot;
</span><span class="cx"> #include &quot;switch_buffer.h&quot;
</span></span></pre></div>
<a id="freeswitchtrunksrcincludeswitch_rtcp_frameh"></a>
<div class="addfile"><h4>Added: freeswitch/trunk/src/include/switch_rtcp_frame.h (0 => 17339)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/trunk/src/include/switch_rtcp_frame.h                                (rev 0)
+++ freeswitch/trunk/src/include/switch_rtcp_frame.h        2010-04-20 16:08:39 UTC (rev 17339)
</span><span class="lines">@@ -0,0 +1,74 @@
</span><ins>+/*
+ * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ * Copyright (C) 2005-2009, Anthony Minessale II &lt;anthm@freeswitch.org&gt;
+ *
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the &quot;License&quot;); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an &quot;AS IS&quot; basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ *
+ * The Initial Developer of the Original Code is
+ * Anthony Minessale II &lt;anthm@freeswitch.org&gt;
+ * Portions created by the Initial Developer are Copyright (C)
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Sherwin Sim
+ *
+ *
+ * switch_rtcp_frame.h -- RTCP Frame Structure
+ *
+ */
+/*! \file switch_rtcp_frame.h
+  \brief RTCP Frame Structure
+*/
+
+#ifndef SWITCH_RTCP_FRAME_H
+#define SWITCH_RTCP_FRAME_H
+
+#include &lt;switch.h&gt;
+
+SWITCH_BEGIN_EXTERN_C
+/*! \brief An abstraction of a rtcp frame */
+        struct switch_rtcp_frame {
+
+        uint16_t report_count;
+
+        uint16_t packet_type;
+
+        uint32_t ssrc;
+
+        uint32_t ntp_msw;
+
+        uint32_t ntp_lsw;
+
+        uint32_t timestamp;
+
+        uint32_t packet_count;
+
+        uint32_t octect_count;
+
+};
+
+SWITCH_END_EXTERN_C
+#endif
+/* For Emacs:
+ * Local Variables:
+ * mode:c
+ * indent-tabs-mode:t
+ * tab-width:4
+ * c-basic-offset:4
+ * End:
+ * For VIM:
+ * vim:set softtabstop=4 shiftwidth=4 tabstop=4:
+ */
</ins></span></pre></div>
<a id="freeswitchtrunksrcincludeswitch_rtph"></a>
<div class="modfile"><h4>Modified: freeswitch/trunk/src/include/switch_rtp.h (17338 => 17339)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/trunk/src/include/switch_rtp.h        2010-04-19 19:42:41 UTC (rev 17338)
+++ freeswitch/trunk/src/include/switch_rtp.h        2010-04-20 16:08:39 UTC (rev 17339)
</span><span class="lines">@@ -41,6 +41,7 @@
</span><span class="cx"> 
</span><span class="cx"> SWITCH_BEGIN_EXTERN_C
</span><span class="cx"> #define SWITCH_RTP_MAX_BUF_LEN 16384
</span><ins>+#define SWITCH_RTCP_MAX_BUF_LEN 16384
</ins><span class="cx"> #define SWITCH_RTP_MAX_CRYPTO_LEN 64
</span><span class="cx"> #define SWITCH_RTP_KEY_LEN 30
</span><span class="cx"> #define SWITCH_RTP_CRYPTO_KEY_32 &quot;AES_CM_128_HMAC_SHA1_32&quot;
</span><span class="lines">@@ -214,6 +215,13 @@
</span><span class="cx"> SWITCH_DECLARE(switch_status_t) switch_rtp_activate_ice(switch_rtp_t *rtp_session, char *login, char *rlogin);
</span><span class="cx"> 
</span><span class="cx"> /*! 
</span><ins>+  \brief Activate sending RTCP Sender Reports (SR's)
+  \param send_rate interval in milliseconds to send at
+  \return SWITCH_STATUS_SUCCESS
+*/
+SWITCH_DECLARE(switch_status_t) switch_rtp_activate_rtcp(switch_rtp_t *rtp_session, int send_rate);
+
+/*! 
</ins><span class="cx">   \brief Acvite a jitter buffer on an RTP session
</span><span class="cx">   \param rtp_session the rtp session
</span><span class="cx">   \param queue_frames the number of frames to delay
</span><span class="lines">@@ -347,6 +355,15 @@
</span><span class="cx"> */
</span><span class="cx"> SWITCH_DECLARE(switch_status_t) switch_rtp_zerocopy_read_frame(switch_rtp_t *rtp_session, switch_frame_t *frame, switch_io_flag_t io_flags);
</span><span class="cx"> 
</span><ins>+
+/*! 
+  \brief Read RTCP data from a given RTP session without copying
+  \param rtp_session the RTP session to read from
+  \param frame an RTCP frame to populate with information
+  \return the number of bytes read
+*/
+SWITCH_DECLARE(switch_status_t) switch_rtcp_zerocopy_read_frame(switch_rtp_t *rtp_session, switch_rtcp_frame_t *frame);
+
</ins><span class="cx"> SWITCH_DECLARE(void) rtp_flush_read_buffer(switch_rtp_t *rtp_session, switch_rtp_flush_t flush);
</span><span class="cx"> 
</span><span class="cx"> /*!
</span></span></pre></div>
<a id="freeswitchtrunksrcincludeswitch_typesh"></a>
<div class="modfile"><h4>Modified: freeswitch/trunk/src/include/switch_types.h (17338 => 17339)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/trunk/src/include/switch_types.h        2010-04-19 19:42:41 UTC (rev 17338)
+++ freeswitch/trunk/src/include/switch_types.h        2010-04-20 16:08:39 UTC (rev 17339)
</span><span class="lines">@@ -534,7 +534,8 @@
</span><span class="cx">         SWITCH_ZRTP_FLAG_SECURE_MITM_RECV = (1 &lt;&lt; 26),
</span><span class="cx">         SWITCH_RTP_FLAG_DEBUG_RTP_READ = (1 &lt;&lt; 27),
</span><span class="cx">         SWITCH_RTP_FLAG_DEBUG_RTP_WRITE = (1 &lt;&lt; 28),
</span><del>-        SWITCH_RTP_FLAG_VIDEO = (1 &lt;&lt; 29)
</del><ins>+        SWITCH_RTP_FLAG_VIDEO = (1 &lt;&lt; 29),
+        SWITCH_RTP_FLAG_ENABLE_RTCP = (1 &lt;&lt; 30)
</ins><span class="cx"> } switch_rtp_flag_enum_t;
</span><span class="cx"> typedef uint32_t switch_rtp_flag_t;
</span><span class="cx"> 
</span><span class="lines">@@ -607,6 +608,35 @@
</span><span class="cx"> #pragma pack(pop, r1)
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#ifdef _MSC_VER
+#pragma pack(push, r1, 1)
+#endif
+
+#if SWITCH_BYTE_ORDER == __BIG_ENDIAN
+typedef struct {
+        unsigned version:2;                        /* protocol version                  */
+        unsigned p:1;                                /* padding flag                      */
+        unsigned count:5;                        /* number of reception report blocks */
+        unsigned type:8;                        /* packet type                       */
+        unsigned length:16;                        /* length in 32-bit words - 1        */
+} switch_rtcp_hdr_t;
+
+#else /*  BIG_ENDIAN */
+
+typedef struct {
+        unsigned count:5;                        /* number of reception report blocks */
+        unsigned p:1;                                /* padding flag                      */
+        unsigned version:2;                        /* protocol version                  */
+        unsigned type:8;                        /* packet type                       */
+        unsigned length:16;                        /* length in 32-bit words - 1        */
+} switch_rtcp_hdr_t;
+
+#endif
+
+#ifdef _MSC_VER
+#pragma pack(pop, r1)
+#endif
+
</ins><span class="cx"> /*!
</span><span class="cx">   \enum switch_priority_t
</span><span class="cx">   \brief Priority Indication
</span><span class="lines">@@ -1352,6 +1382,7 @@
</span><span class="cx">         SWITCH_EVENT_SERVER_DISCONNECTED,
</span><span class="cx">         SWITCH_EVENT_SEND_INFO,
</span><span class="cx">         SWITCH_EVENT_RECV_INFO,
</span><ins>+        SWITCH_EVENT_RECV_RTCP_MESSAGE,
</ins><span class="cx">         SWITCH_EVENT_CALL_SECURE,
</span><span class="cx">         SWITCH_EVENT_NAT,
</span><span class="cx">         SWITCH_EVENT_RECORD_START,
</span><span class="lines">@@ -1472,6 +1503,7 @@
</span><span class="cx"> typedef uint8_t switch_payload_t;
</span><span class="cx"> typedef struct switch_app_log switch_app_log_t;
</span><span class="cx"> typedef struct switch_rtp switch_rtp_t;
</span><ins>+typedef struct switch_rtcp switch_rtcp_t;
</ins><span class="cx"> typedef struct switch_core_session_message switch_core_session_message_t;
</span><span class="cx"> typedef struct switch_event_header switch_event_header_t;
</span><span class="cx"> typedef struct switch_event switch_event_t;
</span><span class="lines">@@ -1479,6 +1511,7 @@
</span><span class="cx"> typedef struct switch_event_node switch_event_node_t;
</span><span class="cx"> typedef struct switch_loadable_module switch_loadable_module_t;
</span><span class="cx"> typedef struct switch_frame switch_frame_t;
</span><ins>+typedef struct switch_rtcp_frame switch_rtcp_frame_t;
</ins><span class="cx"> typedef struct switch_channel switch_channel_t;
</span><span class="cx"> typedef struct switch_file_handle switch_file_handle_t;
</span><span class="cx"> typedef struct switch_core_session switch_core_session_t;
</span></span></pre></div>
<a id="freeswitchtrunksrcmodendpointsmod_sofiamod_sofiac"></a>
<div class="modfile"><h4>Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c (17338 => 17339)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c        2010-04-19 19:42:41 UTC (rev 17338)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c        2010-04-20 16:08:39 UTC (rev 17339)
</span><span class="lines">@@ -802,6 +802,7 @@
</span><span class="cx">         switch_channel_t *channel = switch_core_session_get_channel(session);
</span><span class="cx">         int payload = 0;
</span><span class="cx">         uint32_t sanity = 1000;
</span><ins>+        switch_rtcp_frame_t rtcp_frame;
</ins><span class="cx"> 
</span><span class="cx">         switch_assert(tech_pvt != NULL);
</span><span class="cx"> 
</span><span class="lines">@@ -859,7 +860,51 @@
</span><span class="cx">                                 }
</span><span class="cx">                                 return status;
</span><span class="cx">                         }
</span><ins>+                        
+                        /* Try to read an RTCP frame, if successful raise an event */
+                        if (switch_rtcp_zerocopy_read_frame(tech_pvt-&gt;rtp_session, &amp;rtcp_frame) == SWITCH_STATUS_SUCCESS) {
+                                switch_event_t *event;
</ins><span class="cx"> 
</span><ins>+                                if (switch_event_create(&amp;event, SWITCH_EVENT_RECV_RTCP_MESSAGE) == SWITCH_STATUS_SUCCESS) {
+                                        char buf[30];
+
+                                        char* uuid = switch_core_session_get_uuid(session);
+                                        if (uuid) {
+                                                switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, &quot;Unique-ID&quot;, switch_core_session_get_uuid(session));
+                                        }
+
+                                        snprintf(buf, sizeof(buf), &quot;%.8x&quot;, rtcp_frame.ssrc);
+                                        switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, &quot;SSRC&quot;, buf);
+
+                                        snprintf(buf, sizeof(buf), &quot;%u&quot;, rtcp_frame.ntp_msw);
+                                        switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, &quot;NTP-Most-Significant-Word&quot;, buf);
+
+                                        snprintf(buf, sizeof(buf), &quot;%u&quot;, rtcp_frame.ntp_lsw);
+                                        switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, &quot;NTP-Least-Significant-Word&quot;, buf);
+
+                                        snprintf(buf, sizeof(buf), &quot;%u&quot;, rtcp_frame.timestamp);
+                                        switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, &quot;RTP-Timestamp&quot;, buf);
+
+                                        snprintf(buf,  sizeof(buf), &quot;%u&quot;, rtcp_frame.packet_count);
+                                        switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, &quot;Sender-Packet-Count&quot;, buf);
+
+                                        snprintf(buf,  sizeof(buf), &quot;%u&quot;, rtcp_frame.octect_count);
+                                        switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, &quot;Octect-Packet-Count&quot;, buf);
+
+                                        snprintf(buf, sizeof(buf), &quot;%lu&quot;, tech_pvt-&gt;read_frame.timestamp);
+                                        switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, &quot;Last-RTP-Timestamp&quot;, buf);
+
+                                        snprintf(buf, sizeof(buf), &quot;%u&quot;, tech_pvt-&gt;read_frame.rate);
+                                        switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, &quot;RTP-Rate&quot;, buf);
+
+                                        snprintf(buf, sizeof(buf), &quot;%lu&quot;, switch_time_now());
+                                        switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, &quot;Capture-Time&quot;, buf);
+
+                                        switch_event_fire(&amp;event);
+                                        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG10, &quot;Dispatched RTCP event\n&quot;);
+                                }
+                        }
+
</ins><span class="cx">                         /* Fast PASS! */
</span><span class="cx">                         if (switch_test_flag((&amp;tech_pvt-&gt;read_frame), SFF_PROXY_PACKET)) {
</span><span class="cx">                                 sofia_clear_flag_locked(tech_pvt, TFLAG_READING);
</span></span></pre></div>
<a id="freeswitchtrunksrcmodendpointsmod_sofiamod_sofiah"></a>
<div class="modfile"><h4>Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.h (17338 => 17339)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.h        2010-04-19 19:42:41 UTC (rev 17338)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.h        2010-04-20 16:08:39 UTC (rev 17339)
</span><span class="lines">@@ -466,6 +466,7 @@
</span><span class="cx">         char *record_path;
</span><span class="cx">         char *presence_hosts;
</span><span class="cx">         char *challenge_realm;
</span><ins>+        char *rtcp_interval_msec;
</ins><span class="cx">         sofia_cid_type_t cid_type;
</span><span class="cx">         sofia_dtmf_t dtmf_type;
</span><span class="cx">         int auto_restart;
</span></span></pre></div>
<a id="freeswitchtrunksrcmodendpointsmod_sofiasofiac"></a>
<div class="modfile"><h4>Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c (17338 => 17339)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c        2010-04-19 19:42:41 UTC (rev 17338)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c        2010-04-20 16:08:39 UTC (rev 17339)
</span><span class="lines">@@ -2459,6 +2459,8 @@
</span><span class="cx">                                                 profile-&gt;hold_music = switch_core_strdup(profile-&gt;pool, val);
</span><span class="cx">                                         } else if (!strcasecmp(var, &quot;outbound-proxy&quot;)) {
</span><span class="cx">                                                 profile-&gt;outbound_proxy = switch_core_strdup(profile-&gt;pool, val);
</span><ins>+                                        } else if (!strcasecmp(var, &quot;rtcp-interval-msec&quot;)) {
+                                                profile-&gt;rtcp_interval_msec = switch_core_strdup(profile-&gt;pool, val);
</ins><span class="cx">                                         } else if (!strcasecmp(var, &quot;session-timeout&quot;)) {
</span><span class="cx">                                                 int v_session_timeout = atoi(val);
</span><span class="cx">                                                 if (v_session_timeout &gt;= 0) {
</span><span class="lines">@@ -2996,6 +2998,8 @@
</span><span class="cx">                                                 profile-&gt;hold_music = switch_core_strdup(profile-&gt;pool, val);
</span><span class="cx">                                         } else if (!strcasecmp(var, &quot;outbound-proxy&quot;)) {
</span><span class="cx">                                                 profile-&gt;outbound_proxy = switch_core_strdup(profile-&gt;pool, val);
</span><ins>+                                        } else if (!strcasecmp(var, &quot;rtcp-interval-msec&quot;)) {
+                                                profile-&gt;rtcp_interval_msec = switch_core_strdup(profile-&gt;pool, val);
</ins><span class="cx">                                         } else if (!strcasecmp(var, &quot;session-timeout&quot;)) {
</span><span class="cx">                                                 int v_session_timeout = atoi(val);
</span><span class="cx">                                                 if (v_session_timeout &gt;= 0) {
</span></span></pre></div>
<a id="freeswitchtrunksrcmodendpointsmod_sofiasofia_gluec"></a>
<div class="modfile"><h4>Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_glue.c (17338 => 17339)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_glue.c        2010-04-19 19:42:41 UTC (rev 17338)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_glue.c        2010-04-20 16:08:39 UTC (rev 17339)
</span><span class="lines">@@ -2725,6 +2725,15 @@
</span><span class="cx">                         switch_rtp_activate_stun_ping(tech_pvt-&gt;rtp_session, tech_pvt-&gt;stun_ip, tech_pvt-&gt;stun_port, stun_ping,
</span><span class="cx">                                                                                   (tech_pvt-&gt;stun_flags &amp; STUN_FLAG_FUNNY) ? 1 : 0);
</span><span class="cx">                 }
</span><ins>+                
+                if ((val = switch_channel_get_variable(tech_pvt-&gt;channel, &quot;rtcp_interval_msec&quot;)) || (val = tech_pvt-&gt;profile-&gt;rtcp_interval_msec)) {
+                        int interval = atoi(val);
+                        if (interval &lt; 100 || interval &gt; 5000) {
+                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt-&gt;session), SWITCH_LOG_ERROR, &quot;Invalid rtcp interval spec [%d] must be between 100 and 5000\n&quot;, interval);
+                        } else {
+                                switch_rtp_activate_rtcp(tech_pvt-&gt;rtp_session, interval);
+                        }
+                }
</ins><span class="cx"> 
</span><span class="cx">                 if ((val = switch_channel_get_variable(tech_pvt-&gt;channel, &quot;jitterbuffer_msec&quot;))) {
</span><span class="cx">                         int len = atoi(val);
</span></span></pre></div>
<a id="freeswitchtrunksrcswitch_eventc"></a>
<div class="modfile"><h4>Modified: freeswitch/trunk/src/switch_event.c (17338 => 17339)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/trunk/src/switch_event.c        2010-04-19 19:42:41 UTC (rev 17338)
+++ freeswitch/trunk/src/switch_event.c        2010-04-20 16:08:39 UTC (rev 17339)
</span><span class="lines">@@ -180,6 +180,7 @@
</span><span class="cx">         &quot;SERVER_DISCONNECTED&quot;,
</span><span class="cx">         &quot;SEND_INFO&quot;,
</span><span class="cx">         &quot;RECV_INFO&quot;,
</span><ins>+        &quot;RECV_RTCP_MESSAGE&quot;,
</ins><span class="cx">         &quot;CALL_SECURE&quot;,
</span><span class="cx">         &quot;NAT&quot;,
</span><span class="cx">         &quot;RECORD_START&quot;,
</span></span></pre></div>
<a id="freeswitchtrunksrcswitch_rtpc"></a>
<div class="modfile"><h4>Modified: freeswitch/trunk/src/switch_rtp.c (17338 => 17339)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/trunk/src/switch_rtp.c        2010-04-19 19:42:41 UTC (rev 17338)
+++ freeswitch/trunk/src/switch_rtp.c        2010-04-20 16:08:39 UTC (rev 17339)
</span><span class="lines">@@ -89,6 +89,11 @@
</span><span class="cx">         char body[SWITCH_RTP_MAX_BUF_LEN];
</span><span class="cx"> } rtp_msg_t;
</span><span class="cx"> 
</span><ins>+typedef struct {
+        switch_rtcp_hdr_t header;
+        char body[SWITCH_RTCP_MAX_BUF_LEN];
+} rtcp_msg_t;
+
</ins><span class="cx"> struct switch_rtp_vad_data {
</span><span class="cx">         switch_core_session_t *session;
</span><span class="cx">         switch_codec_t vad_codec;
</span><span class="lines">@@ -137,17 +142,18 @@
</span><span class="cx">          * families are equal, sock_input == sock_output and only one socket is
</span><span class="cx">          * used.
</span><span class="cx">          */
</span><del>-        switch_socket_t *sock_input, *sock_output;
-        switch_pollfd_t *read_pollfd;
</del><ins>+        switch_socket_t *sock_input, *sock_output, *rtcp_sock_input, *rtcp_sock_output;
+        switch_pollfd_t *read_pollfd, *rtcp_read_pollfd;
</ins><span class="cx">         switch_pollfd_t *jb_pollfd;
</span><span class="cx"> 
</span><del>-        switch_sockaddr_t *local_addr;
</del><ins>+        switch_sockaddr_t *local_addr, *rtcp_local_addr;
</ins><span class="cx">         rtp_msg_t send_msg;
</span><ins>+        rtcp_msg_t rtcp_send_msg;
</ins><span class="cx"> 
</span><del>-        switch_sockaddr_t *remote_addr;
</del><ins>+        switch_sockaddr_t *remote_addr, *rtcp_remote_addr;
</ins><span class="cx">         rtp_msg_t recv_msg;
</span><ins>+        rtcp_msg_t rtcp_recv_msg;
</ins><span class="cx"> 
</span><del>-
</del><span class="cx">         switch_sockaddr_t *remote_stun_addr;
</span><span class="cx"> 
</span><span class="cx">         uint32_t autoadj_window;
</span><span class="lines">@@ -173,12 +179,13 @@
</span><span class="cx">         switch_time_t last_write_timestamp;
</span><span class="cx">         uint32_t flags;
</span><span class="cx">         switch_memory_pool_t *pool;
</span><del>-        switch_sockaddr_t *from_addr;
</del><ins>+        switch_sockaddr_t *from_addr, *rtcp_from_addr;
</ins><span class="cx">         char *rx_host;
</span><span class="cx">         switch_port_t rx_port;
</span><span class="cx">         char *ice_user;
</span><span class="cx">         char *user_ice;
</span><span class="cx">         char *timer_name;
</span><ins>+        char *local_host_str;
</ins><span class="cx">         char *remote_host_str;
</span><span class="cx">         switch_time_t last_stun;
</span><span class="cx">         uint32_t samples_per_interval;
</span><span class="lines">@@ -186,6 +193,7 @@
</span><span class="cx">         uint32_t conf_samples_per_interval;
</span><span class="cx">         uint32_t rsamples_per_interval;
</span><span class="cx">         uint32_t ms_per_packet;
</span><ins>+        switch_port_t local_port;
</ins><span class="cx">         switch_port_t remote_port;
</span><span class="cx">         uint32_t stuncount;
</span><span class="cx">         uint32_t funny_stun;
</span><span class="lines">@@ -216,6 +224,8 @@
</span><span class="cx">         switch_rtp_stats_t stats;
</span><span class="cx">         uint32_t hot_hits;
</span><span class="cx">         uint32_t sync_packets;
</span><ins>+        int rtcp_interval;
+        switch_bool_t rtcp_fresh_frame;
</ins><span class="cx"> 
</span><span class="cx"> #ifdef ENABLE_ZRTP
</span><span class="cx">         zrtp_session_t *zrtp_session;
</span><span class="lines">@@ -225,10 +235,16 @@
</span><span class="cx">         int zinit;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-#ifdef RTP_DEBUG_WRITE_DELTA
</del><span class="cx">         switch_time_t send_time;
</span><del>-#endif
</del><ins>+};
</ins><span class="cx"> 
</span><ins>+struct switch_rtcp_senderinfo {
+        unsigned ssrc:32;
+        unsigned ntp_msw:32;
+        unsigned ntp_lsw:32;
+        unsigned ts:32;
+        unsigned pc:32;
+        unsigned oc:32;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> static int global_init = 0;
</span><span class="lines">@@ -284,7 +300,7 @@
</span><span class="cx">         switch_socket_sendto(rtp_session-&gt;sock_output, rtp_session-&gt;remote_stun_addr, 0, (void *) packet, &amp;bytes);
</span><span class="cx">         rtp_session-&gt;stuncount = rtp_session-&gt;default_stuncount;
</span><span class="cx"> 
</span><del>-  end:
</del><ins>+ end:
</ins><span class="cx">         WRITE_DEC(rtp_session);
</span><span class="cx"> 
</span><span class="cx">         return status;
</span><span class="lines">@@ -324,7 +340,7 @@
</span><span class="cx">         switch_socket_sendto(rtp_session-&gt;sock_output, rtp_session-&gt;remote_addr, 0, (void *) packet, &amp;bytes);
</span><span class="cx">         rtp_session-&gt;stuncount = rtp_session-&gt;default_stuncount;
</span><span class="cx"> 
</span><del>-  end:
</del><ins>+ end:
</ins><span class="cx">         WRITE_DEC(rtp_session);
</span><span class="cx"> 
</span><span class="cx">         return status;
</span><span class="lines">@@ -410,7 +426,7 @@
</span><span class="cx">                 switch_socket_sendto(rtp_session-&gt;sock_output, rtp_session-&gt;from_addr, 0, (void *) rpacket, &amp;bytes);
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-  end:
</del><ins>+ end:
</ins><span class="cx"> 
</span><span class="cx">         READ_DEC(rtp_session);
</span><span class="cx">         WRITE_DEC(rtp_session);
</span><span class="lines">@@ -750,6 +766,104 @@
</span><span class="cx">         rtp_session-&gt;rtp_bugs = bugs;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+
+static switch_status_t enable_remote_rtcp_socket(switch_rtp_t *rtp_session, const char **err) {
+        
+        switch_status_t status = SWITCH_STATUS_SUCCESS;
+
+        if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP)) {
+
+                rtp_session-&gt;rtcp_remote_addr = rtp_session-&gt;remote_addr;
+                
+                if (switch_sockaddr_info_get(&amp;rtp_session-&gt;rtcp_remote_addr, rtp_session-&gt;remote_host_str, SWITCH_UNSPEC, 
+                                                                         rtp_session-&gt;remote_port + 1, 0, rtp_session-&gt;pool) != SWITCH_STATUS_SUCCESS || !rtp_session-&gt;rtcp_remote_addr) {
+                        *err = &quot;RTCP Remote Address Error!&quot;;
+                        return SWITCH_STATUS_FALSE;
+                }
+
+                if (rtp_session-&gt;rtcp_sock_input &amp;&amp; switch_sockaddr_get_family(rtp_session-&gt;rtcp_remote_addr) == 
+                        switch_sockaddr_get_family(rtp_session-&gt;rtcp_local_addr)) {
+                        rtp_session-&gt;rtcp_sock_output = rtp_session-&gt;rtcp_sock_input;
+                } else {
+                        if (rtp_session-&gt;rtcp_sock_output &amp;&amp; rtp_session-&gt;rtcp_sock_output != rtp_session-&gt;rtcp_sock_input) {
+                                switch_socket_close(rtp_session-&gt;rtcp_sock_output);
+                        }
+                        if ((status = switch_socket_create(&amp;rtp_session-&gt;rtcp_sock_output,
+                                                                                           switch_sockaddr_get_family(rtp_session-&gt;rtcp_remote_addr),
+                                                                                           SOCK_DGRAM, 0, rtp_session-&gt;pool)) != SWITCH_STATUS_SUCCESS) {
+                                *err = &quot;RTCP Socket Error!&quot;;
+                        }
+                }
+        } else {
+                *err = &quot;RTCP NOT ACTIVE!&quot;;
+        }
+        
+        return status;
+        
+}
+
+static switch_status_t enable_local_rtcp_socket(switch_rtp_t *rtp_session, const char **err) {
+
+        const char *host = rtp_session-&gt;local_host_str;
+        switch_port_t port = rtp_session-&gt;local_port;
+        switch_socket_t *rtcp_new_sock = NULL, *rtcp_old_sock = NULL;
+        switch_status_t status = SWITCH_STATUS_SUCCESS;
+        char bufa[30];
+
+        if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP)) {
+                if (switch_sockaddr_info_get(&amp;rtp_session-&gt;rtcp_local_addr, host, SWITCH_UNSPEC, port+1, 0, rtp_session-&gt;pool) != SWITCH_STATUS_SUCCESS) {
+                        *err = &quot;RTCP Local Address Error!&quot;;
+                        goto done;
+                }
+                
+                if (switch_socket_create(&amp;rtcp_new_sock, switch_sockaddr_get_family(rtp_session-&gt;rtcp_local_addr), SOCK_DGRAM, 0, rtp_session-&gt;pool) != SWITCH_STATUS_SUCCESS) {
+                        *err = &quot;RTCP Socket Error!&quot;;
+                        goto done;
+                }
+                
+                if (switch_socket_opt_set(rtcp_new_sock, SWITCH_SO_REUSEADDR, 1) != SWITCH_STATUS_SUCCESS) {
+                        *err = &quot;RTCP Socket Error!&quot;;
+                        goto done;
+                }
+                
+                if (switch_socket_bind(rtcp_new_sock, rtp_session-&gt;rtcp_local_addr) != SWITCH_STATUS_SUCCESS) {
+                        *err = &quot;RTCP Bind Error!&quot;;
+                        goto done;
+                }
+                
+                if (switch_sockaddr_info_get(&amp;rtp_session-&gt;rtcp_from_addr, switch_get_addr(bufa, sizeof(bufa), rtp_session-&gt;from_addr),
+                                                                                         SWITCH_UNSPEC, switch_sockaddr_get_port(rtp_session-&gt;from_addr) + 1, 0, rtp_session-&gt;pool) != SWITCH_STATUS_SUCCESS) {
+                        *err = &quot;RTCP From Address Error!&quot;;
+                        goto done;
+                }
+
+                rtcp_old_sock = rtp_session-&gt;rtcp_sock_input;
+                rtp_session-&gt;rtcp_sock_input = rtcp_new_sock;
+                rtcp_new_sock = NULL;
+
+                switch_socket_create_pollset(&amp;rtp_session-&gt;rtcp_read_pollfd, rtp_session-&gt;rtcp_sock_input, SWITCH_POLLIN | SWITCH_POLLERR, rtp_session-&gt;pool);
+
+ done:
+                
+                if (*err) {
+                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;Error allocating rtcp [%s]\n&quot;, *err);
+                        status = SWITCH_STATUS_FALSE;
+                }
+
+                if (rtcp_new_sock) {
+                        switch_socket_close(rtcp_new_sock);
+                }
+                        
+                if (rtcp_old_sock) {
+                        switch_socket_close(rtcp_old_sock);
+                }
+        } else {
+                status = SWITCH_STATUS_FALSE;
+        }
+
+        return status;
+}
+
</ins><span class="cx"> SWITCH_DECLARE(switch_status_t) switch_rtp_set_local_address(switch_rtp_t *rtp_session, const char *host, switch_port_t port, const char **err)
</span><span class="cx"> {
</span><span class="cx">         switch_socket_t *new_sock = NULL, *old_sock = NULL;
</span><span class="lines">@@ -781,11 +895,17 @@
</span><span class="cx">                 goto done;
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+
+        rtp_session-&gt;local_host_str = switch_core_strdup(rtp_session-&gt;pool, host);
+        rtp_session-&gt;local_port = port;
+
+
</ins><span class="cx">         if (switch_sockaddr_info_get(&amp;rtp_session-&gt;local_addr, host, SWITCH_UNSPEC, port, 0, rtp_session-&gt;pool) != SWITCH_STATUS_SUCCESS) {
</span><span class="cx">                 *err = &quot;Local Address Error!&quot;;
</span><span class="cx">                 goto done;
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        
</ins><span class="cx">         if (rtp_session-&gt;sock_input) {
</span><span class="cx">                 switch_rtp_kill_socket(rtp_session);
</span><span class="cx">         }
</span><span class="lines">@@ -799,11 +919,12 @@
</span><span class="cx">                 *err = &quot;Socket Error!&quot;;
</span><span class="cx">                 goto done;
</span><span class="cx">         }
</span><del>-
</del><ins>+        
</ins><span class="cx">         if (switch_socket_bind(new_sock, rtp_session-&gt;local_addr) != SWITCH_STATUS_SUCCESS) {
</span><span class="cx">                 *err = &quot;Bind Error!&quot;;
</span><span class="cx">                 goto done;
</span><span class="cx">         }
</span><ins>+
</ins><span class="cx"> #ifndef WIN32
</span><span class="cx">         len = sizeof(i);
</span><span class="cx">         switch_socket_opt_set(new_sock, SWITCH_SO_NONBLOCK, TRUE);
</span><span class="lines">@@ -827,12 +948,15 @@
</span><span class="cx">         }
</span><span class="cx">         switch_socket_opt_set(new_sock, SWITCH_SO_NONBLOCK, FALSE);
</span><span class="cx"> 
</span><del>-#endif
</del><span class="cx"> 
</span><span class="cx">         old_sock = rtp_session-&gt;sock_input;
</span><span class="cx">         rtp_session-&gt;sock_input = new_sock;
</span><span class="cx">         new_sock = NULL;
</span><span class="cx"> 
</span><ins>+
+#endif
+
+
</ins><span class="cx">         if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_USE_TIMER) || switch_test_flag(rtp_session, SWITCH_RTP_FLAG_NOBLOCK)) {
</span><span class="cx">                 switch_socket_opt_set(rtp_session-&gt;sock_input, SWITCH_SO_NONBLOCK, TRUE);
</span><span class="cx">                 switch_set_flag_locked(rtp_session, SWITCH_RTP_FLAG_NOBLOCK);
</span><span class="lines">@@ -840,11 +964,18 @@
</span><span class="cx"> 
</span><span class="cx">         switch_socket_create_pollset(&amp;rtp_session-&gt;read_pollfd, rtp_session-&gt;sock_input, SWITCH_POLLIN | SWITCH_POLLERR, rtp_session-&gt;pool);
</span><span class="cx"> 
</span><del>-        status = SWITCH_STATUS_SUCCESS;
-        *err = &quot;Success&quot;;
</del><ins>+        if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP)) {
+                if ((status = enable_local_rtcp_socket(rtp_session, err)) == SWITCH_STATUS_SUCCESS) {
+                        *err = &quot;Success&quot;;
+                }
+        } else {
+                status = SWITCH_STATUS_SUCCESS;
+                *err = &quot;Success&quot;;
+        }
+        
</ins><span class="cx">         switch_set_flag_locked(rtp_session, SWITCH_RTP_FLAG_IO);
</span><span class="cx"> 
</span><del>-  done:
</del><ins>+ done:
</ins><span class="cx"> 
</span><span class="cx">         if (new_sock) {
</span><span class="cx">                 switch_socket_close(new_sock);
</span><span class="lines">@@ -854,6 +985,7 @@
</span><span class="cx">                 switch_socket_close(old_sock);
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">         if (rtp_session-&gt;ready != 1) {
</span><span class="cx">                 WRITE_DEC(rtp_session);
</span><span class="cx">                 READ_DEC(rtp_session);
</span><span class="lines">@@ -901,6 +1033,7 @@
</span><span class="cx">                 return SWITCH_STATUS_FALSE;
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">         switch_mutex_lock(rtp_session-&gt;write_mutex);
</span><span class="cx"> 
</span><span class="cx">         rtp_session-&gt;remote_addr = remote_addr;
</span><span class="lines">@@ -923,6 +1056,10 @@
</span><span class="cx">                 }
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP)) {        
+                status = enable_remote_rtcp_socket(rtp_session, err);
+        }
+
</ins><span class="cx">         switch_mutex_unlock(rtp_session-&gt;write_mutex);
</span><span class="cx"> 
</span><span class="cx">         return status;
</span><span class="lines">@@ -985,9 +1122,12 @@
</span><span class="cx"> 
</span><span class="cx">         policy-&gt;next = NULL;
</span><span class="cx">         policy-&gt;key = (uint8_t *) crypto_key-&gt;key;
</span><del>-        crypto_policy_set_rtcp_default(&amp;policy-&gt;rtcp);
-        policy-&gt;rtcp.sec_serv = sec_serv_none;
</del><span class="cx"> 
</span><ins>+        if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP)) {
+                crypto_policy_set_rtcp_default(&amp;policy-&gt;rtcp);
+                policy-&gt;rtcp.sec_serv = sec_serv_none;
+        }
+
</ins><span class="cx">         policy-&gt;rtp.sec_serv = sec_serv_conf_and_auth;
</span><span class="cx">         switch (direction) {
</span><span class="cx">         case SWITCH_RTP_CRYPTO_RECV:
</span><span class="lines">@@ -1136,8 +1276,9 @@
</span><span class="cx"> 
</span><span class="cx">         /* for from address on recvfrom calls */
</span><span class="cx">         switch_sockaddr_info_get(&amp;rtp_session-&gt;from_addr, NULL, SWITCH_UNSPEC, 0, 0, pool);
</span><del>-
-
</del><ins>+        if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP)) {
+                switch_sockaddr_info_get(&amp;rtp_session-&gt;rtcp_from_addr, NULL, SWITCH_UNSPEC, 0, 0, pool);
+        }
</ins><span class="cx">         rtp_session-&gt;seq = (uint16_t) rand();
</span><span class="cx">         rtp_session-&gt;ssrc = (uint32_t) ((intptr_t) rtp_session + (uint32_t) switch_epoch_time_now(NULL));
</span><span class="cx"> 
</span><span class="lines">@@ -1162,6 +1303,14 @@
</span><span class="cx"> 
</span><span class="cx">         rtp_session-&gt;payload = payload;
</span><span class="cx"> 
</span><ins>+        if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP)) {        
+                rtp_session-&gt;rtcp_send_msg.header.version = 2;
+                rtp_session-&gt;rtcp_send_msg.header.p = 0;
+                rtp_session-&gt;rtcp_send_msg.header.type = 200;
+                rtp_session-&gt;rtcp_send_msg.header.count = 0;
+                rtp_session-&gt;rtcp_send_msg.header.length = htons(6); 
+        }
+
</ins><span class="cx">         switch_rtp_set_interval(rtp_session, ms_per_packet, samples_per_interval);
</span><span class="cx">         rtp_session-&gt;conf_samples_per_interval = samples_per_interval;
</span><span class="cx"> 
</span><span class="lines">@@ -1257,7 +1406,7 @@
</span><span class="cx">                 }
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-  end:
</del><ins>+ end:
</ins><span class="cx"> 
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="lines">@@ -1316,7 +1465,7 @@
</span><span class="cx">                 goto end;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-  end:
</del><ins>+ end:
</ins><span class="cx"> 
</span><span class="cx">         if (rtp_session) {
</span><span class="cx">                 switch_mutex_unlock(rtp_session-&gt;flag_mutex);
</span><span class="lines">@@ -1382,6 +1531,19 @@
</span><span class="cx">         return SWITCH_STATUS_SUCCESS;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+SWITCH_DECLARE(switch_status_t) switch_rtp_activate_rtcp(switch_rtp_t *rtp_session, int send_rate)
+{
+        const char *err = NULL;
+        
+        switch_set_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP);
+
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;RTCP send rate is: %d and packet rate is: %d\n&quot;, send_rate, rtp_session-&gt;ms_per_packet);
+        rtp_session-&gt;rtcp_interval = send_rate/(rtp_session-&gt;ms_per_packet/1000);
+
+        return enable_local_rtcp_socket(rtp_session, &amp;err) || enable_remote_rtcp_socket(rtp_session, &amp;err);
+
+}
+
</ins><span class="cx"> SWITCH_DECLARE(switch_status_t) switch_rtp_activate_ice(switch_rtp_t *rtp_session, char *login, char *rlogin)
</span><span class="cx"> {
</span><span class="cx">         char ice_user[80];
</span><span class="lines">@@ -1407,6 +1569,10 @@
</span><span class="cx">         uint32_t o = UINT_MAX;
</span><span class="cx">         switch_size_t len = sizeof(o);
</span><span class="cx">         switch_socket_sendto(rtp_session-&gt;sock_input, rtp_session-&gt;local_addr, 0, (void *) &amp;o, &amp;len);
</span><ins>+
+        if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP) &amp;&amp; rtp_session-&gt;rtcp_sock_input) {
+                switch_socket_sendto(rtp_session-&gt;rtcp_sock_input, rtp_session-&gt;rtcp_local_addr, 0, (void *) &amp;o, &amp;len);
+        }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> SWITCH_DECLARE(void) switch_rtp_break(switch_rtp_t *rtp_session)
</span><span class="lines">@@ -1443,6 +1609,16 @@
</span><span class="cx">                 if (rtp_session-&gt;sock_output &amp;&amp; rtp_session-&gt;sock_output != rtp_session-&gt;sock_input) {
</span><span class="cx">                         switch_socket_shutdown(rtp_session-&gt;sock_output, SWITCH_SHUTDOWN_READWRITE);
</span><span class="cx">                 }
</span><ins>+                
+                if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP)) {
+                        if (rtp_session-&gt;rtcp_sock_input) {
+                                ping_socket(rtp_session);
+                                switch_socket_shutdown(rtp_session-&gt;rtcp_sock_input, SWITCH_SHUTDOWN_READWRITE);
+                        }
+                        if (rtp_session-&gt;rtcp_sock_output &amp;&amp; rtp_session-&gt;rtcp_sock_output != rtp_session-&gt;rtcp_sock_input) {
+                                switch_socket_shutdown(rtp_session-&gt;rtcp_sock_output, SWITCH_SHUTDOWN_READWRITE);
+                        }
+                }
</ins><span class="cx">         }
</span><span class="cx">         switch_mutex_unlock(rtp_session-&gt;flag_mutex);
</span><span class="cx"> }
</span><span class="lines">@@ -1746,7 +1922,7 @@
</span><span class="cx">                         } else {
</span><span class="cx">                                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session),
</span><span class="cx">                                                                   SWITCH_LOG_CONSOLE, &quot;%s FLUSH\n&quot;, switch_channel_get_name(switch_core_session_get_channel(session))
</span><del>-                                        );
</del><ins>+                                                                  );
</ins><span class="cx">                         }
</span><span class="cx">                 }
</span><span class="cx"> 
</span><span class="lines">@@ -1841,18 +2017,126 @@
</span><span class="cx">         return status;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static switch_status_t read_rtcp_packet(switch_rtp_t *rtp_session, switch_size_t *bytes, switch_frame_flag_t *flags)
+{
+        switch_status_t status = SWITCH_STATUS_FALSE;
+
+        if (!switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP)) {
+                return SWITCH_STATUS_FALSE;
+        }
+
+        switch_assert(bytes);
+
+        *bytes = sizeof(rtcp_msg_t);
+        if ((status = switch_socket_recvfrom(rtp_session-&gt;rtcp_from_addr, rtp_session-&gt;rtcp_sock_input, 0, (void *) &amp;rtp_session-&gt;rtcp_recv_msg, bytes)) 
+                != SWITCH_STATUS_SUCCESS) {
+                *bytes = 0;
+        }
+
+        if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_SECURE_RECV)) {
+                int sbytes = (int) *bytes;
+                err_status_t stat = 0;
+
+                stat = srtp_unprotect_rtcp(rtp_session-&gt;recv_ctx, &amp;rtp_session-&gt;rtcp_recv_msg.header, &amp;sbytes);
+                
+                if (stat) {
+                        if (++rtp_session-&gt;srtp_errs &gt;= MAX_SRTP_ERRS) {
+                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
+                                                                  &quot;Error: SRTP RTCP unprotect failed with code %d%s\n&quot;, stat,
+                                                                  stat == err_status_replay_fail ? &quot; (replay check failed)&quot; : stat ==
+                                                                  err_status_auth_fail ? &quot; (auth check failed)&quot; : &quot;&quot;);
+                                return SWITCH_STATUS_FALSE;
+                        } else {
+                                sbytes = 0;
+                        }
+                } else {
+                        rtp_session-&gt;srtp_errs = 0;
+                }
+                
+                *bytes = sbytes;
+                
+        }
+
+
+#ifdef ENABLE_ZRTP
+        /* ZRTP Recv */
+        if (bytes) {
+                unsigned int sbytes = (int) bytes;
+                zrtp_status_t stat = 0;
+
+                stat = zrtp_process_srtcp(rtp_session-&gt;zrtp_stream, (void *) &amp;rtp_session-&gt;rtcp_recv_msg, &amp;sbytes);
+
+                switch (stat) {
+                case zrtp_status_ok:
+                        bytes = sbytes;
+                        break;
+                case zrtp_status_drop:
+                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;Error: zRTP protection drop with code %d\n&quot;, stat);
+                        bytes = 0;
+                        goto do_continue;
+                case zrtp_status_fail:
+                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;Error: zRTP protection fail with code %d\n&quot;, stat);
+                        ret = -1;
+                        goto end;
+                default:
+                        break;
+                }
+        }
+#endif
+
+
+        if (*bytes) {
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10,&quot;Received an RTCP packet of length %lu bytes\n&quot;, *bytes);
+                if (rtp_session-&gt;rtcp_recv_msg.header.version == 2) {
+                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10,&quot;RTCP packet type is %d\n&quot;, rtp_session-&gt;rtcp_recv_msg.header.type);
+                        if (rtp_session-&gt;rtcp_recv_msg.header.type == 200) {
+                                struct switch_rtcp_senderinfo* sr = (struct switch_rtcp_senderinfo*)rtp_session-&gt;rtcp_recv_msg.body;
+
+                                rtp_session-&gt;rtcp_fresh_frame = 1;
+
+                                /* sender report */
+                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10,&quot;Received a SR with %d report blocks, &quot; \
+                                                                  &quot;length in words = %d, &quot; \
+                                                                  &quot;SSRC = 0x%X, &quot; \
+                                                                  &quot;NTP MSW = %u, &quot; \
+                                                                  &quot;NTP LSW = %u, &quot; \
+                                                                  &quot;RTP timestamp = %u, &quot; \
+                                                                  &quot;Sender Packet Count = %u, &quot; \
+                                                                  &quot;Sender Octet Count = %u\n&quot;,
+                                                                  rtp_session-&gt;rtcp_recv_msg.header.count,
+                                                                  ntohs(rtp_session-&gt;rtcp_recv_msg.header.length),
+                                                                  ntohl(sr-&gt;ssrc),
+                                                                  ntohl(sr-&gt;ntp_msw),
+                                                                  ntohl(sr-&gt;ntp_lsw),
+                                                                  ntohl(sr-&gt;ts),
+                                                                  ntohl(sr-&gt;pc),
+                                                                  ntohl(sr-&gt;oc));
+                        }
+                } else {
+                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;Received an unsupported RTCP packet version %d\nn&quot;, rtp_session-&gt;rtcp_recv_msg.header.version);
+                }
+                
+                status = SWITCH_STATUS_SUCCESS;
+        }
+
+        return status;
+}
+
</ins><span class="cx"> static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_type, switch_frame_flag_t *flags, switch_io_flag_t io_flags)
</span><span class="cx"> {
</span><span class="cx">         switch_core_session_t *session = switch_core_memory_pool_get_data(rtp_session-&gt;pool, &quot;__session&quot;);
</span><span class="cx">         switch_channel_t *channel = NULL;
</span><span class="cx">         switch_size_t bytes = 0;
</span><ins>+        switch_size_t rtcp_bytes = 0;
</ins><span class="cx">         switch_status_t status = SWITCH_STATUS_SUCCESS, poll_status = SWITCH_STATUS_SUCCESS;
</span><ins>+        switch_status_t rtcp_status = SWITCH_STATUS_SUCCESS, rtcp_poll_status = SWITCH_STATUS_SUCCESS;
</ins><span class="cx">         int check = 0;
</span><span class="cx">         int ret = -1;
</span><span class="cx">         int sleep_mss = 1000;
</span><span class="cx">         int poll_sec = 5;
</span><span class="cx">         int poll_loop = 0;
</span><span class="cx">         int fdr = 0;
</span><ins>+        int rtcp_fdr = 0;
</ins><span class="cx">         int hot_socket = 0;
</span><span class="cx"> 
</span><span class="cx">         if (session) {
</span><span class="lines">@@ -1904,7 +2188,7 @@
</span><span class="cx">                         }
</span><span class="cx">                 }
</span><span class="cx"> 
</span><del>-          recvfrom:
</del><ins>+        recvfrom:
</ins><span class="cx">                 bytes = 0;
</span><span class="cx"> 
</span><span class="cx">                 if (!switch_rtp_ready(rtp_session)) {
</span><span class="lines">@@ -1946,6 +2230,14 @@
</span><span class="cx">                                 return_cng_frame();
</span><span class="cx">                         }
</span><span class="cx">                 }
</span><ins>+                
+                if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP) &amp;&amp; rtp_session-&gt;rtcp_read_pollfd) {
+                        rtcp_poll_status = switch_poll(rtp_session-&gt;rtcp_read_pollfd, 1, &amp;rtcp_fdr, 0);
+                                                
+                        if (rtcp_poll_status == SWITCH_STATUS_SUCCESS) {
+                                rtcp_status = read_rtcp_packet(rtp_session, &amp;rtcp_bytes, flags);
+                        }
+                }
</ins><span class="cx"> 
</span><span class="cx">                 if (bytes &lt; 0) {
</span><span class="cx">                         ret = (int) bytes;
</span><span class="lines">@@ -2210,7 +2502,7 @@
</span><span class="cx">                    We know the real rules here, but if we enforce them, it's an interop nightmare so,
</span><span class="cx">                    we put up with as much as we can so we don't have to deal with being punished for
</span><span class="cx">                    doing it right. Nice guys finish last!
</span><del>-                 */
</del><ins>+                */
</ins><span class="cx">                 if (bytes &amp;&amp; !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA) &amp;&amp;
</span><span class="cx">                         !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PASS_RFC2833) &amp;&amp; rtp_session-&gt;recv_msg.header.pt == rtp_session-&gt;recv_te) {
</span><span class="cx">                         switch_size_t len = bytes - rtp_header_len;
</span><span class="lines">@@ -2324,7 +2616,7 @@
</span><span class="cx">                         return_cng_frame();
</span><span class="cx">                 }
</span><span class="cx"> 
</span><del>-          timer_check:
</del><ins>+        timer_check:
</ins><span class="cx"> 
</span><span class="cx">                 if (do_cng) {
</span><span class="cx">                         uint8_t *data = (uint8_t *) rtp_session-&gt;recv_msg.body;
</span><span class="lines">@@ -2371,7 +2663,7 @@
</span><span class="cx"> 
</span><span class="cx">                 break;
</span><span class="cx"> 
</span><del>-          do_continue:
</del><ins>+        do_continue:
</ins><span class="cx"> 
</span><span class="cx">                 if (!bytes &amp;&amp; !rtp_session-&gt;timer.interval) {
</span><span class="cx">                         switch_yield(sleep_mss);
</span><span class="lines">@@ -2391,7 +2683,7 @@
</span><span class="cx">                 ret = -1;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-  end:
</del><ins>+ end:
</ins><span class="cx"> 
</span><span class="cx">         READ_DEC(rtp_session);
</span><span class="cx"> 
</span><span class="lines">@@ -2513,6 +2805,33 @@
</span><span class="cx">         return SWITCH_STATUS_SUCCESS;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+SWITCH_DECLARE(switch_status_t) switch_rtcp_zerocopy_read_frame(switch_rtp_t *rtp_session, switch_rtcp_frame_t *frame)
+{
+
+        if (!switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP)) {
+                return SWITCH_STATUS_FALSE;
+        }
+
+        /* A fresh frame has been found! */
+        if (rtp_session-&gt;rtcp_fresh_frame) {
+                struct switch_rtcp_senderinfo* sr = (struct switch_rtcp_senderinfo*)rtp_session-&gt;rtcp_recv_msg.body;
+                /* turn the flag off! */
+                rtp_session-&gt;rtcp_fresh_frame = 0;
+
+                frame-&gt;ssrc = ntohl(sr-&gt;ssrc);
+                frame-&gt;packet_type = rtp_session-&gt;rtcp_recv_msg.header.type;
+                frame-&gt;ntp_msw = ntohl(sr-&gt;ntp_msw);
+                frame-&gt;ntp_lsw = ntohl(sr-&gt;ntp_lsw);
+                frame-&gt;timestamp = ntohl(sr-&gt;ts);
+                frame-&gt;packet_count =  ntohl(sr-&gt;pc);
+                frame-&gt;octect_count = ntohl(sr-&gt;oc);
+
+                return SWITCH_STATUS_SUCCESS;
+        }
+
+        return SWITCH_STATUS_TIMEOUT;
+}
+
</ins><span class="cx"> SWITCH_DECLARE(switch_status_t) switch_rtp_zerocopy_read_frame(switch_rtp_t *rtp_session, switch_frame_t *frame, switch_io_flag_t io_flags)
</span><span class="cx"> {
</span><span class="cx">         int bytes = 0;
</span><span class="lines">@@ -2625,10 +2944,11 @@
</span><span class="cx"> static int rtp_common_write(switch_rtp_t *rtp_session,
</span><span class="cx">                                                         rtp_msg_t *send_msg, void *data, uint32_t datalen, switch_payload_t payload, uint32_t timestamp, switch_frame_flag_t *flags)
</span><span class="cx"> {
</span><del>-        switch_size_t bytes;
</del><ins>+        switch_size_t bytes, rtcp_bytes;
</ins><span class="cx">         uint8_t send = 1;
</span><span class="cx">         uint32_t this_ts = 0;
</span><span class="cx">         int ret;
</span><ins>+        switch_time_t now;
</ins><span class="cx"> 
</span><span class="cx">         if (!switch_rtp_ready(rtp_session)) {
</span><span class="cx">                 return SWITCH_STATUS_FALSE;
</span><span class="lines">@@ -2860,16 +3180,15 @@
</span><span class="cx">                 }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+                now = switch_time_now();
</ins><span class="cx"> #ifdef RTP_DEBUG_WRITE_DELTA
</span><span class="cx">                 {
</span><del>-                        switch_time_t now = switch_time_now();
</del><span class="cx">                         int delta = (int) (now - rtp_session-&gt;send_time) / 1000;
</span><span class="cx">                         printf(&quot;WRITE %d delta %d\n&quot;, (int) bytes, delta);
</span><del>-                        rtp_session-&gt;send_time = now;
</del><span class="cx">                 }
</span><span class="cx"> #endif
</span><ins>+                rtp_session-&gt;send_time = now;
</ins><span class="cx"> 
</span><del>-
</del><span class="cx">                 if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_DEBUG_RTP_WRITE)) {
</span><span class="cx">                         switch_core_session_t *session = switch_core_memory_pool_get_data(rtp_session-&gt;pool, &quot;__session&quot;);
</span><span class="cx"> 
</span><span class="lines">@@ -2924,6 +3243,61 @@
</span><span class="cx">                 }
</span><span class="cx"> 
</span><span class="cx">                 rtp_session-&gt;last_write_ts = this_ts;
</span><ins>+                
+                if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP) &amp;&amp; 
+                        rtp_session-&gt;rtcp_interval &amp;&amp; (rtp_session-&gt;stats.outbound.packet_count % rtp_session-&gt;rtcp_interval) == 0) {
+                        struct switch_rtcp_senderinfo* sr = (struct switch_rtcp_senderinfo*)rtp_session-&gt;rtcp_send_msg.body;
+
+                        sr-&gt;ssrc = send_msg-&gt;header.ssrc;
+                        sr-&gt;ntp_msw = htonl(rtp_session-&gt;send_time / 1000000 + 2208988800UL);
+                        sr-&gt;ntp_lsw = htonl(rtp_session-&gt;send_time % 1000000 * ((UINT_MAX * 1.0)/ 1000000.0));
+                        sr-&gt;ts = send_msg-&gt;header.ts;
+                        sr-&gt;pc = htonl(rtp_session-&gt;stats.outbound.packet_count);
+                        sr-&gt;oc = htonl((rtp_session-&gt;stats.outbound.raw_bytes - rtp_session-&gt;stats.outbound.packet_count * sizeof(srtp_hdr_t)));
+
+                        rtcp_bytes = sizeof(switch_rtcp_hdr_t) + sizeof(struct switch_rtcp_senderinfo);
+
+                        if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_SECURE_SEND)) {
+                                int sbytes = (int) rtcp_bytes;
+                                int stat = srtp_protect_rtcp(rtp_session-&gt;send_ctx, &amp;rtp_session-&gt;rtcp_send_msg.header, &amp;sbytes);
+                                if (stat) {
+                                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;Error: SRTP RTCP protection failed with code %d\n&quot;, stat);
+                                }
+                                rtcp_bytes = sbytes;
+                        }
+
+#ifdef ENABLE_ZRTP
+                        /* ZRTP Send */
+                        if (1) {
+                                unsigned int sbytes = (int) bytes;
+                                zrtp_status_t stat = zrtp_status_fail;
+
+                                stat = zrtp_process_rtcp(rtp_session-&gt;zrtp_stream, (void *) &amp;rtp_session-&gt;rtcp_send_msg, &amp;sbytes);
+
+                                switch (stat) {
+                                case zrtp_status_ok:
+                                        break;
+                                case zrtp_status_drop:
+                                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;Error: zRTP protection drop with code %d\n&quot;, stat);
+                                        ret = (int) bytes;
+                                        goto end;
+                                        break;
+                                case zrtp_status_fail:
+                                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;Error: zRTP protection fail with code %d\n&quot;, stat);
+                                        break;
+                                default:
+                                        break;
+                                }
+
+                                bytes = sbytes;
+                        }
+#endif
+
+                        if (switch_socket_sendto(rtp_session-&gt;rtcp_sock_output, rtp_session-&gt;rtcp_remote_addr, 0, 
+                                                                         (const char*)&amp;rtp_session-&gt;rtcp_send_msg, &amp;rtcp_bytes ) != SWITCH_STATUS_SUCCESS) {
+                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,&quot;RTCP packet not written\n&quot;);
+                        }
+                }
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         if (rtp_session-&gt;remote_stun_addr) {
</span><span class="lines">@@ -2939,7 +3313,7 @@
</span><span class="cx"> 
</span><span class="cx">         ret = (int) bytes;
</span><span class="cx"> 
</span><del>-  end:
</del><ins>+ end:
</ins><span class="cx"> 
</span><span class="cx">         WRITE_DEC(rtp_session);
</span><span class="cx"> 
</span><span class="lines">@@ -3031,9 +3405,9 @@
</span><span class="cx">                 send_msg = frame-&gt;packet;
</span><span class="cx"> 
</span><span class="cx">                 /*
</span><del>-                if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO)) {
-                        send_msg-&gt;header.pt = rtp_session-&gt;payload;
-                }
</del><ins>+                  if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO)) {
+                  send_msg-&gt;header.pt = rtp_session-&gt;payload;
+                  }
</ins><span class="cx">                 */
</span><span class="cx"> 
</span><span class="cx">                 if (switch_socket_sendto(rtp_session-&gt;sock_output, rtp_session-&gt;remote_addr, 0, frame-&gt;packet, &amp;bytes) != SWITCH_STATUS_SUCCESS) {
</span><span class="lines">@@ -3131,9 +3505,9 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         /*
</span><del>-        if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO)) {
-                send_msg-&gt;header.pt = rtp_session-&gt;payload;
-        }
</del><ins>+          if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO)) {
+          send_msg-&gt;header.pt = rtp_session-&gt;payload;
+          }
</ins><span class="cx">         */
</span><span class="cx"> 
</span><span class="cx">         return rtp_common_write(rtp_session, send_msg, data, len, payload, ts, &amp;frame-&gt;flags);
</span><span class="lines">@@ -3234,7 +3608,7 @@
</span><span class="cx"> 
</span><span class="cx">         ret = (int) bytes;
</span><span class="cx"> 
</span><del>-  end:
</del><ins>+ end:
</ins><span class="cx"> 
</span><span class="cx">         WRITE_DEC(rtp_session);
</span><span class="cx"> 
</span></span></pre>
</div>
</div>
<div id="footer">See you at ClueCon</div>

</body>
</html>