Enroute Flight Navigation
A navigation app for VFR pilots
TrafficDataProvider.h
1/***************************************************************************
2 * Copyright (C) 2021-2025 by Stefan Kebekus *
3 * stefan.kebekus@gmail.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 3 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20
21#pragma once
22
23#include <QNetworkDatagram>
24#include <QStandardPaths>
25#include <QUdpSocket>
26
27#include "GlobalObject.h"
28#include "positioning/PositionInfoSource_Abstract.h"
29#include "traffic/ConnectionInfo.h"
30#include "traffic/TrafficDataSource_Abstract.h"
31
32namespace Traffic {
33
54 Q_OBJECT
55 QML_ELEMENT
56 QML_SINGLETON
57
58public:
63 explicit TrafficDataProvider(QObject *parent = nullptr);
64
65 // No default constructor, important for QML singleton
66 explicit TrafficDataProvider() = delete;
67
68 // factory function for QML singleton
69 static Traffic::TrafficDataProvider* create(QQmlEngine* /*unused*/, QJSEngine* /*unused*/)
70 {
72 }
73
74 //
75 // Properties
76 //
77
84
90 Q_PROPERTY(QList<Traffic::TrafficDataSource_Abstract*> dataSources READ dataSources NOTIFY dataSourcesChanged)
91
92
98
107
116 Q_PROPERTY(QList<Traffic::TrafficFactor_WithPosition*> trafficObjects READ trafficObjects CONSTANT)
117
125
134
143
150 Q_PROPERTY(Traffic::Warning warning READ warning NOTIFY warningChanged)
151
152
153
154 //
155 // Getter Methods
156 //
157
162 [[nodiscard]] bool currentSourceIsInternetService() const {return m_currentSourceIsInternetService.value();}
163
168 [[nodiscard]] QBindable<bool> bindableCurrentSourceIsInternetService() const {return &m_currentSourceIsInternetService;}
169
174 [[nodiscard]] QList<Traffic::TrafficDataSource_Abstract*> dataSources() const;
175
180 [[nodiscard]] Units::Distance pressureAltitude() const {return m_pressureAltitude.value();}
181
186 [[nodiscard]] QBindable<Units::Distance> bindablePressureAltitude() const {return &m_pressureAltitude;}
187
192 [[nodiscard]] bool receivingHeartbeat() const
193 {
194 return m_receivingHeartbeat.value();
195 }
196
201 [[nodiscard]] QBindable<bool> bindableReceivingHeartbeat() const
202 {
203 return &m_receivingHeartbeat;
204 }
205
210 [[nodiscard]] QList<Traffic::TrafficFactor_WithPosition*> trafficObjects() const
211 {
212 return m_trafficObjects;
213 }
214
220 {
221 return m_trafficObjectWithoutPosition;
222 }
223
228 [[nodiscard]] QString trafficReceiverRuntimeError() const
229 {
230 return m_trafficReceiverRuntimeError;
231 }
232
237 [[nodiscard]] QString trafficReceiverSelfTestError() const
238 {
239 return m_trafficReceiverSelfTestError;
240 }
241
246 [[nodiscard]] Traffic::Warning warning() const
247 {
248 return m_Warning;
249 }
250
251
252
253 //
254 // Methods
255 //
256
266
276 Q_INVOKABLE QString addDataSource(const Traffic::ConnectionInfo &connectionInfo);
277
286 Q_INVOKABLE QString addDataSource_UDP(quint16 port);
287
296 Q_INVOKABLE QString addDataSource_SerialPort(const QString& portName);
297
308 Q_INVOKABLE QString addDataSource_TCP(const QString& host, quint16 port);
309
316 Q_INVOKABLE QString addDataSource_OGN();
317
326
327signals:
330
338 void passwordRequest(const QString& SSID);
339
346 void passwordStorageRequest(const QString& SSID, const QString& password);
347
350
353
356
359
360public slots:
369
375
386 void setPassword(const QString& SSID, const QString &password);
387
388private slots:
389 // Identical to addDataSource, but handles Bluetooth Classic connections only.
390 QString addDataSource_BluetoothClassic(const Traffic::ConnectionInfo &connectionInfo);
391
392 // Identical to addDataSource, but handles Bluetooth Low Energy connections only.
393 QString addDataSource_BluetoothLowEnergy(const Traffic::ConnectionInfo &connectionInfo);
394
395 // Clear all data sources
396 void clearDataSources();
397
398 // Intializations that are moved out of the constructor, in order to avoid
399 // nested uses of constructors in Global.
400 void deferredInitialization();
401
402 // Sends out foreflight broadcast message See
403 // https://www.foreflight.com/connect/spec/
404 void foreFlightBroadcast();
405
406 // Load connection infos from file and create connections
407 void loadConnectionInfos();
408
409 // Called if one of the sources indicates a heartbeat change
410 void onCurrentSourceChanged();
411
412 // Called if one of the sources reports traffic (position unknown)
413 void onTrafficFactorWithPosition(const Traffic::TrafficFactor_WithPosition& factor);
414
415 // Called if one of the sources reports traffic (position known)
416 void onTrafficFactorWithoutPosition(const Traffic::TrafficFactor_DistanceOnly& factor);
417
418 // Resetter method
419 void resetWarning();
420
421 // Save connection infos to file
422 void saveConnectionInfos();
423
424 // Setter method
425 void setWarning(const Traffic::Warning& warning);
426
427private:
428 //
429 // Compute Methods
430 //
431
432 QString computeStatusString();
433
434 // UDP Socket for ForeFlight Broadcast messages.
435 // See https://www.foreflight.com/connect/spec/
436 QNetworkDatagram foreFlightBroadcastDatagram {R"({"App":"Enroute Flight Navigation","GDL90":{"port":4000}})", QHostAddress::Broadcast, 63093};
437 QUdpSocket foreFlightBroadcastSocket;
438 QTimer foreFlightBroadcastTimer;
439
440 // Targets
441 QList<Traffic::TrafficFactor_WithPosition *> m_trafficObjects;
442 QPointer<Traffic::TrafficFactor_DistanceOnly> m_trafficObjectWithoutPosition;
443
444 // TrafficData Sources
445 QProperty<QList<QPointer<Traffic::TrafficDataSource_Abstract>>> m_dataSources;
446
447 QProperty<QPointer<Traffic::TrafficDataSource_Abstract>> m_currentSource;
448 QPropertyNotifier m_currentSourceNotifier;
449 QPointer<Traffic::TrafficDataSource_Abstract> computeCurrentSource();
450
451 QProperty<bool> m_currentSourceIsInternetService;
452
453 // Property cache
454 Traffic::Warning m_Warning;
455 QTimer m_WarningTimer;
456
457 Q_OBJECT_BINDABLE_PROPERTY(Traffic::TrafficDataProvider, QString, m_trafficReceiverRuntimeError, &Traffic::TrafficDataProvider::trafficReceiverRuntimeErrorChanged);
458 QString computeTrafficReceiverRuntimeError();
459
460 Q_OBJECT_BINDABLE_PROPERTY(Traffic::TrafficDataProvider, QString, m_trafficReceiverSelfTestError, &Traffic::TrafficDataProvider::trafficReceiverSelfTestErrorChanged);
461 QString computeTrafficReceiverSelfTestError();
462
463 QProperty<Units::Distance> m_pressureAltitude;
464 Units::Distance computePressureAltitude();
465
466 // Reconnect
467 QTimer reconnectionTimer;
468
469 Q_OBJECT_BINDABLE_PROPERTY(Traffic::TrafficDataProvider, bool, m_receivingHeartbeat, &Traffic::TrafficDataProvider::receivingHeartbeatChanged);
470 bool computeReceivingHeartbeat();
471
472 // Standard file name for saveConnectionInfos()
473 QString stdFileName{QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + u"/connectionInfos.data"_s};
474};
475
476} // namespace Traffic
static Q_INVOKABLE Traffic::TrafficDataProvider * trafficDataProvider()
Pointer to appplication-wide static TrafficDataProvider instance.
Abstract base class for all classes that provide geographic position information.
Connection to a traffic data receiver.
QString trafficReceiverSelfTestError
String describing the traffic data receiver errors found in self-test.
QString trafficReceiverRuntimeError
String describing the current traffic data receiver errors.
bool currentSourceIsInternetService
Internet service flag.
void passwordStorageRequest(const QString &SSID, const QString &password)
Password storage request.
void passwordRequest(const QString &SSID)
Password request.
QString trafficReceiverSelfTestError() const
Getter function for the property with the same name.
Traffic::TrafficFactor_DistanceOnly * trafficObjectWithoutPosition() const
Getter method for property with the same name.
QList< Traffic::TrafficDataSource_Abstract * > dataSources
Traffic data sources.
QBindable< bool > bindableReceivingHeartbeat() const
Getter method for property with the same name.
Q_INVOKABLE QString addDataSource_TCP(const QString &host, quint16 port)
Add an additional data source.
Traffic::Warning warning
Current traffic warning.
QList< Traffic::TrafficDataSource_Abstract * > dataSources() const
Getter method for property with the same name.
Q_INVOKABLE QString addDataSource_UDP(quint16 port)
Add an additional data source.
QList< Traffic::TrafficFactor_WithPosition * > trafficObjects() const
Getter method for property with the same name.
QString trafficReceiverRuntimeError() const
Getter function for the property with the same name.
bool receivingHeartbeat() const
Getter method for property with the same name.
bool receivingHeartbeat
Heartbeat indicator.
Units::Distance pressureAltitude
Pressure altitude.
void receivingHeartbeatChanged()
Notifier signal.
void connectToTrafficReceiver()
Start attempt to connect to traffic receiver.
void trafficReceiverRuntimeErrorChanged()
Notifier signal.
Q_INVOKABLE QString addDataSource_SerialPort(const QString &portName)
Add an additional data source.
void trafficReceiverSelfTestErrorChanged()
Notifier signal.
void dataSourcesChanged()
Notifier signal.
void setPassword(const QString &SSID, const QString &password)
Send password to the traffic data sources.
Q_INVOKABLE void removeDataSource(Traffic::TrafficDataSource_Abstract *source)
Remove data sources.
void disconnectFromTrafficReceiver()
Disconnect from traffic receiver.
Traffic::Warning warning() const
Getter method for property with the same name.
void addDataSource(Traffic::TrafficDataSource_Abstract *source)
Add an additional data source.
Q_INVOKABLE QString addDataSource_OGN()
Add an additional data source.
TrafficDataProvider(QObject *parent=nullptr)
Default constructor.
QBindable< Units::Distance > bindablePressureAltitude() const
Getter method for property with the same name.
QList< Traffic::TrafficFactor_WithPosition * > trafficObjects
Traffic objects whose position is known.
QBindable< bool > bindableCurrentSourceIsInternetService() const
Getter method for property with the same name.
Units::Distance pressureAltitude() const
Getter method for property with the same name.
Traffic::TrafficFactor_DistanceOnly * trafficObjectWithoutPosition
Most relevant traffic object whose position is not known.
void warningChanged(const Traffic::Warning &)
Notifier signal.
Q_INVOKABLE QString addDataSource(const Traffic::ConnectionInfo &connectionInfo)
Add an additional data source.
Base class for all traffic receiver data sources.
Traffic factor where only distance is known.
Traffic factor whose precise position is known.
Traffic warning.
Definition Warning.h:40
Convenience class for distance computations.
Definition Distance.h:35
Conversion between units used in aviation.
Definition Angle.h:34