OpenLCP/platform/qt/qsacnnode.cpp

130 lines
3.3 KiB
C++
Raw Normal View History

#include "qsacnnode.h"
#include <QDebug>
#include <QNetworkDatagram>
2021-07-30 14:40:03 -04:00
#include <QNetworkInterface>
2021-07-30 14:40:03 -04:00
/**
* @brief QSacnNode::QSacnNode
* @param parent
* @param cid
*/
2021-06-21 10:18:36 -04:00
QSacnNode::QSacnNode(QObject *parent, QUuid cid)
: Component(UUID::uuid(cid.toString().toStdString()))
2021-06-21 10:18:36 -04:00
, QUdpSocket(parent)
{
fctn_ = "OpenLCP QSacnNode";
2021-07-30 13:57:27 -04:00
bind(QHostAddress::AnyIPv4, sACN::ACN_SDT_MULTICAST_PORT);
connect(this, &QUdpSocket::readyRead,
2021-08-06 12:14:29 -04:00
this, &QSacnNode::udpReceive);
}
2021-07-30 14:40:03 -04:00
/**
* @brief QSacnNode::subscribe
* @param num
*/
void QSacnNode::subscribe(const uint16_t num)
{
if (Receiver::universe(num)) // already subscribed
return;
if (num != sACN::E131_DISCOVERY_UNIVERSE) {
qDebug() << "Subscribing to universe" << QString::number(num);
Receiver::subscribe(num);
rx_universes_.insert(num, new QSacnUniverse(this, Receiver::universe(num)));
}
2021-07-30 14:40:03 -04:00
for (QNetworkInterface &iface : QNetworkInterface::allInterfaces())
joinMulticastGroup(IPv4MulticastAddress(num), iface);
for (QNetworkInterface &iface : QNetworkInterface::allInterfaces())
joinMulticastGroup(IPv6MulticastAddress(num), iface);
}
2021-07-30 14:40:03 -04:00
/**
* @brief QSacnNode::unsubscribe
* @param num
*/
void QSacnNode::unsubscribe(const uint16_t num)
{
2021-07-30 14:40:03 -04:00
for (QNetworkInterface &iface : QNetworkInterface::allInterfaces())
leaveMulticastGroup(IPv4MulticastAddress(num), iface);
for (QNetworkInterface &iface : QNetworkInterface::allInterfaces())
leaveMulticastGroup(IPv6MulticastAddress(num), iface);
2021-07-30 14:40:03 -04:00
if (Receiver::universe(num)) {
qDebug() << "Unsubscribing from universe " << QString::number(num);
delete rx_universes_.take(num);
Receiver::unsubscribe(num);
}
}
/**
* @brief QSacnNode::create
* @param num
*/
void QSacnNode::create(const uint16_t num)
{
if (Source::universe(num)) // already subscribed
return;
Source::create(num);
tx_universes_.insert(num, new QSacnUniverse(this, Source::universe(num)));
}
/**
* @brief QSacnNode::terminate
* @param num
*/
void QSacnNode::terminate(const uint16_t num)
{
if (Source::universe(num)) {
qDebug() << "terminating universe " << QString::number(num);
delete tx_universes_.take(num);
Source::terminate(num);
}
}
2021-07-30 14:40:03 -04:00
/**
* @brief QSacnNode::UdpPayloadReceiver
*/
2021-08-06 12:14:29 -04:00
void QSacnNode::udpReceive()
{
while (hasPendingDatagrams()) {
QNetworkDatagram datagram = receiveDatagram();
// Expecting IANA registered Session Data Transport traffic
if (datagram.destinationPort() != sACN::ACN_SDT_MULTICAST_PORT)
return;
// wrap a PDU io stream around the QNetworkDatagram data buffer
ACN::PDU::Stream stream(new ACN::PDU::pdu_stream(
(uint8_t*)datagram.data().constData(),
datagram.data().length()));
2021-08-06 12:14:29 -04:00
UdpPayloadReceiver(stream);
}
}
void QSacnNode::rlpSend(const ACN::PDU::Stream stream,
const ACN::SDT::UDP::ipAddress& ip)
{
QHostAddress addr;
switch (ip.type) {
case ACN::SDT::SDT_ADDR_IPV4:
addr = QHostAddress(ip.address.ipv4.value);
break;
case ACN::SDT::SDT_ADDR_IPV6:
addr = QHostAddress(ip.address.ipv6.bytes);
break;
default:
return;
}
writeDatagram(reinterpret_cast<char*>(stream->base()), stream->size(),
addr, ip.port);
}