#include #include #include "packeteer/net/rtcp.hpp" using namespace packeteer::net; namespace { std::vector rtcp_packet(std::uint8_t packet_type, std::uint16_t length_words, std::size_t total_bytes) { std::vector bytes(total_bytes, 0); bytes[0] = 0x80; // version 2, no padding, RC/SC = 0 bytes[1] = packet_type; bytes[2] = static_cast(length_words >> 8); bytes[3] = static_cast(length_words & 0xFF); return bytes; } } // namespace TEST_CASE("parse_rtcp_heuristic decodes a Sender Report") { auto bytes = rtcp_packet(kRtcpSenderReport, 5, 24); // (5+1)*4 = 24 bytes auto rtcp = parse_rtcp_heuristic(bytes); REQUIRE(rtcp.has_value()); CHECK(rtcp->version == 2); CHECK(rtcp->packet_type == kRtcpSenderReport); CHECK(rtcp->length_words == 5); } TEST_CASE("parse_rtcp_heuristic accepts the first packet of a longer compound datagram") { auto bytes = rtcp_packet(kRtcpReceiverReport, 1, 8); // declares 8 bytes bytes.resize(40, 0); // but the datagram continues with more RTCP packets after it auto rtcp = parse_rtcp_heuristic(bytes); REQUIRE(rtcp.has_value()); CHECK(rtcp->packet_type == kRtcpReceiverReport); } TEST_CASE("parse_rtcp_heuristic rejects a packet type outside 200-204") { auto bytes = rtcp_packet(199, 1, 8); CHECK_FALSE(parse_rtcp_heuristic(bytes).has_value()); auto bytes2 = rtcp_packet(205, 1, 8); CHECK_FALSE(parse_rtcp_heuristic(bytes2).has_value()); } TEST_CASE("parse_rtcp_heuristic rejects version other than 2") { std::vector bytes = {0x00, kRtcpBye, 0x00, 0x00}; CHECK_FALSE(parse_rtcp_heuristic(bytes).has_value()); } TEST_CASE("parse_rtcp_heuristic rejects a buffer shorter than the declared length") { auto bytes = rtcp_packet(kRtcpBye, 10, 8); // declares (10+1)*4=44 bytes, buffer is only 8 CHECK_FALSE(parse_rtcp_heuristic(bytes).has_value()); } TEST_CASE("parse_rtcp_heuristic rejects a buffer shorter than the fixed header") { std::vector bytes = {0x80, kRtcpBye}; CHECK_FALSE(parse_rtcp_heuristic(bytes).has_value()); } TEST_CASE("rtcp_packet_type_name names every known type") { CHECK(rtcp_packet_type_name(kRtcpSenderReport) == "SR"); CHECK(rtcp_packet_type_name(kRtcpReceiverReport) == "RR"); CHECK(rtcp_packet_type_name(kRtcpSourceDescription) == "SDES"); CHECK(rtcp_packet_type_name(kRtcpBye) == "BYE"); CHECK(rtcp_packet_type_name(kRtcpApp) == "APP"); }