#include "common.hpp"
#include "RTC/RTCP/XR.hpp"
#include "RTC/RTCP/XrDelaySinceLastRr.hpp"
#include "RTC/RTCP/XrReceiverReferenceTime.hpp"
#include <catch2/catch_test_macros.hpp>
#include <cstring>
SCENARIO("RTCP XR", "[rtcp][xr]")
{
alignas(4) uint8_t buffer[] =
{
0xa0, 0xcf, 0x00, 0x09, 0x5d, 0x93, 0x15, 0x34, 0x05, 0x00, 0x00, 0x06, 0x11, 0x12, 0x13, 0x14, 0x00, 0x11, 0x00, 0x11, 0x11, 0x00, 0x11, 0x00, 0x21, 0x22, 0x23, 0x24, 0x00, 0x22, 0x00, 0x22, 0x22, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x04 };
SECTION("alignof() RTCP structs")
{
REQUIRE(alignof(RTC::RTCP::ExtendedReportBlock::CommonHeader) == 2);
REQUIRE(alignof(RTC::RTCP::DelaySinceLastRr::SsrcInfo::Body) == 4);
REQUIRE(alignof(RTC::RTCP::ReceiverReferenceTime::Body) == 4);
}
SECTION("parse XR packet")
{
std::unique_ptr<RTC::RTCP::ExtendedReportPacket> packet(
RTC::RTCP::ExtendedReportPacket::Parse(buffer, sizeof(buffer)));
REQUIRE(packet);
REQUIRE(packet->GetSize() == 36);
REQUIRE(packet->GetCount() == 0);
REQUIRE(packet->GetSsrc() == 0x5d931534);
size_t blockIdx{ 0u };
for (auto it = packet->Begin(); it != packet->End(); ++it, ++blockIdx)
{
auto* block = *it;
switch (blockIdx)
{
case 0:
{
REQUIRE(block->GetSize() == 28);
size_t ssrcInfoIdx{ 0u };
auto* dlrrBlock = reinterpret_cast<RTC::RTCP::DelaySinceLastRr*>(block);
for (auto it2 = dlrrBlock->Begin(); it2 != dlrrBlock->End(); ++it2, ++ssrcInfoIdx)
{
auto* ssrcInfo = *it2;
switch (ssrcInfoIdx)
{
case 0:
{
REQUIRE(ssrcInfo->GetSsrc() == 0x11121314);
REQUIRE(ssrcInfo->GetLastReceiverReport() == 0x00110011);
REQUIRE(ssrcInfo->GetDelaySinceLastReceiverReport() == 0x11001100);
break;
}
case 1:
{
REQUIRE(ssrcInfo->GetSsrc() == 0x21222324);
REQUIRE(ssrcInfo->GetLastReceiverReport() == 0x00220022);
REQUIRE(ssrcInfo->GetDelaySinceLastReceiverReport() == 0x22002200);
break;
}
default:;
}
}
REQUIRE(ssrcInfoIdx == 2);
break;
}
default:;
}
}
REQUIRE(blockIdx == 1);
SECTION("serialize packet instance")
{
const size_t paddingBytes{ 4 };
const size_t serializedBufferLength = sizeof(buffer) - paddingBytes;
alignas(4) uint8_t serialized[serializedBufferLength] = { 0 };
alignas(4) uint8_t clonedBuffer[serializedBufferLength] = { 0 };
std::memcpy(clonedBuffer, buffer, serializedBufferLength);
clonedBuffer[0] = 0x80;
clonedBuffer[3] = clonedBuffer[3] - 1;
packet->Serialize(serialized);
std::unique_ptr<RTC::RTCP::ExtendedReportPacket> packet2(
RTC::RTCP::ExtendedReportPacket::Parse(serialized, serializedBufferLength));
REQUIRE(packet2->GetType() == RTC::RTCP::Type::XR);
REQUIRE(packet2->GetCount() == 0);
REQUIRE(packet2->GetSize() == 36);
REQUIRE(std::memcmp(clonedBuffer, serialized, serializedBufferLength) == 0);
}
}
}
SCENARIO("RTCP XrDelaySinceLastRt", "[rtcp][xr]")
{
SECTION("create RRT")
{
auto* report1 = new RTC::RTCP::ReceiverReferenceTime();
report1->SetNtpSec(11111111);
report1->SetNtpFrac(22222222);
REQUIRE(report1->GetType() == RTC::RTCP::ExtendedReportBlock::Type::RRT);
REQUIRE(report1->GetNtpSec() == 11111111);
REQUIRE(report1->GetNtpFrac() == 22222222);
alignas(4) uint8_t bufferReport1[256]{ 0 };
report1->Serialize(bufferReport1);
auto* report2 = RTC::RTCP::ReceiverReferenceTime::Parse(bufferReport1, report1->GetSize());
REQUIRE(report1->GetType() == report2->GetType());
REQUIRE(report1->GetNtpSec() == report2->GetNtpSec());
REQUIRE(report1->GetNtpFrac() == report2->GetNtpFrac());
std::unique_ptr<RTC::RTCP::ExtendedReportPacket> packet1(new RTC::RTCP::ExtendedReportPacket());
packet1->SetSsrc(2222);
packet1->AddReport(report1);
packet1->AddReport(report2);
REQUIRE(packet1->GetType() == RTC::RTCP::Type::XR);
REQUIRE(packet1->GetCount() == 0);
REQUIRE(packet1->GetSsrc() == 2222);
REQUIRE(packet1->GetSize() == 4 + 4 + 12 + 12);
alignas(4) uint8_t bufferPacket1[256]{ 0 };
alignas(4) uint8_t bufferPacket2[256]{ 0 };
packet1->Serialize(bufferPacket1);
std::unique_ptr<RTC::RTCP::ExtendedReportPacket> packet2(
RTC::RTCP::ExtendedReportPacket::Parse(bufferPacket1, packet1->GetSize()));
REQUIRE(packet2->GetType() == packet1->GetType());
REQUIRE(packet2->GetCount() == packet1->GetCount());
REQUIRE(packet2->GetSsrc() == packet1->GetSsrc());
REQUIRE(packet2->GetSize() == packet1->GetSize());
packet2->Serialize(bufferPacket2);
REQUIRE(std::memcmp(bufferPacket1, bufferPacket2, packet1->GetSize()) == 0);
}
SECTION("create DLRR")
{
auto* report1 = new RTC::RTCP::DelaySinceLastRr();
auto* ssrcInfo1 = new RTC::RTCP::DelaySinceLastRr::SsrcInfo();
ssrcInfo1->SetSsrc(1234);
ssrcInfo1->SetLastReceiverReport(11111111);
ssrcInfo1->SetDelaySinceLastReceiverReport(22222222);
REQUIRE(ssrcInfo1->GetSsrc() == 1234);
REQUIRE(ssrcInfo1->GetLastReceiverReport() == 11111111);
REQUIRE(ssrcInfo1->GetDelaySinceLastReceiverReport() == 22222222);
REQUIRE(ssrcInfo1->GetSize() == sizeof(RTC::RTCP::DelaySinceLastRr::SsrcInfo::Body));
report1->AddSsrcInfo(ssrcInfo1);
alignas(4) uint8_t bufferReport1[256]{ 0 };
report1->Serialize(bufferReport1);
auto* report2 = RTC::RTCP::DelaySinceLastRr::Parse(bufferReport1, report1->GetSize());
REQUIRE(report1->GetType() == report2->GetType());
auto ssrcInfoIt = report2->Begin();
auto* ssrcInfo2 = *ssrcInfoIt;
REQUIRE(ssrcInfo1->GetSsrc() == ssrcInfo2->GetSsrc());
REQUIRE(ssrcInfo1->GetLastReceiverReport() == ssrcInfo2->GetLastReceiverReport());
REQUIRE(
ssrcInfo1->GetDelaySinceLastReceiverReport() == ssrcInfo2->GetDelaySinceLastReceiverReport());
REQUIRE(ssrcInfo1->GetSize() == ssrcInfo2->GetSize());
std::unique_ptr<RTC::RTCP::ExtendedReportPacket> packet1(new RTC::RTCP::ExtendedReportPacket());
packet1->SetSsrc(2222);
packet1->AddReport(report1);
packet1->AddReport(report2);
REQUIRE(packet1->GetType() == RTC::RTCP::Type::XR);
REQUIRE(packet1->GetCount() == 0);
REQUIRE(packet1->GetSsrc() == 2222);
REQUIRE(packet1->GetSize() == 4 + 4 + 16 + 16);
alignas(4) uint8_t bufferPacket1[256]{ 0 };
alignas(4) uint8_t bufferPacket2[256]{ 0 };
packet1->Serialize(bufferPacket1);
std::unique_ptr<RTC::RTCP::ExtendedReportPacket> packet2(
RTC::RTCP::ExtendedReportPacket::Parse(bufferPacket1, packet1->GetSize()));
REQUIRE(packet2->GetType() == packet1->GetType());
REQUIRE(packet2->GetCount() == packet1->GetCount());
REQUIRE(packet2->GetSsrc() == packet1->GetSsrc());
REQUIRE(packet2->GetSize() == packet1->GetSize());
packet2->Serialize(bufferPacket2);
REQUIRE(std::memcmp(bufferPacket1, bufferPacket2, packet1->GetSize()) == 0);
}
}