#define MS_CLASS "RTC::RTCP::XR"
#include "Logger.hpp"
#include "Utils.hpp"
#include "RTC/RTCP/XrDelaySinceLastRr.hpp"
#include "RTC/RTCP/XrReceiverReferenceTime.hpp"
namespace RTC
{
namespace RTCP
{
ExtendedReportBlock* ExtendedReportBlock::Parse(const uint8_t* data, size_t len)
{
MS_TRACE();
auto* header = const_cast<CommonHeader*>(reinterpret_cast<const CommonHeader*>(data));
if (len < sizeof(CommonHeader))
{
MS_WARN_TAG(rtcp, "not enough space for a extended report block, report discarded");
return nullptr;
}
switch (ExtendedReportBlock::Type(header->blockType))
{
case RTC::RTCP::ExtendedReportBlock::Type::RRT:
{
return ReceiverReferenceTime::Parse(data, len);
}
case RTC::RTCP::ExtendedReportBlock::Type::DLRR:
{
return DelaySinceLastRr::Parse(data, len);
}
default:
{
MS_DEBUG_TAG(rtcp, "unknown RTCP XR block type [blockType:%" PRIu8 "]", header->blockType);
break;
}
}
return nullptr;
}
ExtendedReportPacket* ExtendedReportPacket::Parse(const uint8_t* data, size_t len)
{
MS_TRACE();
auto* header = const_cast<CommonHeader*>(reinterpret_cast<const CommonHeader*>(data));
if (len < sizeof(CommonHeader) + 4u)
{
MS_WARN_TAG(rtcp, "not enough space for a extended report packet, packet discarded");
return nullptr;
}
std::unique_ptr<ExtendedReportPacket> packet(new ExtendedReportPacket(header));
uint32_t ssrc =
Utils::Byte::Get4Bytes(reinterpret_cast<uint8_t*>(header), sizeof(CommonHeader));
packet->SetSsrc(ssrc);
auto offset = sizeof(Packet::CommonHeader) + 4u ;
while (len > offset)
{
ExtendedReportBlock* report = ExtendedReportBlock::Parse(data + offset, len - offset);
if (report)
{
packet->AddReport(report);
offset += report->GetSize();
}
else
{
return packet.release();
}
}
return packet.release();
}
size_t ExtendedReportPacket::Serialize(uint8_t* buffer)
{
MS_TRACE();
size_t offset = Packet::Serialize(buffer);
Utils::Byte::Set4Bytes(buffer, sizeof(CommonHeader), this->ssrc);
offset += 4u ;
for (auto* report : this->reports)
{
offset += report->Serialize(buffer + offset);
}
return offset;
}
void ExtendedReportPacket::Dump() const
{
MS_TRACE();
MS_DUMP("<ExtendedReportPacket>");
MS_DUMP(" ssrc: %" PRIu32, this->ssrc);
for (auto* report : this->reports)
{
report->Dump();
}
MS_DUMP("</ExtendedReportPacket>");
}
} }