#ifndef MS_RTC_RTCP_PACKET_HPP
#define MS_RTC_RTCP_PACKET_HPP
#include "common.hpp"
#include <map>
#include <string>
namespace RTC
{
namespace RTCP
{
constexpr size_t BufferSize{ 65536 };
extern uint8_t Buffer[BufferSize];
constexpr uint16_t MaxAudioIntervalMs{ 5000 };
constexpr uint16_t MaxVideoIntervalMs{ 1000 };
enum class Type : uint8_t
{
SR = 200,
RR = 201,
SDES = 202,
BYE = 203,
APP = 204,
RTPFB = 205,
PSFB = 206,
XR = 207
};
class Packet
{
public:
struct CommonHeader
{
#if defined(MS_LITTLE_ENDIAN)
uint8_t count : 5;
uint8_t padding : 1;
uint8_t version : 2;
#elif defined(MS_BIG_ENDIAN)
uint8_t version : 2;
uint8_t padding : 1;
uint8_t count : 5;
#endif
uint8_t packetType : 8;
uint16_t length : 16;
};
public:
static bool IsRtcp(const uint8_t* data, size_t len)
{
auto header = const_cast<CommonHeader*>(reinterpret_cast<const CommonHeader*>(data));
return (
(len >= sizeof(CommonHeader)) &&
(data[0] > 127 && data[0] < 192) &&
(header->version == 2) &&
(header->packetType >= 192 && header->packetType <= 223)
);
}
static Packet* Parse(const uint8_t* data, size_t len);
static const std::string& Type2String(Type type);
private:
static std::map<Type, std::string> type2String;
public:
explicit Packet(Type type) : type(type)
{
}
explicit Packet(CommonHeader* commonHeader)
{
this->type = RTCP::Type(commonHeader->packetType);
this->header = commonHeader;
}
virtual ~Packet() = default;
void SetNext(Packet* packet)
{
this->next = packet;
}
Packet* GetNext() const
{
return this->next;
}
const uint8_t* GetData() const
{
return reinterpret_cast<uint8_t*>(this->header);
}
public:
virtual void Dump() const = 0;
virtual size_t Serialize(uint8_t* buffer) = 0;
virtual Type GetType() const
{
return this->type;
}
virtual size_t GetCount() const
{
return 0u;
}
virtual size_t GetSize() const = 0;
private:
Type type;
Packet* next{ nullptr };
CommonHeader* header{ nullptr };
};
} }
#endif