1
0
Fork 0

move all of transmitting to the helper class

This commit is contained in:
Kevin Matz 2022-12-08 21:22:20 -05:00
parent 47bc2c9ffd
commit 4d7413b949
4 changed files with 90 additions and 85 deletions

View File

@ -22,7 +22,6 @@
SOFTWARE.
*/
#include "source.h"
#include "universe.h"
namespace sACN {
@ -35,7 +34,6 @@ Universe::Universe(Source* src)
: DMX::Universe(E131_NETWORK_DATA_LOSS_TIMEOUT)
, ACN::DMP::Component(UUID::uuid(), "OpenLCP sACN Universe")
, metadata_(std::make_shared<DATA::data_header>())
, source_(src)
, active_data_slots_(1) // start code
, sync_sequence_(0)
, sender_(nullptr)
@ -44,10 +42,7 @@ Universe::Universe(Source* src)
// create a sending thread
if (src)
sender_ = new UniverseSender(this);
// add ourself as a sender of our own DMP messages
addDmpSender(std::bind(&Universe::dataFrameSender, this, std::placeholders::_1));
sender_ = new UniverseSender(src, this);
}
@ -162,7 +157,7 @@ bool Universe::isSyncronized()
*/
bool Universe::isEditable() const
{
return source_;
return sender_;
}
@ -324,71 +319,4 @@ void Universe::setSyncData(const std::vector<uint8_t> & data)
sync_data_ = new std::vector<uint8_t>(data);
}
/**
* @brief Universe::as_DMP_
* @return
*/
ACN::PDU::Message<ACN::DMP::Pdu> Universe::as_DMP_() const
{
// header
auto addrtyp = std::make_shared<ACN::DMP::address_type>();
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);
pr.address = 0;
pr.incriment = 1;
pr.count = active_data_slots_ < null_start_data.size() ? active_data_slots_ : null_start_data.size();
// property data
std::vector<octet> pd;
std::copy_n(null_start_data.begin(), pr.count, std::back_inserter(pd));
// data segment
auto addrlst = std::make_shared<ACN::DMP::address_pair_list>(*addrtyp);
addrlst->properties.emplace_back(ACN::DMP::address_data_pair(pr, pd));
// DMP layer
auto dmp = std::make_shared<ACN::DMP::Pdu>();
dmp->setVector(ACN::DMP::SET_PROPERTY);
dmp->setHeader(addrtyp);
dmp->setData(addrlst);
return dmp;
}
/**
* @brief Universe::dataFrameSender
* @param dmp
*/
void Universe::dataFrameSender(ACN::PDU::Message<ACN::DMP::Pdu> dmp) const
{
// sACN Framing Layer
auto frame = std::make_shared<DATA::Pdu>();
frame->setVector(VECTOR_E131_DATA_PACKET);
frame->setHeader(metadata_);
frame->setData(dmp);
// send
switch (destination.type)
{
case ACN::SDT::SDT_ADDR_NULL:
source_->rlpSendUdp(VECTOR_ROOT_E131_DATA, frame,
IPv4MulticastAddress(metadata_->universe));
source_->rlpSendUdp(VECTOR_ROOT_E131_DATA, frame,
IPv6MulticastAddress(metadata_->universe));
break;
default:
source_->rlpSendUdp(VECTOR_ROOT_E131_DATA, frame, destination);
}
}
}; // namespace SACN

View File

@ -34,8 +34,6 @@
namespace sACN {
class Source; ///< forward declare from "sacn/source.h"
/**
* @brief \cite sACN 3.2 Universe
*
@ -95,8 +93,6 @@ public:
};
protected:
void dataFrameSender(ACN::PDU::Message<ACN::DMP::Pdu>) const;
// ACN::DMP::Component overrides
virtual void rxDmpGetProperty(ACN::PDU::Message<ACN::DMP::Pdu>) override;
virtual void rxDmpSetProperty(ACN::PDU::Message<ACN::DMP::Pdu>) override;
@ -105,7 +101,6 @@ protected:
private:
std::shared_ptr<DATA::data_header> metadata_;
std::vector<uint8_t> * sync_data_ = nullptr;
Source* source_;
/**
* @brief \cite sACN 3.7 Active Data Slots
@ -132,7 +127,6 @@ private:
uint8_t sync_sequence_;
UniverseSender * sender_;
ACN::PDU::Message<ACN::DMP::Pdu> as_DMP_() const;
};
} // SACN namespace

View File

@ -23,23 +23,45 @@
*/
#include "universesender.h"
#include "universe.h"
#include "source.h"
namespace sACN {
/**
* @brief UniverseSender::UniverseSender
* @param source
* @param universe
*/
UniverseSender::UniverseSender(Universe * universe)
: mUniverse(universe)
UniverseSender::UniverseSender(Source * source, Universe * universe)
: mSource(source)
, mUniverse(universe)
, terminated_resend(3)
, minimum_update_time(22700)
, last_null_data({0})
, retransmission_count(0)
, keep_alive_interval(800)
, enable_(true)
, worker_(&UniverseSender::loop_, this)
, dmp_(std::make_shared<ACN::DMP::Pdu>())
{
// add ourself as a sender for DMP messages
mUniverse->addDmpSender(std::bind(&UniverseSender::dataFrameSender, this,
std::placeholders::_1));
// header segment
auto addrtyp = std::make_shared<ACN::DMP::address_type>();
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...
// DMP layer
dmp_->setVector(ACN::DMP::SET_PROPERTY);
dmp_->setHeader(addrtyp);
update_dmp_(); // initial data segment
// start the thread after setting up the PDU
worker_ = std::thread(&UniverseSender::loop_, this);
}
@ -119,6 +141,7 @@ void UniverseSender::loop_()
{
last_null_data = mUniverse->null_start_data;
retransmission_count = 0;
update_dmp_();
}
mUniverse->null_start_mutex.unlock();
if (++retransmission_count > 3)
@ -138,7 +161,7 @@ void UniverseSender::loop_()
}
// send the sACN message
mUniverse->sendDMP(mUniverse->as_DMP_());
mUniverse->sendDMP(dmp_);
mUniverse->last_updated_ = std::chrono::system_clock::now();
/// > \cite sACN 6.2.5 E1.31 Data Packet: Sequence Number
/// >
@ -152,4 +175,57 @@ void UniverseSender::loop_()
}
/**
* @brief UniverseSender::update_dmp_
*/
void UniverseSender::update_dmp_()
{
// header segment
auto addrtyp = std::static_pointer_cast<ACN::DMP::address_type>(dmp_->header());
// property range
ACN::DMP::Range pr(*addrtyp);
pr.address = 0;
pr.incriment = 1;
pr.count = mUniverse->active_data_slots_ < mUniverse->null_start_data.size()
? mUniverse->active_data_slots_
: mUniverse->null_start_data.size();
// property data
std::vector<octet> pd;
std::copy_n(mUniverse->null_start_data.begin(), pr.count, std::back_inserter(pd));
// data segment
auto addrlst = std::make_shared<ACN::DMP::address_pair_list>(*addrtyp);
addrlst->properties.emplace_back(ACN::DMP::address_data_pair(pr, pd));
dmp_->setData(addrlst);
}
/**
* @brief Universe::dataFrameSender
* @param dmp
*/
void UniverseSender::dataFrameSender(ACN::PDU::Message<ACN::DMP::Pdu> dmp) const
{
// sACN Framing Layer
auto frame = std::make_shared<DATA::Pdu>();
frame->setVector(VECTOR_E131_DATA_PACKET);
frame->setHeader(mUniverse->metadata_);
frame->setData(dmp);
// send
switch (mUniverse->destination.type)
{
case ACN::SDT::SDT_ADDR_NULL:
mSource->rlpSendUdp(VECTOR_ROOT_E131_DATA, frame,
IPv4MulticastAddress(mUniverse->metadata_->universe));
mSource->rlpSendUdp(VECTOR_ROOT_E131_DATA, frame,
IPv6MulticastAddress(mUniverse->metadata_->universe));
break;
default:
mSource->rlpSendUdp(VECTOR_ROOT_E131_DATA, frame, mUniverse->destination);
}
}
} // namespace sACN

View File

@ -24,6 +24,7 @@
#pragma once
#include "../dmx/universe.h"
#include "dmp.h"
#include <condition_variable>
#include <memory>
#include <thread>
@ -31,6 +32,7 @@
namespace sACN {
class Universe;
class Source;
/**
* @brief The UniverseSender class
@ -38,7 +40,7 @@ class Universe;
class UniverseSender
{
public:
UniverseSender(Universe *);
UniverseSender(Source*, Universe *);
~UniverseSender();
bool isSending();
@ -47,6 +49,7 @@ public:
void kill();
private:
Source * mSource;
Universe * mUniverse;
/// \cite sACN 6.2.6 E1.31 Data Packet: Options - Stream_Terminated
@ -83,6 +86,10 @@ private:
std::condition_variable_any request_;
std::thread worker_;
void loop_();
void update_dmp_();
ACN::PDU::Message<ACN::DMP::Pdu> dmp_;
void dataFrameSender(ACN::PDU::Message<ACN::DMP::Pdu>) const;
};
} // namespace sACN