From 0fd1e34d0327ae0b96506f1406d94adbb5d88ff3 Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Tue, 12 Nov 2019 18:04:24 +0100 Subject: [PATCH] [FSD] Verify we really have FSD ICAO data Problem: Sometime there are aircraft without ICAO daza * check that we really have received ICAO data * if not, query data again * if nothing helps, use data as best guessed (by flightplan data) --- src/blackcore/airspacemonitor.cpp | 69 +++++++++++++++++++++++-------- src/blackcore/airspacemonitor.h | 28 +++++++++++-- 2 files changed, 76 insertions(+), 21 deletions(-) diff --git a/src/blackcore/airspacemonitor.cpp b/src/blackcore/airspacemonitor.cpp index 410bc987c..484a75bb7 100644 --- a/src/blackcore/airspacemonitor.cpp +++ b/src/blackcore/airspacemonitor.cpp @@ -117,7 +117,7 @@ namespace BlackCore // timer connect(&m_processTimer, &QTimer::timeout, this, &CAirspaceMonitor::process); - m_processTimer.start(ProcessInterval); + m_processTimer.start(ProcessIntervalMs); } bool CAirspaceMonitor::updateFastPositionEnabled(const CCallsign &callsign, bool enableFastPositonUpdates) @@ -564,17 +564,12 @@ namespace BlackCore if (!this->isConnectedAndNotShuttingDown()) { return; } Q_ASSERT_X(!callsign.isEmpty(), Q_FUNC_INFO, "missing callsign"); - // times - constexpr qint64 CheckAgainMs = 2000; - constexpr qint64 MaxAgeMs = CheckAgainMs * 3; - constexpr qint64 MaxAgeThreshold = CheckAgainMs * 10; - // set flag and init ts Readiness &readiness = this->addMatchingReadinessFlag(callsign, rf); // skip if already sent in the last x seconds const qint64 ageMs = readiness.getAgeMs(); - if (readiness.wasMatchingSent() && readiness.getAgeMs() < MaxAgeThreshold) { return; } + if (readiness.wasMatchingSent() && readiness.getAgeMs() < MMMaxAgeThresholdMs) { return; } // checking for min. situations ensures the aircraft is stable, can be interpolated ... const CSimulatedAircraft remoteAircraft = this->getAircraftInRangeForCallsign(callsign); @@ -589,14 +584,14 @@ namespace BlackCore ); const ReverseLookupLogging revLogEnabled = this->whatToReverseLog(); - if (validRemoteCs && ageMs <= MaxAgeMs && !complete) + if (rf != Verified && validRemoteCs && ageMs <= MMMaxAgeMs && !complete) { static const QString ws("Wait for further data, '%1' age: %2ms ts: %3"); static const QString format("hh:mm:ss.zzz"); if (!revLogEnabled.testFlag(RevLogSimplifiedInfo)) { this->addReverseLookupMessage(callsign, ws.arg(readiness.toQString()).arg(ageMs).arg(QDateTime::currentDateTimeUtc().toString(format))); } const QPointer myself(this); - QTimer::singleShot(CheckAgainMs, this, [ = ]() + QTimer::singleShot(MMCheckAgainMs, this, [ = ]() { if (!myself || !sApp || sApp->isShuttingDown()) { return; } if (!this->isAircraftInRange(callsign)) @@ -640,6 +635,35 @@ namespace BlackCore } } + void CAirspaceMonitor::verifyReceivedIcaoData(const CCallsign &callsign) + { + if (callsign.isEmpty() || !this->isAircraftInRange(callsign)) { return; } + + // set flag and init ts + Readiness &readiness = m_readiness[callsign]; + if (readiness.wasMatchingSent()) { return; } + if (readiness.wasVerified()) + { + CLogMessage(this).warning(u"Verfied '%1' again, using it as it is!") << callsign; + this->sendReadyForModelMatching(callsign, Verified); + return; + } + + // new trial + readiness.addFlag(Verified); + + if (!readiness.receivedIcaoCodes()) + { + CLogMessage(this).info(u"Query ICAO codes for '%1' again") << callsign; + this->sendInitialPilotQueries(callsign, true, true); + return; + } + + // normally we should never get here + CLogMessage(this).info(u"Verified '%1' again, has ICAO codes, ready for matching!") << callsign; + this->sendReadyForModelMatching(callsign, Verified); + } + void CAirspaceMonitor::onAtcPositionUpdate(const CCallsign &callsign, const CFrequency &frequency, const CCoordinateGeodetic &position, const BlackMisc::PhysicalQuantities::CLength &range) { Q_ASSERT_X(CThreadUtils::isCurrentThreadObjectThread(this), Q_FUNC_INFO, "wrong thread"); @@ -1008,14 +1032,25 @@ namespace BlackCore sApp->getWebDataServices()->updateWithVatsimDataFileData(newAircraft); } const bool added = CRemoteAircraftProvider::addNewAircraftInRange(newAircraft); - if (added && aircraft.hasModelString()) + if (added) { - // most likely I could take the CG at this time from aircraft - // to make sure it is really the DB value i query again - const CAircraftModel model = sApp->getWebDataServices()->getModelForModelString(aircraft.getModelString()); - const CLength cg = model.hasValidDbKey() ? model.getCG() : CLength::null(); - this->rememberCGFromDB(cg, aircraft.getModelString()); - this->rememberCGFromDB(cg, aircraft.getCallsign()); + const QPointer myself(this); + QTimer::singleShot(MMVerifyMs, this, [ = ]() + { + // makes sure we have ICAO data + if (!myself || !sApp || sApp->isShuttingDown()) { return; } + this->verifyReceivedIcaoData(callsign); + }); + + if (aircraft.hasModelString()) + { + // most likely I could take the CG at this time from aircraft + // to make sure it is really the DB value I query again + const CAircraftModel model = sApp->getWebDataServices()->getModelForModelString(aircraft.getModelString()); + const CLength cg = model.hasValidDbKey() ? model.getCG() : CLength::null(); + this->rememberCGFromDB(cg, aircraft.getModelString()); + this->rememberCGFromDB(cg, aircraft.getCallsign()); + } } return added; } @@ -1367,7 +1402,7 @@ namespace BlackCore if (!this->isConnectedAndNotShuttingDown()) { return; } if (withIcaoQuery) { m_fsdClient->sendPlaneInfoRequest(callsign); } - if (withFsInn) { m_fsdClient->sendPlaneInfoRequestFsinn(callsign); } + if (withFsInn) { m_fsdClient->sendPlaneInfoRequestFsinn(callsign); } m_fsdClient->sendClientQueryCom1Freq(callsign); m_fsdClient->sendClientQueryRealName(callsign); diff --git a/src/blackcore/airspacemonitor.h b/src/blackcore/airspacemonitor.h index 3a318f0ce..fdef3e21f 100644 --- a/src/blackcore/airspacemonitor.h +++ b/src/blackcore/airspacemonitor.h @@ -161,7 +161,8 @@ namespace BlackCore ReceivedFsInnPacket = 1 << 1, //!< FsInn pcket received ReadyForMatchingSent = 1 << 2, //!< Read for matching sending RecursiveCall = 1 << 3, //!< recursion - ReceivedAll = ReceivedIcaoCodes | ReceivedFsInnPacket + ReceivedAll = ReceivedIcaoCodes | ReceivedFsInnPacket, + Verified = 1 << 4, //!< verified already }; Q_DECLARE_FLAGS(MatchingReadiness, MatchingReadinessFlag) @@ -224,6 +225,9 @@ namespace BlackCore return *this; } + //! Reset timestamp to now + void resetTimestampToNow() { ts = QDateTime::currentMSecsSinceEpoch(); } + //! Set the flag Readiness &setFlag(MatchingReadinessFlag flag) { @@ -233,12 +237,18 @@ namespace BlackCore return *this; } - //! Received all data + //! Received all data? bool receivedAll() const { return readyness.testFlag(ReceivedIcaoCodes) && readyness.testFlag(ReceivedFsInnPacket); } - //! Was matching ready sent? + //! Received ICAO codes? + bool receivedIcaoCodes() const { return readyness.testFlag(ReceivedIcaoCodes); } + + //! Was matching already sent? bool wasMatchingSent() const { return readyness.testFlag(ReadyForMatchingSent); } + //! Was verifed? + bool wasVerified() const { return readyness.testFlag(Verified); } + //! currnt age in ms qint64 getAgeMs() const { @@ -265,7 +275,13 @@ namespace BlackCore CAirspaceAnalyzer *m_analyzer = nullptr; //!< owned analyzer bool m_bookingsRequested = false; //!< bookings have been requested, it can happen we receive an BlackCore::Vatsim::CVatsimBookingReader::atcBookingsReadUnchanged signal QTimer m_processTimer; - static constexpr int ProcessInterval = 50; // in ms + static constexpr int ProcessIntervalMs = 50; // in ms + + // model matching times + static constexpr qint64 MMCheckAgainMs = 2000; + static constexpr qint64 MMMaxAgeMs = MMCheckAgainMs * 3; + static constexpr qint64 MMMaxAgeThresholdMs = MMCheckAgainMs * 10; + static constexpr qint64 MMVerifyMs = MMCheckAgainMs * 12; //! Processing by timer void process(); @@ -351,6 +367,10 @@ namespace BlackCore //! \sa reverseLookupModelWithFlightplanData void sendReadyForModelMatching(const BlackMisc::Aviation::CCallsign &callsign, MatchingReadinessFlag rf); + //! Make sure we got ICAO data + //! \remark did we get any responses for ICAO data (standard, FsInn) + void verifyReceivedIcaoData(const BlackMisc::Aviation::CCallsign &callsign); + //! Reverse lookup, if available flight plan data are considered //! \remark this is where a model is created based on network data //! \ingroup reverselookup