aboutsummaryrefslogtreecommitdiffstats
path: root/mock-server/EchoServer.cpp
diff options
context:
space:
mode:
authorThomas Vanbesien <tvanbesi@proton.me>2026-03-13 11:47:00 +0100
committerThomas Vanbesien <tvanbesi@proton.me>2026-03-13 11:47:00 +0100
commita2b1ccf17845e55caef7f69a5e68f49a55b6a166 (patch)
treea7e8c414dbadeeb9bcac29478cf3fbf7e99a4a05 /mock-server/EchoServer.cpp
parent34faf3cdea798c1948229ec1bb53c828e2b40bb7 (diff)
downloadQtXpl2-a2b1ccf17845e55caef7f69a5e68f49a55b6a166.tar.gz
QtXpl2-a2b1ccf17845e55caef7f69a5e68f49a55b6a166.zip
XPL2 protocol foundation: wire framing, typed API, KA_PING, GS_JC_VERSION
Add Xpl2Protocol namespace with buildMessage/parseMessage for wire serialization. Replace raw send/receive API on Xpl2Client with typed protocol methods and internal dispatch. Auto-reply to KA_PING on all sockets (qDebug only). Add GS_JC_VERSION as first typed command with controllerId, firmwareVersion, hardwareVersion, printheadCount properties. Upgrade mock server from echo to line-based command dispatch with 1s KA_PING timer and canned GS_JC_VERSION response. Unknown commands produce qWarning instead of echo. Overhaul demo: remove raw send UI and port config, add wireDebug toggle and Get JC Version button.
Diffstat (limited to 'mock-server/EchoServer.cpp')
-rw-r--r--mock-server/EchoServer.cpp61
1 files changed, 54 insertions, 7 deletions
diff --git a/mock-server/EchoServer.cpp b/mock-server/EchoServer.cpp
index 43fc6f9..8d86df1 100644
--- a/mock-server/EchoServer.cpp
+++ b/mock-server/EchoServer.cpp
@@ -1,6 +1,6 @@
/**
* @file EchoServer.cpp
- * @brief Simple TCP echo server for a single port.
+ * @brief Mock XPL2 server for a single port.
*/
#include "EchoServer.h"
@@ -12,11 +12,16 @@ EchoServer::EchoServer (quint16 port, const char *name, QObject *parent)
connect (this, &QTcpServer::newConnection, this,
&EchoServer::onNewConnection);
+ connect (&m_pingTimer, &QTimer::timeout, this, &EchoServer::sendKaPing);
+
if (!listen (QHostAddress::Any, port))
qCritical ("Failed to listen on %s port %d: %s", m_name, m_port,
qPrintable (errorString ()));
else
- qInfo ("Listening on %s port %d", m_name, m_port);
+ {
+ qInfo ("Listening on %s port %d", m_name, m_port);
+ m_pingTimer.start (1000);
+ }
}
void
@@ -25,20 +30,23 @@ EchoServer::onNewConnection ()
while (auto *sock = nextPendingConnection ())
{
qInfo ("[%s:%d] client connected", m_name, m_port);
+ m_clients.append (sock);
connect (sock, &QTcpSocket::readyRead, this,
- &EchoServer::onClientReadyRead);
+ &EchoServer::onClientMessageReady);
connect (sock, &QTcpSocket::disconnected, this,
&EchoServer::onClientDisconnected);
}
}
void
-EchoServer::onClientReadyRead ()
+EchoServer::onClientMessageReady ()
{
auto *sock = qobject_cast<QTcpSocket *> (sender ());
- QByteArray data = sock->readAll ();
- qInfo ("[%s:%d] echo %lld bytes", m_name, m_port, data.size ());
- sock->write (data);
+ while (sock->canReadLine ())
+ {
+ QByteArray line = sock->readLine ();
+ handleCommand (sock, line);
+ }
}
void
@@ -46,5 +54,44 @@ EchoServer::onClientDisconnected ()
{
auto *sock = qobject_cast<QTcpSocket *> (sender ());
qInfo ("[%s:%d] client disconnected", m_name, m_port);
+ m_clients.removeOne (sock);
sock->deleteLater ();
}
+
+void
+EchoServer::sendKaPing ()
+{
+ for (auto *client : m_clients)
+ {
+ if (client->state () == QAbstractSocket::ConnectedState)
+ client->write ("KA_PING\n");
+ }
+}
+
+void
+EchoServer::handleCommand (QTcpSocket *client, const QByteArray &line)
+{
+ QByteArray trimmed = line.trimmed ();
+ if (trimmed.isEmpty ())
+ return;
+
+ /* Split on first comma to get command token. */
+ int comma = trimmed.indexOf (',');
+ QByteArray cmd = (comma >= 0) ? trimmed.left (comma) : trimmed;
+
+ if (cmd == "KA_PING")
+ {
+ qDebug ("[%s:%d] KA_PING ACK received", m_name, m_port);
+ return;
+ }
+
+ if (cmd == "GS_JC_VERSION")
+ {
+ qInfo ("[%s:%d] -> GS_JC_VERSION reply", m_name, m_port);
+ client->write ("GS_JC_VERSION,1,\"1.05\",\"2.00\",15\n");
+ return;
+ }
+
+ qWarning ("[%s:%d] Unknown command: %s", m_name, m_port,
+ trimmed.constData ());
+}