1
0
Fork 0

uniform PDU::Stream io functions

This commit is contained in:
Kevin Matz 2021-07-29 11:20:03 -04:00
parent 1d4d99c9c2
commit 7351e3c0df
14 changed files with 327 additions and 89 deletions

View File

@ -75,7 +75,7 @@ void Appliance::UdpPayloadReceiver(PDU::Stream stream)
if (stream->fail())
return;
for(auto const &root : *block) {
for(auto const &root : *block.pdu) {
RlpReceiver(root);
}
}
@ -103,7 +103,7 @@ void Appliance::TcpPacketReceiver(PDU::Stream stream)
if (stream->fail())
return;
for(auto const &root : *block)
for(auto const &root : *block.pdu)
RlpReceiver(root);
}

View File

@ -41,6 +41,30 @@ address_type::address_type(const uint8_t val)
}
/**
* @brief address_type::streamSize
* @return
*/
size_t address_type::streamSize()
{
return 1;
}
/**
* @brief address_type::oStream
* @return
*/
void address_type::oStream(PDU::Stream stream) const
{
uint8_t val = 0;
val |= relative << 6;
val |= type << 4;
val |= width;
*stream << val;
}
/**
* @brief range::range
* @param stream
@ -79,6 +103,17 @@ uint32_t range::read(PDU::Stream stream, address_length length)
}
/**
* @brief dmp_set_data::streamSize
* @return
*/
size_t dmp_set_data::streamSize()
{
/// TODO: verify size of data
return 71;
}
/**
* @brief Pdu::Pdu
* @param stream

View File

@ -60,6 +60,10 @@ struct address_type : PDU::pdu_header {
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;
};
// 5.1.5
@ -76,6 +80,10 @@ private:
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 {};
};
// 7 Response Messages

View File

@ -36,10 +36,10 @@ namespace PDU {
Pdu::Pdu(Stream stream, size_t vector_size)
: flags_(stream->peek())
{
header_ = nullptr;
data_ = nullptr;
parent_ = nullptr;
inherit_ = nullptr; // pointer to previous PDU in block
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

View File

@ -53,6 +53,14 @@ struct pdu_flags
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;
};
@ -62,6 +70,14 @@ struct pdu_header
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;
};
@ -115,21 +131,39 @@ private:
};
/**
* @brief Callback that understands how to proccess a PDU type.
* @tparam T PDU decendant subclass
*/
template <typename T>
using Handler = std::function<void(std::shared_ptr<T>)>;
/**
* @brief PDU::pdu_data subclass that encapsulates other PDU.
* @tparam T PDU decendant subclass
*/
template <typename T>
using Block = std::shared_ptr<std::vector<std::shared_ptr<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 {};
};
/**
@brief Template creator of a PDU Block.
@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
* @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>(new std::vector<std::shared_ptr<T>>);
auto block = Block<T>();
while(buffer->good()) {
std::shared_ptr<T> pdu(new T(buffer));
if (buffer->fail()) // stream failed during pdu constructor
@ -138,9 +172,9 @@ Block<T> readBlock(Stream buffer, std::shared_ptr<PDU::Pdu> parent = nullptr) {
continue;
if (parent) // set parent
pdu->setParent(parent);
if (!block->empty()) // set inheritee
pdu->setInherit(block->back());
block->push_back(pdu); // add to block
if (!block.pdu->empty()) // set inheritee
pdu->setInherit(block.pdu->back());
block.pdu->push_back(pdu); // add to block
}
return block;
}

View File

@ -40,19 +40,37 @@ rlp_header::rlp_header(PDU::Stream stream)
/**
* @brief operator >>
* @param stream
* @param h
* @brief rlp_header::streamSize
* @return
*/
PDU::Stream& operator>> (PDU::Stream &stream, rlp_header &h)
size_t rlp_header::streamSize()
{
uint8_t buf[16];
stream->read(buf, 16);
if (stream->gcount() != 16)
return CID_LENGTH;
}
/**
* @brief rlp_header::iStream
* @param stream
*/
void rlp_header::iStream(PDU::Stream stream)
{
uint8_t * buffer = new uint8_t[CID_LENGTH];
stream->read(buffer, CID_LENGTH);
if (stream->gcount() != CID_LENGTH)
stream->setstate(std::ios_base::failbit);
h.cid = UUID::uuid(buf);
return stream;
cid = UUID::uuid(buffer);
delete[] buffer;
}
/**
* @brief rlp_header::oStream
* @param stream
*/
void rlp_header::oStream(PDU::Stream stream) const
{
stream->write(cid.bytes(), CID_LENGTH);
}

View File

@ -31,15 +31,28 @@
namespace ACN {
namespace RLP {
// 2.6.1.2.2. Header Field in Root Layer PDUs
// The Header field in Root Layer PDUs shall contain the CID of the component
// that generated the PDU (the Source CID).
struct rlp_header : PDU::pdu_header {
#define CID_LENGTH 16
/**
* @brief 2.6.1.2.2. Header Field in Root Layer PDUs
*
* The Header field in Root Layer PDUs shall contain the CID of the component
* that generated the PDU (the Source CID).
*/
struct rlp_header : PDU::pdu_header
{
UUID::uuid cid;
rlp_header(PDU::Stream);
friend PDU::Stream& operator>> (PDU::Stream &stream, rlp_header &h);
size_t streamSize() override;
protected:
void iStream(PDU::Stream) override;
void oStream(PDU::Stream) const override;
};
/**
* @brief The RLP::Pdu class
*/
class Pdu
: public PDU::Pdu
{

View File

@ -155,6 +155,11 @@ client_pdu_header_t::client_pdu_header_t(PDU::Stream stream) {
association = stream->readType<decltype(association)>();
}
/**
* @brief ClientPdu::ClientPdu
* @param stream
*/
ClientPdu::ClientPdu(PDU::Stream stream)
: PDU::Pdu(stream, 2) // vectors are 2 octets (MID)
{

View File

@ -81,6 +81,10 @@ struct join_data_t : PDU::pdu_data {
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 {};
};
// 4.4.2 Join Accept
@ -92,6 +96,10 @@ struct join_accept_data_t : PDU::pdu_data {
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 {};
};
// 4.4.3 Join Refuse
@ -104,6 +112,10 @@ struct join_refuse_data_t : PDU::pdu_data {
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 {};
};
// 4.4.5 NAK
@ -116,6 +128,10 @@ struct nak_data_t : PDU::pdu_data {
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 {};
};
// 4.4.6 Reliable Wrapper and Unreliable Wrapper
@ -129,6 +145,10 @@ struct wrapper_data_t : PDU::pdu_data {
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 {};
};
// 4.4.7 SDT Client Block
@ -137,6 +157,10 @@ struct client_pdu_header_t : PDU::pdu_header {
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 {};
};
// Client Block PDU
@ -150,6 +174,10 @@ public:
// 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 {};
};
@ -168,11 +196,19 @@ struct channel_info_block_t {
// 4.4.9 Sessions
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 {};
};
// 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 {};
};
// 4.5.2 Channel Params
@ -180,6 +216,10 @@ 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 {};
};
// 4.5.3 Connect
@ -187,6 +227,10 @@ struct channel_params_data_t : PDU::pdu_data {
// 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 {};
};
// 4.5.5 Connect Refuse
@ -194,6 +238,10 @@ struct connect_data_t : PDU::pdu_data {
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 {};
};

View File

@ -27,7 +27,6 @@
namespace SACN {
namespace DATA {
/**
* @brief frame_header::frame_header
* @param stream
@ -39,43 +38,51 @@ frame_header::frame_header(PDU::Stream stream)
/**
* @brief operator >>
* @param stream
* @param h
* @brief frame_header::streamSize
* @return
*/
PDU::Stream& operator>> (PDU::Stream& stream, frame_header& h)
size_t frame_header::streamSize()
{
stream->read(h.source_name, 64);
if (stream->gcount() != 64)
stream->setstate(std::ios_base::failbit);
*stream >> h.priority;
*stream >> h.sync_address;
*stream >> h.sequence_number;
*stream >> h.options;
*stream >> h.universe;
return stream;
return sizeof(source_name)
+ sizeof(priority)
+ sizeof(sync_address)
+ sizeof(sequence_number)
+ sizeof(options)
+ sizeof(universe);
}
/**
* @brief operator <<
* @brief frame_header::iStream
* @param stream
* @param h
* @return
*/
PDU::Stream& operator<< (PDU::Stream &stream, const frame_header &h)
void frame_header::iStream(PDU::Stream stream)
{
stream->write(h.source_name, 64);
*stream << h.priority;
*stream << h.sync_address;
*stream << h.sequence_number;
*stream << h.options;
*stream << h.universe;
return stream;
stream->read(source_name, 64);
if (stream->gcount() != 64)
stream->setstate(std::ios_base::failbit);
*stream >> priority;
*stream >> sync_address;
*stream >> sequence_number;
*stream >> options;
*stream >> universe;
}
/**
* @brief frame_header::asStream
* @return
*/
void frame_header::oStream(PDU::Stream stream) const
{
stream->write(source_name, 64);
*stream << priority;
*stream << sync_address;
*stream << sequence_number;
*stream << options;
*stream << universe;
}
/**
* @brief Pdu::Pdu

View File

@ -40,8 +40,10 @@ struct frame_header : PDU::pdu_header {
uint8_t options;
uint16_t universe;
frame_header(PDU::Stream);
friend PDU::Stream& operator>> (PDU::Stream &stream, frame_header &h);
friend PDU::Stream& operator<< (PDU::Stream &stream, const frame_header &h);
size_t streamSize() override;
protected:
void iStream(PDU::Stream) override;
void oStream(PDU::Stream) const override;
};
// 6.2.6 E1.31 Data Packet: Options

View File

@ -39,19 +39,38 @@ frame_sync_header::frame_sync_header(PDU::Stream stream)
/**
* @brief operator >>
* @param stream
* @param h
* @brief frame_sync_header::streamSize
* @return
*/
PDU::Stream& operator>> (PDU::Stream &stream, frame_sync_header &h)
size_t frame_sync_header::streamSize()
{
*stream >> h.sequence_number;
*stream >> h.sync_address;
stream->read(h.reserved, sizeof(h.reserved));
if (stream->gcount() != sizeof(h.reserved))
return sizeof(sequence_number)
+ sizeof(sync_address)
+ sizeof(reserved);
}
/**
* @brief frame_sync_header::iStream
* @param stream
*/
void frame_sync_header::iStream(PDU::Stream stream)
{
*stream >> sequence_number;
*stream >> sync_address;
stream->read(reserved, sizeof(reserved));
if (stream->gcount() != sizeof(reserved))
stream->setstate(std::ios_base::failbit);
return stream;
}
/**
* @brief frame_sync_header::oStream
* @return
*/
void frame_sync_header::oStream(PDU::Stream stream) const
{
/// TODO: write header to stream
}
@ -66,23 +85,45 @@ frame_discovery_header::frame_discovery_header(PDU::Stream stream)
/**
* @brief operator >>
* @param stream
* @param h
* @brief frame_discovery_header::streamSize
* @return
*/
PDU::Stream& operator>> (PDU::Stream &stream, frame_discovery_header &h)
size_t frame_discovery_header::streamSize()
{
stream->read(h.source_name, sizeof(h.source_name));
if (stream->gcount() != sizeof(h.source_name))
stream->setstate(std::ios_base::failbit);
stream->read(h.reserved, sizeof(h.reserved));
if (stream->gcount() != sizeof(h.reserved))
stream->setstate(std::ios_base::failbit);
return stream;
return sizeof(source_name)
+ sizeof(reserved);
}
/**
* @brief frame_discovery_header::iStream
* @param stream
*/
void frame_discovery_header::iStream(PDU::Stream stream)
{
stream->read(source_name, sizeof(source_name));
if (stream->gcount() != sizeof(source_name))
stream->setstate(std::ios_base::failbit);
stream->read(reserved, sizeof(reserved));
if (stream->gcount() != sizeof(reserved))
stream->setstate(std::ios_base::failbit);
}
/**
* @brief frame_discovery_header::oStream
* @return
*/
void frame_discovery_header::oStream(PDU::Stream stream) const
{
/// TODO: write header to stream
}
/**
* @brief Pdu::Pdu
* @param stream
*/
Pdu::Pdu(PDU::Stream stream)
: PDU::Pdu(stream, 4) // vectors are 4 octets
{
@ -114,16 +155,34 @@ discovery_list_header::discovery_list_header(PDU::Stream stream) {
/**
* @brief operator >>
* @param stream
* @param h
* @brief discovery_list_header::streamSize
* @return
*/
PDU::Stream& operator>> (PDU::Stream &stream, discovery_list_header &h)
size_t discovery_list_header::streamSize()
{
*stream >> h.page;
*stream >> h.last_page;
return stream;
return sizeof(page)
+ sizeof(last_page);
}
/**
* @brief discovery_list_header::iStream
* @param stream
*/
void discovery_list_header::iStream(PDU::Stream stream)
{
*stream >> page;
*stream >> last_page;
}
/**
* @brief discovery_list_header::oStream
* @return
*/
void discovery_list_header::oStream(PDU::Stream stream) const
{
/// TODO: write header to stream
}

View File

@ -39,7 +39,10 @@ struct frame_sync_header : PDU::pdu_header {
uint16_t sync_address;
uint8_t reserved[2];
frame_sync_header(PDU::Stream);
friend PDU::Stream& operator>> (PDU::Stream &stream, frame_sync_header &h);
size_t streamSize() override;
protected:
void iStream(PDU::Stream) override;
void oStream(PDU::Stream) const override;
};
@ -48,7 +51,10 @@ struct frame_discovery_header : PDU::pdu_header {
uint8_t source_name[64];
uint8_t reserved[4];
frame_discovery_header(PDU::Stream);
friend PDU::Stream& operator>> (PDU::Stream &stream, frame_discovery_header &h);
size_t streamSize() override;
protected:
void iStream(PDU::Stream) override;
void oStream(PDU::Stream) const override;
};
@ -67,7 +73,10 @@ struct discovery_list_header : PDU::pdu_header {
uint8_t page;
uint8_t last_page;
discovery_list_header(PDU::Stream);
friend PDU::Stream& operator>> (PDU::Stream &stream, discovery_list_header &h);
size_t streamSize() override;
protected:
void iStream(PDU::Stream) override;
void oStream(PDU::Stream) const override;
};
class Pdu

View File

@ -112,7 +112,7 @@ void Receiver::dataReceiver(std::shared_ptr<RLP::Pdu> root) {
auto block = PDU::readBlock<DATA::Pdu>(root->stream(), root);
if (root->stream()->fail())
return;
for(auto const &frame : *block) {
for(auto const &frame : *block.pdu) {
// 6.2.1 E1.31 Data Packet: Vector
// Sources sending an E1.31 Data Packet shall set the E1.31 Layer's Vector
// to VECTOR_E131_DATA_PACKET. This value indicates that the E1.31 framing
@ -138,7 +138,7 @@ void Receiver::extendedReceiver(std::shared_ptr<RLP::Pdu> root) {
auto block = PDU::readBlock<EXTENDED::Pdu>(root->stream(), root);
if (root->stream()->fail())
return;
for(auto const &frame : *block) {
for(auto const &frame : *block.pdu) {
switch(frame->vector()) {
// 6.3 E1.31 Synchronization Packet Framing Layer
case VECTOR_E131_EXTENDED_SYNCHRONIZATION:
@ -235,7 +235,7 @@ void Receiver::dataFrameHandler(std::shared_ptr<DATA::Pdu> frame) {
auto block = PDU::readBlock<DMP::Pdu>(frame->stream(), frame);
if (frame->stream()->fail())
return;
for (auto const &dmp : *block) {
for (auto const &dmp : *block.pdu) {
// 7.2 DMP Layer: Vector
// The DMP Layer's Vector shall be set to VECTOR_DMP_SET_PROPERTY, which
// indicates a DMP Set Property message by sources. Receivers shall discard
@ -270,7 +270,7 @@ void Receiver::discoveryFrameHandler(std::shared_ptr<EXTENDED::Pdu> frame) {
if (frame->stream()->fail())
return;
for(auto const &pdu : *block) {
for(auto const &pdu : *block.pdu) {
// 8 Universe Discovery Layer
// Universe Discovery data only appears in E1.31 Universe Discovery
// Packets and shall not be included in E1.31 Data Packets or E1.31