swift
airspacemonitor.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (C) 2013 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
5 
6 #ifndef SWIFT_CORE_AIRSPACE_MONITOR_H
7 #define SWIFT_CORE_AIRSPACE_MONITOR_H
8 
9 #include <QHash>
10 #include <QJsonObject>
11 #include <QMetaObject>
12 #include <QObject>
13 #include <QQueue>
14 #include <QString>
15 #include <QTimer>
16 #include <QtGlobal>
17 
18 #include "core/swiftcoreexport.h"
26 #include "misc/identifier.h"
29 #include "misc/network/ecosystem.h"
30 #include "misc/network/server.h"
31 #include "misc/network/userlist.h"
32 #include "misc/pq/angle.h"
33 #include "misc/pq/frequency.h"
34 #include "misc/pq/length.h"
45 
46 namespace swift::core
47 {
48  namespace fsd
49  {
50  class CFSDClient;
51  }
52  class CAirspaceAnalyzer;
53 
57  public swift::misc::simulation::CRemoteAircraftProvider, // those data will be provided from the class
58  // CAirspaceMonitor
59  public swift::misc::network::CClientProvider, // those data will be provided from the class CAirspaceMonitor
60  public swift::misc::simulation::COwnAircraftAware, // used to obtain in memory information about own aircraft
61  public swift::misc::simulation::CSimulationEnvironmentAware // elevation info etc. from simulator
62  {
63  // CRemoteAircraftProvider is QObject
64  Q_OBJECT
67 
68  public:
70  static const QStringList &getLogCategories();
71 
75  fsd::CFSDClient *fsdClient, QObject *parent);
76 
80  QObject *asQObject() override { return this; }
81  misc::simulation::CAirspaceAircraftSnapshot getLatestAirspaceAircraftSnapshot() const override;
82  bool updateFastPositionEnabled(const misc::aviation::CCallsign &callsign,
83  bool enableFastPositonUpdates) override;
85 
87  misc::network::CUserList getUsers() const;
88 
90  misc::network::CUserList getUsersForCallsigns(const misc::aviation::CCallsignSet &callsigns) const;
91 
95  misc::aviation::CFlightPlan loadFlightPlanFromNetwork(const misc::aviation::CCallsign &callsign);
96 
100  misc::aviation::CFlightPlanRemarks tryToGetFlightPlanRemarks(const misc::aviation::CCallsign &callsign) const;
101 
103  misc::aviation::CAtcStationList getAtcStationsOnline() const { return m_atcStationsOnline; }
104 
106  misc::aviation::CAtcStationList getAtcStationsOnlineRecalculated();
107 
109  misc::aviation::CAtcStation getAtcStationForComUnit(const misc::aviation::CComSystem &comSystem) const;
110 
112  void clear();
113 
115  void requestAircraftDataUpdates();
116 
118  void requestAtisUpdates();
119 
121  CAirspaceAnalyzer *analyzer() const { return m_analyzer; }
122 
124  void gracefulShutdown();
125 
127  int reInitializeAllAircraft();
128 
130  void setMaxRange(const swift::misc::physical_quantities::CLength &range);
131 
134  void testCreateDummyOnlineAtcStations(int number);
135 
138  void testAddAircraftParts(const swift::misc::aviation::CCallsign &callsign,
139  const swift::misc::aviation::CAircraftParts &parts, bool incremental);
140 
143  {
144  NotReady = 0,
145  ReceivedIcaoCodes = 1 << 0,
146  ReceivedFsInnPacket = 1 << 1,
147  ReadyForMatchingSent = 1 << 2,
148  RecursiveCall = 1 << 3,
149  ReceivedAll = ReceivedIcaoCodes | ReceivedFsInnPacket,
150  Verified = 1 << 4,
151  };
152  Q_DECLARE_FLAGS(MatchingReadiness, MatchingReadinessFlag)
153 
154 
156  static const QString &enumFlagToString(MatchingReadinessFlag r);
157  static QString enumToString(MatchingReadiness r);
159 
165  bool parseCommandLine(const QString &commandLine, const swift::misc::CIdentifier &originator);
166 
168  static void registerHelp()
169  {
170  if (swift::misc::CSimpleCommandParser::registered("swift::core::fsd::CFSDClient")) { return; }
171  swift::misc::CSimpleCommandParser::registerCommand({ ".fsd range distance", "FSD max. range" });
172  }
173 
174  signals:
177 
180 
184  void requestedNewAircraft(const swift::misc::aviation::CCallsign &callsign, const QString &aircraftDesignator,
185  const QString &airlineDesignator, const QString &livery);
186 
189 
192 
193  private:
195  struct FsInnPacket
196  {
198  FsInnPacket() {}
199 
201  FsInnPacket(const QString &aircraftIcaoDesignator, const QString &airlineIcaoDesignator,
202  const QString &combinedCode, const QString &modelString);
203 
204  QString aircraftIcaoDesignator;
205  QString airlineIcaoDesignator;
206  QString combinedCode;
207  QString modelString;
208  };
209 
211  struct Readiness
212  {
213  private:
214  qint64 ts = -1;
215  MatchingReadiness readyness = NotReady;
216 
217  public:
219  Readiness &addFlag(MatchingReadinessFlag flag)
220  {
221  if (flag == RecursiveCall) { return *this; }
222  if (ts < 0) { ts = QDateTime::currentMSecsSinceEpoch(); }
223  readyness.setFlag(flag, true);
224  return *this;
225  }
226 
228  void resetTimestampToNow() { ts = QDateTime::currentMSecsSinceEpoch(); }
229 
231  Readiness &setFlag(MatchingReadinessFlag flag)
232  {
233  if (flag == RecursiveCall) { return *this; }
234  readyness = NotReady;
235  this->addFlag(flag);
236  return *this;
237  }
238 
240  bool receivedAll() const
241  {
242  return readyness.testFlag(ReceivedIcaoCodes) && readyness.testFlag(ReceivedFsInnPacket);
243  }
244 
246  bool receivedIcaoCodes() const { return readyness.testFlag(ReceivedIcaoCodes); }
247 
249  bool wasMatchingSent() const { return readyness.testFlag(ReadyForMatchingSent); }
250 
252  bool wasVerified() const { return readyness.testFlag(Verified); }
253 
255  qint64 getAgeMs() const
256  {
257  if (ts < 0) { return -1; }
258  return QDateTime::currentMSecsSinceEpoch() - ts;
259  }
260 
262  QString toQString() const
263  {
264  return QStringLiteral("ts: %1 ready: %2").arg(ts).arg(CAirspaceMonitor::enumToString(readyness));
265  }
266  };
267 
268  swift::misc::aviation::CAtcStationList m_atcStationsOnline;
271  m_flightPlanCache;
274  this
275  };
276  QQueue<swift::misc::aviation::CCallsign> m_queryAtis;
277  QQueue<swift::misc::aviation::CCallsign> m_queryPilot;
278  misc::simulation::IAircraftModelSetProvider *m_modelSetProvider = nullptr;
279  fsd::CFSDClient *m_fsdClient = nullptr;
280  CAirspaceAnalyzer *m_analyzer = nullptr;
281  int m_maxDistanceNM = 125;
282  int m_maxDistanceNMHysteresis = qRound(1.1 * m_maxDistanceNM);
283  int m_foundInNonMovingAircraft = 0;
284  int m_foundInElevationsOnGnd = 0;
285 
286  // Processing for queries etc. (fast)
287  static constexpr int FastProcessIntervalMs = 50;
288  QTimer m_fastProcessTimer;
289 
291  void fastProcessing();
292 
293  // Processing for validations etc. (slow)
294  static constexpr int SlowProcessIntervalMs = 125 * 1000;
295  QTimer m_slowProcessTimer;
296 
298  void slowProcessing();
299 
300  // model matching times
301  static constexpr qint64 MMCheckAgainMs = 2000;
302  static constexpr qint64 MMMaxAgeMs = MMCheckAgainMs * 3;
303  static constexpr qint64 MMMaxAgeThresholdMs = MMCheckAgainMs * 10;
304  static constexpr qint64 MMVerifyMs = MMCheckAgainMs * 12;
305 
307  void removeAllOnlineAtcStations();
308 
311  void removeAllAircraft();
312 
315  void removeFromAircraftCachesAndLogs(const swift::misc::aviation::CCallsign &callsign);
316 
318  void sendInitialAtcQueries(const swift::misc::aviation::CCallsign &callsign);
319 
321  void queryAllOnlineAtcStations();
322 
324  bool sendNextStaggeredAtisQuery();
325 
327  void sendInitialPilotQueries(const swift::misc::aviation::CCallsign &callsign, bool withIcaoQuery,
328  bool withFsInn);
329 
331  bool sendNextStaggeredPilotDataQuery();
332 
334  bool isConnected() const;
335 
337  bool isConnectedAndNotShuttingDown() const;
338 
340  const swift::misc::network::CServer &getConnectedServer() const;
341 
343  const swift::misc::network::CEcosystem &getCurrentEcosystem() const;
344 
347  bool supportsVatsimDataFile() const;
348 
351  calculateDistanceToOwnAircraft(const swift::misc::aviation::CAircraftSituation &situation) const;
352 
355  calculateBearingToOwnAircraft(const swift::misc::aviation::CAircraftSituation &situation) const;
356 
362  storeAircraftSituation(const swift::misc::aviation::CAircraftSituation &situation,
363  bool allowTestOffset = true) override;
364 
367  addOrUpdateAircraftInRange(const swift::misc::aviation::CCallsign &callsign, const QString &aircraftIcao,
368  const QString &airlineIcao, const QString &livery, const QString &modelString,
371 
375  bool addNewAircraftInRange(const swift::misc::simulation::CSimulatedAircraft &aircraft);
376 
380  void asyncReInitializeAllAircraft(const swift::misc::simulation::CSimulatedAircraftList &aircraft,
381  bool readyForModelMatching);
382 
384  int updateOnlineStation(const swift::misc::aviation::CCallsign &callsign,
385  const swift::misc::CPropertyIndexVariantMap &vm, bool skipEqualValues = true,
386  bool sendSignal = true);
387 
389  bool handleMaxRange(const swift::misc::aviation::CAircraftSituation &situation);
390 
392  bool recallFsInnPacket(const swift::misc::aviation::CCallsign &callsign);
393 
397  void sendReadyForModelMatching(const swift::misc::aviation::CCallsign &callsign, MatchingReadinessFlag rf);
398 
401  void verifyReceivedIcaoData(const swift::misc::aviation::CCallsign &callsign);
402 
407  reverseLookupModelWithFlightplanData(const swift::misc::aviation::CCallsign &callsign,
408  const QString &aircraftIcao, const QString &airlineIcao,
409  const QString &liveryString, const QString &modelString,
411  swift::misc::CStatusMessageList *log, bool runMatchinScript = true);
412 
414  bool isCopilotAircraft(const swift::misc::aviation::CCallsign &callsign) const;
415 
417  Readiness &addMatchingReadinessFlag(const swift::misc::aviation::CCallsign &callsign,
418  MatchingReadinessFlag mrf);
419 
422  static bool extrapolateElevation(swift::misc::aviation::CAircraftSituationList &situations,
424 
429  static bool extrapolateElevation(swift::misc::aviation::CAircraftSituation &situationToBeUpdated,
430  const swift::misc::aviation::CAircraftSituation &oldSituation,
431  const swift::misc::aviation::CAircraftSituation &olderSituation,
433 
435  void onAircraftUpdateReceived(const swift::misc::aviation::CAircraftSituation &situation,
436  const swift::misc::aviation::CTransponder &transponder);
437 
439  void onAtcPositionUpdate(const swift::misc::aviation::CCallsign &callsign,
443 
446  void onCustomFSInnPacketReceived(const swift::misc::aviation::CCallsign &callsign,
447  const QString &airlineIcaoDesignator, const QString &aircraftIcaoDesignator,
448  const QString &combinedAircraftType, const QString &modelString);
449 
450  void onRealNameReplyReceived(const swift::misc::aviation::CCallsign &callsign, const QString &realname);
451  void onCapabilitiesReplyReceived(const swift::misc::aviation::CCallsign &callsign,
452  swift::misc::network::CClient::Capabilities clientCaps);
453  void onServerReplyReceived(const swift::misc::aviation::CCallsign &callsign, const QString &server);
454  void onFlightPlanReceived(const swift::misc::aviation::CCallsign &callsign,
455  const swift::misc::aviation::CFlightPlan &flightPlan);
456  void onAtcControllerDisconnected(const swift::misc::aviation::CCallsign &callsign);
457  void onAtisReceived(const swift::misc::aviation::CCallsign &callsign,
458  const swift::misc::aviation::CInformationMessage &atisMessage);
459  void onAtisLogoffTimeReceived(const swift::misc::aviation::CCallsign &callsign, const QString &zuluTime);
460  void onIcaoCodesReceived(const swift::misc::aviation::CCallsign &callsign,
461  const QString &aircraftIcaoDesignator, const QString &airlineIcaoDesignator,
462  const QString &livery);
463  void onPilotDisconnected(const swift::misc::aviation::CCallsign &callsign);
464  void onFrequencyReceived(const swift::misc::aviation::CCallsign &callsign,
466  void onReceivedVatsimDataFile();
467  void onAircraftConfigReceived(const swift::misc::aviation::CCallsign &callsign, const QJsonObject &jsonObject,
468  qint64 currentOffsetMs);
469  void onAircraftInterimUpdateReceived(const swift::misc::aviation::CAircraftSituation &situation);
470  void onAircraftVisualUpdateReceived(const swift::misc::aviation::CAircraftSituation &situation);
471  void onAircraftSimDataUpdateReceived(const swift::misc::aviation::CAircraftSituation &situation,
472  const swift::misc::aviation::CAircraftParts &parts, qint64 currentOffsetMs,
473  const QString &aircraftIcao, const QString &airlineIcao);
474  void onConnectionStatusChanged(swift::misc::network::CConnectionStatus oldStatus,
476  void onRevBAircraftConfigReceived(const swift::misc::aviation::CCallsign &callsign, const QString &config,
477  qint64 currentOffsetMs);
478  };
479 } // namespace swift::core
480 
482 Q_DECLARE_OPERATORS_FOR_FLAGS(swift::core::CAirspaceMonitor::MatchingReadiness)
483 
484 #endif // SWIFT_CORE_AIRSPACE_MONITOR_H
Class monitoring and analyzing (closest aircraft, outdated aircraft / watchdog) airspace in backgroun...
Keeps track of other entities in the airspace: aircraft, ATC stations, etc. Central instance of data ...
MatchingReadinessFlag
Matching readiness.
misc::aviation::CAtcStationList getAtcStationsOnline() const
Returns the current online ATC stations.
QObject * asQObject()
Members not implenented or fully implenented by CRemoteAircraftProvider.
void atcStationDisconnected(const swift::misc::aviation::CAtcStation &station)
ATC station disconnected.
CAirspaceAnalyzer * analyzer() const
Analyzer.
void readyForModelMatching(const swift::misc::simulation::CSimulatedAircraft &remoteAircraft)
Ready for model matching.
void changedAtisReceived(const swift::misc::aviation::CCallsign &callsign)
An ATIS has been received.
void changedAtcStationsOnline()
Online ATC stations were changed.
static QString enumToString(MatchingReadiness r)
As string.
static void registerHelp()
Register help.
FSD client Todo: Send (interim) data updates automatically Todo Check ':' in FSD messages....
Definition: fsdclient.h:85
Value object encapsulating information identifying a component of a modular distributed swift process...
Definition: identifier.h:29
Specialized value object compliant map for variants, based on indexes.
static void registerCommand(const CommandHtmlHelp &command)
Register a command.
static bool registered(const QString &helpContext)
Help already registered.
Status messages, e.g. from Core -> GUI.
Value object encapsulating information of aircraft's parts.
Definition: aircraftparts.h:26
Value object about changes in situations.
Value object encapsulating information of an aircraft's situation.
Value object encapsulating information about an ATC station.
Definition: atcstation.h:38
Value object for a list of ATC stations.
Value object encapsulating information of a callsign.
Definition: callsign.h:30
Value object for a set of callsigns.
Definition: callsignset.h:26
COM system (aka "radio")
Definition: comsystem.h:37
Value object for a flight plan.
Definition: flightplan.h:148
Flight plan remarks, parsed values.
Definition: flightplan.h:46
Value object encapsulating information message (ATIS, METAR, TAF)
Direct in memory access to client (network client) data.
Value object encapsulating information about a connection status.
Ecosystem of server belonging together.
Definition: ecosystem.h:21
Value object encapsulating information of a server.
Definition: server.h:28
Value object encapsulating a list of voice rooms.
Definition: userlist.h:26
Direct in memory access to client (network client) data.
Physical unit angle (radians, degrees)
Definition: angle.h:23
Physical unit length (length)
Definition: length.h:18
Aircraft model (used by another pilot, my models on disk)
Definition: aircraftmodel.h:71
Delegating class which can be directly used to access an.
Implementaion of the interface, which can also be used for testing.
Comprehensive information of an aircraft.
Value object encapsulating a list of aircraft.
Class which can be directly used to access an.
Value object encapsulating a list of aircraft models.
Direct threadsafe in memory access to own aircraft.
Direct thread safe in memory access to remote aircraft.
Backend services of the swift project, like dealing with the network or the simulators.
Definition: actionbind.cpp:7
#define SWIFT_CORE_EXPORT
Export a class or function from the library.