diff options
| author | Thomas Vanbesien <tvanbesi@proton.me> | 2026-03-13 11:47:00 +0100 |
|---|---|---|
| committer | Thomas Vanbesien <tvanbesi@proton.me> | 2026-03-13 11:47:00 +0100 |
| commit | a2b1ccf17845e55caef7f69a5e68f49a55b6a166 (patch) | |
| tree | a7e8c414dbadeeb9bcac29478cf3fbf7e99a4a05 /mock-server/EchoServer.cpp | |
| parent | 34faf3cdea798c1948229ec1bb53c828e2b40bb7 (diff) | |
| download | QtXpl2-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.cpp | 61 |
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 ()); +} |
