Skip to content

Commit

Permalink
plugins/artnet: conform ArtPollReply to v4 specs (fix mcallegari#1541)
Browse files Browse the repository at this point in the history
  • Loading branch information
mcallegari committed Apr 25, 2024
1 parent e0dc567 commit e77f7ef
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 25 deletions.
19 changes: 13 additions & 6 deletions plugins/artnet/src/artnetcontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
#include <QStringList>
#include <QDebug>

#define POLL_INTERVAL_MS 5000
#define POLL_INTERVAL_MS 3000
#define SEND_INTERVAL_MS 2000

#define TRANSMIT_STANDARD "Standard"
Expand Down Expand Up @@ -429,9 +429,16 @@ bool ArtNetController::handleArtNetPoll(QByteArray const& datagram, QHostAddress
qDebug() << "[ArtNet] ArtPoll received";
#endif
QByteArray pollReplyPacket;
m_packetizer->setupArtNetPollReply(pollReplyPacket, m_ipAddr, m_MACAddress);
m_udpSocket->writeDatagram(pollReplyPacket, senderAddress, ARTNET_PORT);
++m_packetSent;
for (QMap<quint32, UniverseInfo>::iterator it = m_universeMap.begin(); it != m_universeMap.end(); ++it)
{
quint32 universe = it.key();
UniverseInfo &info = it.value();
bool isInput = (info.type & Input) ? true : false;

m_packetizer->setupArtNetPollReply(pollReplyPacket, m_ipAddr, m_MACAddress, universe, isInput);
m_udpSocket->writeDatagram(pollReplyPacket, senderAddress, ARTNET_PORT);
++m_packetSent;
}
++m_packetReceived;
return true;
}
Expand All @@ -451,7 +458,7 @@ bool ArtNetController::handleArtNetDmx(QByteArray const& datagram, QHostAddress
#if _DEBUG_RECEIVED_PACKETS
qDebug() << "[ArtNet] DMX data received. Universe:" << artnetUniverse << ", Data size:" << dmxData.size()
<< ", data[0]=" << (int)dmxData[0]
<< ", from=" << senderAddress.toString();
<< ", from=" << QHostAddress(senderAddress.toIPv4Address()).toString();
#endif

for (QMap<quint32, UniverseInfo>::iterator it = m_universeMap.begin(); it != m_universeMap.end(); ++it)
Expand Down Expand Up @@ -524,7 +531,7 @@ bool ArtNetController::handlePacket(QByteArray const& datagram, QHostAddress con
// return false;

#if _DEBUG_RECEIVED_PACKETS
qDebug() << "Received packet with size: " << datagram.size() << ", host: " << senderAddress.toString();
qDebug() << "Received packet with size: " << datagram.size() << ", host: " << QHostAddress(senderAddress.toIPv4Address()).toString();
#endif
quint16 opCode = -1;

Expand Down
46 changes: 30 additions & 16 deletions plugins/artnet/src/artnetpacketizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ void ArtNetPacketizer::setupArtNetPoll(QByteArray& data)
data.append('\0'); // Priority
}

void ArtNetPacketizer::setupArtNetPollReply(QByteArray &data, QHostAddress ipAddr, QString MACaddr)
void ArtNetPacketizer::setupArtNetPollReply(QByteArray &data, QHostAddress ipAddr, QString MACaddr, quint32 universe, bool isInput)
{
int i = 0;
data.clear();
Expand All @@ -87,28 +87,42 @@ void ArtNetPacketizer::setupArtNetPollReply(QByteArray &data, QHostAddress ipAdd
data.append((char)0xF0); // Status1 - Ready and booted
data.append((char)0xFF); // ESTA Manufacturer MSB
data.append((char)0xFF); // ESTA Manufacturer LSB

data.append("QLC+"); // Short Name
for (i = 0; i < 14; i++)
data.append((char)0x00); // 14 bytes of stuffing
data.append("Q Light Controller Plus - ArtNet interface"); // Long Name
for (i = 0; i < 22; i++) // 64-42 bytes of stuffing. 42 is the length of the long name
data.append((char)0x00);

for (i = 0; i < 64; i++)
data.append((char)0x00); // Node report
data.append((char)0x00); // NumPort MSB
// FIXME: this should reflect the actual state of QLC+ output ports !
data.append((char)0x01); // NumPort LSB
data.append((char)0x80); // Port 1 type: can output DMX512 data
data.append((char)0x80); // Port 2 type: can output DMX512 data
data.append((char)0x80); // Port 3 type: can output DMX512 data
data.append((char)0x80); // Port 4 type: can output DMX512 data
// FIXME: this should reflect the actual state of QLC+ output ports !
for (i = 0; i < 12; i++)
data.append((char)0x00); // Set GoodInput[4], GoodOutput[4] and SwIn[4] all to unknown state
data.append((char)0x00); // SwOut0 - output 0
data.append((char)0x01); // SwOut1 - output 1
data.append((char)0x02); // SwOut2 - output 2
data.append((char)0x03); // SwOut3 - output 3
data.append((char)0x00); // NumPortsHi
data.append((char)0x01); // NumPortsLo
data.append(isInput ? (char)0x40 : (char)0x80); // PortTypes[0]: can input or output DMX512 data
data.append((char)0x00); // PortTypes[1]: nothing
data.append((char)0x00); // PortTypes[2]: nothing
data.append((char)0x00); // PortTypes[3]: nothing

data.append(isInput ? (char)0x80 : (char)0x00); // GoodInput[0] - input status port 1
data.append((char)0x00); // GoodInput[1] - input status port 2
data.append((char)0x00); // GoodInput[2] - input status port 3
data.append((char)0x00); // GoodInput[3] - input status port 4

data.append(isInput ? (char)0x00 : (char)0x80); // GoodOutputA[0] - output status port 1
data.append((char)0x00); // GoodOutputA[0] - output status port 2
data.append((char)0x00); // GoodOutputA[0] - output status port 3
data.append((char)0x00); // GoodOutputA[0] - output status port 4

data.append(isInput ? (char)universe : (char)0x00); // SwIn[0] - port 1
data.append((char)0x00); // SwIn[1] - port 2
data.append((char)0x00); // SwIn[2] - port 3
data.append((char)0x00); // SwIn[3] - port 4

data.append(isInput ? (char)0x00 : (char)universe); // SwOut[0] - port 1
data.append((char)0x00); // SwOut[1] - port 2
data.append((char)0x00); // SwOut[2] - port 3
data.append((char)0x00); // SwOut[3] - port 4
for (i = 0; i < 7; i++)
data.append((char)0x00); // SwVideo, SwMacro, SwRemote and 4 spare bytes
QStringList MAC = MACaddr.split(":");
Expand Down Expand Up @@ -208,7 +222,7 @@ bool ArtNetPacketizer::checkPacketAndCode(QByteArray const& data, quint16 &code)
if (data.at(7) != 0x00)
return false;

code = ((int)data.at(9) << 8) + data.at(8);
code = (quint16(data.at(9)) << 8) + quint16(data.at(8));

return true;
}
Expand Down
3 changes: 2 additions & 1 deletion plugins/artnet/src/artnetpacketizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ class ArtNetPacketizer
void setupArtNetPoll(QByteArray& data);

/** Prepare an ArtNetPollReply packet */
void setupArtNetPollReply(QByteArray &data, QHostAddress ipAddr, QString MACaddr);
void setupArtNetPollReply(QByteArray &data, QHostAddress ipAddr,
QString MACaddr, quint32 universe, bool isInput);

/** Prepare an ArtNetDmx packet */
void setupArtNetDmx(QByteArray& data, const int& universe, const QByteArray &values);
Expand Down
2 changes: 1 addition & 1 deletion plugins/artnet/src/artnetplugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,7 @@ void ArtNetPlugin::slotReadyRead()

void ArtNetPlugin::handlePacket(QByteArray const& datagram, QHostAddress const& senderAddress)
{
// A firts filter: look for a controller on the same subnet as the sender.
// A first filter: look for a controller on the same subnet as the sender.
// This allows having the same ArtNet Universe on 2 different network interfaces.
foreach (ArtNetIO io, m_IOmapping)
{
Expand Down
2 changes: 1 addition & 1 deletion plugins/artnet/src/configureartnet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ void ConfigureArtNet::fillNodesTree()
it.next();
QTreeWidgetItem* nitem = new QTreeWidgetItem(pitem);
ArtNetNodeInfo nInfo = it.value();
nitem->setText(KNodesColumnIP, it.key().toString());
nitem->setText(KNodesColumnIP, QHostAddress(it.key().toIPv4Address()).toString());
nitem->setText(KNodesColumnShortName, nInfo.shortName);
nitem->setText(KNodesColumnLongName, nInfo.longName);
}
Expand Down

0 comments on commit e77f7ef

Please sign in to comment.