This commit is contained in:
Anthony Minessale 2013-01-16 19:04:57 -06:00
parent 36d1388a99
commit 12e70149ff
4 changed files with 239 additions and 116 deletions

View File

@ -230,7 +230,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_rtcp_ice(switch_rtp_t *rtp_s
\param send_rate interval in milliseconds to send at \param send_rate interval in milliseconds to send at
\return SWITCH_STATUS_SUCCESS \return SWITCH_STATUS_SUCCESS
*/ */
SWITCH_DECLARE(switch_status_t) switch_rtp_activate_rtcp(switch_rtp_t *rtp_session, int send_rate, switch_port_t remote_port); SWITCH_DECLARE(switch_status_t) switch_rtp_activate_rtcp(switch_rtp_t *rtp_session, int send_rate, switch_port_t remote_port, switch_bool_t mux);
/*! /*!
\brief Acvite a jitter buffer on an RTP session \brief Acvite a jitter buffer on an RTP session

View File

@ -641,10 +641,10 @@ typedef enum {
SWITCH_RTP_FLAG_DEBUG_RTP_WRITE, SWITCH_RTP_FLAG_DEBUG_RTP_WRITE,
SWITCH_RTP_FLAG_VIDEO, SWITCH_RTP_FLAG_VIDEO,
SWITCH_RTP_FLAG_ENABLE_RTCP, SWITCH_RTP_FLAG_ENABLE_RTCP,
/* don't add any below this one */ SWITCH_RTP_FLAG_RTCP_MUX,
SWITCH_RTP_FLAG_INVALID SWITCH_RTP_FLAG_INVALID
} switch_rtp_flag_enum_t; } switch_rtp_flag_t;
typedef uint32_t switch_rtp_flag_t;
typedef enum { typedef enum {
RTP_BUG_NONE = 0, /* won't be using this one much ;) */ RTP_BUG_NONE = 0, /* won't be using this one much ;) */
@ -1336,7 +1336,8 @@ typedef enum {
SFF_DYNAMIC = (1 << 6), SFF_DYNAMIC = (1 << 6),
SFF_ZRTP = (1 << 7), SFF_ZRTP = (1 << 7),
SFF_UDPTL_PACKET = (1 << 8), SFF_UDPTL_PACKET = (1 << 8),
SFF_NOT_AUDIO = (1 << 9) SFF_NOT_AUDIO = (1 << 9),
SFF_RTCP = (1 << 10)
} switch_frame_flag_enum_t; } switch_frame_flag_enum_t;
typedef uint32_t switch_frame_flag_t; typedef uint32_t switch_frame_flag_t;

View File

@ -29,7 +29,7 @@
* *
*/ */
#define RTCP_MUX
#include <switch.h> #include <switch.h>
#include <switch_ssl.h> #include <switch_ssl.h>
#include <switch_stun.h> #include <switch_stun.h>
@ -118,8 +118,6 @@ typedef struct ice_s {
char *pwd; char *pwd;
char *options; char *options;
} ice_t; } ice_t;
typedef struct switch_rtp_engine_s { typedef struct switch_rtp_engine_s {
@ -160,6 +158,8 @@ typedef struct switch_rtp_engine_s {
ice_t ice_in; ice_t ice_in;
ice_t ice_out; ice_t ice_out;
int8_t rtcp_mux;
} switch_rtp_engine_t; } switch_rtp_engine_t;
@ -1799,7 +1799,7 @@ static void check_ice(switch_media_handle_t *smh, switch_media_type_t type, sdp_
{ {
switch_rtp_engine_t *engine = &smh->engines[type]; switch_rtp_engine_t *engine = &smh->engines[type];
sdp_attribute_t *attr; sdp_attribute_t *attr;
int i = 0; int i = 0, got_rtcp_mux = 0;
char tmp[80] = ""; char tmp[80] = "";
for (attr = m->m_attributes; attr; attr = attr->a_next) { for (attr = m->m_attributes; attr; attr = attr->a_next) {
@ -1818,11 +1818,17 @@ static void check_ice(switch_media_handle_t *smh, switch_media_type_t type, sdp_
engine->ice_in.pwd = switch_core_session_strdup(smh->session, attr->a_value); engine->ice_in.pwd = switch_core_session_strdup(smh->session, attr->a_value);
} else if (!strcasecmp(attr->a_name, "ice-options")) { } else if (!strcasecmp(attr->a_name, "ice-options")) {
engine->ice_in.options = switch_core_session_strdup(smh->session, attr->a_value); engine->ice_in.options = switch_core_session_strdup(smh->session, attr->a_value);
#ifdef RTCP_MUX
} else if (!strcasecmp(attr->a_name, "rtcp-mux")) {
engine->rtcp_mux = SWITCH_TRUE;
got_rtcp_mux++;
#endif
} else if (!strcasecmp(attr->a_name, "candidate")) { } else if (!strcasecmp(attr->a_name, "candidate")) {
if (!engine->cand_acl_count) { if (!engine->cand_acl_count) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_WARNING, "NO candidate ACL defined, skipping candidate check.\n"); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_WARNING, "NO candidate ACL defined, skipping candidate check.\n");
return; goto end;
} }
@ -1921,6 +1927,13 @@ static void check_ice(switch_media_handle_t *smh, switch_media_type_t type, sdp_
engine->remote_rtcp_port = engine->ice_in.cands[1].con_port; engine->remote_rtcp_port = engine->ice_in.cands[1].con_port;
} }
end:
if (!got_rtcp_mux) {
engine->rtcp_mux = -1;
}
} }
//? //?
@ -2117,8 +2130,8 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
got_webrtc++; got_webrtc++;
switch_channel_set_flag(session->channel, CF_WEBRTC); switch_channel_set_flag(session->channel, CF_WEBRTC);
switch_channel_set_flag(session->channel, CF_ICE); switch_channel_set_flag(session->channel, CF_ICE);
smh->mparams->rtcp_audio_interval_msec = "2500"; smh->mparams->rtcp_audio_interval_msec = "5000";
smh->mparams->rtcp_video_interval_msec = "2500"; smh->mparams->rtcp_video_interval_msec = "5000";
} }
if (m->m_proto == sdp_proto_srtp || m->m_proto == sdp_proto_extended_srtp) { if (m->m_proto == sdp_proto_srtp || m->m_proto == sdp_proto_extended_srtp) {
@ -3256,6 +3269,12 @@ static void gen_ice(switch_core_session_t *session, switch_media_type_t type, co
engine = &smh->engines[type]; engine = &smh->engines[type];
#ifdef RTCP_MUX
if (!engine->rtcp_mux && type == SWITCH_MEDIA_TYPE_AUDIO) {
engine->rtcp_mux = SWITCH_TRUE;
}
#endif
if (!smh->msid) { if (!smh->msid) {
switch_stun_random_string(tmp, 32, NULL); switch_stun_random_string(tmp, 32, NULL);
tmp[32] = '\0'; tmp[32] = '\0';
@ -3655,7 +3674,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
if (!strcasecmp(val, "passthru")) { if (!strcasecmp(val, "passthru")) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Activating RTCP PASSTHRU PORT %d\n", remote_rtcp_port); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Activating RTCP PASSTHRU PORT %d\n", remote_rtcp_port);
switch_rtp_activate_rtcp(a_engine->rtp_session, -1, remote_rtcp_port); switch_rtp_activate_rtcp(a_engine->rtp_session, -1, remote_rtcp_port, a_engine->rtcp_mux > 0);
} else { } else {
int interval = atoi(val); int interval = atoi(val);
if (interval < 100 || interval > 5000) { if (interval < 100 || interval > 5000) {
@ -3663,7 +3682,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
"Invalid rtcp interval spec [%d] must be between 100 and 5000\n", interval); "Invalid rtcp interval spec [%d] must be between 100 and 5000\n", interval);
} else { } else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Activating RTCP PORT %d\n", remote_rtcp_port); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Activating RTCP PORT %d\n", remote_rtcp_port);
switch_rtp_activate_rtcp(a_engine->rtp_session, interval, remote_rtcp_port); switch_rtp_activate_rtcp(a_engine->rtp_session, interval, remote_rtcp_port, a_engine->rtcp_mux > 0);
} }
} }
@ -4029,7 +4048,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
} }
if (!strcasecmp(val, "passthru")) { if (!strcasecmp(val, "passthru")) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Activating VIDEO RTCP PASSTHRU PORT %d\n", remote_port); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Activating VIDEO RTCP PASSTHRU PORT %d\n", remote_port);
switch_rtp_activate_rtcp(v_engine->rtp_session, -1, remote_port); switch_rtp_activate_rtcp(v_engine->rtp_session, -1, remote_port, v_engine->rtcp_mux > 0);
} else { } else {
int interval = atoi(val); int interval = atoi(val);
if (interval < 100 || interval > 5000) { if (interval < 100 || interval > 5000) {
@ -4037,7 +4056,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
"Invalid rtcp interval spec [%d] must be between 100 and 5000\n", interval); "Invalid rtcp interval spec [%d] must be between 100 and 5000\n", interval);
} else { } else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Activating VIDEO RTCP PORT %d\n", remote_port); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Activating VIDEO RTCP PORT %d\n", remote_port);
switch_rtp_activate_rtcp(v_engine->rtp_session, interval, remote_port); switch_rtp_activate_rtcp(v_engine->rtp_session, interval, remote_port, v_engine->rtcp_mux > 0);
} }
} }
@ -4258,7 +4277,11 @@ static void generate_m(switch_core_session_t *session, char *buf, size_t buflen,
} }
if (smh->mparams->rtcp_audio_interval_msec) { if (smh->mparams->rtcp_audio_interval_msec) {
switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=rtcp:%d IN %s %s\n", port + 1, family, ip); if (a_engine->rtcp_mux > 0) {
switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=rtcp-mux\n");
} else {
switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=rtcp:%d IN %s %s\n", port + 1, family, ip);
}
} }
//switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ssrc:%u\n", a_engine->ssrc); //switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ssrc:%u\n", a_engine->ssrc);
@ -4302,13 +4325,14 @@ static void generate_m(switch_core_session_t *session, char *buf, size_t buflen,
switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=candidate:%s 2 %s %u %s %d typ host generation 0\n", switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=candidate:%s 2 %s %u %s %d typ host generation 0\n",
tmp1, ice_out->cands[0].transport, c2, tmp1, ice_out->cands[0].transport, c2,
ice_out->cands[0].con_addr, ice_out->cands[0].con_port + 1 ice_out->cands[0].con_addr, ice_out->cands[0].con_port + (a_engine->rtcp_mux > 0 ? 0 : 1)
); );
switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=candidate:%s 2 %s %u %s %d typ srflx generation 0\n", switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=candidate:%s 2 %s %u %s %d typ srflx generation 0\n",
tmp2, ice_out->cands[0].transport, c4, tmp2, ice_out->cands[0].transport, c4,
ice_out->cands[0].con_addr, ice_out->cands[0].con_port + 1 ice_out->cands[0].con_addr, ice_out->cands[0].con_port + (a_engine->rtcp_mux > 0 ? 0 : 1)
); );
@ -4703,7 +4727,11 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
if (smh->mparams->rtcp_audio_interval_msec) { if (smh->mparams->rtcp_audio_interval_msec) {
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtcp:%d IN %s %s\n", port + 1, family, ip); if (a_engine->rtcp_mux > 0) {
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtcp-mux\n");
} else {
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtcp:%d IN %s %s\n", port + 1, family, ip);
}
} }
//switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ssrc:%u\n", a_engine->ssrc); //switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ssrc:%u\n", a_engine->ssrc);
@ -4743,16 +4771,17 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
); );
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=candidate:%s 2 %s %u %s %d typ host generation 0\n",
tmp1, ice_out->cands[0].transport, c2,
ice_out->cands[0].con_addr, ice_out->cands[0].con_port + 1
);
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=candidate:%s 2 %s %u %s %d typ srflx generation 0\n",
tmp2, ice_out->cands[0].transport, c4,
ice_out->cands[0].con_addr, ice_out->cands[0].con_port + 1
);
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=candidate:%s 2 %s %u %s %d typ host generation 0\n",
tmp1, ice_out->cands[0].transport, c2,
ice_out->cands[0].con_addr, ice_out->cands[0].con_port + (a_engine->rtcp_mux > 0 ? 0 : 1)
);
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=candidate:%s 2 %s %u %s %d typ srflx generation 0\n",
tmp2, ice_out->cands[0].transport, c4,
ice_out->cands[0].con_addr, ice_out->cands[0].con_port + (a_engine->rtcp_mux > 0 ? 0 : 1)
);
#ifdef GOOGLE_ICE #ifdef GOOGLE_ICE
@ -4978,7 +5007,11 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
if (smh->mparams->rtcp_audio_interval_msec) { if (smh->mparams->rtcp_audio_interval_msec) {
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtcp:%d IN %s %s\n", v_port + 1, family, ip); if (v_engine->rtcp_mux > 0) {
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtcp-mux\n");
} else {
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtcp:%d IN %s %s\n", v_port + 1, family, ip);
}
} }
//switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ssrc:%u\n", v_engine->ssrc); //switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ssrc:%u\n", v_engine->ssrc);
@ -5019,13 +5052,14 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=candidate:%s 2 %s %u %s %d typ host generation 0\n", switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=candidate:%s 2 %s %u %s %d typ host generation 0\n",
tmp1, ice_out->cands[0].transport, c2, tmp1, ice_out->cands[0].transport, c2,
ice_out->cands[0].con_addr, ice_out->cands[0].con_port + 1 ice_out->cands[0].con_addr, ice_out->cands[0].con_port + (v_engine->rtcp_mux > 0 ? 0 : 1)
); );
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=candidate:%s 2 %s %u %s %d typ srflx generation 0\n", switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=candidate:%s 2 %s %u %s %d typ srflx generation 0\n",
tmp2, ice_out->cands[0].transport, c4, tmp2, ice_out->cands[0].transport, c4,
ice_out->cands[0].con_addr, ice_out->cands[0].con_port + 1 ice_out->cands[0].con_addr, ice_out->cands[0].con_port + (v_engine->rtcp_mux > 0 ? 0 : 1)
); );

View File

@ -193,6 +193,7 @@ struct switch_rtp {
switch_sockaddr_t *remote_addr, *rtcp_remote_addr; switch_sockaddr_t *remote_addr, *rtcp_remote_addr;
rtp_msg_t recv_msg; rtp_msg_t recv_msg;
rtcp_msg_t rtcp_recv_msg; rtcp_msg_t rtcp_recv_msg;
rtcp_msg_t *rtcp_recv_msg_p;
switch_sockaddr_t *remote_stun_addr; switch_sockaddr_t *remote_stun_addr;
@ -1115,7 +1116,7 @@ static int check_srtp_and_ice(switch_rtp_t *rtp_session)
} }
} }
if (rtp_session->rtcp_ice.ice_user && !rtp_session->rtcp_ice.ready) { if (rtp_session->rtcp_ice.ice_user && !rtp_session->rtcp_ice.rready) {
rtcp_ok = 0; rtcp_ok = 0;
} }
@ -1124,7 +1125,6 @@ static int check_srtp_and_ice(switch_rtp_t *rtp_session)
rtp_session->rtcp_interval && (rtp_session->stats.read_count % rtp_session->rtcp_interval) == 0) { rtp_session->rtcp_interval && (rtp_session->stats.read_count % rtp_session->rtcp_interval) == 0) {
struct switch_rtcp_senderinfo *sr = (struct switch_rtcp_senderinfo*) rtp_session->rtcp_send_msg.body; struct switch_rtcp_senderinfo *sr = (struct switch_rtcp_senderinfo*) rtp_session->rtcp_send_msg.body;
const char* str_cname=NULL; const char* str_cname=NULL;
//rtp_msg_t *send_msg = &rtp_session->send_msg; //rtp_msg_t *send_msg = &rtp_session->send_msg;
switch_size_t rtcp_bytes; switch_size_t rtcp_bytes;
switch_byte_t *ptr = (switch_byte_t *)rtp_session->rtcp_send_msg.body; switch_byte_t *ptr = (switch_byte_t *)rtp_session->rtcp_send_msg.body;
@ -1237,9 +1237,9 @@ static int check_srtp_and_ice(switch_rtp_t *rtp_session)
rtcp_bytes = sbytes; rtcp_bytes = sbytes;
} }
#endif #endif
if (switch_socket_sendto(rtp_session->rtcp_sock_output, rtp_session->rtcp_remote_addr, 0,
(void *)&rtp_session->rtcp_send_msg, &rtcp_bytes ) != SWITCH_STATUS_SUCCESS) {
if (switch_socket_sendto(rtp_session->rtcp_sock_output, rtp_session->rtcp_remote_addr, 0, (void *)&rtp_session->rtcp_send_msg, &rtcp_bytes ) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG,"RTCP packet not written\n"); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG,"RTCP packet not written\n");
} else { } else {
rtp_session->stats.inbound.period_packet_count = 0; rtp_session->stats.inbound.period_packet_count = 0;
@ -1719,14 +1719,19 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_udptl_mode(switch_rtp_t *rtp_session)
switch_socket_shutdown(rtp_session->rtcp_sock_output, SWITCH_SHUTDOWN_READWRITE); switch_socket_shutdown(rtp_session->rtcp_sock_output, SWITCH_SHUTDOWN_READWRITE);
} }
if ((sock = rtp_session->rtcp_sock_input)) { if (rtp_session->flags[SWITCH_RTP_FLAG_RTCP_MUX]) {
rtp_session->rtcp_sock_input = NULL; rtp_session->rtcp_sock_input = NULL;
switch_socket_close(sock); rtp_session->rtcp_sock_output = NULL;
} else {
if (rtp_session->rtcp_sock_output && rtp_session->rtcp_sock_output != sock) { if ((sock = rtp_session->rtcp_sock_input)) {
if ((sock = rtp_session->rtcp_sock_output)) { rtp_session->rtcp_sock_input = NULL;
rtp_session->rtcp_sock_output = NULL; switch_socket_close(sock);
switch_socket_close(sock);
if (rtp_session->rtcp_sock_output && rtp_session->rtcp_sock_output != sock) {
if ((sock = rtp_session->rtcp_sock_output)) {
rtp_session->rtcp_sock_output = NULL;
switch_socket_close(sock);
}
} }
} }
} }
@ -2417,7 +2422,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t *
return SWITCH_STATUS_FALSE; return SWITCH_STATUS_FALSE;
} }
SWITCH_DECLARE(switch_status_t) switch_rtp_activate_rtcp(switch_rtp_t *rtp_session, int send_rate, switch_port_t remote_port) SWITCH_DECLARE(switch_status_t) switch_rtp_activate_rtcp(switch_rtp_t *rtp_session, int send_rate, switch_port_t remote_port, switch_bool_t mux)
{ {
const char *err = NULL; const char *err = NULL;
@ -2430,6 +2435,11 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_rtcp(switch_rtp_t *rtp_sessi
if (!(rtp_session->remote_rtcp_port = remote_port)) { if (!(rtp_session->remote_rtcp_port = remote_port)) {
rtp_session->remote_rtcp_port = rtp_session->remote_port + 1; rtp_session->remote_rtcp_port = rtp_session->remote_port + 1;
} }
if (mux) {
rtp_session->flags[SWITCH_RTP_FLAG_RTCP_MUX]++;
}
if (send_rate == -1) { if (send_rate == -1) {
@ -2437,11 +2447,29 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_rtcp(switch_rtp_t *rtp_sessi
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG, "RTCP passthru enabled. Remote Port: %d\n", rtp_session->remote_rtcp_port); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG, "RTCP passthru enabled. Remote Port: %d\n", rtp_session->remote_rtcp_port);
} else { } else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG, "RTCP send rate is: %d and packet rate is: %d Remote Port: %d\n", switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG, "RTCP send rate is: %d and packet rate is: %d Remote Port: %d\n", send_rate, rtp_session->ms_per_packet, rtp_session->remote_rtcp_port);
send_rate, rtp_session->ms_per_packet, rtp_session->remote_rtcp_port);
rtp_session->rtcp_interval = send_rate/(rtp_session->ms_per_packet/1000); rtp_session->rtcp_interval = send_rate/(rtp_session->ms_per_packet/1000);
} }
if (rtp_session->flags[SWITCH_RTP_FLAG_RTCP_MUX]) {
if (switch_sockaddr_info_get(&rtp_session->rtcp_remote_addr, rtp_session->eff_remote_host_str, SWITCH_UNSPEC,
rtp_session->remote_rtcp_port, 0, rtp_session->pool) != SWITCH_STATUS_SUCCESS || !rtp_session->rtcp_remote_addr) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "RTCP MUX Remote Address Error!");
return SWITCH_STATUS_FALSE;
}
rtp_session->rtcp_local_addr = rtp_session->local_addr;
rtp_session->rtcp_sock_input = rtp_session->sock_input;
rtp_session->rtcp_sock_output = rtp_session->rtcp_sock_output;
rtp_session->rtcp_recv_msg_p = (rtcp_msg_t *) &rtp_session->recv_msg;
return enable_remote_rtcp_socket(rtp_session, &err);
} else {
rtp_session->rtcp_recv_msg_p = (rtcp_msg_t *) &rtp_session->rtcp_recv_msg;
}
return enable_local_rtcp_socket(rtp_session, &err) || enable_remote_rtcp_socket(rtp_session, &err); return enable_local_rtcp_socket(rtp_session, &err) || enable_remote_rtcp_socket(rtp_session, &err);
} }
@ -3100,6 +3128,18 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
*bytes = sizeof(rtp_msg_t); *bytes = sizeof(rtp_msg_t);
status = switch_socket_recvfrom(rtp_session->from_addr, rtp_session->sock_input, 0, (void *) &rtp_session->recv_msg, bytes); status = switch_socket_recvfrom(rtp_session->from_addr, rtp_session->sock_input, 0, (void *) &rtp_session->recv_msg, bytes);
if (status == SWITCH_STATUS_SUCCESS && *bytes && rtp_session->flags[SWITCH_RTP_FLAG_RTCP_MUX]) {
if (rtp_session->recv_msg.header.pt != rtp_session->rpayload && (!rtp_session->recv_te || rtp_session->recv_msg.header.pt != rtp_session->recv_te) &&
(!rtp_session->cng_pt || rtp_session->recv_msg.header.pt != rtp_session->cng_pt) &&
rtp_session->rtcp_recv_msg_p->header.version == 2 &&
rtp_session->rtcp_recv_msg_p->header.type > 199 && rtp_session->rtcp_recv_msg_p->header.type < 300) { //rtcp muxed
*flags |= SFF_RTCP;
return SWITCH_STATUS_SUCCESS;
}
}
ts = ntohl(rtp_session->recv_msg.header.ts); ts = ntohl(rtp_session->recv_msg.header.ts);
rtp_session->recv_msg.ebody = NULL; rtp_session->recv_msg.ebody = NULL;
@ -3171,6 +3211,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
if (*bytes) { if (*bytes) {
rtp_session->stats.inbound.raw_bytes += *bytes; rtp_session->stats.inbound.raw_bytes += *bytes;
if (rtp_session->recv_te && rtp_session->recv_msg.header.pt == rtp_session->recv_te) { if (rtp_session->recv_te && rtp_session->recv_msg.header.pt == rtp_session->recv_te) {
@ -3241,9 +3282,9 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
if (++rtp_session->srtp_errs >= MAX_SRTP_ERRS) { if (++rtp_session->srtp_errs >= MAX_SRTP_ERRS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR,
"Error: SRTP %s unprotect failed with code %d%s\n", rtp_type(rtp_session), stat, "Error: SRTP %s unprotect failed with code %d%s %ld\n", rtp_type(rtp_session), stat,
stat == err_status_replay_fail ? " (replay check failed)" : stat == stat == err_status_replay_fail ? " (replay check failed)" : stat ==
err_status_auth_fail ? " (auth check failed)" : ""); err_status_auth_fail ? " (auth check failed)" : "", *bytes);
return SWITCH_STATUS_FALSE; return SWITCH_STATUS_FALSE;
} else { } else {
sbytes = 0; sbytes = 0;
@ -3318,6 +3359,61 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
return status; return status;
} }
static switch_status_t process_rtcp_packet(switch_rtp_t *rtp_session, switch_size_t *bytes)
{
switch_status_t status = SWITCH_STATUS_FALSE;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG10,"Received an RTCP packet of length %" SWITCH_SIZE_T_FMT " bytes\n", *bytes);
if (rtp_session->rtcp_recv_msg_p->header.version == 2) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG10,"RTCP packet type is %d\n", rtp_session->rtcp_recv_msg_p->header.type);
if (rtp_session->rtcp_recv_msg_p->header.type == 200) {
struct switch_rtcp_senderinfo* sr = (struct switch_rtcp_senderinfo*)rtp_session->rtcp_recv_msg_p->body;
rtp_session->rtcp_fresh_frame = 1;
rtp_session->stats.rtcp.packet_count += ntohl(sr->pc);
rtp_session->stats.rtcp.octet_count += ntohl(sr->oc);
rtp_session->stats.rtcp.peer_ssrc = ntohl(sr->ssrc);
/* sender report */
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG10,"Received a SR with %d report blocks, " \
"length in words = %d, " \
"SSRC = 0x%X, " \
"NTP MSW = %u, " \
"NTP LSW = %u, " \
"RTP timestamp = %u, " \
"Sender Packet Count = %u, " \
"Sender Octet Count = %u\n",
rtp_session->rtcp_recv_msg_p->header.count,
ntohs((uint16_t)rtp_session->rtcp_recv_msg_p->header.length),
ntohl(sr->ssrc),
ntohl(sr->ntp_msw),
ntohl(sr->ntp_lsw),
ntohl(sr->ts),
ntohl(sr->pc),
ntohl(sr->oc));
}
} else {
if (rtp_session->rtcp_recv_msg_p->header.version != 2) {
if (rtp_session->rtcp_recv_msg_p->header.version == 0) {
if (rtp_session->ice.ice_user) {
handle_ice(rtp_session, &rtp_session->rtcp_ice, (void *) rtp_session->rtcp_recv_msg_p, *bytes);
}
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session),
SWITCH_LOG_DEBUG, "Received an unsupported RTCP packet version %d\nn", rtp_session->rtcp_recv_msg_p->header.version);
}
}
status = SWITCH_STATUS_SUCCESS;
}
return status;
}
static switch_status_t read_rtcp_packet(switch_rtp_t *rtp_session, switch_size_t *bytes, switch_frame_flag_t *flags) 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; switch_status_t status = SWITCH_STATUS_FALSE;
@ -3329,20 +3425,21 @@ static switch_status_t read_rtcp_packet(switch_rtp_t *rtp_session, switch_size_t
switch_assert(bytes); switch_assert(bytes);
*bytes = sizeof(rtcp_msg_t); *bytes = sizeof(rtcp_msg_t);
if ((status = switch_socket_recvfrom(rtp_session->rtcp_from_addr, rtp_session->rtcp_sock_input, 0, (void *) &rtp_session->rtcp_recv_msg, bytes))
if ((status = switch_socket_recvfrom(rtp_session->rtcp_from_addr, rtp_session->rtcp_sock_input, 0, (void *) rtp_session->rtcp_recv_msg_p, bytes))
!= SWITCH_STATUS_SUCCESS) { != SWITCH_STATUS_SUCCESS) {
*bytes = 0; *bytes = 0;
} }
#ifdef ENABLE_SRTP #ifdef ENABLE_SRTP
if (rtp_session->flags[SWITCH_RTP_FLAG_SECURE_RECV] && rtp_session->rtcp_recv_msg.header.version == 2 && rtp_session->srtp_errs > 1) { if (rtp_session->flags[SWITCH_RTP_FLAG_SECURE_RECV] && rtp_session->rtcp_recv_msg_p->header.version == 2 && rtp_session->srtp_errs > 1) {
//if (rtp_session->flags[SWITCH_RTP_FLAG_SECURE_RECV] && (!rtp_session->ice.ice_user || rtp_session->rtcp_recv_msg.header.version == 2)) { //if (rtp_session->flags[SWITCH_RTP_FLAG_SECURE_RECV] && (!rtp_session->ice.ice_user || rtp_session->rtcp_recv_msg_p->header.version == 2)) {
int sbytes = (int) *bytes; int sbytes = (int) *bytes;
err_status_t stat = 0; err_status_t stat = 0;
if ((stat = srtp_unprotect_rtcp(rtp_session->recv_ctx, &rtp_session->rtcp_recv_msg.header, &sbytes))) { if ((stat = srtp_unprotect_rtcp(rtp_session->recv_ctx, &rtp_session->rtcp_recv_msg_p->header, &sbytes))) {
if (++rtp_session->srtp_errs > 1) { if (++rtp_session->srtp_errs > 1) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "Disable Secure RTP due to unprotect error.\n"); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "Disable Secure RTP due to unprotect error.\n");
} }
@ -3357,13 +3454,13 @@ static switch_status_t read_rtcp_packet(switch_rtp_t *rtp_session, switch_size_t
#ifdef ENABLE_ZRTP #ifdef ENABLE_ZRTP
if (zrtp_on && !rtp_session->flags[SWITCH_RTP_FLAG_PROXY_MEDIA]) { if (zrtp_on && !rtp_session->flags[SWITCH_RTP_FLAG_PROXY_MEDIA] && rtp_session->rtcp_recv_msg_p->header.version == 2) {
/* ZRTP Recv */ /* ZRTP Recv */
if (bytes) { if (bytes) {
unsigned int sbytes = (int) *bytes; unsigned int sbytes = (int) *bytes;
zrtp_status_t stat = 0; zrtp_status_t stat = 0;
stat = zrtp_process_srtcp(rtp_session->zrtp_stream, (void *) &rtp_session->rtcp_recv_msg, &sbytes); stat = zrtp_process_srtcp(rtp_session->zrtp_stream, (void *) rtp_session->rtcp_recv_msg_p, &sbytes);
switch (stat) { switch (stat) {
case zrtp_status_ok: case zrtp_status_ok:
@ -3386,52 +3483,7 @@ static switch_status_t read_rtcp_packet(switch_rtp_t *rtp_session, switch_size_t
if (*bytes) { if (*bytes) {
return process_rtcp_packet(rtp_session, bytes);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG10,"Received an RTCP packet of length %" SWITCH_SIZE_T_FMT " bytes\n", *bytes);
if (rtp_session->rtcp_recv_msg.header.version == 2) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG10,"RTCP packet type is %d\n", rtp_session->rtcp_recv_msg.header.type);
if (rtp_session->rtcp_recv_msg.header.type == 200) {
struct switch_rtcp_senderinfo* sr = (struct switch_rtcp_senderinfo*)rtp_session->rtcp_recv_msg.body;
rtp_session->rtcp_fresh_frame = 1;
rtp_session->stats.rtcp.packet_count += ntohl(sr->pc);
rtp_session->stats.rtcp.octet_count += ntohl(sr->oc);
rtp_session->stats.rtcp.peer_ssrc = ntohl(sr->ssrc);
/* sender report */
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG10,"Received a SR with %d report blocks, " \
"length in words = %d, " \
"SSRC = 0x%X, " \
"NTP MSW = %u, " \
"NTP LSW = %u, " \
"RTP timestamp = %u, " \
"Sender Packet Count = %u, " \
"Sender Octet Count = %u\n",
rtp_session->rtcp_recv_msg.header.count,
ntohs((uint16_t)rtp_session->rtcp_recv_msg.header.length),
ntohl(sr->ssrc),
ntohl(sr->ntp_msw),
ntohl(sr->ntp_lsw),
ntohl(sr->ts),
ntohl(sr->pc),
ntohl(sr->oc));
}
} else {
if (rtp_session->rtcp_recv_msg.header.version != 2) {
if (rtp_session->rtcp_recv_msg.header.version == 0) {
if (rtp_session->ice.ice_user) {
handle_ice(rtp_session, &rtp_session->rtcp_ice, (void *) &rtp_session->rtcp_recv_msg, *bytes);
}
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session),
SWITCH_LOG_DEBUG, "Received an unsupported RTCP packet version %d\nn", rtp_session->rtcp_recv_msg.header.version);
}
}
status = SWITCH_STATUS_SUCCESS;
}
} }
return status; return status;
@ -3476,6 +3528,8 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
while (switch_rtp_ready(rtp_session)) { while (switch_rtp_ready(rtp_session)) {
int do_cng = 0; int do_cng = 0;
int read_pretriggered = 0; int read_pretriggered = 0;
int has_rtcp = 0;
bytes = 0; bytes = 0;
if (rtp_session->flags[SWITCH_RTP_FLAG_USE_TIMER]) { if (rtp_session->flags[SWITCH_RTP_FLAG_USE_TIMER]) {
@ -3486,6 +3540,12 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
rtp_session->read_pollfd) { rtp_session->read_pollfd) {
if (switch_poll(rtp_session->read_pollfd, 1, &fdr, 0) == SWITCH_STATUS_SUCCESS) { if (switch_poll(rtp_session->read_pollfd, 1, &fdr, 0) == SWITCH_STATUS_SUCCESS) {
status = read_rtp_packet(rtp_session, &bytes, flags, SWITCH_FALSE); status = read_rtp_packet(rtp_session, &bytes, flags, SWITCH_FALSE);
if ((*flags & SFF_RTCP)) {
*flags &= ~SFF_RTCP;
has_rtcp = 1;
goto rtcp;
}
/* switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG, "Initial (%i) %d\n", status, bytes); */ /* switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG, "Initial (%i) %d\n", status, bytes); */
if (status != SWITCH_STATUS_FALSE) { if (status != SWITCH_STATUS_FALSE) {
read_pretriggered = 1; read_pretriggered = 1;
@ -3539,6 +3599,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
recvfrom: recvfrom:
rtp_session->stats.read_count++; rtp_session->stats.read_count++;
if (!read_pretriggered) { if (!read_pretriggered) {
@ -3567,7 +3628,6 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
poll_status = switch_poll(rtp_session->read_pollfd, 1, &fdr, pt); poll_status = switch_poll(rtp_session->read_pollfd, 1, &fdr, pt);
if (rtp_session->dtmf_data.out_digit_dur > 0) { if (rtp_session->dtmf_data.out_digit_dur > 0) {
return_cng_frame(); return_cng_frame();
} }
@ -3580,6 +3640,11 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
read_pretriggered = 0; read_pretriggered = 0;
} else { } else {
status = read_rtp_packet(rtp_session, &bytes, flags, SWITCH_TRUE); status = read_rtp_packet(rtp_session, &bytes, flags, SWITCH_TRUE);
if ((*flags & SFF_RTCP)) {
*flags &= ~SFF_RTCP;
has_rtcp = 1;
goto rtcp;
}
//switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG, "Read bytes (%i) %ld\n", status, bytes); //switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG, "Read bytes (%i) %ld\n", status, bytes);
} }
poll_loop = 0; poll_loop = 0;
@ -3649,18 +3714,35 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
} }
} }
rtcp:
if (rtp_session->flags[SWITCH_RTP_FLAG_ENABLE_RTCP] && rtp_session->rtcp_read_pollfd) {
rtcp_poll_status = switch_poll(rtp_session->rtcp_read_pollfd, 1, &rtcp_fdr, 0);
if (bytes && rtp_session->flags[SWITCH_RTP_FLAG_ENABLE_RTCP]) {
rtcp_poll_status = SWITCH_STATUS_FALSE;
if (rtp_session->flags[SWITCH_RTP_FLAG_RTCP_MUX] && has_rtcp) {
if (rtp_session->rtcp_recv_msg_p->header.version == 2) { //rtcp muxed
rtcp_status = rtcp_poll_status = SWITCH_STATUS_SUCCESS;
rtcp_bytes = bytes;
}
has_rtcp = 0;
} else if (rtp_session->rtcp_read_pollfd) {
rtcp_poll_status = switch_poll(rtp_session->rtcp_read_pollfd, 1, &rtcp_fdr, 0);
}
if (rtcp_poll_status == SWITCH_STATUS_SUCCESS) { if (rtcp_poll_status == SWITCH_STATUS_SUCCESS) {
rtcp_status = read_rtcp_packet(rtp_session, &rtcp_bytes, flags);
if (!rtp_session->flags[SWITCH_RTP_FLAG_RTCP_MUX]) {
rtcp_status = read_rtcp_packet(rtp_session, &rtcp_bytes, flags);
}
if (rtcp_status == SWITCH_STATUS_SUCCESS) { if (rtcp_status == SWITCH_STATUS_SUCCESS) {
switch_rtp_reset_media_timer(rtp_session); switch_rtp_reset_media_timer(rtp_session);
if (rtp_session->flags[SWITCH_RTP_FLAG_RTCP_PASSTHRU]) { if (rtp_session->flags[SWITCH_RTP_FLAG_RTCP_PASSTHRU]) {
switch_channel_t *channel = switch_core_session_get_channel(rtp_session->session); switch_channel_t *channel = switch_core_session_get_channel(rtp_session->session);
const char *uuid = switch_channel_get_partner_uuid(channel); const char *uuid = switch_channel_get_partner_uuid(channel);
@ -3673,7 +3755,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
if ((other_rtp_session = switch_channel_get_private(other_channel, "__rtcp_audio_rtp_session")) && if ((other_rtp_session = switch_channel_get_private(other_channel, "__rtcp_audio_rtp_session")) &&
other_rtp_session->rtcp_sock_output && other_rtp_session->rtcp_sock_output &&
switch_rtp_test_flag(other_rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP)) { switch_rtp_test_flag(other_rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP)) {
*other_rtp_session->rtcp_send_msg.body = *rtp_session->rtcp_recv_msg.body; *other_rtp_session->rtcp_send_msg.body = *rtp_session->rtcp_recv_msg_p->body;
#ifdef ENABLE_SRTP #ifdef ENABLE_SRTP
if (switch_rtp_test_flag(other_rtp_session, SWITCH_RTP_FLAG_SECURE_SEND)) { if (switch_rtp_test_flag(other_rtp_session, SWITCH_RTP_FLAG_SECURE_SEND)) {
@ -3727,12 +3809,16 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
} }
} }
if (rtp_session->flags[SWITCH_RTP_FLAG_RTCP_MUX]) {
process_rtcp_packet(rtp_session, &bytes);
ret = 1;
goto end;
}
} }
} }
} }
if (bytes && rtp_session->recv_msg.header.version == 2 && if (bytes && rtp_session->recv_msg.header.version == 2 &&
!rtp_session->flags[SWITCH_RTP_FLAG_PROXY_MEDIA] && !rtp_session->flags[SWITCH_RTP_FLAG_UDPTL] && !rtp_session->flags[SWITCH_RTP_FLAG_PROXY_MEDIA] && !rtp_session->flags[SWITCH_RTP_FLAG_UDPTL] &&
rtp_session->recv_msg.header.pt != 13 && rtp_session->recv_msg.header.pt != 13 &&
@ -4179,15 +4265,17 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_read(switch_rtp_t *rtp_session, void
SWITCH_DECLARE(switch_status_t) switch_rtcp_zerocopy_read_frame(switch_rtp_t *rtp_session, switch_rtcp_frame_t *frame) SWITCH_DECLARE(switch_status_t) switch_rtcp_zerocopy_read_frame(switch_rtp_t *rtp_session, switch_rtcp_frame_t *frame)
{ {
if (!rtp_session->flags[SWITCH_RTP_FLAG_ENABLE_RTCP]) { if (!rtp_session->flags[SWITCH_RTP_FLAG_ENABLE_RTCP]) {
return SWITCH_STATUS_FALSE; return SWITCH_STATUS_FALSE;
} }
/* A fresh frame has been found! */ /* A fresh frame has been found! */
if (rtp_session->rtcp_fresh_frame) { if (rtp_session->rtcp_fresh_frame) {
struct switch_rtcp_senderinfo* sr = (struct switch_rtcp_senderinfo*)rtp_session->rtcp_recv_msg.body; struct switch_rtcp_senderinfo* sr = (struct switch_rtcp_senderinfo*)rtp_session->rtcp_recv_msg_p->body;
/* we remove the header lenght because with directly have a pointer on the body */ /* we remove the header lenght because with directly have a pointer on the body */
unsigned packet_length = (ntohs((uint16_t) rtp_session->rtcp_recv_msg.header.length) + 1) * 4 - sizeof(switch_rtcp_hdr_t); unsigned packet_length = (ntohs((uint16_t) rtp_session->rtcp_recv_msg_p->header.length) + 1) * 4 - sizeof(switch_rtcp_hdr_t);
unsigned int reportsOffset = sizeof(struct switch_rtcp_senderinfo); unsigned int reportsOffset = sizeof(struct switch_rtcp_senderinfo);
int i = 0; int i = 0;
unsigned int offset; unsigned int offset;
@ -4196,7 +4284,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtcp_zerocopy_read_frame(switch_rtp_t *rt
rtp_session->rtcp_fresh_frame = 0; rtp_session->rtcp_fresh_frame = 0;
frame->ssrc = ntohl(sr->ssrc); frame->ssrc = ntohl(sr->ssrc);
frame->packet_type = (uint16_t)rtp_session->rtcp_recv_msg.header.type; frame->packet_type = (uint16_t)rtp_session->rtcp_recv_msg_p->header.type;
frame->ntp_msw = ntohl(sr->ntp_msw); frame->ntp_msw = ntohl(sr->ntp_msw);
frame->ntp_lsw = ntohl(sr->ntp_lsw); frame->ntp_lsw = ntohl(sr->ntp_lsw);
frame->timestamp = ntohl(sr->ts); frame->timestamp = ntohl(sr->ts);
@ -4204,7 +4292,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtcp_zerocopy_read_frame(switch_rtp_t *rt
frame->octect_count = ntohl(sr->oc); frame->octect_count = ntohl(sr->oc);
for (offset = reportsOffset; offset < packet_length; offset += sizeof(struct switch_rtcp_report_block)) { for (offset = reportsOffset; offset < packet_length; offset += sizeof(struct switch_rtcp_report_block)) {
struct switch_rtcp_report_block* report = (struct switch_rtcp_report_block*) (rtp_session->rtcp_recv_msg.body + offset); struct switch_rtcp_report_block* report = (struct switch_rtcp_report_block*) (rtp_session->rtcp_recv_msg_p->body + offset);
frame->reports[i].ssrc = ntohl(report->ssrc); frame->reports[i].ssrc = ntohl(report->ssrc);
frame->reports[i].fraction = (uint8_t)ntohl(report->fraction); frame->reports[i].fraction = (uint8_t)ntohl(report->fraction);
frame->reports[i].lost = ntohl(report->lost); frame->reports[i].lost = ntohl(report->lost);