#ifndef INC_SRT_PACKET_H
#define INC_SRT_PACKET_H
#include "udt.h"
#include "common.h"
#include "utilities.h"
#include "netinet_any.h"
#include "packetfilter_api.h"
class IOVector
#ifdef _WIN32
: public WSABUF
#else
: public iovec
#endif
{
public:
inline void set(void *buffer, size_t length)
{
#ifdef _WIN32
len = (ULONG)length;
buf = (CHAR*)buffer;
#else
iov_base = (void*)buffer;
iov_len = length;
#endif
}
inline char*& dataRef()
{
#ifdef _WIN32
return buf;
#else
return (char*&) iov_base;
#endif
}
inline char* data()
{
#ifdef _WIN32
return buf;
#else
return (char*)iov_base;
#endif
}
inline size_t size() const
{
#ifdef _WIN32
return (size_t) len;
#else
return iov_len;
#endif
}
inline void setLength(size_t length)
{
#ifdef _WIN32
len = length;
#else
iov_len = length;
#endif
}
};
enum PacketBoundary
{
PB_SUBSEQUENT = 0, PB_LAST = 1, PB_FIRST = 2, PB_SOLO = 3, };
typedef Bits<31> SEQNO_CONTROL;
typedef Bits<30, 16> SEQNO_MSGTYPE;
typedef Bits<15, 0> SEQNO_EXTTYPE;
typedef Bits<30, 0> SEQNO_VALUE;
const int32_t LOSSDATA_SEQNO_RANGE_FIRST = SEQNO_CONTROL::mask;
const int32_t LOSSDATA_SEQNO_RANGE_LAST = 0, LOSSDATA_SEQNO_SOLO = 0;
inline int32_t CreateControlSeqNo(UDTMessageType type)
{
return SEQNO_CONTROL::mask | SEQNO_MSGTYPE::wrap(size_t(type));
}
inline int32_t CreateControlExtSeqNo(int exttype)
{
return SEQNO_CONTROL::mask | SEQNO_MSGTYPE::wrap(size_t(UMSG_EXT)) | SEQNO_EXTTYPE::wrap(exttype);
}
typedef Bits<31, 30> MSGNO_PACKET_BOUNDARY;
typedef Bits<29> MSGNO_PACKET_INORDER;
typedef Bits<28, 27> MSGNO_ENCKEYSPEC;
#if 1 typedef Bits<26> MSGNO_REXMIT;
typedef Bits<25, 0> MSGNO_SEQ;
typedef Bits<26, 0> MSGNO_SEQ_OLD;
const uint32_t PACKET_SND_NORMAL = 0, PACKET_SND_REXMIT = MSGNO_REXMIT::mask;
const int MSGNO_SEQ_MAX = MSGNO_SEQ::mask;
#else#endif
typedef RollNumber<MSGNO_SEQ::size-1, 1> MsgNo;
inline int32_t PacketBoundaryBits(PacketBoundary o) { return MSGNO_PACKET_BOUNDARY::wrap(int32_t(o)); }
enum EncryptionKeySpec
{
EK_NOENC = 0,
EK_EVEN = 1,
EK_ODD = 2
};
enum EncryptionStatus
{
ENCS_CLEAR = 0,
ENCS_FAILED = -1,
ENCS_NOTSUP = -2
};
const int32_t PMASK_MSGNO_ENCKEYSPEC = MSGNO_ENCKEYSPEC::mask;
inline int32_t EncryptionKeyBits(EncryptionKeySpec f)
{
return MSGNO_ENCKEYSPEC::wrap(int32_t(f));
}
inline EncryptionKeySpec GetEncryptionKeySpec(int32_t msgno)
{
return EncryptionKeySpec(MSGNO_ENCKEYSPEC::unwrap(msgno));
}
const int32_t PUMASK_SEQNO_PROBE = 0xF;
std::string PacketMessageFlagStr(uint32_t msgno_field);
class CChannel;
class CPacket
{
friend class CChannel;
friend class CSndQueue;
friend class CRcvQueue;
public:
CPacket();
~CPacket();
void allocate(size_t size);
void deallocate();
size_t getLength() const;
void setLength(size_t len);
void pack(UDTMessageType pkttype, const int32_t* lparam = NULL, void* rparam = NULL, int size = 0);
IOVector* getPacketVector();
uint32_t* getHeader() { return m_nHeader; }
ATR_DEPRECATED
int getFlag() const
{
return isControl() ? 1 : 0;
}
UDTMessageType getType() const;
bool isControl(UDTMessageType type) const
{
return isControl() && type == getType();
}
bool isControl() const
{
return 0!= SEQNO_CONTROL::unwrap(m_nHeader[SRT_PH_SEQNO]);
}
void setControl(UDTMessageType type)
{
m_nHeader[SRT_PH_SEQNO] = SEQNO_CONTROL::mask | SEQNO_MSGTYPE::wrap(type);
}
int getExtendedType() const;
int32_t getAckSeqNo() const;
uint16_t getControlFlags() const;
int32_t getSeqNo() const
{
return m_nHeader[SRT_PH_SEQNO];
}
PacketBoundary getMsgBoundary() const;
bool getMsgOrderFlag() const;
bool getRexmitFlag() const;
int32_t getMsgSeq(bool has_rexmit = true) const;
EncryptionKeySpec getMsgCryptoFlags() const;
void setMsgCryptoFlags(EncryptionKeySpec spec);
uint32_t getMsgTimeStamp() const;
#ifdef SRT_DEBUG_TSBPD_WRAP
static const uint32_t MAX_TIMESTAMP = 0x07FFFFFF; #else
static const uint32_t MAX_TIMESTAMP = 0xFFFFFFFF; #endif
protected:
static const uint32_t TIMESTAMP_MASK = MAX_TIMESTAMP; public:
CPacket* clone() const;
enum PacketVectorFields
{
PV_HEADER = 0,
PV_DATA = 1,
PV_SIZE = 2
};
public:
void toNL();
void toHL();
protected:
typedef DynamicStruct<uint32_t, SRT_PH_E_SIZE, SrtPktHeaderFields> HEADER_TYPE;
HEADER_TYPE m_nHeader;
IOVector m_PacketVector[PV_SIZE];
int32_t m_extra_pad;
bool m_data_owned;
protected:
CPacket& operator=(const CPacket&);
CPacket (const CPacket&);
public:
int32_t& m_iSeqNo; int32_t& m_iMsgNo; int32_t& m_iTimeStamp; int32_t& m_iID; char*& m_pcData;
char* getData();
char* release();
static const size_t HDR_SIZE = sizeof(HEADER_TYPE);
static const size_t UDP_HDR_SIZE = 28;
static const size_t SRT_DATA_HDR_SIZE = UDP_HDR_SIZE + HDR_SIZE;
static const size_t ETH_MAX_MTU_SIZE = 1500;
static const size_t SRT_MAX_PAYLOAD_SIZE = ETH_MAX_MTU_SIZE - SRT_DATA_HDR_SIZE;
char* data() { return m_pcData; }
const char* data() const { return m_pcData; }
size_t size() const { return getLength(); }
uint32_t header(SrtPktHeaderFields field) const { return m_nHeader[field]; }
#if ENABLE_LOGGING
std::string MessageFlagStr() { return PacketMessageFlagStr(m_nHeader[SRT_PH_MSGNO]); }
std::string Info();
#else
std::string MessageFlagStr() { return std::string(); }
std::string Info() { return std::string(); }
#endif
};
#endif