Filter ATIS query replies from normal text messages

Non-VATSIM FSD servers send the controller ATIS message as a regular
text message. swift therefore could not recognize it as such and was
handling the reply as any other text message.
This changes adds some checks to detect ATIS replies after a query.

Maniphest Tasks: T216
This commit is contained in:
Roland Winklmeier
2018-01-02 15:11:57 +01:00
committed by Klaus Basan
parent d68f678cc5
commit 8bb841398d
2 changed files with 72 additions and 1 deletions

View File

@@ -570,6 +570,10 @@ namespace BlackCore
void CNetworkVatlib::sendAtisQuery(const CCallsign &callsign)
{
Q_ASSERT_X(isConnected(), Q_FUNC_INFO, "Can't send to server when disconnected");
if (m_server.getServerType() != CServer::FSDServerVatsim)
{
m_pendingAtisQueries.insert(callsign, {});
}
Vat_SendClientQuery(m_net.data(), vatClientQueryAtis, toFSD(callsign));
}
@@ -801,7 +805,24 @@ namespace BlackCore
void CNetworkVatlib::onTextMessageReceived(VatFsdClient *, const char *from, const char *to, const char *msg, void *cbvar)
{
CTextMessage tm(cbvar_cast(cbvar)->fromFSD(msg), CCallsign(cbvar_cast(cbvar)->fromFSD(from)), CCallsign(cbvar_cast(cbvar)->fromFSD(to)));
auto *self = cbvar_cast(cbvar);
CCallsign sender(self->fromFSD(from));
CCallsign receiver(self->fromFSD(to));
QString message(self->fromFSD(msg));
// Other FSD servers send the controller ATIS as text message. The following conditions need to be met:
// * non-VATSIM server. VATSIM has a specific ATIS message
// * Receiver callsign must be owner callsign and not any type of broadcast.
// * We have requested the ATIS of this controller before.
if (self->m_server.getServerType() != CServer::FSDServerVatsim &&
self->m_ownCallsign == receiver &&
self->m_pendingAtisQueries.contains(sender))
{
self->maybeHandleAtisReply(sender, receiver, message);
return;
}
CTextMessage tm(message, sender, receiver);
tm.setCurrentUtcTime();
cbvar_cast(cbvar)->consolidateTextMessage(tm);
}
@@ -1012,6 +1033,43 @@ namespace BlackCore
emit self->metarReplyReceived(self->fromFSD(data));
}
void CNetworkVatlib::maybeHandleAtisReply(const CCallsign &sender, const CCallsign &receiver, const QString &message)
{
Q_ASSERT(m_pendingAtisQueries.contains(sender));
PendingAtisQuery &pendingQuery = m_pendingAtisQueries[sender];
pendingQuery.m_atisMessage.push_back(message);
// Wait maximum 3 seconds for the reply and release as text message after
if (pendingQuery.m_queryTime.secsTo(QDateTime::currentDateTimeUtc()) > 3)
{
QString atisMessage(pendingQuery.m_atisMessage.join(QChar::LineFeed));
CTextMessage tm(atisMessage, sender, receiver);
tm.setCurrentUtcTime();
consolidateTextMessage(tm);
m_pendingAtisQueries.remove(sender);
return;
}
// 4 digits followed by z (e.g. 0200z) is always the last atis line.
// Some controllers leave the logoff time empty. Hence we accept anything
// between 0-4 digits.
QRegularExpression reLogoff("\\d{0,4}z");
if (reLogoff.match(message).hasMatch())
{
emit atisLogoffTimeReplyReceived(sender, message);
CInformationMessage atisMessage;
atisMessage.setType(CInformationMessage::ATIS);
for (const auto &line : as_const(pendingQuery.m_atisMessage))
{
if (!atisMessage.isEmpty()) atisMessage.appendMessage("\n");
atisMessage.appendMessage(line);
}
emit atisReplyReceived(CCallsign(sender.toQString(), CCallsign::Atc), atisMessage);
m_pendingAtisQueries.remove(sender);
return;
}
}
void CNetworkVatlib::onInfoQueryRequestReceived(VatFsdClient *, const char *callsignString, VatClientQueryType type, const char *, void *cbvar)
{
auto *self = cbvar_cast(cbvar);

View File

@@ -207,6 +207,10 @@ namespace BlackCore
//! Send the consolidatedTextMessages
void emitConsolidatedTextMessages();
//! Handles ATIS replies from non-VATSIM servers. If the conditions are not met, the message is
//! released as normal text message.
void maybeHandleAtisReply(const BlackMisc::Aviation::CCallsign &sender, const BlackMisc::Aviation::CCallsign &receiver, const QString &message);
//! Deletion policy for QScopedPointer
struct VatFsdClientDeleter
{
@@ -239,6 +243,15 @@ namespace BlackCore
static int const c_processingIntervalMsec = 100; //!< interval for the processing timer
static int const c_updatePostionIntervalMsec = 5000; //!< interval for the position update timer (send our position to network)
static int const c_updateInterimPostionIntervalMsec = 1000; //!< interval for iterim position updates (send our position as interim position)
struct PendingAtisQuery
{
QDateTime m_queryTime = QDateTime::currentDateTimeUtc();
QStringList m_atisMessage;
};
QHash<BlackMisc::Aviation::CCallsign, PendingAtisQuery> m_pendingAtisQueries;
};
} //namespace
} //namespace