1
0
Fork 0

template header/data reading in PDU

This commit is contained in:
Kevin Matz 2021-08-15 13:16:59 -04:00
parent 83e7a8d711
commit 53406333e3
6 changed files with 141 additions and 159 deletions

View File

@ -113,9 +113,18 @@ void Appliance::RlpRegisterVector(uint32_t vect, PDU::Handler<RLP::Pdu> handle)
* @brief Appliance::SdtReceiver
* @param rlp
*/
void Appliance::SdtReceiver(__attribute__((unused)) std::shared_ptr<RLP::Pdu> rlp)
void Appliance::SdtReceiver(std::shared_ptr<RLP::Pdu> root)
{
/// TODO: handle SDT
root->createDataBlock<SDT::Pdu>();
auto block = static_cast<PDU::Block<SDT::Pdu>*>(root->data());
for(auto const &sdt : *block->pdu) {
switch(sdt->vector()) {
/// TODO: handle SDT
default:
break;
}
}
}
@ -125,20 +134,16 @@ void Appliance::SdtReceiver(__attribute__((unused)) std::shared_ptr<RLP::Pdu> rl
*/
void Appliance::DmpReceiver(std::shared_ptr<RLP::Pdu> root)
{
auto block = PDU::Block<DMP::Pdu>();
block.iStream(root->stream());
if (root->stream()->fail())
return;
block.setParent(std::shared_ptr<RLP::Pdu>(root));
root->setData(&block);
root->createDataBlock<DMP::Pdu>();
auto block = static_cast<PDU::Block<DMP::Pdu>*>(root->data());
for(auto const &dmp : *block.pdu) {
for(auto const &dmp : *block->pdu) {
switch(dmp->vector()) {
/// TODO: DMP in root
default:
break;
}
}
/// TODO: DMP in root
}
}; // ACN

View File

@ -132,25 +132,19 @@ Pdu::Pdu()
*/
void Pdu::iStream(PDU::Stream stream)
{
PDU::Pdu::iStream(stream); //! do base class first
PDU::Pdu::iStream(stream);
if (stream->fail()) return;
if (!stream_->good()) return;
if (flags_.hasHeader)
{
header_ = new address_type();
header_->iStream(stream_);
}
createHeader<address_type>();
createData<dmp_set_data>();
if (flags_.hasData) {
switch(vector()) {
case SET_PROPERTY:
readSetData();
break;
default:
break;
switch(vector()) {
case SET_PROPERTY:
readSetData();
break;
default:
break;
}
}
}
@ -159,14 +153,11 @@ void Pdu::iStream(PDU::Stream stream)
*/
void Pdu::readSetData()
{
// header may be inherited. check that one exists
if (!header()) {
stream_->setstate(std::ios_base::failbit);
if (!flags_.hasData)
return;
}
auto header = (address_type*)this->header();
auto data = new dmp_set_data();
auto header = static_cast<address_type*>(this->header());
auto data = static_cast<dmp_set_data*>(data_);
while(stream_->good()) {
// Property Address
@ -174,7 +165,7 @@ void Pdu::readSetData()
if (!stream_->good() || pr.count * pr.incriment > stream_->available()) {
stream_->setstate(std::ios_base::failbit);
break;
return;
}
// Property Data
@ -191,7 +182,6 @@ void Pdu::readSetData()
if (stream_->available() < header->width * (header->type == SINGLE? 1 : 3))
stream_->setstate(std::ios_base::eofbit);
}
data_ = data;
}
} // DMP

144
acn/pdu.h
View File

@ -31,6 +31,8 @@
namespace ACN {
namespace PDU {
class Pdu; // forward declare
/**
* @brief 2.4.1. Flags
*
@ -68,62 +70,6 @@ struct pdu_header : public pdu_stream_object {};
struct pdu_data : public pdu_stream_object {};
/**
* @brief The Pdu class
*
* All PDU share common structure of:
* flags, length, vector,
* and protocol specific header/data.
*
* Flag values indicate if lenght, vector, header or data
* are present in the PDU, or if they should be inherited from the
* preceding PDU.
*/
class Pdu
: public std::enable_shared_from_this<Pdu>
, public pdu_data
{
public:
Pdu(size_t vector_size);
~Pdu();
// getters
uint32_t vector(); // may inherit
pdu_header * header(); // may inherit
pdu_data * data(); // may inherit
std::shared_ptr<Pdu> parent() {return parent_;}
Stream stream() {return stream_;}
virtual size_t streamSize() const override;
virtual void iStream(Stream) override;
virtual void oStream(Stream) const override;
// setters
void setVector (const uint32_t v) { vector_ = v; flags_.hasVector = true; }
void setHeader (pdu_header * h) { header_ = h; flags_.hasHeader = true; }
void setData (pdu_data * d) { data_ = d; flags_.hasData = true; }
void setParent (std::shared_ptr<Pdu> pdu) {parent_ = pdu;}
void setInherit(std::shared_ptr<Pdu> pdu) {inherit_ = pdu;}
protected:
pdu_flags flags_;
uint32_t vector_ = 0;
size_t vector_size_;
std::shared_ptr<Pdu> parent_;
std::shared_ptr<Pdu> inherit_;
pdu_header * header_ = nullptr;
pdu_data * data_ = nullptr;
Stream stream_;
};
/**
* @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
@ -165,5 +111,91 @@ struct Block
};
/**
* @brief The Pdu class
*
* All PDU share common structure of:
* flags, length, vector,
* and protocol specific header/data.
*
* Flag values indicate if lenght, vector, header or data
* are present in the PDU, or if they should be inherited from the
* preceding PDU.
*/
class Pdu
: public std::enable_shared_from_this<Pdu>
, public pdu_data
{
public:
Pdu(size_t vector_size);
~Pdu();
// getters
uint32_t vector(); // may inherit
pdu_header * header(); // may inherit
pdu_data * data(); // may inherit
std::shared_ptr<Pdu> parent() {return parent_;}
Stream stream() {return stream_;}
virtual size_t streamSize() const override;
virtual void iStream(Stream) override;
virtual void oStream(Stream) const override;
// setters
void setVector (const uint32_t v) { vector_ = v; flags_.hasVector = true; }
void setHeader (pdu_header * h) { header_ = h; flags_.hasHeader = true; }
void setData (pdu_data * d) { data_ = d; flags_.hasData = true; }
void setParent (std::shared_ptr<Pdu> pdu) {parent_ = pdu;}
void setInherit(std::shared_ptr<Pdu> pdu) {inherit_ = pdu;}
// protocol payloads
template<class T>
void createHeader()
{
if (flags_.hasHeader)
{
header_ = new T();
if (stream_->good())
header_->iStream(stream_);
}
}
template<class T>
void createData()
{
if (flags_.hasData)
{
data_ = new T();
if (stream_->good())
data_->iStream(stream_);
}
}
template<class T>
void createDataBlock() {
auto block = new PDU::Block<T>();
block->iStream(stream_);
block->setParent(shared_from_this());
data_ = block;
}
protected:
pdu_flags flags_;
uint32_t vector_ = 0;
size_t vector_size_;
std::shared_ptr<Pdu> parent_;
std::shared_ptr<Pdu> inherit_;
pdu_header * header_ = nullptr;
pdu_data * data_ = nullptr;
Stream stream_;
};
/**
* @brief Callback that understands how to proccess a PDU type.
* @tparam T PDU decendant subclass
*/
template <class T>
using Handler = std::function<void(std::shared_ptr<T>)>;
} // PDU
} // ACN

View File

@ -92,21 +92,9 @@ void Pdu::iStream(PDU::Stream stream)
{
PDU::Pdu::iStream(stream);
if (stream->fail()) return;
if (!stream_->good()) return;
if (flags_.hasHeader)
{
header_ = new data_header();
header_->iStream(stream_);
}
if (flags_.hasData)
{
data_ = new PDU::Block<DMP::Pdu>();
data_->iStream(stream_);
static_cast<PDU::Block<DMP::Pdu>*>(data_)
->setParent(shared_from_this());
}
createHeader<data_header>();
createDataBlock<DMP::Pdu>();
}
} // DATA

View File

@ -113,39 +113,21 @@ 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 sync_header();
header_->iStream(stream_);
}
break;
case VECTOR_E131_EXTENDED_DISCOVERY:
{
header_ = new discovery_header();
header_->iStream(stream_);
}
break;
default:
break;
}
if (flags_.hasData)
switch (vector_) {
case VECTOR_E131_EXTENDED_DISCOVERY:
{
data_ = new PDU::Block<DISCOVERY::Pdu>();
data_->iStream(stream_);
static_cast<PDU::Block<DISCOVERY::Pdu>*>(data_)
->setParent(shared_from_this());
}
break;
default:
break;
switch(vector_)
{
case VECTOR_E131_EXTENDED_SYNCHRONIZATION:
createHeader<sync_header>();
break;
case VECTOR_E131_EXTENDED_DISCOVERY:
{
createHeader<discovery_header>();
createDataBlock<DISCOVERY::Pdu>();
}
break;
default:
break;
}
}
namespace DISCOVERY {
@ -225,19 +207,12 @@ void Pdu::iStream(PDU::Stream stream)
{
PDU::Pdu::iStream(stream);
if (stream->fail()) return;
if (!stream_->good()) return;
if (flags_.hasHeader)
createHeader<discovery_list_header>();
createData<discovery_list_data>();
if (data_)
{
header_ = new discovery_list_header();
header_->iStream(stream_);
}
if (flags_.hasData)
{
data_ = new discovery_list_data();
data_->iStream(stream_);
auto data = static_cast<discovery_list_data*>(data_);
auto root_header = static_cast<RLP::rlp_header*>(parent_->parent()->header());
auto frame_header = static_cast<EXTENDED::discovery_header*>(parent_->header());

View File

@ -124,14 +124,10 @@ void Receiver::onDiscovered(const EXTENDED::DISCOVERY::Watcher cb) {
*/
void Receiver::dataReceiver(std::shared_ptr<RLP::Pdu> root)
{
auto block = PDU::Block<DATA::Pdu>();
block.iStream(root->stream());
if (root->stream()->fail())
return;
block.setParent(std::shared_ptr<ACN::PDU::Pdu>(root));
root->setData(&block);
root->createDataBlock<DATA::Pdu>();
auto block = static_cast<PDU::Block<DATA::Pdu>*>(root->data());
for(auto const &frame : *block.pdu)
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
@ -156,14 +152,10 @@ void Receiver::dataReceiver(std::shared_ptr<RLP::Pdu> root)
*/
void Receiver::extendedReceiver(std::shared_ptr<RLP::Pdu> root)
{
auto block = PDU::Block<EXTENDED::Pdu>();
block.iStream(root->stream());
if (root->stream()->fail())
return;
block.setParent(std::shared_ptr<ACN::PDU::Pdu>(root));
root->setData(&block);
root->createDataBlock<EXTENDED::Pdu>();
auto block = static_cast<PDU::Block<EXTENDED::Pdu>*>(root->data());
for(auto const &frame : *block.pdu)
for(auto const &frame : *block->pdu)
{
switch(frame->vector()) {
// 6.3 E1.31 Synchronization Packet Framing Layer