#define MS_CLASS "RTC::RTCP::XrDelaySinceLastRr"
#include "RTC/RTCP/XrDelaySinceLastRr.hpp"
#include "Logger.hpp"
#include <cstring>
namespace RTC
{
namespace RTCP
{
DelaySinceLastRr::SsrcInfo* DelaySinceLastRr::SsrcInfo::Parse(const uint8_t* data, size_t len)
{
MS_TRACE();
if (len < sizeof(Body))
{
MS_WARN_TAG(rtcp, "not enough space for a extended DSLR sub-block, sub-block discarded");
return nullptr;
}
auto* body = const_cast<SsrcInfo::Body*>(reinterpret_cast<const SsrcInfo::Body*>(data));
auto* ssrcInfo = new DelaySinceLastRr::SsrcInfo(body);
return ssrcInfo;
}
void DelaySinceLastRr::SsrcInfo::Dump() const
{
MS_TRACE();
MS_DUMP(" <SsrcInfo>");
MS_DUMP(" ssrc : %" PRIu32, GetSsrc());
MS_DUMP(" lrr : %" PRIu32, GetLastReceiverReport());
MS_DUMP(" dlrr : %" PRIu32, GetDelaySinceLastReceiverReport());
MS_DUMP(" <SsrcInfo>");
}
size_t DelaySinceLastRr::SsrcInfo::Serialize(uint8_t* buffer)
{
MS_TRACE();
std::memcpy(buffer, this->body, sizeof(DelaySinceLastRr::SsrcInfo::Body));
return sizeof(DelaySinceLastRr::SsrcInfo::Body);
}
DelaySinceLastRr* DelaySinceLastRr::Parse(const uint8_t* data, size_t len)
{
MS_TRACE();
auto* header = const_cast<ExtendedReportBlock::CommonHeader*>(
reinterpret_cast<const ExtendedReportBlock::CommonHeader*>(data));
std::unique_ptr<DelaySinceLastRr> report(new DelaySinceLastRr(header));
size_t offset{ sizeof(ExtendedReportBlock::CommonHeader) };
uint16_t reportLength = ntohs(header->length) * 4;
while (len > offset && reportLength >= sizeof(DelaySinceLastRr::SsrcInfo::Body))
{
DelaySinceLastRr::SsrcInfo* ssrcInfo =
DelaySinceLastRr::SsrcInfo::Parse(data + offset, len - offset);
if (ssrcInfo)
{
report->AddSsrcInfo(ssrcInfo);
offset += ssrcInfo->GetSize();
}
else
{
return report.release();
}
offset += ssrcInfo->GetSize();
reportLength -= sizeof(DelaySinceLastRr::SsrcInfo::Body);
}
return report.release();
}
size_t DelaySinceLastRr::Serialize(uint8_t* buffer)
{
MS_TRACE();
size_t length = static_cast<uint16_t>((sizeof(SsrcInfo::Body) * this->ssrcInfos.size() / 4));
this->header->blockType = static_cast<uint8_t>(this->type);
this->header->reserved = 0;
this->header->length = uint16_t{ htons(length) };
std::memcpy(buffer, this->header, sizeof(ExtendedReportBlock::CommonHeader));
size_t offset{ sizeof(ExtendedReportBlock::CommonHeader) };
for (auto* ssrcInfo : this->ssrcInfos)
{
offset += ssrcInfo->Serialize(buffer + offset);
}
return offset;
}
void DelaySinceLastRr::Dump() const
{
MS_TRACE();
MS_DUMP("<DelaySinceLastRr>");
MS_DUMP(" block type : %" PRIu8, (uint8_t)this->type);
MS_DUMP(" reserved : 0");
MS_DUMP(
" length : %" PRIu16,
static_cast<uint16_t>((sizeof(SsrcInfo::Body) * this->ssrcInfos.size() / 4)));
for (auto* ssrcInfo : this->ssrcInfos)
{
ssrcInfo->Dump();
}
MS_DUMP("</DelaySinceLastRr>");
}
} }