1
0
Fork 0

stream IO refactoring

This commit is contained in:
Kevin Matz 2021-07-29 19:26:49 -04:00
parent d69566bbc9
commit aaca7ea461
18 changed files with 505 additions and 435 deletions

View File

@ -71,7 +71,8 @@ void Appliance::UdpPayloadReceiver(PDU::Stream stream)
if (!stream->good())
return;
auto block = PDU::readBlock<RLP::Pdu>(stream);
auto block = PDU::Block<RLP::Pdu>();
block.readBlock(stream);
if (stream->fail())
return;
@ -99,7 +100,8 @@ void Appliance::TcpPacketReceiver(PDU::Stream stream)
if (!stream->good())
return;
auto block = PDU::readBlock<RLP::Pdu>(stream);
auto block = PDU::Block<RLP::Pdu>();
block.readBlock(stream);
if (stream->fail())
return;

View File

@ -27,20 +27,6 @@
namespace ACN {
namespace DMP {
/**
* @brief address_type::address_type
* @param val
*/
address_type::address_type(const uint8_t val)
{
z_reserved = (val >> 7) & 0b1;
relative = (val >> 6) & 0b1;
type = (data_type)((val >> 4) & 0b11);
x_reserved = (val >> 2) & 0b11;
width = (address_length)(val & 0b11);
}
/**
* @brief address_type::streamSize
* @return
@ -51,6 +37,23 @@ size_t address_type::streamSize()
}
/**
* @brief address_type::iStream
* @param stream
*/
void address_type::iStream(PDU::Stream stream)
{
uint8_t val;
*stream >> val;
z_reserved = (val >> 7) & 0b1;
relative = (val >> 6) & 0b1;
type = (data_type)((val >> 4) & 0b11);
x_reserved = (val >> 2) & 0b11;
width = (address_length)(val & 0b11);
}
/**
* @brief address_type::oStream
* @return
@ -71,14 +74,13 @@ void address_type::oStream(PDU::Stream stream) const
* @param t
* @param l
*/
range::range(PDU::Stream stream, data_type t, address_length l) :
incriment(0),
count(0)
range::range(PDU::Stream stream, const data_type t, const address_length l)
{
address = read(stream, l);
if (t == SINGLE) return;
incriment = read(stream, l);
count = read(stream, l);
}
@ -88,7 +90,7 @@ range::range(PDU::Stream stream, data_type t, address_length l) :
* @param length
* @return
*/
uint32_t range::read(PDU::Stream stream, address_length length)
uint32_t range::read(PDU::Stream stream, const address_length length)
{
switch (length) {
case ONE:
@ -118,24 +120,37 @@ size_t dmp_set_data::streamSize()
* @brief Pdu::Pdu
* @param stream
*/
Pdu::Pdu(PDU::Stream stream)
: PDU::Pdu(stream, 1) // vectors are 1 octet
Pdu::Pdu()
: PDU::Pdu(1) // vectors are 1 octet
{
if (stream->fail()) return;
if (!stream_->good()) return;
}
if (flags_.hasHeader)
setHeader(new address_type(stream_->readType<uint8_t>()));
if (flags_.hasData) {
switch(vector()) {
case SET_PROPERTY:
readSetData();
break;
default:
break;
/**
* @brief DMP::Pdu::iStream
* @param stream
*/
void Pdu::iStream(PDU::Stream stream)
{
PDU::Pdu::iStream(stream); //! do base class first
if (stream->fail()) return;
if (!stream_->good()) return;
if (flags_.hasHeader)
{
header_ = new address_type();
header_->iStream(stream_);
}
if (flags_.hasData) {
switch(vector()) {
case SET_PROPERTY:
readSetData();
break;
default:
break;
}
}
}
}
@ -176,7 +191,7 @@ void Pdu::readSetData()
if (stream_->available() < header->width * (header->type == SINGLE? 1 : 3))
stream_->setstate(std::ios_base::eofbit);
}
setData(data);
data_ = data;
}
} // DMP

View File

@ -54,36 +54,32 @@ enum address_length {
};
struct address_type : PDU::pdu_header {
bool z_reserved : 1; // Z
bool relative : 1; // R
bool z_reserved : 1; // Z
bool relative : 1; // R
data_type type : 2; // D1, D0
uint8_t x_reserved : 2; // X1, X0
uint8_t x_reserved : 2; // X1, X0
address_length width : 2; // A1, A0
address_type(const uint8_t);
size_t streamSize() override;
protected:
void iStream(PDU::Stream) override {};
void oStream(PDU::Stream) const override;
size_t streamSize() override;
void iStream(PDU::Stream) override;
void oStream(PDU::Stream) const override;
};
// 5.1.5
struct range {
uint32_t address;
uint32_t incriment;
uint32_t count;
range() {};
range(PDU::Stream, data_type, address_length);
uint32_t address = 0;
uint32_t incriment = 0;
uint32_t count = 0;
range(PDU::Stream, const data_type, const address_length);
private:
uint32_t read(PDU::Stream, address_length);
uint32_t read(PDU::Stream, const address_length);
};
typedef pair<range, vector<uint8_t>> set_property;
struct dmp_set_data : PDU::pdu_data {
vector<set_property> properties;
size_t streamSize() override;
protected:
void iStream(PDU::Stream) override {};
void oStream(PDU::Stream) const override {};
void iStream(PDU::Stream) override {};
void oStream(PDU::Stream) const override {};
};
// 7 Response Messages
@ -119,7 +115,9 @@ class Pdu
: public PDU::Pdu
{
public:
Pdu(PDU::Stream);
Pdu();
void iStream(PDU::Stream) override;
void oStream(PDU::Stream) const override {};
private:
void readSetData();
};

View File

@ -33,51 +33,10 @@ namespace PDU {
* @param stream
* @param vector_size
*/
Pdu::Pdu(Stream stream, size_t vector_size)
: flags_(stream->peek())
Pdu::Pdu(size_t vector_size)
: vector_size_(vector_size)
{
header_ = nullptr; //!< pointer to PDU::pdu_header
data_ = nullptr; //!< pointer to PDU::pdu_data
parent_ = nullptr; //!< pointer to encapsulating PDU
inherit_ = nullptr; //!< pointer to previous PDU in block
// read length and vector off of the stream
// abort if the remaining PDU length isn't available
if (stream->available() < (flags_.hasLength ? 3 : 2)) {
stream->setstate(std::ios_base::failbit);
return;
}
readLength(stream);
if (!length_ || length_ > std::pow(2, (8 * (flags_.hasLength ? 3 : 2)) - 4)) {
stream->setstate(std::ios_base::failbit);
return;
}
// length includes the flags, length, and vector
// calculate the remaining length of the PDU
int len = length_ - (flags_.hasLength ? 3 : 2);
// abort if the remaining PDU length isn't available
if (!stream->good() || stream->available() < len) {
stream->setstate(std::ios_base::failbit);
return;
}
// create a stream buffer for the header and data
stream_ = Stream(new pdu_stream(stream->data(), len));
if (stream_->available() != len) {
stream->setstate(std::ios_base::failbit);
return;
}
// fast-forward the input stream
for (int i = 0; i < len; i++)
stream->get();
if (!stream->available())
stream->setstate(std::ios_base::eofbit);
if (flags_.hasVector)
readVector(vector_size);
}
@ -134,26 +93,80 @@ pdu_data * Pdu::data()
/**
* @brief Pdu::readLength
* @param stream
* @brief Pdu::streamSize
* @return
*/
void Pdu::readLength(Stream stream)
size_t Pdu::streamSize()
{
length_ = stream->readType<uint16_t>() & 0x0fff; // high 4 bytes are flags
if (flags_.hasLength)
length_ = (length_ << 8 ) | stream->readType<uint8_t>();
return 1 /// TODO: real size of vector + flags + length
+ header_->streamSize()
+ data_->streamSize();
}
/**
* @brief Pdu::readVector
* @param vector_size
* @brief Pdu::iStream
* @param stream
*/
void Pdu::readVector(uint8_t vector_size)
void Pdu::iStream(Stream stream)
{
vector_ = 0;
for (int o = vector_size - 1; o >= 0; o--)
vector_ |= (stream_->readType<uint8_t>() << (8 * o));
// get the flags
flags_ = pdu_flags(stream->peek());
// get the length
length_ = stream->readType<uint16_t>() & 0x0fff; // high 4 bits are flags
if (flags_.hasLength)
length_ = (length_ << 8 ) | stream->readType<uint8_t>();
// get the vector
if (flags_.hasVector)
switch (vector_size_) {
case 1:
vector_ = stream->readType<uint8_t>();
break;
case 2:
vector_ = stream->readType<uint16_t>();
break;
case 4:
vector_ = stream->readType<uint32_t>();
break;
default:
stream->setstate(std::ios_base::failbit);
return;
}
// length includes the flags, length, and vector.
// the remainder of the length of header and data
int hd_length = length_ - (flags_.hasLength ? 3 : 2) - vector_size_;
// abort if the remaining PDU length isn't available
if (!stream->good() || stream->available() < hd_length) {
stream->setstate(std::ios_base::failbit);
return;
}
// create a stream buffer for the header and data
stream_ = Stream(new pdu_stream(stream->data(), hd_length));
if (stream_->available() != hd_length) {
stream->setstate(std::ios_base::failbit);
return;
}
// fast-forward the input stream
for (int i = 0; i < hd_length; i++)
stream->get();
if (!stream->available())
stream->setstate(std::ios_base::eofbit);
}
/**
* @brief Pdu::oStream
* @param stream
*/
void Pdu::oStream(Stream stream) const
{
/// TODO: write to stream
}

128
acn/pdu.h
View File

@ -43,42 +43,33 @@ struct pdu_flags
bool hasVector : 1;
bool hasHeader : 1;
bool hasData : 1;
pdu_flags() {};
pdu_flags(uint8_t);
};
/**
* @brief The pdu_base_member struct
*/
struct pdu_base_member
{
virtual ~pdu_base_member() {};
virtual size_t streamSize() = 0;
virtual void iStream(Stream) = 0;
virtual void oStream(Stream) const = 0;
};
/**
* @brief The pdu_header struct
*/
struct pdu_header
{
virtual ~pdu_header() {}
friend PDU::Stream& operator>> (PDU::Stream &stream, pdu_header &h)
{ h.iStream(stream); return stream; }
friend PDU::Stream& operator<< (PDU::Stream &stream, const pdu_header &h)
{ h.oStream(stream); return stream; }
virtual size_t streamSize() = 0;
protected:
virtual void iStream(Stream) = 0;
virtual void oStream(Stream) const = 0;
};
struct pdu_header : public pdu_base_member {};
/**
* @brief The pdu_data struct
*/
struct pdu_data
{
virtual ~pdu_data() {}
friend PDU::Stream& operator>> (PDU::Stream &stream, pdu_data &d)
{ d.iStream(stream); return stream; }
friend PDU::Stream& operator<< (PDU::Stream &stream, const pdu_data &d)
{ d.oStream(stream); return stream; }
virtual size_t streamSize() = 0;
protected:
virtual void iStream(Stream) = 0;
virtual void oStream(Stream) const = 0;
};
struct pdu_data : public pdu_base_member {};
/**
@ -92,9 +83,9 @@ protected:
* are present in the PDU, or if they should be inherited from the
* preceding PDU.
*/
class Pdu {
class Pdu : public pdu_base_member {
public:
Pdu(Stream, size_t vector_size);
Pdu(size_t vector_size);
~Pdu();
// getters
@ -105,6 +96,9 @@ public:
pdu_data * data(); // may inherit
std::shared_ptr<Pdu> parent() {return parent_;}
Stream stream() {return stream_;}
virtual size_t streamSize() override;
virtual void iStream(Stream) override;
virtual void oStream(Stream) const override;
// setters
void setParent (std::shared_ptr<Pdu> pdu) {parent_ = pdu;}
@ -114,20 +108,12 @@ protected:
pdu_flags flags_;
uint32_t length_;
uint32_t vector_;
std::shared_ptr<Pdu> parent_;
std::shared_ptr<Pdu> inherit_;
size_t vector_size_;
std::shared_ptr<Pdu> parent_ = nullptr;
std::shared_ptr<Pdu> inherit_ = nullptr;
pdu_header * header_ = nullptr;
pdu_data * data_ = nullptr;
Stream stream_;
// private setters
void setHeader (pdu_header * h) {header_ = h;}
void setData (pdu_data * d) {data_ = d;}
private:
pdu_header * header_;
pdu_data * data_;
void readLength(Stream);
void readVector(uint8_t);
};
@ -146,40 +132,40 @@ using Handler = std::function<void(std::shared_ptr<T>)>;
template <typename T>
struct Block : public pdu_data
{
std::shared_ptr<std::vector<std::shared_ptr<T>>> pdu;
size_t streamSize() { return 0; }
protected:
void iStream(Stream s) {};
void oStream(Stream s) const {};
std::shared_ptr<std::vector<std::shared_ptr<T>>> pdu
= std::shared_ptr<std::vector<std::shared_ptr<T>>>(
new std::vector<std::shared_ptr<T>>);
size_t streamSize() {
size_t s = 0;
for (auto &child : *pdu)
s += child->streamSize();
return s;
}
void iStream(Stream s) { //!< you should call readBlock() directly.
readBlock(s, nullptr);
};
void oStream(Stream s) const {
for ( const auto & child : *pdu )
child->oStream(s);
};
void readBlock(Stream s, std::shared_ptr<PDU::Pdu> parent = nullptr) {
while(s->good()) {
std::shared_ptr<T> p(new T());
p->iStream(s);
if (s->fail()) // stream failed during pdu read
break;
if (p->stream()->fail()) // pdu buffer failed
continue;
if (parent) // set parent
p->setParent(parent);
if (!pdu->empty()) // set inheritee
p->setInherit(pdu->back());
pdu->push_back(p); // add to block
}
}
};
/**
* @brief PDU::readBlock
* reads a PDU::Block from a PDU::Stream
* @param std::shared_ptr<PDU::pdu_stream> The stream to read from.
* @return std::shared_ptr<std::vector<std::shared_ptr<T>>> A block of PDU
* @tparam T PDU decendant subclass
*/
template<typename T>
Block<T> readBlock(Stream buffer, std::shared_ptr<PDU::Pdu> parent = nullptr) {
auto block = Block<T>();
while(buffer->good()) {
std::shared_ptr<T> pdu(new T(buffer));
if (buffer->fail()) // stream failed during pdu constructor
break;
if (pdu->stream()->fail()) // pdu buffer errors
continue;
if (parent) // set parent
pdu->setParent(parent);
if (!block.pdu->empty()) // set inheritee
pdu->setInherit(block.pdu->back());
block.pdu->push_back(pdu); // add to block
}
return block;
}
} // PDU
} // ACN

View File

@ -36,15 +36,26 @@ namespace UDP {
using std::uint8_t;
using std::uint16_t;
// The ACN Packet Identifier shall be the text string
// “ASC-E1.17\0\0\0” encoded in [ASCII].
/**
* @brief ACN_PACKET_IDENTIFIER
*
* The ACN Packet Identifier shall be the text string
* ASC-E1.17\0\0\0 encoded in [ASCII].
*/
static constexpr uint8_t ACN_PACKET_IDENTIFIER[] = { 0x41, 0x53, 0x43, 0x2d, 0x45, 0x31, 0x2e, 0x31, 0x37, 0x00, 0x00, 0x00 };
// 2. Preamble Format: The preamble size includes both size fields so the
// minimum value for preamble size is 16 (octets).
/**
* @brief PREAMBLE_MINIMUM_SIZE
*
* 2. Preamble Format: The preamble size includes both size fields so the
* minimum value for preamble size is 16 (octets).
*/
static const uint8_t PREAMBLE_MINIMUM_SIZE = 16;
// 2. Preamble Format
/**
* @brief 2. Preamble Format
*/
struct preamble_t {
uint16_t length;
uint16_t postamble_size;

View File

@ -27,18 +27,6 @@
namespace ACN {
namespace RLP {
/**
* @brief rlp_header::rlp_header
* @param stream
*/
rlp_header::rlp_header(PDU::Stream stream)
: PDU::pdu_header()
, cid()
{
stream >> *this;
}
/**
* @brief rlp_header::streamSize
* @return
@ -75,17 +63,30 @@ void rlp_header::oStream(PDU::Stream stream) const
/**
* @brief Pdu::Pdu
* @brief RLP::Pdu::Pdu
* @param stream
*/
Pdu::Pdu(PDU::Stream stream)
: ACN::PDU::Pdu(stream, 4)
Pdu::Pdu()
: ACN::PDU::Pdu(4)
{
if (stream->fail()) return;
if (!stream_->good()) return;
}
if (flags_.hasHeader)
setHeader(new rlp_header(stream_));
/**
* @brief Pdu::iStream
* @param stream
*/
void Pdu::iStream(PDU::Stream stream)
{
PDU::Pdu::iStream(stream); //! do base class first
if (stream->fail()) return;
if (!stream_->good()) return;
if (flags_.hasHeader)
{
header_ = new rlp_header();
header_->iStream(stream_);
}
}
} // RLP

View File

@ -42,11 +42,9 @@ namespace RLP {
struct rlp_header : PDU::pdu_header
{
UUID::uuid cid;
rlp_header(PDU::Stream);
size_t streamSize() override;
protected:
void iStream(PDU::Stream) override;
void oStream(PDU::Stream) const override;
size_t streamSize() override;
void iStream(PDU::Stream) override;
void oStream(PDU::Stream) const override;
};
@ -57,7 +55,9 @@ class Pdu
: public PDU::Pdu
{
public:
Pdu(PDU::Stream);
Pdu();
void iStream(PDU::Stream) override;
void oStream(PDU::Stream) const override {};
};
} // RLP

View File

@ -28,20 +28,24 @@ namespace ACN {
namespace SDT {
namespace UDP {
address_t::address_t(PDU::Stream stream) {
type = stream->readType<decltype(type)>();
/**
* @brief address_t::iStream
* @param stream
*/
void address_t::iStream(PDU::Stream stream) {
*stream >> type;
if (type != SDT_ADDR_NULL)
port = stream->readType<decltype(port)>();
*stream >> port;
switch (type) {
case SDT_ADDR_IPV4:
for (unsigned int i = 0; i < sizeof(ipv4); i++)
ipv4[i] = stream->readType<uint8_t>();
*stream >> ipv4[i];
break;
case SDT_ADDR_IPV6:
for (unsigned int i = 0; i < sizeof(ipv6); i++)
ipv6[i] = stream->readType<uint8_t>();
*stream >> ipv6[i];
break;
case SDT_ADDR_NULL:
default:

View File

@ -60,8 +60,7 @@ struct address_t {
uint8_t ipv4[4];
uint8_t ipv6[16] = {0};
};
address_t() {};
address_t(PDU::Stream);
void iStream(PDU::Stream);
};
} // UDP

View File

@ -27,61 +27,96 @@
namespace ACN {
namespace SDT {
params_t::params_t(PDU::Stream stream) {
Expiry = stream->readType<decltype(Expiry)>();
auto packed = stream->readType<uint8_t>();
NAK_Outbound = packed >> 7;
reserved = packed & 0xef;
NAKholdoff = stream->readType<decltype(NAKholdoff)>();
NAKmodulus = stream->readType<decltype(NAKmodulus)>();
NAKmaxwait = stream->readType<decltype(NAKmaxwait)>();
/**
* @brief params_t::iStream
* @param stream
*/
void params_t::iStream(PDU::Stream stream)
{
*stream >> Expiry;
uint8_t packed;
*stream >> packed;
NAK_Outbound = packed >> 7;
reserved = packed & 0xef;
*stream >> NAKholdoff;
*stream >> NAKmodulus;
*stream >> NAKmaxwait;
}
join_data_t::join_data_t(PDU::Stream stream) {
mid = stream->readType<decltype(mid)>();
number = stream->readType<decltype(number)>();
reciprocal = stream->readType<decltype(reciprocal)>();
sequence = stream->readType<decltype(sequence)>();
reliable = stream->readType<decltype(reliable)>();
destination = UDP::address_t(stream);
parameters = params_t(stream);
expiry = stream->readType<decltype(expiry)>();
/**
* @brief join_data_t::iStream
* @param stream
*/
void join_data_t::iStream(PDU::Stream stream)
{
*stream >> mid;
*stream >> number;
*stream >> reciprocal;
*stream >> sequence;
*stream >> reliable;
destination.iStream(stream);
parameters.iStream(stream);
*stream >> expiry;
}
join_accept_data_t::join_accept_data_t(PDU::Stream stream) {
/**
* @brief join_accept_data_t::iStream
* @param stream
*/
void join_accept_data_t::iStream(PDU::Stream stream)
{
uint8_t buf[16];
stream->read(buf, sizeof(buf));
leader = UUID::uuid(buf);
*stream >> number;
*stream >> mid;
*stream >> reliable;
*stream >> reciprocal;
}
/**
* @brief join_refuse_data_t::iStream
* @param stream
*/
void join_refuse_data_t::iStream(PDU::Stream stream)
{
uint8_t buf[16];
stream->read(buf, sizeof(buf));
leader = UUID::uuid(buf);
number = stream->readType<decltype(number)>();
mid = stream->readType<decltype(mid)>();
reliable = stream->readType<decltype(reliable)>();
reciprocal = stream->readType<decltype(reciprocal)>();
*stream >> number;
*stream >> mid;
*stream >> reliable;
*stream >> code;
}
join_refuse_data_t::join_refuse_data_t(PDU::Stream stream) {
uint8_t buf[16];
stream->read(buf, sizeof(buf));
leader = UUID::uuid(buf);
number = stream->readType<decltype(number)>();
mid = stream->readType<decltype(mid)>();
reliable = stream->readType<decltype(reliable)>();
code = stream->readType<decltype(code)>();
/**
* @brief nak_data_t::iStream
* @param stream
*/
void nak_data_t::iStream(PDU::Stream stream)
{
uint8_t buf[16];
stream->read(buf, sizeof(buf));
leader = UUID::uuid(buf);
*stream >> number;
*stream >> mid;
*stream >> reliable;
*stream >> missed_first;
*stream >> missed_last;
}
nak_data_t::nak_data_t(PDU::Stream stream) {
uint8_t buf[16];
stream->read(buf, sizeof(buf));
leader = UUID::uuid(buf);
number = stream->readType<decltype(number)>();
mid = stream->readType<decltype(mid)>();
reliable = stream->readType<decltype(reliable)>();
missed_first = stream->readType<decltype(missed_first)>();
missed_last = stream->readType<decltype(missed_last)>();
}
wrapper_data_t::wrapper_data_t(PDU::Stream stream) {
number = stream->readType<decltype(number)>();
/**
* @brief wrapper_data_t::iStream
* @param stream
*/
void wrapper_data_t::iStream(PDU::Stream stream)
{
*stream >> number;
}
@ -143,16 +178,35 @@ SessionId Session::id() {
return ret;
}
Pdu::Pdu(PDU::Stream stream)
: PDU::Pdu(stream, 1) // vectors are 1 octet
/**
* @brief Pdu::Pdu
*/
Pdu::Pdu()
: PDU::Pdu(1) // vectors are 1 octet
{
// if (stream->fail()) return;
// if (!buffer_->good()) return;
}
client_pdu_header_t::client_pdu_header_t(PDU::Stream stream) {
protocol = stream->readType<decltype(protocol)>();
association = stream->readType<decltype(association)>();
/**
* @brief Pdu::iStream
* @param stream
*/
void Pdu::iStream(PDU::Stream stream)
{
PDU::Pdu::iStream(stream); //! do base class first
if (stream->fail()) return;
if (!stream_->good()) return;
}
/**
* @brief client_pdu_header_t::iStream
* @param stream
*/
void client_pdu_header_t::iStream(PDU::Stream stream)
{
*stream >> protocol;
*stream >> association;
}
@ -160,14 +214,27 @@ client_pdu_header_t::client_pdu_header_t(PDU::Stream stream) {
* @brief ClientPdu::ClientPdu
* @param stream
*/
ClientPdu::ClientPdu(PDU::Stream stream)
: PDU::Pdu(stream, 2) // vectors are 2 octets (MID)
ClientPdu::ClientPdu()
: PDU::Pdu(2) // vectors are 2 octets (MID)
{
if (stream->fail()) return;
if (!stream_->good()) return;
}
if (flags_.hasHeader)
setHeader(new client_pdu_header_t(stream_));
/**
* @brief ClientPdu::iStream
* @param stream
*/
void ClientPdu::iStream(PDU::Stream stream)
{
PDU::Pdu::iStream(stream); //! do base class first
if (stream->fail()) return;
if (!stream_->good()) return;
if (flags_.hasHeader)
{
header_ = new client_pdu_header_t();
header_->iStream(stream_);
}
}
}; // SDT

View File

@ -65,8 +65,7 @@ struct params_t {
uint16_t NAKholdoff; // calculation of a standoff time for sending NAKs
uint16_t NAKmodulus; // calculation of a standoff time for sending NAKs
uint16_t NAKmaxwait; // maximum milliseconds to wait before sending a NAK.
params_t() {};
params_t(PDU::Stream);
void iStream(PDU::Stream);
};
// 4.4.1 Join
@ -79,12 +78,9 @@ struct join_data_t : PDU::pdu_data {
UDP::address_t destination;
params_t parameters;
uint8_t expiry;
join_data_t() {};
join_data_t(PDU::Stream);
size_t streamSize() override { return 0; }
protected:
void iStream(PDU::Stream) override {};
void oStream(PDU::Stream) const override {};
size_t streamSize() override { return 0; }
void iStream(PDU::Stream) override;
void oStream(PDU::Stream) const override {};
};
// 4.4.2 Join Accept
@ -94,12 +90,9 @@ struct join_accept_data_t : PDU::pdu_data {
MID mid;
uint32_t reliable;
uint16_t reciprocal;
join_accept_data_t() {};
join_accept_data_t(PDU::Stream);
size_t streamSize() override { return 0; }
protected:
void iStream(PDU::Stream) override {};
void oStream(PDU::Stream) const override {};
void iStream(PDU::Stream) override;
void oStream(PDU::Stream) const override {};
};
// 4.4.3 Join Refuse
@ -110,12 +103,9 @@ struct join_refuse_data_t : PDU::pdu_data {
MID mid;
uint32_t reliable;
uint8_t code;
join_refuse_data_t() {};
join_refuse_data_t(PDU::Stream);
size_t streamSize() override { return 0; }
protected:
void iStream(PDU::Stream) override {};
void oStream(PDU::Stream) const override {};
void iStream(PDU::Stream) override;
void oStream(PDU::Stream) const override {};
};
// 4.4.5 NAK
@ -126,12 +116,9 @@ struct nak_data_t : PDU::pdu_data {
uint32_t reliable;
uint32_t missed_first;
uint32_t missed_last;
nak_data_t() {};
nak_data_t(PDU::Stream);
size_t streamSize() override { return 0; }
protected:
void iStream(PDU::Stream) override {};
void oStream(PDU::Stream) const override {};
void iStream(PDU::Stream) override;
void oStream(PDU::Stream) const override {};
};
// 4.4.6 Reliable Wrapper and Unreliable Wrapper
@ -143,24 +130,18 @@ struct wrapper_data_t : PDU::pdu_data {
MID ack_range_begin;
MID ack_range_end;
uint16_t MAK_threshold;
wrapper_data_t() {};
wrapper_data_t(PDU::Stream);
size_t streamSize() override { return 0; }
protected:
void iStream(PDU::Stream) override {};
void oStream(PDU::Stream) const override {};
void iStream(PDU::Stream) override;
void oStream(PDU::Stream) const override {};
};
// 4.4.7 SDT Client Block
struct client_pdu_header_t : PDU::pdu_header {
uint32_t protocol;
uint16_t association;
client_pdu_header_t() {};
client_pdu_header_t(PDU::Stream);
protected:
size_t streamSize() override;
void iStream(PDU::Stream) override {};
void oStream(PDU::Stream) const override {};
void iStream(PDU::Stream) override;
void oStream(PDU::Stream) const override {};
};
// Client Block PDU
@ -168,16 +149,17 @@ class ClientPdu
: public PDU::Pdu
{
public:
ClientPdu(PDU::Stream);
ClientPdu();
void iStream(PDU::Stream) override;
void oStream(PDU::Stream) const override {};
};
// 4.4.8 Get Sessions
struct get_sessions_data_t : PDU::pdu_data {
UUID::uuid cid;
size_t streamSize() override { return 0; }
protected:
void iStream(PDU::Stream) override {};
void oStream(PDU::Stream) const override {};
void iStream(PDU::Stream) override {};
void oStream(PDU::Stream) const override {};
};
@ -197,18 +179,16 @@ struct channel_info_block_t {
struct sessions_data_t : PDU::pdu_data {
std::list<channel_info_block_t> list;
size_t streamSize() override { return 0; }
protected:
void iStream(PDU::Stream) override {};
void oStream(PDU::Stream) const override {};
void iStream(PDU::Stream) override {};
void oStream(PDU::Stream) const override {};
};
// 4.5.1 ACK
struct ack_data_t : PDU::pdu_data {
uint32_t reliable;
size_t streamSize() override { return 0; }
protected:
void iStream(PDU::Stream) override {};
void oStream(PDU::Stream) const override {};
size_t streamSize() override { return 0; }
void iStream(PDU::Stream) override {};
void oStream(PDU::Stream) const override {};
};
// 4.5.2 Channel Params
@ -216,10 +196,9 @@ struct channel_params_data_t : PDU::pdu_data {
params_t parameters;
UDP::address_t address;
uint8_t expiry;
size_t streamSize() override { return 0; }
protected:
void iStream(PDU::Stream) override {};
void oStream(PDU::Stream) const override {};
size_t streamSize() override { return 0; }
void iStream(PDU::Stream) override {};
void oStream(PDU::Stream) const override {};
};
// 4.5.3 Connect
@ -227,10 +206,9 @@ protected:
// 4.5.6 Disconnect
struct connect_data_t : PDU::pdu_data {
uint32_t protocol;
size_t streamSize() override { return 0; }
protected:
void iStream(PDU::Stream) override {};
void oStream(PDU::Stream) const override {};
size_t streamSize() override { return 0; }
void iStream(PDU::Stream) override {};
void oStream(PDU::Stream) const override {};
};
// 4.5.5 Connect Refuse
@ -238,10 +216,9 @@ protected:
struct connect_refuse_data_t : PDU::pdu_data {
uint32_t protocol;
uint8_t code;
size_t streamSize() override { return 0; }
protected:
void iStream(PDU::Stream) override {};
void oStream(PDU::Stream) const override {};
size_t streamSize() override { return 0; }
void iStream(PDU::Stream) override {};
void oStream(PDU::Stream) const override {};
};
@ -300,7 +277,9 @@ class Pdu
: public PDU::Pdu
{
public:
Pdu(PDU::Stream);
Pdu();
void iStream(PDU::Stream) override;
void oStream(PDU::Stream) const override {};
};

View File

@ -27,16 +27,6 @@
namespace SACN {
namespace DATA {
/**
* @brief frame_header::frame_header
* @param stream
*/
frame_header::frame_header(PDU::Stream stream)
{
stream >> *this;
}
/**
* @brief frame_header::streamSize
* @return
@ -88,14 +78,27 @@ void frame_header::oStream(PDU::Stream stream) const
* @brief Pdu::Pdu
* @param stream
*/
Pdu::Pdu(PDU::Stream stream)
: PDU::Pdu(stream, 4) // vectors are 4 octets
Pdu::Pdu()
: PDU::Pdu(4) // vectors are 4 octets
{
if (stream->fail()) return;
if (!stream_->good()) return;
}
if (flags_.hasHeader)
setHeader(new frame_header(stream_));
/**
* @brief Pdu::iStream
* @param stream
*/
void Pdu::iStream(PDU::Stream stream)
{
PDU::Pdu::iStream(stream);
if (stream->fail()) return;
if (!stream_->good()) return;
if (flags_.hasHeader)
{
header_ = new frame_header();
header_->iStream(stream_);
}
}
} // DATA

View File

@ -39,11 +39,9 @@ struct frame_header : PDU::pdu_header {
uint8_t sequence_number;
uint8_t options;
uint16_t universe;
frame_header(PDU::Stream);
size_t streamSize() override;
protected:
void iStream(PDU::Stream) override;
void oStream(PDU::Stream) const override;
size_t streamSize() override;
void iStream(PDU::Stream) override;
void oStream(PDU::Stream) const override;
};
// 6.2.6 E1.31 Data Packet: Options
@ -57,7 +55,9 @@ class Pdu
: public PDU::Pdu
{
public:
Pdu(PDU::Stream);
Pdu();
void iStream(PDU::Stream) override;
void oStream(PDU::Stream) const override {};
};
} // DATA

View File

@ -23,21 +23,11 @@
*/
#include "extended.h"
#include "../build/has_rtti.h"
namespace SACN {
namespace EXTENDED {
/**
* @brief frame_sync_header::frame_sync_header
* @param stream
*/
frame_sync_header::frame_sync_header(PDU::Stream stream)
{
stream >> *this;
}
/**
* @brief frame_sync_header::streamSize
* @return
@ -74,16 +64,6 @@ void frame_sync_header::oStream(PDU::Stream stream) const
}
/**
* @brief frame_discovery_header::frame_discovery_header
* @param stream
*/
frame_discovery_header::frame_discovery_header(PDU::Stream stream)
{
stream >> *this;
}
/**
* @brief frame_discovery_header::streamSize
* @return
@ -124,36 +104,38 @@ void frame_discovery_header::oStream(PDU::Stream stream) const
* @brief Pdu::Pdu
* @param stream
*/
Pdu::Pdu(PDU::Stream stream)
: PDU::Pdu(stream, 4) // vectors are 4 octets
Pdu::Pdu()
: PDU::Pdu(4) // vectors are 4 octets
{
if (stream->fail()) return;
if (!stream_->good()) return;
}
if (flags_.hasHeader)
switch(vector()) {
case VECTOR_E131_EXTENDED_SYNCHRONIZATION:
setHeader(new frame_sync_header(stream_));
break;
case VECTOR_E131_EXTENDED_DISCOVERY:
setHeader(new frame_discovery_header(stream_));
break;
default:
break;
}
void Pdu::iStream(PDU::Stream stream)
{
PDU::Pdu::iStream(stream);
if (stream->fail()) return;
if (!stream_->good()) return;
if (flags_.hasHeader)
switch(vector()) {
case VECTOR_E131_EXTENDED_SYNCHRONIZATION:
{
header_ = new frame_sync_header();
header_->iStream(stream_);
}
break;
case VECTOR_E131_EXTENDED_DISCOVERY:
{
header_ = new frame_discovery_header();
header_->iStream(stream_);
}
break;
default:
break;
}
}
namespace DISCOVERY {
/**
* @brief discovery_list_header::discovery_list_header
* @param stream
*/
discovery_list_header::discovery_list_header(PDU::Stream stream) {
stream >> *this;
}
/**
* @brief discovery_list_header::streamSize
* @return
@ -190,28 +172,39 @@ void discovery_list_header::oStream(PDU::Stream stream) const
* @brief Pdu::Pdu
* @param stream
*/
Pdu::Pdu(PDU::Stream stream)
: PDU::Pdu(stream, 4) // vectors are 4 octets
Pdu::Pdu()
: PDU::Pdu(4) // vectors are 4 octets
{
if (stream->fail()) return;
if (!stream_->good()) return;
if (flags_.hasHeader)
setHeader(new discovery_list_header(stream_));
}
void Pdu::iStream(PDU::Stream stream)
{
PDU::Pdu::iStream(stream);
if (stream->fail()) return;
if (!stream_->good()) return;
if (flags_.hasHeader)
{
header_ = new discovery_list_header();
header_->iStream(stream_);
}
}
/**
Construct a Universe Source from an sACN discovery layer PDU
*/
DiscoveredUniverse::DiscoveredUniverse(const std::shared_ptr<EXTENDED::DISCOVERY::Pdu> pdu) {
auto root_header = (RLP::rlp_header*)pdu->parent()->parent()->header();
#ifdef RTTI_ENABLED
auto root_header = dynamic_cast<RLP::rlp_header*>(pdu->parent()->parent()->header());
auto frame_header = dynamic_cast<EXTENDED::frame_discovery_header*>(pdu->parent()->header());
#else
auto root_header = static_cast<RLP::rlp_header*>(pdu->parent()->parent()->header());
auto frame_header = static_cast<EXTENDED::frame_discovery_header*>(pdu->parent()->header());
#endif
cid_ = root_header->cid;
auto frame_header = (EXTENDED::frame_discovery_header*)pdu->parent()->header();
description_ = std::string((char*)frame_header->source_name);
universe_ = pdu->stream()->readType<decltype(universe_)>();
*pdu->stream() >> universe_;
}
} // DISCOVERY

View File

@ -38,11 +38,9 @@ struct frame_sync_header : PDU::pdu_header {
uint8_t sequence_number;
uint16_t sync_address;
uint8_t reserved[2];
frame_sync_header(PDU::Stream);
size_t streamSize() override;
protected:
void iStream(PDU::Stream) override;
void oStream(PDU::Stream) const override;
size_t streamSize() override;
void iStream(PDU::Stream) override;
void oStream(PDU::Stream) const override;
};
@ -50,11 +48,9 @@ protected:
struct frame_discovery_header : PDU::pdu_header {
uint8_t source_name[64];
uint8_t reserved[4];
frame_discovery_header(PDU::Stream);
size_t streamSize() override;
protected:
void iStream(PDU::Stream) override;
void oStream(PDU::Stream) const override;
size_t streamSize() override;
void iStream(PDU::Stream) override;
void oStream(PDU::Stream) const override;
};
@ -62,7 +58,9 @@ class Pdu
: public PDU::Pdu
{
public:
Pdu(PDU::Stream);
Pdu();
void iStream(PDU::Stream) override;
void oStream(PDU::Stream) const override {};
};
@ -72,18 +70,18 @@ namespace DISCOVERY {
struct discovery_list_header : PDU::pdu_header {
uint8_t page;
uint8_t last_page;
discovery_list_header(PDU::Stream);
size_t streamSize() override;
protected:
void iStream(PDU::Stream) override;
void oStream(PDU::Stream) const override;
size_t streamSize() override;
void iStream(PDU::Stream) override;
void oStream(PDU::Stream) const override;
};
class Pdu
: public PDU::Pdu
{
public:
Pdu(PDU::Stream);
Pdu();
void iStream(PDU::Stream) override;
void oStream(PDU::Stream) const override {};
};

View File

@ -109,7 +109,8 @@ void Receiver::onDiscovered(const EXTENDED::DISCOVERY::Watcher cb) {
* Receive VECTOR_ROOT_E131_DATA vector'd packets.
*/
void Receiver::dataReceiver(std::shared_ptr<RLP::Pdu> root) {
auto block = PDU::readBlock<DATA::Pdu>(root->stream(), root);
auto block = PDU::Block<DATA::Pdu>();
block.readBlock(root->stream(), root);
if (root->stream()->fail())
return;
for(auto const &frame : *block.pdu) {
@ -135,7 +136,8 @@ void Receiver::dataReceiver(std::shared_ptr<RLP::Pdu> root) {
* Receive VECTOR_ROOT_E131_EXTENDED vector'd packets.
*/
void Receiver::extendedReceiver(std::shared_ptr<RLP::Pdu> root) {
auto block = PDU::readBlock<EXTENDED::Pdu>(root->stream(), root);
auto block = PDU::Block<EXTENDED::Pdu>();
block.readBlock(root->stream(), root);
if (root->stream()->fail())
return;
for(auto const &frame : *block.pdu) {
@ -232,7 +234,8 @@ void Receiver::dataFrameHandler(std::shared_ptr<DATA::Pdu> frame) {
/// TODO: do something with merging and arbitration
// PDU data will be a block of DMP
auto block = PDU::readBlock<DMP::Pdu>(frame->stream(), frame);
auto block = PDU::Block<DMP::Pdu>();
block.readBlock(frame->stream(), frame);
if (frame->stream()->fail())
return;
for (auto const &dmp : *block.pdu) {
@ -266,7 +269,8 @@ void Receiver::syncFrameHandler(std::shared_ptr<EXTENDED::Pdu> frame)
* @param frame
*/
void Receiver::discoveryFrameHandler(std::shared_ptr<EXTENDED::Pdu> frame) {
auto block = PDU::readBlock<EXTENDED::DISCOVERY::Pdu>(frame->stream(), frame);
auto block = PDU::Block<EXTENDED::DISCOVERY::Pdu>();
block.readBlock(frame->stream(), frame);
if (frame->stream()->fail())
return;

View File

@ -49,17 +49,14 @@ UniverseSource::UniverseSource()
UniverseSource::UniverseSource(std::shared_ptr<DATA::Pdu> pdu)
{
#if defined(RTTI_ENABLED)
auto root_header = dynamic_cast<RLP::rlp_header*>(pdu->parent()->header());
#else
auto root_header = static_cast<RLP::rlp_header*>(pdu->parent()->header());
#endif
cid_ = root_header->cid;
#if defined(RTTI_ENABLED)
auto root_header = dynamic_cast<RLP::rlp_header*>(pdu->parent()->header());
auto frame_header = dynamic_cast<DATA::frame_header*>(pdu->header());
#else
auto root_header = static_cast<RLP::rlp_header*>(pdu->parent()->header());
auto frame_header = static_cast<DATA::frame_header*>(pdu->header());
#endif
cid_ = root_header->cid;
description_ = std::string((char*)frame_header->source_name);
universe_ = frame_header->universe;
priority_ = frame_header->priority;