1
0
Fork 0

Provenance can be a POD struct

This commit is contained in:
Kevin Matz 2021-08-27 12:09:19 -04:00
parent 2a26e7fa49
commit 193899b4d7
6 changed files with 113 additions and 193 deletions

View File

@ -238,7 +238,7 @@ Universe* MergeProxyUniverse::dominant_() const
{ {
if (uni->rxRate() < (DMX::E111_DATA_LOSS_TIMEOUT / 1000.0)) if (uni->rxRate() < (DMX::E111_DATA_LOSS_TIMEOUT / 1000.0))
continue; // stale universes cannot be dominant continue; // stale universes cannot be dominant
if (!ret || uni->source()->priority() > ret->source()->priority()) if (!ret || uni->source()->priority > ret->source()->priority)
ret = uni; ret = uni;
} }
return ret; return ret;

View File

@ -25,19 +25,18 @@
#include "provenance.h" #include "provenance.h"
#include "rlp/rlp.h" #include "rlp/rlp.h"
namespace SACN { namespace sACN {
/** /**
* @brief Provenance::Provenance * @brief Provenance::Provenance
*/ */
Provenance::Provenance() Provenance::Provenance()
: cid_(UUID::uuid()) : cid(UUID::uuid())
, description_(std::string()) , source_name(std::string())
, universe_(0) , priority(100)
, priority_(100) , sync_address(0)
, sync_address_(0) , sequence_number(0)
, options_(0) , universe(0)
{} {}
@ -45,169 +44,58 @@ Provenance::Provenance()
* @brief Construct a Universe Source from an sACN frame PDU * @brief Construct a Universe Source from an sACN frame PDU
* @param pdu * @param pdu
*/ */
Provenance::Provenance(std::shared_ptr<DATA::Pdu> pdu) Provenance::Provenance(ACN::PDU::Message<DATA::Pdu> pdu)
{ {
auto root_header = static_cast<ACN::RLP::rlp_header*>(pdu->parent()->header()); auto root_header = static_cast<ACN::RLP::rlp_header*>(pdu->parent()->header());
auto frame_header = static_cast<DATA::data_header*>(pdu->header()); auto frame_header = static_cast<DATA::data_header*>(pdu->header());
cid_ = root_header->cid; cid = root_header->cid;
description_ = frame_header->source_name; source_name = frame_header->source_name;
universe_ = frame_header->universe; universe = frame_header->universe;
priority_ = frame_header->priority; priority = frame_header->priority;
sync_address_ = frame_header->sync_address; sync_address = frame_header->sync_address;
options_ = frame_header->options; sequence_number = frame_header->sequence_number;
options = frame_header->options;
}; };
/** /**
* @brief Provenance::CID * @brief Metadata is equivalent if the CID, Priority, and Universe match.
* @return
*/
const UUID::uuid Provenance::CID() const
{
return cid_;
}
/**
* @brief Provenance::description
* @return
*/
const std::string Provenance::description() const
{
return description_;
}
/**
* @brief Provenance::universe
* @return
*/
uint16_t Provenance::universe() const
{
return universe_;
}
/**
* @brief Provenance::priority
* @return
*/
uint8_t Provenance::priority() const
{
return priority_;
}
/**
* @brief Provenance::syncAddress
* @return
*/
uint16_t Provenance::syncAddress() const
{
return sync_address_;
}
/**
* @brief Provenance::isTerminated
* @return
*/
bool Provenance::isTerminated() const
{
return options_ & DATA::STREAM_TERMINATED;
}
/**
* @brief Provenance::isPreview
* @return
*/
bool Provenance::isPreview() const
{
return options_ & DATA::PREVIEW_DATA;
}
/**
* @brief Provenance::isForced
* @return
*/
bool Provenance::isForced() const
{
return options_ & DATA::FORCE_SYNCHRONIZATION;
}
/**
* @brief operator ==
* @param a * @param a
* @param b * @param b
* @return * @return
*/ */
bool operator== (const Provenance& a, const Provenance& b) bool operator== (const Provenance& a, const Provenance& b)
{ {
return (std::hash<Provenance>{}(a) == std::hash<Provenance>{}(b)); return (a.cid == b.cid &&
a.priority == b.priority &&
a.universe == b.universe);
} }
/** /**
* @brief Provenance::setCID * @brief For matching universe numbers, lower priorities are lesser.
* @param cid
*/
void Provenance::setCID(UUID::uuid cid)
{
cid_ = cid;
}
/**
* @brief Provenance::setDescription
* @param desc
*/
void Provenance::setDescription(std::string desc)
{
description_ = desc;
}
/**
* @brief Provenance::setOptions
* @param o
*/
void Provenance::setOptions(uint8_t o)
{
options_ = o;
}
/**
* @brief Provenance::setUniverse
* @param n
*/
void Provenance::setUniverse(uint16_t n)
{
if (n >= 1 && n <= 63999) universe_ = n;
}
/**
* @brief Provenance::setSyncAddress
* @param a * @param a
* @param b
* @return
*/ */
void Provenance::setSyncAddress(uint16_t a) bool operator< (const Provenance& a, const Provenance& b)
{ {
if (a >= 1 && a <= 63999) sync_address_ = a; return (a.universe == b.universe &&
a.priority < b.priority);
} }
/** /**
* @brief Provenance::setPriority * @brief For matching universe numbers, higher priorities are greater.
* @param p * @param a
* @param b
* @return
*/ */
void Provenance::setPriority(uint8_t p) bool operator> (const Provenance& a, const Provenance& b)
{ {
if (p <= 200) priority_ = p; return (a.universe == b.universe &&
a.priority > b.priority);
} }

View File

@ -29,43 +29,75 @@
#include <cstdint> #include <cstdint>
#include <string> #include <string>
namespace SACN { namespace sACN {
/** /**
* @brief The Provenance class * @brief Metadata for a sACN::Universe
*/ */
class Provenance struct Provenance
{ {
public:
Provenance(); Provenance();
Provenance(std::shared_ptr<DATA::Pdu>); explicit Provenance(ACN::PDU::Message<DATA::Pdu>);
const UUID::uuid CID() const; /// \cite sACN 5.6 CID (Component Identifier)
const std::string description() const; ///
uint16_t universe() const; /// The Root Layer contains a CID. The CID shall be compliant with RFC 4122
uint8_t priority() const; /// \cite uuid.
uint16_t syncAddress() const; UUID::uuid cid;
bool isTerminated() const;
bool isPreview() const; /// \cite sACN 6.2.2 E1.31 Data Packet: Source Name
bool isForced() const; ///
/// A user-assigned name provided by the source of the packet for use in
/// displaying the identity of a source to a user.
///
/// If the source component implements ACN discovery as defined in EPI 19
/// \cite epi19, then this name shall be the same as the UACN field specified
/// in EPI 19 \cite epi19. User-Assigned Component Names supply a single name
/// for an entire component, so this Source Name field will exist for each
/// unique CID, but may be the same across multiple universes sourced by the
/// same component.
std::string source_name;
/// \cite sACN 6.2.3 E1.31 Data Packet: Priority
///
/// Sources that do not support variable priority shall transmit a priority
/// of 100. Priority increases with numerical value, e.g., 200 is a higher
/// priority than 100.
uint8_t priority;
/// \cite sACN 6.2.4 E1.31 Data Packet: Synchronization Address
///
/// The Synchronization Address identifies a universe number to be used for
/// universe synchronization.
uint16_t sync_address;
/// \cite sACN 6.2.5 E1.31 Data Packet: Sequence Number
///
/// Sources shall maintain a sequence for each universe they
/// transmit. The sequence number for a universe shall be incremented by one
/// for every packet sent on that universe. There is no implied relationship
/// between the sequence number of an E1.31 Synchronization Packet and the
/// sequence number of an E1.31 Data Packet on that same universe.
uint8_t sequence_number;
/// \cite sACN 6.2.6 E1.31 Data Packet: Options
///
/// This bit-oriented field is used to encode optional flags that control
/// how the packet is used.
DATA::data_options options;
/// \cite sACN 6.2.7 E1.31 Data Packet: Universe
///
/// The Universe is a 16-bit field that defines the universe number of the
/// data carried in the packet. Universe values shall be limited to the range
/// 1 to 63999.
uint16_t universe;
friend bool operator== (const Provenance& a, const Provenance& b); friend bool operator== (const Provenance& a, const Provenance& b);
friend bool operator< (const Provenance& a, const Provenance& b);
void setCID(UUID::uuid cid); friend bool operator> (const Provenance& a, const Provenance& b);
void setDescription(std::string desc);
void setOptions(uint8_t o);
void setUniverse(uint16_t n);
void setSyncAddress(uint16_t a);
void setPriority(uint8_t p);
private:
UUID::uuid cid_;
std::string description_;
uint16_t universe_;
uint8_t priority_;
uint16_t sync_address_;
uint8_t options_;
}; };
} // SACN namespace } // SACN namespace
@ -75,18 +107,18 @@ namespace std
/** /**
* @brief The hash struct specilizaton for SACN::Provenance * @brief The hash struct specilizaton for SACN::Provenance
*/ */
struct hash<SACN::Provenance> struct hash<sACN::Provenance>
{ {
/** /**
* @brief operator () * @brief operator ()
* @param src * @param src
* @return * @return
*/ */
size_t operator()(SACN::Provenance const& src) const noexcept size_t operator()(sACN::Provenance const& src) const noexcept
{ {
size_t h1 = hash<string>{}(src.description()); size_t h1 = hash<string>{}(src.source_name);
size_t h2 = hash<UUID::uuid>{}(src.CID()); size_t h2 = hash<UUID::uuid>{}(src.cid);
size_t h3 = hash<int>{}(src.priority()); size_t h3 = hash<uint8_t>{}(src.priority);
size_t h = h1 ^ h2 ^ h3; // or use boost::hash_combine size_t h = h1 ^ h2 ^ h3; // or use boost::hash_combine
return h; return h;
} }

View File

@ -192,9 +192,9 @@ void Receiver::extendedReceiver(ACN::PDU::Message<ACN::RLP::Pdu> root)
void Receiver::dataFrameHandler(ACN::PDU::Message<DATA::Pdu> frame) { void Receiver::dataFrameHandler(ACN::PDU::Message<DATA::Pdu> frame) {
auto source = std::shared_ptr<Provenance>(new Provenance(frame)); auto source = std::shared_ptr<Provenance>(new Provenance(frame));
if (!universes_.count(source->universe())) if (!universes_.count(source->universe))
return; return;
auto universe = universes_.at(source->universe())->sourceUniverse(*source); auto universe = universes_.at(source->universe)->sourceUniverse(*source);
/// \cite sACN /// \cite sACN
/// 6.2.6 E1.31 Data Packet: Options /// 6.2.6 E1.31 Data Packet: Options
@ -202,7 +202,7 @@ void Receiver::dataFrameHandler(ACN::PDU::Message<DATA::Pdu> frame) {
/// This bit, when set to 1, indicates that the data in this packet is /// This bit, when set to 1, indicates that the data in this packet is
/// intended for use in visualization or media server preview applications and /// intended for use in visualization or media server preview applications and
/// shall not be used to generate live output. /// shall not be used to generate live output.
if (source->isPreview()) if (source->options.preview_data)
return; return;
/// \cite sACN /// \cite sACN
@ -212,8 +212,8 @@ void Receiver::dataFrameHandler(ACN::PDU::Message<DATA::Pdu> frame) {
/// universe synchronization without waiting for a timeout to occur. /// universe synchronization without waiting for a timeout to occur.
/// Any property values in an E1.31 Data Packet containing this bit /// Any property values in an E1.31 Data Packet containing this bit
/// shall be ignored. /// shall be ignored.
if (source->isTerminated()) { if (source->options.stream_terminated) {
universes_[source->universe()]->deleteSourceUniverse(*source); universes_[source->universe]->deleteSourceUniverse(*source);
return; return;
} }
@ -221,8 +221,8 @@ void Receiver::dataFrameHandler(ACN::PDU::Message<DATA::Pdu> frame) {
/// 6.2.4.1 Synchronization Address Usage in an E1.31 Data Packet /// 6.2.4.1 Synchronization Address Usage in an E1.31 Data Packet
/// a value of 0 in the Synchronization Address indicates that the universe /// a value of 0 in the Synchronization Address indicates that the universe
/// data is not synchronized. /// data is not synchronized.
if (source->syncAddress() != 0) if (source->sync_address != 0)
subscribe(source->syncAddress()); subscribe(source->sync_address);
// PDU data will be a block of DMP // PDU data will be a block of DMP
auto block = static_cast<ACN::PDU::Block<ACN::DMP::Pdu>*>(frame->data()); auto block = static_cast<ACN::PDU::Block<ACN::DMP::Pdu>*>(frame->data());

View File

@ -47,9 +47,9 @@ void Source::create(const uint16_t num)
universes_.emplace(num, new Universe()); universes_.emplace(num, new Universe());
auto source = std::shared_ptr<Provenance>(new Provenance()); auto source = std::shared_ptr<Provenance>(new Provenance());
source->setCID(this->cid()); source->cid = this->cid();
source->setDescription(this->name()); source->source_name = this->name();
source->setUniverse(num); source->universe = num;
universes_[num]->setProvenance(source); universes_[num]->setProvenance(source);
} }

View File

@ -127,11 +127,11 @@ TEST_F(sACNdataTest, stream_in) {
auto source = universe->source(); auto source = universe->source();
ASSERT_TRUE(source) << "stream failure"; ASSERT_TRUE(source) << "stream failure";
EXPECT_EQ(source->CID(), cid) << "UUID mismatch"; EXPECT_EQ(source->cid, cid) << "UUID mismatch";
EXPECT_EQ(source->description(), desc) << "Source Description mismatch"; EXPECT_EQ(source->source_name, desc) << "Source Description mismatch";
EXPECT_EQ(source->universe(), univ) << "universe number mismatch"; EXPECT_EQ(source->universe, univ) << "universe number mismatch";
EXPECT_EQ(source->priority(), priority) << "priority mismatch"; EXPECT_EQ(source->priority, priority) << "priority mismatch";
EXPECT_EQ(source->syncAddress(), 0) << "sync address mismatch"; EXPECT_EQ(source->sync_address, 0) << "sync address mismatch";
EXPECT_EQ(universe->slot(512), (univ & 0xff)) << "slot 512 data mismatch"; EXPECT_EQ(universe->slot(512), (univ & 0xff)) << "slot 512 data mismatch";
node.unsubscribe(univ); node.unsubscribe(univ);