From 9d536964179df3f9ddb80e79d3b037a25fc9d18e Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Sun, 10 Nov 2019 01:49:17 +0100 Subject: [PATCH] {FSD] Improved FSD socket handling * restricter number of lines handled at once * messageTypeToString * add parsing to statistics --- src/blackcore/fsd/fsdclient.cpp | 64 ++++++++++++++++++++++++++++----- src/blackcore/fsd/fsdclient.h | 7 +++- 2 files changed, 62 insertions(+), 9 deletions(-) diff --git a/src/blackcore/fsd/fsdclient.cpp b/src/blackcore/fsd/fsdclient.cpp index 21af37a6a..64aea29f7 100644 --- a/src/blackcore/fsd/fsdclient.cpp +++ b/src/blackcore/fsd/fsdclient.cpp @@ -89,7 +89,7 @@ namespace BlackCore m_tokenBucket(10, CTime(5, CTimeUnit::s()), 1) { initializeMessageTypes(); - connect(&m_socket, &QTcpSocket::readyRead, this, &CFSDClient::readDataFromSocket); + connect(&m_socket, &QTcpSocket::readyRead, this, &CFSDClient::readDataFromSocket, Qt::QueuedConnection); connect(&m_socket, qOverload(&QTcpSocket::error), this, &CFSDClient::printSocketError, Qt::QueuedConnection); connect(&m_socket, qOverload(&QTcpSocket::error), this, &CFSDClient::handleSocketError, Qt::QueuedConnection); connect(&m_socket, &QTcpSocket::connected, this, &CFSDClient::handleSocketConnected); @@ -213,7 +213,7 @@ namespace BlackCore m_filterPasswordFromLogin = true; m_loginSince = QDateTime::currentMSecsSinceEpoch(); - QPointer myself(this); + const QPointer myself(this); const qint64 timerMs = qRound(PendingConnectionTimeoutMs * 1.25); QTimer::singleShot(timerMs, this, [ = ] @@ -1375,9 +1375,14 @@ namespace BlackCore } } + void CFSDClient::handleUnknownPacket(const QString &line) + { + CLogMessage(this).warning(u"FSD unknown packet: '%1'") << line; + } + void CFSDClient::handleUnknownPacket(const QStringList &tokens) { - CLogMessage(this).warning(u"FSD unknown packet: %1") << tokens.join(", "); + this->handleUnknownPacket(tokens.join(", ")); } void CFSDClient::printSocketError(QAbstractSocket::SocketError socketError) @@ -1708,11 +1713,25 @@ namespace BlackCore void CFSDClient::readDataFromSocket() { + if (m_socket.bytesAvailable() < 1) { return; } + + int lines = 0; while (m_socket.canReadLine()) { const QByteArray dataEncoded = m_socket.readLine(); const QString data = m_fsdTextCodec->toUnicode(dataEncoded); - parseMessage(data); + this->parseMessage(data); + lines++; + if (lines > 30) + { + CLogMessage(this).debug(u"ReadDataFromSocket has too many lines"); + QPointer myself(this); + QTimer::singleShot(10, this, [ = ] + { + if (myself) { myself->readDataFromSocket(); } + }); + break; + } } } @@ -1722,24 +1741,31 @@ namespace BlackCore return metaEnum.valueToKey(error); } - void CFSDClient::parseMessage(const QString &line) + void CFSDClient::parseMessage(const QString &lineRaw) { MessageType messageType = MessageType::Unknown; QString cmd; + const QString line = lineRaw.trimmed(); if (m_printToConsole) { qDebug() << "FSD Recv=>" << line; } - emitRawFsdMessage(line.trimmed(), false); + emitRawFsdMessage(line, false); - for (const auto &str : makeKeysRange(as_const(m_messageTypeMapping))) + for (const QString &str : makeKeysRange(as_const(m_messageTypeMapping))) { if (line.startsWith(str)) { cmd = str; - messageType = m_messageTypeMapping[str]; + messageType = m_messageTypeMapping.value(str, MessageType::Unknown); break; } } + // statistics + if (m_statistics) + { + this->increaseStatisticsValue(QStringLiteral("parseMessage"), this->messageTypeToString(messageType)); + } + if (messageType != MessageType::Unknown) { // Cutoff the cmd from the beginning @@ -1771,8 +1797,17 @@ namespace BlackCore case MessageType::TextMessage: handleTextMessage(tokens); break; case MessageType::PilotClientCom: handleCustomPilotPacket(tokens); break; + // normally we should not get here + default: + case MessageType::Unknown: + handleUnknownPacket(tokens); + break; } } + else + { + handleUnknownPacket(line); + } } void CFSDClient::emitRawFsdMessage(const QString &fsdMessage, bool isSent) @@ -1933,6 +1968,19 @@ namespace BlackCore return copy.remove(':'); } + const QString &CFSDClient::messageTypeToString(MessageType mt) const + { + QHash::const_iterator i = m_messageTypeMapping.constBegin(); + while (i != m_messageTypeMapping.constEnd()) + { + if (i.value() == mt) { return i.key(); } + ++i; + } + + static const QString empty; + return empty; + } + void CFSDClient::handleIllegalFsdState(const QString &message) { if (CBuildConfig::isLocalDeveloperDebugBuild()) diff --git a/src/blackcore/fsd/fsdclient.h b/src/blackcore/fsd/fsdclient.h index 5586bd5c7..3a2b34cb4 100644 --- a/src/blackcore/fsd/fsdclient.h +++ b/src/blackcore/fsd/fsdclient.h @@ -283,11 +283,14 @@ namespace BlackCore void readDataFromSocket(); QString socketErrorToQString(QAbstractSocket::SocketError error); - void parseMessage(const QString &line); + void parseMessage(const QString &lineRaw); //! Init. the message types void initializeMessageTypes(); + // Type to string + const QString &messageTypeToString(MessageType mt) const; + //! Handle response tokens @{ void handleAtcDataUpdate(const QStringList &tokens); void handleAuthChallenge(const QStringList &tokens); @@ -305,6 +308,8 @@ namespace BlackCore void handleServerError(const QStringList &tokens); void handleCustomPilotPacket(const QStringList &tokens); void handleFsdIdentification(const QStringList &tokens); + // + void handleUnknownPacket(const QString &line); void handleUnknownPacket(const QStringList &tokens); //! @}