{FSD] Improved FSD socket handling

* restricter number of lines handled at once
* messageTypeToString
* add parsing to statistics
This commit is contained in:
Klaus Basan
2019-11-10 01:49:17 +01:00
committed by Mat Sutcliffe
parent 3705818445
commit 9d53696417
2 changed files with 62 additions and 9 deletions

View File

@@ -89,7 +89,7 @@ namespace BlackCore
m_tokenBucket(10, CTime(5, CTimeUnit::s()), 1) m_tokenBucket(10, CTime(5, CTimeUnit::s()), 1)
{ {
initializeMessageTypes(); initializeMessageTypes();
connect(&m_socket, &QTcpSocket::readyRead, this, &CFSDClient::readDataFromSocket); connect(&m_socket, &QTcpSocket::readyRead, this, &CFSDClient::readDataFromSocket, Qt::QueuedConnection);
connect(&m_socket, qOverload<QAbstractSocket::SocketError>(&QTcpSocket::error), this, &CFSDClient::printSocketError, Qt::QueuedConnection); connect(&m_socket, qOverload<QAbstractSocket::SocketError>(&QTcpSocket::error), this, &CFSDClient::printSocketError, Qt::QueuedConnection);
connect(&m_socket, qOverload<QAbstractSocket::SocketError>(&QTcpSocket::error), this, &CFSDClient::handleSocketError, Qt::QueuedConnection); connect(&m_socket, qOverload<QAbstractSocket::SocketError>(&QTcpSocket::error), this, &CFSDClient::handleSocketError, Qt::QueuedConnection);
connect(&m_socket, &QTcpSocket::connected, this, &CFSDClient::handleSocketConnected); connect(&m_socket, &QTcpSocket::connected, this, &CFSDClient::handleSocketConnected);
@@ -213,7 +213,7 @@ namespace BlackCore
m_filterPasswordFromLogin = true; m_filterPasswordFromLogin = true;
m_loginSince = QDateTime::currentMSecsSinceEpoch(); m_loginSince = QDateTime::currentMSecsSinceEpoch();
QPointer<CFSDClient> myself(this); const QPointer<CFSDClient> myself(this);
const qint64 timerMs = qRound(PendingConnectionTimeoutMs * 1.25); const qint64 timerMs = qRound(PendingConnectionTimeoutMs * 1.25);
QTimer::singleShot(timerMs, this, [ = ] 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) 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) void CFSDClient::printSocketError(QAbstractSocket::SocketError socketError)
@@ -1708,11 +1713,25 @@ namespace BlackCore
void CFSDClient::readDataFromSocket() void CFSDClient::readDataFromSocket()
{ {
if (m_socket.bytesAvailable() < 1) { return; }
int lines = 0;
while (m_socket.canReadLine()) while (m_socket.canReadLine())
{ {
const QByteArray dataEncoded = m_socket.readLine(); const QByteArray dataEncoded = m_socket.readLine();
const QString data = m_fsdTextCodec->toUnicode(dataEncoded); 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<CFSDClient> myself(this);
QTimer::singleShot(10, this, [ = ]
{
if (myself) { myself->readDataFromSocket(); }
});
break;
}
} }
} }
@@ -1722,24 +1741,31 @@ namespace BlackCore
return metaEnum.valueToKey(error); return metaEnum.valueToKey(error);
} }
void CFSDClient::parseMessage(const QString &line) void CFSDClient::parseMessage(const QString &lineRaw)
{ {
MessageType messageType = MessageType::Unknown; MessageType messageType = MessageType::Unknown;
QString cmd; QString cmd;
const QString line = lineRaw.trimmed();
if (m_printToConsole) { qDebug() << "FSD Recv=>" << line; } 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)) if (line.startsWith(str))
{ {
cmd = str; cmd = str;
messageType = m_messageTypeMapping[str]; messageType = m_messageTypeMapping.value(str, MessageType::Unknown);
break; break;
} }
} }
// statistics
if (m_statistics)
{
this->increaseStatisticsValue(QStringLiteral("parseMessage"), this->messageTypeToString(messageType));
}
if (messageType != MessageType::Unknown) if (messageType != MessageType::Unknown)
{ {
// Cutoff the cmd from the beginning // Cutoff the cmd from the beginning
@@ -1771,8 +1797,17 @@ namespace BlackCore
case MessageType::TextMessage: handleTextMessage(tokens); break; case MessageType::TextMessage: handleTextMessage(tokens); break;
case MessageType::PilotClientCom: handleCustomPilotPacket(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) void CFSDClient::emitRawFsdMessage(const QString &fsdMessage, bool isSent)
@@ -1933,6 +1968,19 @@ namespace BlackCore
return copy.remove(':'); return copy.remove(':');
} }
const QString &CFSDClient::messageTypeToString(MessageType mt) const
{
QHash<QString, MessageType>::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) void CFSDClient::handleIllegalFsdState(const QString &message)
{ {
if (CBuildConfig::isLocalDeveloperDebugBuild()) if (CBuildConfig::isLocalDeveloperDebugBuild())

View File

@@ -283,11 +283,14 @@ namespace BlackCore
void readDataFromSocket(); void readDataFromSocket();
QString socketErrorToQString(QAbstractSocket::SocketError error); QString socketErrorToQString(QAbstractSocket::SocketError error);
void parseMessage(const QString &line); void parseMessage(const QString &lineRaw);
//! Init. the message types //! Init. the message types
void initializeMessageTypes(); void initializeMessageTypes();
// Type to string
const QString &messageTypeToString(MessageType mt) const;
//! Handle response tokens @{ //! Handle response tokens @{
void handleAtcDataUpdate(const QStringList &tokens); void handleAtcDataUpdate(const QStringList &tokens);
void handleAuthChallenge(const QStringList &tokens); void handleAuthChallenge(const QStringList &tokens);
@@ -305,6 +308,8 @@ namespace BlackCore
void handleServerError(const QStringList &tokens); void handleServerError(const QStringList &tokens);
void handleCustomPilotPacket(const QStringList &tokens); void handleCustomPilotPacket(const QStringList &tokens);
void handleFsdIdentification(const QStringList &tokens); void handleFsdIdentification(const QStringList &tokens);
//
void handleUnknownPacket(const QString &line);
void handleUnknownPacket(const QStringList &tokens); void handleUnknownPacket(const QStringList &tokens);
//! @} //! @}