1
0
Fork 0

don't rely on packed structures

This commit is contained in:
Kevin Matz 2021-09-17 08:49:28 -04:00
parent c30d6a33f2
commit 6a24a9ed57
5 changed files with 91 additions and 28 deletions

View File

@ -26,6 +26,43 @@
namespace ACN::DMP {
/**
* @brief address_type::iStream
* @param stream
*/
void address_type::iStream(PDU::Stream stream)
{
auto byte = stream->readType<uint8_t>();
address_length = static_cast<element_length>(byte & 0b11);
x_reserved = (byte >> 2) & 0b11;
data_type = static_cast<data_type_t>((byte >> 4) & 0b11);
relative = byte & 0b01000000;
z_reserved = byte & 0b10000000;
*stream >> byte;
}
/**
* @brief address_type::oStream
* @param stream
*/
void address_type::oStream(PDU::Stream stream) const
{
uint8_t byte = 0;
byte |= static_cast<uint8_t>(address_length);
byte |= (x_reserved & 0b11) << 2;
byte |= static_cast<uint8_t>(data_type) << 4;
if (relative)
byte |= 0b01000000;
if (z_reserved)
byte |= 0b10000000;
*stream << byte;
}
/**
* @brief range::read_
* @param stream
@ -243,12 +280,12 @@ void Pdu::iStream(PDU::Stream stream)
auto header = std::static_pointer_cast<address_type>(this->header());
auto dataIsAddressList = [&] () {
auto dataIsAddressList = [this, header] () {
data_ = std::make_shared<address_list>(*header);
data_->iStream(stream_);
};
auto dataIsAdddresPairList = [&] () {
auto dataIsAdddresPairList = [this, header] () {
data_ = std::make_shared<address_pair_list>(*header);
data_->iStream(stream_);
};

View File

@ -63,20 +63,15 @@ enum element_length {
struct address_type
: PDU::pdu_header
{
union {
uint8_t byte = 0;
struct __attribute__((packed)) {
element_length address_length : 2; //!< A1, A0 = Size of Address elements
uint8_t x_reserved : 2; //!< X1, X0
data_type_t data_type : 2; //!< D1, D0
bool relative : 1; //!< R = Specifies whether address is relative or not.
bool z_reserved : 1; //!< Z
};
};
element_length address_length; //!< A1, A0 = Size of Address elements
uint8_t x_reserved; //!< X1, X0
data_type_t data_type; //!< D1, D0
bool relative; //!< R = Specifies whether address is relative or not.
bool z_reserved; //!< Z
size_t streamSize() const override { return 1; }
void iStream(PDU::Stream s) override { *s >> byte; }
void oStream(PDU::Stream s) const override { *s << byte; }
size_t streamSize() const override { return 1; }
void iStream(PDU::Stream) override;
void oStream(PDU::Stream) const override;
};

View File

@ -113,6 +113,35 @@ void Pdu::iStream(ACN::PDU::Stream stream)
namespace ProbeRequest {
/**
* @brief filter_t::iStream
* @param stream
*/
void filter_t::iStream(ACN::PDU::Stream stream)
{
auto val = stream->readType<uint16_t>();
client_tcp_inactive = val & 0b01;
brokers_only = val & 0b10;
reserved = val >> 2;
}
/**
* @brief filter_t::oStream
* @param stream
*/
void filter_t::oStream(ACN::PDU::Stream stream) const
{
uint16_t val = reserved << 2;
if (client_tcp_inactive)
val |= 0b01;
if (brokers_only)
val |= 0b10;
*stream << val;
}
/**
* @brief request_data::iStream
* @param stream
@ -121,7 +150,7 @@ void request_data::iStream(ACN::PDU::Stream stream)
{
*stream >> lower;
*stream >> upper;
*stream >> filter.value;
*stream >> filter;
while (stream->good())
{
known.emplace_back(RDM::UID());
@ -138,7 +167,7 @@ void request_data::oStream(ACN::PDU::Stream stream) const
{
*stream << lower;
*stream << upper;
*stream << filter.value;
*stream << filter;
for (const auto& id : known)
*stream << id;
}

View File

@ -76,15 +76,16 @@ namespace ProbeRequest {
* This bit field indicates a filter to be checked against the state of an
* LLRP Target.
*/
struct filter_t {
union {
uint16_t value = 0;
struct {
bool client_tcp_inactive : 1; //!< filter inactive clients
bool brokers_only : 1; //!< only brokers
uint16_t reserved : 14; //!< reserved bits
} __attribute__((packed));
};
struct filter_t
: ACN::PDU::pdu_stream_object
{
bool client_tcp_inactive; //!< filter inactive clients
bool brokers_only; //!< only brokers
uint16_t reserved; //!< reserved bits
size_t streamSize() const override { return 2; }
void iStream(ACN::PDU::Stream) override;
void oStream(ACN::PDU::Stream) const override;
};
@ -93,7 +94,7 @@ struct filter_t {
* Table 5-2: Probe Request PDU
*/
struct request_data
: public ACN::PDU::pdu_data
: ACN::PDU::pdu_data
{
RDM::UID lower; //!< UID of upper bound
RDM::UID upper; //!< UID of lower bound

View File

@ -348,10 +348,11 @@ void Universe::sACNsend() const
// header
auto addrtyp = std::make_shared<ACN::DMP::address_type>();
addrtyp->byte = 0;
addrtyp->address_length = ACN::DMP::TWO;
addrtyp->x_reserved = 0;
addrtyp->data_type = ACN::DMP::ARRAY;
addrtyp->relative = false;
addrtyp->z_reserved = true; // buy why? Its in the standard...
// property range
ACN::DMP::range pr(*addrtyp);