rtcp: Use a common function for rtcp packet header construction

This commit removes little bit of duplicate code, making future bug
fixes easier. The length of the packet is not set correctly, but that
will bi fixed in future.
This commit is contained in:
Joni Räsänen 2021-06-08 10:32:21 +03:00
parent 06f2f20384
commit 6449f9d614
7 changed files with 43 additions and 45 deletions

View File

@ -353,6 +353,10 @@ namespace uvgrtp {
* must be set to zero manually */
void zero_stats(uvgrtp::rtcp_statistics *stats);
/* Set the first four or eight bytes of an RTCP packet */
rtp_error_t construct_rtcp_header(size_t packet_size, uint8_t*& frame,
uint16_t secondField, uvgrtp::frame::RTCP_FRAME_TYPE frame_type, bool addLocalSSRC);
/* Pointer to RTP context from which clock rate etc. info is collected and which is
* used to change SSRC if a collision is detected */
uvgrtp::rtp *rtp_;

View File

@ -5,6 +5,7 @@
#include "debug.hh"
#include "util.hh"
#include "rtp.hh"
#include "frame.hh"
#ifndef _WIN32
#include <sys/time.h>
@ -522,3 +523,34 @@ rtp_error_t uvgrtp::rtcp::handle_incoming_packet(uint8_t *buffer, size_t size)
return ret;
}
rtp_error_t uvgrtp::rtcp::construct_rtcp_header(size_t packet_size,
uint8_t*& frame,
uint16_t secondField,
uvgrtp::frame::RTCP_FRAME_TYPE frame_type,
bool add_local_ssrc
)
{
if (packet_size > UINT16_MAX)
{
LOG_ERROR("RTCP receiver report packet size too large!");
return RTP_GENERIC_ERROR;
}
frame = new uint8_t[packet_size];
memset(frame, 0, packet_size);
// header |V=2|P| SC | PT | length |
frame[0] = (2 << 6) | (0 << 5) | secondField;
frame[1] = frame_type;
// TODO: This should be size in 32-bit words - 1
*(uint16_t*)&frame[2] = htons((u_short)packet_size);
if (add_local_ssrc)
{
*(uint32_t*)&frame[4] = htonl(ssrc_);
}
return RTP_OK;
}

View File

@ -69,7 +69,8 @@ rtp_error_t uvgrtp::rtcp::handle_app_packet(uint8_t *packet, size_t size)
return RTP_OK;
}
rtp_error_t uvgrtp::rtcp::send_app_packet(char *name, uint8_t subtype, size_t payload_len, uint8_t *payload)
rtp_error_t uvgrtp::rtcp::send_app_packet(char *name, uint8_t subtype,
size_t payload_len, uint8_t *payload)
{
size_t frame_size;
rtp_error_t ret = RTP_OK;
@ -80,14 +81,7 @@ rtp_error_t uvgrtp::rtcp::send_app_packet(char *name, uint8_t subtype, size_t pa
frame_size += 4; /* name */
frame_size += payload_len;
frame = new uint8_t[frame_size];
memset(frame, 0, frame_size);
frame[0] = (2 << 6) | (0 << 5) | (subtype & 0x1f);
frame[1] = (uint8_t)uvgrtp::frame::RTCP_FT_APP;
*(uint16_t *)&frame[2] = htons((u_short)frame_size);
*(uint32_t *)&frame[4] = htonl(ssrc_);
construct_rtcp_header(frame_size, frame, (subtype & 0x1f), uvgrtp::frame::RTCP_FT_APP, true);
memcpy(&frame[ 8], name, 4);
memcpy(&frame[12], payload, payload_len);

View File

@ -37,11 +37,7 @@ rtp_error_t uvgrtp::rtcp::send_bye_packet(std::vector<uint32_t> ssrcs)
frame_size = 4; /* rtcp header */
frame_size += ssrcs.size() * sizeof(uint32_t);
frame = new uint8_t[frame_size];
memset(frame, 0, frame_size);
frame[0] = (2 << 6) | (0 << 5) | (ssrcs.size() & 0x1f);
frame[1] = uvgrtp::frame::RTCP_FT_BYE;
construct_rtcp_header(frame_size, frame, (ssrcs.size() & 0x1f), uvgrtp::frame::RTCP_FT_BYE, false);
for (auto& ssrc : ssrcs)
SET_NEXT_FIELD_32(frame, ptr, htonl(ssrc));

View File

@ -109,23 +109,10 @@ rtp_error_t uvgrtp::rtcp::generate_receiver_report()
frame_size += 4; /* our ssrc */
frame_size += (size_t)num_receivers_ * 24; /* report blocks */
if (frame_size > UINT16_MAX)
{
LOG_ERROR("RTCP receiver report packet size too large!");
return RTP_GENERIC_ERROR;
}
if (flags_ & RCE_SRTP)
frame_size += UVG_SRTCP_INDEX_LENGTH + UVG_AUTH_TAG_LENGTH;
frame = new uint8_t[frame_size];
memset(frame, 0, frame_size);
frame[0] = (2 << 6) | (0 << 5) | num_receivers_;
frame[1] = uvgrtp::frame::RTCP_FT_RR;
*(uint16_t *)&frame[2] = htons((u_short)frame_size);
*(uint32_t *)&frame[4] = htonl(ssrc_);
construct_rtcp_header(frame_size, frame, num_receivers_, uvgrtp::frame::RTCP_FT_RR, true);
LOG_DEBUG("Receiver Report from 0x%x has %zu blocks", ssrc_, num_receivers_);

View File

@ -103,15 +103,7 @@ rtp_error_t uvgrtp::rtcp::send_sdes_packet(std::vector<uvgrtp::frame::rtcp_sdes_
for (auto& item : items)
frame_size += item.length;
frame = new uint8_t[frame_size];
memset(frame, 0, frame_size);
// header |V=2|P| SC | PT=SDES=202 | length |
frame[0] = (2 << 6) | (0 << 5) | num_receivers_;
frame[1] = uvgrtp::frame::RTCP_FT_SDES;
*(uint16_t *)&frame[2] = htons((u_short)frame_size);
*(uint32_t *)&frame[4] = htonl(ssrc_);
construct_rtcp_header(frame_size, frame, num_receivers_, uvgrtp::frame::RTCP_FT_SDES, true);
for (auto& item : items) {
frame[ptr++] = item.type;

View File

@ -117,14 +117,7 @@ rtp_error_t uvgrtp::rtcp::generate_sender_report()
if (flags_ & RCE_SRTP)
frame_size += UVG_SRTCP_INDEX_LENGTH + UVG_AUTH_TAG_LENGTH;
frame = new uint8_t[frame_size];
memset(frame, 0, frame_size);
frame[0] = (2 << 6) | (0 << 5) | num_receivers_;
frame[1] = uvgrtp::frame::RTCP_FT_SR;
*(uint16_t *)&frame[2] = htons((u_short)frame_size);
*(uint32_t *)&frame[4] = htonl(ssrc_);
construct_rtcp_header(frame_size, frame, num_receivers_, uvgrtp::frame::RTCP_FT_SR, true);
/* Sender information */
ntp_ts = uvgrtp::clock::ntp::now();