1
0
Fork 0

improving PDU write support

This commit is contained in:
Kevin Matz 2021-07-29 23:40:46 -04:00
parent aaca7ea461
commit 00d769c22e
12 changed files with 151 additions and 53 deletions

View File

@ -31,7 +31,7 @@ namespace DMP {
* @brief address_type::streamSize
* @return
*/
size_t address_type::streamSize()
size_t address_type::streamSize() const
{
return 1;
}
@ -109,7 +109,7 @@ uint32_t range::read(PDU::Stream stream, const address_length length)
* @brief dmp_set_data::streamSize
* @return
*/
size_t dmp_set_data::streamSize()
size_t dmp_set_data::streamSize() const
{
/// TODO: verify size of data
return 71;

View File

@ -59,7 +59,7 @@ struct address_type : PDU::pdu_header {
data_type type : 2; // D1, D0
uint8_t x_reserved : 2; // X1, X0
address_length width : 2; // A1, A0
size_t streamSize() override;
size_t streamSize() const override;
void iStream(PDU::Stream) override;
void oStream(PDU::Stream) const override;
};
@ -77,7 +77,7 @@ private:
typedef pair<range, vector<uint8_t>> set_property;
struct dmp_set_data : PDU::pdu_data {
vector<set_property> properties;
size_t streamSize() override;
size_t streamSize() const override;
void iStream(PDU::Stream) override {};
void oStream(PDU::Stream) const override {};
};

View File

@ -36,7 +36,6 @@ namespace PDU {
Pdu::Pdu(size_t vector_size)
: vector_size_(vector_size)
{
}
@ -95,12 +94,47 @@ pdu_data * Pdu::data()
/**
* @brief Pdu::streamSize
* @return
*
* The maximum buffer size that could be required to buffer this PDU
*/
size_t Pdu::streamSize()
size_t Pdu::streamSize() const
{
return 1 /// TODO: real size of vector + flags + length
+ header_->streamSize()
+ data_->streamSize();
size_t s = 2; // flength is at least 2 octets
// plus the length of the vector
if (flags_.hasVector) {
if (inherit_) {
if (vector_ != inherit_->vector())
s += vector_size_;
} else {
s += vector_size_;
}
}
// plus the length of the header
if (header_) {
if (inherit_) {
if (header_ != inherit_->header())
s += header_->streamSize();
} else {
s += header_->streamSize();
}
}
// plus the lenth of the data
if (data_) {
if (inherit_) {
if (data_ != inherit_->data())
s += data_->streamSize();
} else {
s += data_->streamSize();
}
}
// and another bit if the length needs it
if (s > 0x0fff)
s++;
return s;
}
@ -111,12 +145,13 @@ size_t Pdu::streamSize()
void Pdu::iStream(Stream stream)
{
// get the flags
flags_ = pdu_flags(stream->peek());
flags_.set(stream->peek());
// get the length
length_ = stream->readType<uint16_t>() & 0x0fff; // high 4 bits are flags
size_t length;
length = stream->readType<uint16_t>() & 0x0fff; // high 4 bits are flags
if (flags_.hasLength)
length_ = (length_ << 8 ) | stream->readType<uint8_t>();
length = (length << 8 ) | stream->readType<uint8_t>();
// get the vector
if (flags_.hasVector)
@ -137,7 +172,7 @@ void Pdu::iStream(Stream stream)
// 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_;
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) {
@ -166,15 +201,68 @@ void Pdu::iStream(Stream stream)
*/
void Pdu::oStream(Stream stream) const
{
/// TODO: write to stream
pdu_flags flags = flags_;
size_t length = streamSize();
// check if length flag need to be set
if (length > 0x0fff)
flags.hasLength = true;
// see if we can inherit members
if (inherit_) {
if (flags.hasVector)
if (vector_ == inherit_->vector())
flags.hasVector = false;
if (flags.hasHeader)
if (header_ == inherit_->header())
flags.hasHeader = false;
if (flags.hasData)
if (data_ == inherit_->data())
flags.hasData = false;
}
// inject flags onto the high 4 bits of the length
auto flength = reinterpret_cast<uint8_t*>(length);
if (flags.hasLength)
flength[2] = (flength[2] & 0x0f) | (uint8_t)flags;
else
flength[1] = (flength[1] & 0x0f) | (uint8_t)flags;
// write the flength to stream
stream->write(flength, (flags.hasLength ? 3 : 2));
// write the vector to stream
if (flags.hasVector)
switch (vector_size_) {
case 1:
stream->writeType<uint8_t>(vector_);
break;
case 2:
stream->writeType<uint16_t>(vector_);
break;
case 4:
stream->writeType<uint32_t>(vector_);
break;
default:
stream->setstate(std::ios_base::failbit);
return;
}
// write the header to stream
if (flags.hasHeader)
header_->oStream(stream);
// write the data to steam
if (flags.hasData)
data_->oStream(stream);
}
/**
* @brief pdu_flags::pdu_flags
* @brief pdu_flags::set
* @param val
*/
pdu_flags::pdu_flags(uint8_t val)
void pdu_flags::set(const uint8_t val)
{
hasLength = (val >> 7) & 0b1;
hasVector = (val >> 6) & 0b1;

View File

@ -39,12 +39,20 @@ namespace PDU {
*/
struct pdu_flags
{
bool hasLength : 1;
bool hasVector : 1;
bool hasHeader : 1;
bool hasData : 1;
pdu_flags() {};
pdu_flags(uint8_t);
bool hasLength : 1; //!< true if pdu length is > 0x0fff
bool hasVector : 1; //!< false if Pdu inherits it's vector
bool hasHeader : 1; //!< false if Pdu inherits it's header
bool hasData : 1; //!< false if Pdu inherits it's data
pdu_flags() { set(0); }
void set(const uint8_t);
operator uint8_t() const {
uint8_t ret = 0;
if (hasLength) ret |= 0b10000000;
if (hasVector) ret |= 0b01000000;
if (hasHeader) ret |= 0b00100000;
if (hasData) ret |= 0b00010000;
return ret;
};
};
@ -54,7 +62,7 @@ struct pdu_flags
struct pdu_base_member
{
virtual ~pdu_base_member() {};
virtual size_t streamSize() = 0;
virtual size_t streamSize() const = 0;
virtual void iStream(Stream) = 0;
virtual void oStream(Stream) const = 0;
};
@ -83,31 +91,31 @@ struct pdu_data : public pdu_base_member {};
* are present in the PDU, or if they should be inherited from the
* preceding PDU.
*/
class Pdu : public pdu_base_member {
class Pdu : public pdu_data {
public:
Pdu(size_t vector_size);
~Pdu();
// getters
const pdu_flags flags() {return flags_;}
const uint32_t length() {return length_;}
const 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() override;
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 length_;
uint32_t vector_;
uint32_t vector_ = 0;
size_t vector_size_;
std::shared_ptr<Pdu> parent_ = nullptr;
std::shared_ptr<Pdu> inherit_ = nullptr;
@ -135,7 +143,7 @@ struct Block : public pdu_data
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 streamSize() const {
size_t s = 0;
for (auto &child : *pdu)
s += child->streamSize();

View File

@ -31,7 +31,7 @@ namespace RLP {
* @brief rlp_header::streamSize
* @return
*/
size_t rlp_header::streamSize()
size_t rlp_header::streamSize() const
{
return CID_LENGTH;
}

View File

@ -42,7 +42,7 @@ namespace RLP {
struct rlp_header : PDU::pdu_header
{
UUID::uuid cid;
size_t streamSize() override;
size_t streamSize() const override;
void iStream(PDU::Stream) override;
void oStream(PDU::Stream) const override;
};

View File

@ -78,7 +78,7 @@ struct join_data_t : PDU::pdu_data {
UDP::address_t destination;
params_t parameters;
uint8_t expiry;
size_t streamSize() override { return 0; }
size_t streamSize() const override { return 0; }
void iStream(PDU::Stream) override;
void oStream(PDU::Stream) const override {};
};
@ -90,7 +90,7 @@ struct join_accept_data_t : PDU::pdu_data {
MID mid;
uint32_t reliable;
uint16_t reciprocal;
size_t streamSize() override { return 0; }
size_t streamSize() const override { return 26; }
void iStream(PDU::Stream) override;
void oStream(PDU::Stream) const override {};
};
@ -103,7 +103,7 @@ struct join_refuse_data_t : PDU::pdu_data {
MID mid;
uint32_t reliable;
uint8_t code;
size_t streamSize() override { return 0; }
size_t streamSize() const override { return 25; }
void iStream(PDU::Stream) override;
void oStream(PDU::Stream) const override {};
};
@ -116,7 +116,7 @@ struct nak_data_t : PDU::pdu_data {
uint32_t reliable;
uint32_t missed_first;
uint32_t missed_last;
size_t streamSize() override { return 0; }
size_t streamSize() const override { return 32; }
void iStream(PDU::Stream) override;
void oStream(PDU::Stream) const override {};
};
@ -130,7 +130,7 @@ struct wrapper_data_t : PDU::pdu_data {
MID ack_range_begin;
MID ack_range_end;
uint16_t MAK_threshold;
size_t streamSize() override { return 0; }
size_t streamSize() const override { return 20; }
void iStream(PDU::Stream) override;
void oStream(PDU::Stream) const override {};
};
@ -139,7 +139,7 @@ struct wrapper_data_t : PDU::pdu_data {
struct client_pdu_header_t : PDU::pdu_header {
uint32_t protocol;
uint16_t association;
size_t streamSize() override;
size_t streamSize() const override;
void iStream(PDU::Stream) override;
void oStream(PDU::Stream) const override {};
};
@ -157,7 +157,7 @@ public:
// 4.4.8 Get Sessions
struct get_sessions_data_t : PDU::pdu_data {
UUID::uuid cid;
size_t streamSize() override { return 0; }
size_t streamSize() const override { return 0; }
void iStream(PDU::Stream) override {};
void oStream(PDU::Stream) const override {};
};
@ -178,7 +178,7 @@ 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; }
size_t streamSize() const override { return 0; }
void iStream(PDU::Stream) override {};
void oStream(PDU::Stream) const override {};
};
@ -186,7 +186,7 @@ struct sessions_data_t : PDU::pdu_data {
// 4.5.1 ACK
struct ack_data_t : PDU::pdu_data {
uint32_t reliable;
size_t streamSize() override { return 0; }
size_t streamSize() const override { return 4; }
void iStream(PDU::Stream) override {};
void oStream(PDU::Stream) const override {};
};
@ -196,7 +196,7 @@ struct channel_params_data_t : PDU::pdu_data {
params_t parameters;
UDP::address_t address;
uint8_t expiry;
size_t streamSize() override { return 0; }
size_t streamSize() const override { return 0; }
void iStream(PDU::Stream) override {};
void oStream(PDU::Stream) const override {};
};
@ -206,7 +206,7 @@ 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; }
size_t streamSize() const override { return 0; }
void iStream(PDU::Stream) override {};
void oStream(PDU::Stream) const override {};
};
@ -216,7 +216,7 @@ 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; }
size_t streamSize() const override { return 0; }
void iStream(PDU::Stream) override {};
void oStream(PDU::Stream) const override {};
};

View File

@ -31,7 +31,7 @@ namespace DATA {
* @brief frame_header::streamSize
* @return
*/
size_t frame_header::streamSize()
size_t frame_header::streamSize() const
{
return sizeof(source_name)
+ sizeof(priority)

View File

@ -39,7 +39,7 @@ struct frame_header : PDU::pdu_header {
uint8_t sequence_number;
uint8_t options;
uint16_t universe;
size_t streamSize() override;
size_t streamSize() const override;
void iStream(PDU::Stream) override;
void oStream(PDU::Stream) const override;
};

View File

@ -32,7 +32,7 @@ namespace EXTENDED {
* @brief frame_sync_header::streamSize
* @return
*/
size_t frame_sync_header::streamSize()
size_t frame_sync_header::streamSize() const
{
return sizeof(sequence_number)
+ sizeof(sync_address)
@ -68,7 +68,7 @@ void frame_sync_header::oStream(PDU::Stream stream) const
* @brief frame_discovery_header::streamSize
* @return
*/
size_t frame_discovery_header::streamSize()
size_t frame_discovery_header::streamSize() const
{
return sizeof(source_name)
+ sizeof(reserved);
@ -140,7 +140,7 @@ namespace DISCOVERY {
* @brief discovery_list_header::streamSize
* @return
*/
size_t discovery_list_header::streamSize()
size_t discovery_list_header::streamSize() const
{
return sizeof(page)
+ sizeof(last_page);

View File

@ -38,7 +38,7 @@ struct frame_sync_header : PDU::pdu_header {
uint8_t sequence_number;
uint16_t sync_address;
uint8_t reserved[2];
size_t streamSize() override;
size_t streamSize() const override;
void iStream(PDU::Stream) override;
void oStream(PDU::Stream) const override;
};
@ -48,7 +48,7 @@ struct frame_sync_header : PDU::pdu_header {
struct frame_discovery_header : PDU::pdu_header {
uint8_t source_name[64];
uint8_t reserved[4];
size_t streamSize() override;
size_t streamSize() const override;
void iStream(PDU::Stream) override;
void oStream(PDU::Stream) const override;
};
@ -70,7 +70,7 @@ namespace DISCOVERY {
struct discovery_list_header : PDU::pdu_header {
uint8_t page;
uint8_t last_page;
size_t streamSize() override;
size_t streamSize() const override;
void iStream(PDU::Stream) override;
void oStream(PDU::Stream) const override;
};

View File

@ -221,7 +221,9 @@ void Receiver::dataFrameHandler(std::shared_ptr<DATA::Pdu> frame) {
if (source->syncAddress() != 0) {
/// TODO: do somthing to engage synchronization
}
// If a receiver is presented with an E1.31 Data Packet containing a Synchronization Address of 0, it shall discard any data waiting to be processed and immediately act on that Data Packet.
// If a receiver is presented with an E1.31 Data Packet containing a
// Synchronization Address of 0, it shall discard any data waiting to be
// processed and immediately act on that Data Packet.
if (source->syncAddress() == 0 && universe->isSyncronized()) {
/// TODO:: do something to break synchronization
}