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 "traffic/ConnectionInfo.h"
29#include "traffic/TrafficDataSource_Abstract.h"
30
31namespace Traffic {
32
52class TrafficDataProvider : public QObject {
53 Q_OBJECT
54 QML_ELEMENT
55 QML_SINGLETON
56
57public:
62 explicit TrafficDataProvider(QObject *parent = nullptr);
63
64 // No default constructor, important for QML singleton
65 explicit TrafficDataProvider() = delete;
66
67 // factory function for QML singleton
68 static Traffic::TrafficDataProvider* create(QQmlEngine* /*unused*/, QJSEngine* /*unused*/)
69 {
71 }
72
73 //
74 // Properties
75 //
76
83
89 Q_PROPERTY(QList<Traffic::TrafficDataSource_Abstract*> dataSources READ dataSources NOTIFY dataSourcesChanged)
90
91
98 Q_PROPERTY(Positioning::PositionInfo positionInfo READ positionInfo BINDABLE bindablePositionInfo)
99
106
115
122 Q_PROPERTY(QString statusString READ statusString BINDABLE bindableStatusString)
123
132 Q_PROPERTY(QList<Traffic::TrafficFactor_WithPosition*> trafficObjects READ trafficObjects CONSTANT)
133
141
150
159
166 Q_PROPERTY(Traffic::Warning warning READ warning NOTIFY warningChanged)
167
168
169
170 //
171 // Getter Methods
172 //
173
178 [[nodiscard]] bool currentSourceIsInternetService() const {return m_currentSourceIsInternetService.value();}
179
184 [[nodiscard]] QBindable<bool> bindableCurrentSourceIsInternetService() const {return &m_currentSourceIsInternetService;}
185
190 [[nodiscard]] QList<Traffic::TrafficDataSource_Abstract*> dataSources() const;
191
197 {
198 return m_positionInfo.value();
199 }
200
205 [[nodiscard]] QBindable<Positioning::PositionInfo> bindablePositionInfo() const
206 {
207 return &m_positionInfo;
208 }
209
214 [[nodiscard]] Units::Distance pressureAltitude() const {return m_pressureAltitude.value();}
215
220 [[nodiscard]] QBindable<Units::Distance> bindablePressureAltitude() const {return &m_pressureAltitude;}
221
226 [[nodiscard]] bool receivingHeartbeat() const
227 {
228 return m_receivingHeartbeat.value();
229 }
230
235 [[nodiscard]] QBindable<bool> bindableReceivingHeartbeat() const
236 {
237 return &m_receivingHeartbeat;
238 }
239
244 [[nodiscard]] QString statusString() const
245 {
246 return m_statusString.value();
247 }
248
253 [[nodiscard]] QBindable<QString> bindableStatusString() const
254 {
255 return &m_statusString;
256 }
257
262 [[nodiscard]] QList<Traffic::TrafficFactor_WithPosition*> trafficObjects() const
263 {
264 return m_trafficObjects;
265 }
266
272 {
273 return m_trafficObjectWithoutPosition;
274 }
275
280 [[nodiscard]] QString trafficReceiverRuntimeError() const
281 {
282 return m_trafficReceiverRuntimeError.value();
283 }
284
289 [[nodiscard]] QString trafficReceiverSelfTestError() const
290 {
291 return m_trafficReceiverSelfTestError.value();
292 }
293
298 [[nodiscard]] Traffic::Warning warning() const
299 {
300 return m_Warning;
301 }
302
303
304
305 //
306 // Methods
307 //
308
318
328 Q_INVOKABLE QString addDataSource(const Traffic::ConnectionInfo &connectionInfo);
329
338 Q_INVOKABLE QString addDataSource_UDP(quint16 port);
339
348 Q_INVOKABLE QString addDataSource_SerialPort(const QString& portName);
349
360 Q_INVOKABLE QString addDataSource_TCP(const QString& host, quint16 port);
361
368 Q_INVOKABLE QString addDataSource_OGN();
369
378
379signals:
382
390 void passwordRequest(const QString& SSID);
391
398 void passwordStorageRequest(const QString& SSID, const QString& password);
399
402
405
408
411
412public slots:
421
427
438 void setPassword(const QString& SSID, const QString &password);
439
440private slots:
441 // Identical to addDataSource, but handles Bluetooth Classic connections only.
442 QString addDataSource_BluetoothClassic(const Traffic::ConnectionInfo &connectionInfo);
443
444 // Identical to addDataSource, but handles Bluetooth Low Energy connections only.
445 QString addDataSource_BluetoothLowEnergy(const Traffic::ConnectionInfo &connectionInfo);
446
447 // Clear all data sources
448 void clearDataSources();
449
450 // Intializations that are moved out of the constructor, in order to avoid
451 // nested uses of constructors in Global.
452 void deferredInitialization();
453
454 // Sends out foreflight broadcast message See
455 // https://www.foreflight.com/connect/spec/
456 void foreFlightBroadcast();
457
458 // Load connection infos from file and create connections
459 void loadConnectionInfos();
460
461 // Called if one of the sources indicates a heartbeat change
462 void onCurrentSourceChanged();
463
464 // Called if one of the sources reports traffic (position unknown)
465 void onTrafficFactorWithPosition(const Traffic::TrafficFactor_WithPosition& factor);
466
467 // Called if one of the sources reports traffic (position known)
468 void onTrafficFactorWithoutPosition(const Traffic::TrafficFactor_DistanceOnly& factor);
469
470 // Resetter method
471 void resetWarning();
472
473 // Save connection infos to file
474 void saveConnectionInfos();
475
476 // Setter method
477 void setWarning(const Traffic::Warning& warning);
478
479private:
480 //
481 // Compute Methods
482 //
483
484
485 QProperty<QString> m_statusString;
486 QString computeStatusString();
487
488 // UDP Socket for ForeFlight Broadcast messages.
489 // See https://www.foreflight.com/connect/spec/
490 QNetworkDatagram foreFlightBroadcastDatagram {R"({"App":"Enroute Flight Navigation","GDL90":{"port":4000}})", QHostAddress::Broadcast, 63093};
491 QUdpSocket foreFlightBroadcastSocket;
492 QTimer foreFlightBroadcastTimer;
493
494 // Targets
495 QList<Traffic::TrafficFactor_WithPosition *> m_trafficObjects;
496 QPointer<Traffic::TrafficFactor_DistanceOnly> m_trafficObjectWithoutPosition;
497
498 // TrafficData Sources
499 QProperty<QList<QPointer<Traffic::TrafficDataSource_Abstract>>> m_dataSources;
500
501 QProperty<QPointer<Traffic::TrafficDataSource_Abstract>> m_currentSource;
502 QPropertyNotifier m_currentSourceNotifier;
503 QPointer<Traffic::TrafficDataSource_Abstract> computeCurrentSource();
504
505 QProperty<bool> m_currentSourceIsInternetService;
506
507 // Property cache
508 Traffic::Warning m_Warning;
509 QTimer m_WarningTimer;
510
511 Q_OBJECT_BINDABLE_PROPERTY(Traffic::TrafficDataProvider, QString, m_trafficReceiverRuntimeError, &Traffic::TrafficDataProvider::trafficReceiverRuntimeErrorChanged);
512 QString computeTrafficReceiverRuntimeError();
513
514 Q_OBJECT_BINDABLE_PROPERTY(Traffic::TrafficDataProvider, QString, m_trafficReceiverSelfTestError, &Traffic::TrafficDataProvider::trafficReceiverSelfTestErrorChanged);
515 QString computeTrafficReceiverSelfTestError();
516
517 QProperty<Positioning::PositionInfo> m_positionInfo;
518 Positioning::PositionInfo computePositionInfo();
519
520 QProperty<Units::Distance> m_pressureAltitude;
521 Units::Distance computePressureAltitude();
522
523 // Reconnect
524 QTimer reconnectionTimer;
525
526 Q_OBJECT_BINDABLE_PROPERTY(Traffic::TrafficDataProvider, bool, m_receivingHeartbeat, &Traffic::TrafficDataProvider::receivingHeartbeatChanged);
527 bool computeReceivingHeartbeat();
528
529 // Standard file name for saveConnectionInfos()
530 QString stdFileName{QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + u"/connectionInfos.data"_s};
531};
532
533} // namespace Traffic
static Q_INVOKABLE Traffic::TrafficDataProvider * trafficDataProvider()
Pointer to appplication-wide static TrafficDataProvider instance.
Geographic position.
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.
Positioning::PositionInfo positionInfo
Position information.
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.
Positioning::PositionInfo positionInfo() const
Getter method for property with the same name.
bool receivingHeartbeat
Heartbeat indicator.
QString statusString
Source status.
Units::Distance pressureAltitude
Pressure altitude.
void receivingHeartbeatChanged()
Notifier signal.
void connectToTrafficReceiver()
Start attempt to connect to traffic receiver.
void trafficReceiverRuntimeErrorChanged()
Notifier signal.
QBindable< Positioning::PositionInfo > bindablePositionInfo() const
Getter method for property with the same name.
Q_INVOKABLE QString addDataSource_SerialPort(const QString &portName)
Add an additional data source.
void trafficReceiverSelfTestErrorChanged()
Notifier signal.
QString statusString() const
Getter method for property with the same name.
void dataSourcesChanged()
Notifier signal.
QBindable< QString > bindableStatusString() const
Getter method for property with the same name.
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