move all of transmitting to the helper class
This commit is contained in:
parent
47bc2c9ffd
commit
4d7413b949
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue