aboutsummaryrefslogtreecommitdiffstats
path: root/src/Xpl2Client.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Xpl2Client.cpp')
-rw-r--r--src/Xpl2Client.cpp204
1 files changed, 132 insertions, 72 deletions
diff --git a/src/Xpl2Client.cpp b/src/Xpl2Client.cpp
index d3a6da2..4fa502e 100644
--- a/src/Xpl2Client.cpp
+++ b/src/Xpl2Client.cpp
@@ -5,6 +5,7 @@
#include "Xpl2Client.h"
#include <QDebug>
+#include <QTcpSocket>
bool Xpl2Client::s_wireDebug = false;
@@ -157,36 +158,19 @@ Xpl2Client::s_responseTable = {
Xpl2Client::Xpl2Client (QObject *parent) : QObject (parent)
{
- for (auto *socket : { &m_commandSocket, &m_imagingSocket, &m_statusSocket })
- {
- connect (socket, &QTcpSocket::connected, this,
- &Xpl2Client::onSocketConnected);
- connect (socket, &QTcpSocket::disconnected, this,
- &Xpl2Client::onSocketDisconnected);
- connect (socket, &QTcpSocket::readyRead, this,
- &Xpl2Client::onSocketMessageReady);
- connect (socket, &QAbstractSocket::errorOccurred, this,
- &Xpl2Client::onSocketError);
- }
+ setupServer (m_commandServer, m_commandPort);
+ setupServer (m_imagingServer, m_imagingPort);
+ setupServer (m_statusServer, m_statusPort);
}
/* ------------------------------------------------------------------ */
/* Properties */
/* ------------------------------------------------------------------ */
-QString
-Xpl2Client::host () const
-{
- return m_host;
-}
-
-void
-Xpl2Client::setHost (const QString &host)
+bool
+Xpl2Client::isListening () const
{
- if (m_host == host)
- return;
- m_host = host;
- emit hostChanged ();
+ return m_listening;
}
bool
@@ -230,25 +214,78 @@ Xpl2Client::enableWireDebug ()
/* ------------------------------------------------------------------ */
void
-Xpl2Client::connectToServer ()
+Xpl2Client::setupServer (QTcpServer &server, quint16 port)
+{
+ Q_UNUSED (port)
+ connect (&server, &QTcpServer::newConnection, this,
+ &Xpl2Client::onNewConnection);
+}
+
+void
+Xpl2Client::startListening ()
{
- if (m_connected)
+ if (m_listening)
{
- emit statusMessage (QStringLiteral ("Already connected"));
+ emit statusMessage (QStringLiteral ("Already listening"));
return;
}
- emit statusMessage (QStringLiteral ("Connecting to %1…").arg (m_host));
- m_commandSocket.connectToHost (m_host, m_commandPort);
- m_imagingSocket.connectToHost (m_host, m_imagingPort);
- m_statusSocket.connectToHost (m_host, m_statusPort);
+ if (!m_commandServer.listen (QHostAddress::Any, m_commandPort)
+ || !m_imagingServer.listen (QHostAddress::Any, m_imagingPort)
+ || !m_statusServer.listen (QHostAddress::Any, m_statusPort))
+ {
+ emit errorOccurred (QStringLiteral ("Failed to listen: %1 / %2 / %3")
+ .arg (m_commandServer.errorString ())
+ .arg (m_imagingServer.errorString ())
+ .arg (m_statusServer.errorString ()));
+ m_commandServer.close ();
+ m_imagingServer.close ();
+ m_statusServer.close ();
+ return;
+ }
+ m_listening = true;
+ emit listeningChanged ();
+ emit statusMessage (QStringLiteral ("Listening on ports %1/%2/%3…")
+ .arg (m_commandPort)
+ .arg (m_imagingPort)
+ .arg (m_statusPort));
}
void
-Xpl2Client::disconnectFromServer ()
+Xpl2Client::stopListening ()
+{
+ m_commandServer.close ();
+ m_imagingServer.close ();
+ m_statusServer.close ();
+
+ auto cleanup = [] (QTcpSocket *&sock)
+ {
+ if (sock)
+ {
+ sock->disconnectFromHost ();
+ sock->deleteLater ();
+ sock = nullptr;
+ }
+ };
+ cleanup (m_commandSocket);
+ cleanup (m_imagingSocket);
+ cleanup (m_statusSocket);
+
+ if (m_listening)
+ {
+ m_listening = false;
+ emit listeningChanged ();
+ }
+ updateConnectedState ();
+}
+
+QTcpSocket *&
+Xpl2Client::socketForServer (QTcpServer *server)
{
- m_commandSocket.disconnectFromHost ();
- m_imagingSocket.disconnectFromHost ();
- m_statusSocket.disconnectFromHost ();
+ if (server == &m_commandServer)
+ return m_commandSocket;
+ if (server == &m_imagingServer)
+ return m_imagingSocket;
+ return m_statusSocket;
}
void
@@ -609,22 +646,22 @@ Xpl2Client::imageCount ()
/* ------------------------------------------------------------------ */
void
-Xpl2Client::sendCommand (QTcpSocket &socket, const QByteArray &command,
+Xpl2Client::sendCommand (QTcpSocket *socket, const QByteArray &command,
const QVariantList &params)
{
- if (socket.state () != QAbstractSocket::ConnectedState)
+ if (!socket || socket->state () != QAbstractSocket::ConnectedState)
{
emit errorOccurred (QStringLiteral ("Not connected for %1")
.arg (QString::fromUtf8 (command)));
return;
}
QByteArray data = Xpl2Protocol::buildMessage (command, params);
- socket.write (data);
+ socket->write (data);
QByteArray wire;
if (s_wireDebug)
wire = " >> " + data.trimmed ();
- qDebug ("%s TX %s%s", qPrintable (logTag (&socket)), command.constData (),
+ qDebug ("%s TX %s%s", qPrintable (logTag (socket)), command.constData (),
wire.constData ());
}
@@ -639,8 +676,8 @@ Xpl2Client::dispatchCommandMessage (const Xpl2Protocol::ParsedMessage &msg)
handleGsJcVersion (msg.params);
else if (msg.command == "GS_PH_VERSION")
handleGsPhVersion (msg.params);
- else if (!dispatchResponse (msg.command, msg.params, &m_commandSocket))
- qWarning ("%s Unknown command: %s", qPrintable (logTag (&m_commandSocket)),
+ else if (!dispatchResponse (msg.command, msg.params, m_commandSocket))
+ qWarning ("%s Unknown command: %s", qPrintable (logTag (m_commandSocket)),
msg.command.constData ());
}
@@ -656,7 +693,7 @@ Xpl2Client::dispatchImagingMessage (const Xpl2Protocol::ParsedMessage &msg)
int lines = 0;
if (!msg.params.isEmpty ())
lines = msg.params[0].toString ().toInt (nullptr, 16);
- qDebug ("%s n imageLines=%d", qPrintable (logTag (&m_imagingSocket)),
+ qDebug ("%s n imageLines=%d", qPrintable (logTag (m_imagingSocket)),
lines);
emit statusMessage (QStringLiteral ("RX n: imageLines=%1").arg (lines));
emit imagingReply (lines);
@@ -664,13 +701,13 @@ Xpl2Client::dispatchImagingMessage (const Xpl2Protocol::ParsedMessage &msg)
else if (msg.command == "m4")
{
bool ok = !msg.params.isEmpty () && msg.params[0].toInt () == 1;
- qDebug ("%s m4 success=%d", qPrintable (logTag (&m_imagingSocket)),
+ qDebug ("%s m4 success=%d", qPrintable (logTag (m_imagingSocket)),
ok);
emit statusMessage (QStringLiteral ("RX m4: success=%1").arg (ok));
emit imagingStopResult (ok);
}
- else if (!dispatchResponse (msg.command, msg.params, &m_imagingSocket))
- qWarning ("%s Unknown command: %s", qPrintable (logTag (&m_imagingSocket)),
+ else if (!dispatchResponse (msg.command, msg.params, m_imagingSocket))
+ qWarning ("%s Unknown command: %s", qPrintable (logTag (m_imagingSocket)),
msg.command.constData ());
}
@@ -685,13 +722,13 @@ Xpl2Client::dispatchStatusMessage (const Xpl2Protocol::ParsedMessage &msg)
handleEvStatusMsgJc (msg.params);
else if (msg.command == "EV_STATUS_MSG_PH")
handleEvStatusMsgPh (msg.params);
- else if (!dispatchResponse (msg.command, msg.params, &m_statusSocket))
- qWarning ("%s Unknown command: %s", qPrintable (logTag (&m_statusSocket)),
+ else if (!dispatchResponse (msg.command, msg.params, m_statusSocket))
+ qWarning ("%s Unknown command: %s", qPrintable (logTag (m_statusSocket)),
msg.command.constData ());
}
void
-Xpl2Client::handleKaPing (QTcpSocket &socket)
+Xpl2Client::handleKaPing (QTcpSocket *socket)
{
sendCommand (socket, "KA_PING", { 1 });
}
@@ -709,7 +746,7 @@ Xpl2Client::handleGsJcVersion (const QVariantList &params)
m_hardwareVersion = params[2].toString ();
m_printheadCount = params[3].toInt ();
qDebug ("%s controller=%d fw=%s hw=%s phCount=%d",
- qPrintable (logTag (&m_commandSocket)), m_controllerId,
+ qPrintable (logTag (m_commandSocket)), m_controllerId,
qPrintable (m_firmwareVersion), qPrintable (m_hardwareVersion),
m_printheadCount);
emit statusMessage (
@@ -739,7 +776,7 @@ Xpl2Client::handleGsPhVersion (const QVariantList &params)
QString bootVer = params[7].toString ();
qDebug ("%s PH[%d] mcuFw=%s mcuHw=%s mcuFwVar=%s fpgaFw=%s fpgaHw=%s "
"boot=%s",
- qPrintable (logTag (&m_commandSocket)), phId, qPrintable (mcuFw),
+ qPrintable (logTag (m_commandSocket)), phId, qPrintable (mcuFw),
qPrintable (mcuHw), qPrintable (mcuFwVar), qPrintable (fpgaFw),
qPrintable (fpgaHw), qPrintable (bootVer));
emit statusMessage (
@@ -905,7 +942,7 @@ Xpl2Client::handleEvStatusMsgJc (const QVariantList &params)
{
Xpl2JcStatus status = Xpl2JcStatus::fromParams (params);
qDebug ("%s EV_STATUS_MSG_JC controller=%d level=%d temp=%.1f cpu=%.1f%%",
- qPrintable (logTag (&m_statusSocket)), status.controllerId,
+ qPrintable (logTag (m_statusSocket)), status.controllerId,
status.statusLevel, status.temperature, status.cpuPercentageBusy);
emit statusMessage (
QStringLiteral ("RX EV_STATUS_MSG_JC: controller=%1 level=%2")
@@ -919,7 +956,7 @@ Xpl2Client::handleEvStatusMsgPh (const QVariantList &params)
{
Xpl2PhStatus status = Xpl2PhStatus::fromParams (params);
qDebug ("%s EV_STATUS_MSG_PH controller=%d level=%d ph=%d temp=%.1f",
- qPrintable (logTag (&m_statusSocket)), status.controllerId,
+ qPrintable (logTag (m_statusSocket)), status.controllerId,
status.statusLevel, status.printheadId, status.temperature);
emit statusMessage (
QStringLiteral ("RX EV_STATUS_MSG_PH: controller=%1 level=%2 ph=%3")
@@ -937,9 +974,12 @@ void
Xpl2Client::updateConnectedState ()
{
bool allConnected
- = m_commandSocket.state () == QAbstractSocket::ConnectedState
- && m_imagingSocket.state () == QAbstractSocket::ConnectedState
- && m_statusSocket.state () == QAbstractSocket::ConnectedState;
+ = m_commandSocket
+ && m_commandSocket->state () == QAbstractSocket::ConnectedState
+ && m_imagingSocket
+ && m_imagingSocket->state () == QAbstractSocket::ConnectedState
+ && m_statusSocket
+ && m_statusSocket->state () == QAbstractSocket::ConnectedState;
if (m_connected == allConnected)
return;
m_connected = allConnected;
@@ -951,17 +991,17 @@ Xpl2Client::logTag (const QTcpSocket *socket) const
{
const char *name = "Unknown";
quint16 port = 0;
- if (socket == &m_commandSocket)
+ if (socket == m_commandSocket)
{
name = "Command";
port = m_commandPort;
}
- else if (socket == &m_imagingSocket)
+ else if (socket == m_imagingSocket)
{
name = "Imaging";
port = m_imagingPort;
}
- else if (socket == &m_statusSocket)
+ else if (socket == m_statusSocket)
{
name = "Status";
port = m_statusPort;
@@ -975,26 +1015,46 @@ Xpl2Client::logTag (const QTcpSocket *socket) const
/* ------------------------------------------------------------------ */
void
-Xpl2Client::onSocketConnected ()
+Xpl2Client::onNewConnection ()
{
- auto *socket = qobject_cast<QTcpSocket *> (sender ());
- qInfo ("%s Connected", qPrintable (logTag (socket)));
- updateConnectedState ();
+ auto *server = qobject_cast<QTcpServer *> (sender ());
+ QTcpSocket *&slot = socketForServer (server);
+
+ while (auto *pending = server->nextPendingConnection ())
+ {
+ if (slot)
+ {
+ qWarning ("%s Rejected extra connection",
+ qPrintable (logTag (slot)));
+ pending->deleteLater ();
+ continue;
+ }
+ slot = pending;
+ connect (slot, &QTcpSocket::readyRead, this,
+ &Xpl2Client::onSocketMessageReady);
+ connect (slot, &QTcpSocket::disconnected, this,
+ &Xpl2Client::onSocketDisconnected);
+ connect (slot, &QAbstractSocket::errorOccurred, this,
+ &Xpl2Client::onSocketError);
+ qInfo ("%s Controller connected", qPrintable (logTag (slot)));
+ updateConnectedState ();
+ }
}
void
Xpl2Client::onSocketDisconnected ()
{
auto *socket = qobject_cast<QTcpSocket *> (sender ());
- if (!socket)
- {
- /* Identify by elimination — which socket just left ConnectedState? */
- for (auto *s : { &m_commandSocket, &m_imagingSocket, &m_statusSocket })
- if (s->state () != QAbstractSocket::ConnectedState)
- qInfo ("%s Disconnected", qPrintable (logTag (s)));
- }
- else
- qInfo ("%s Disconnected", qPrintable (logTag (socket)));
+ qInfo ("%s Controller disconnected", qPrintable (logTag (socket)));
+
+ if (socket == m_commandSocket)
+ m_commandSocket = nullptr;
+ else if (socket == m_imagingSocket)
+ m_imagingSocket = nullptr;
+ else if (socket == m_statusSocket)
+ m_statusSocket = nullptr;
+
+ socket->deleteLater ();
updateConnectedState ();
}
@@ -1014,9 +1074,9 @@ Xpl2Client::onSocketMessageReady ()
qDebug ("%s RX %s%s", qPrintable (logTag (socket)),
msg.command.constData (), wire.constData ());
- if (socket == &m_commandSocket)
+ if (socket == m_commandSocket)
dispatchCommandMessage (msg);
- else if (socket == &m_imagingSocket)
+ else if (socket == m_imagingSocket)
dispatchImagingMessage (msg);
else
dispatchStatusMessage (msg);