Enroute Flight Navigation
A navigation app for VFR pilots
TrafficDataProvider.h
1/***************************************************************************
2 * Copyright (C) 2021-2026 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
54class TrafficDataProvider : public QObject {
55 Q_OBJECT
56 QML_ELEMENT
57 QML_SINGLETON
58
59public:
64 explicit TrafficDataProvider(QObject *parent = nullptr);
65
66 // No default constructor, important for QML singleton
67 explicit TrafficDataProvider() = delete;
68
69 // factory function for QML singleton
70 static Traffic::TrafficDataProvider* create(QQmlEngine* /*unused*/, QJSEngine* /*unused*/)
71 {
73 }
74
75 // Standard destructor
76 ~TrafficDataProvider() override;
77
78 //
79 // Properties
80 //
81
87 Q_PROPERTY(QList<Traffic::ConnectionInfo> connectionInfos READ connectionInfos BINDABLE bindableConnectionInfos NOTIFY connectionInfosChanged)
88
89
95
102
110 Q_PROPERTY(Positioning::PositionInfo positionInfo READ positionInfo BINDABLE bindablePositionInfo)
111
118
127
134 Q_PROPERTY(QString statusString READ statusString BINDABLE bindableStatusString)
135
143 Q_PROPERTY(QList<Traffic::TrafficFactor_WithPosition*> trafficObjects READ trafficObjects CONSTANT)
144
152
161
170
177 Q_PROPERTY(Traffic::Warning warning READ warning NOTIFY warningChanged)
178
179
180 //
181 // Getter Methods
182 //
183
188 [[nodiscard]] QList<Traffic::ConnectionInfo> connectionInfos() const {return m_connectionInfos.value();}
189
194 [[nodiscard]] QBindable<QList<Traffic::ConnectionInfo>> bindableConnectionInfos() {return &m_connectionInfos;}
195
200 [[nodiscard]] bool currentSourceIsInternetService() const {return m_currentSourceIsInternetService.value();}
201
206 [[nodiscard]] QBindable<bool> bindableCurrentSourceIsInternetService() {return &m_currentSourceIsInternetService;}
207
212 [[nodiscard]] QList<Traffic::TrafficDataSource_Abstract*> dataSources() const;
213
219 {
220 return m_positionInfo.value();
221 }
222
227 [[nodiscard]] QBindable<Positioning::PositionInfo> bindablePositionInfo() {return &m_positionInfo;}
228
233 [[nodiscard]] Units::Distance pressureAltitude() const {return m_pressureAltitude.value();}
234
239 [[nodiscard]] QBindable<Units::Distance> bindablePressureAltitude() {return &m_pressureAltitude;}
240
245 [[nodiscard]] bool receivingHeartbeat() const
246 {
247 return m_receivingHeartbeat.value();
248 }
249
254 [[nodiscard]] QBindable<bool> bindableReceivingHeartbeat() {return &m_receivingHeartbeat;}
255
260 [[nodiscard]] QString statusString() const
261 {
262 return m_statusString.value();
263 }
264
269 [[nodiscard]] QBindable<QString> bindableStatusString() {return &m_statusString;}
270
275 [[nodiscard]] QList<Traffic::TrafficFactor_WithPosition*> trafficObjects() const
276 {
277 return m_trafficObjects;
278 }
279
285 {
286 return m_trafficObjectWithoutPosition;
287 }
288
293 [[nodiscard]] QString trafficReceiverRuntimeError() const
294 {
295 return m_trafficReceiverRuntimeError.value();
296 }
297
302 [[nodiscard]] QString trafficReceiverSelfTestError() const
303 {
304 return m_trafficReceiverSelfTestError.value();
305 }
306
311 [[nodiscard]] Traffic::Warning warning() const
312 {
313 return m_Warning;
314 }
315
316
317 //
318 // Methods
319 //
320
330
340 Q_INVOKABLE QString addDataSource(const Traffic::ConnectionInfo &connectionInfo);
341
350 Q_INVOKABLE QString addDataSource_UDP(quint16 port);
351
367 Q_INVOKABLE QString addDataSource_SerialPort(const QString& portNameOrDescription,
368 ConnectionInfo::BaudRate baudRate,
369 ConnectionInfo::StopBits stopBits,
370 ConnectionInfo::FlowControl flowControl);
371
382 Q_INVOKABLE QString addDataSource_TCP(const QString& host, quint16 port);
383
390 Q_INVOKABLE QString addDataSource_OGN();
391
399 Q_INVOKABLE bool hasDataSource_SerialPort(const QString& portNameOrDescription);
400
409
411 Q_INVOKABLE void removeDataSources();
412
413
414signals:
417
420
428 void passwordRequest(const QString& SSID);
429
440 void passwordStorageRequest(const QString& SSID, const QString& password);
441
444
447
450
453
454public slots:
463
469
480 void setPassword(const QString& SSID, const QString &password);
481
482private slots:
483 // Identical to addDataSource, but handles Bluetooth Classic connections only.
484 QString addDataSource_BluetoothClassic(const Traffic::ConnectionInfo &connectionInfo);
485
486 // Identical to addDataSource, but handles Bluetooth Low Energy connections only.
487 QString addDataSource_BluetoothLowEnergy(const Traffic::ConnectionInfo &connectionInfo);
488
489 // Intializations that are moved out of the constructor, in order to avoid
490 // nested uses of constructors in Global.
491 void deferredInitialization();
492
493 // Sends out foreflight broadcast message See
494 // https://www.foreflight.com/connect/spec/
495 void foreFlightBroadcast();
496
497 // Load connection infos from file and create connections
498 void loadConnectionInfos();
499
500 // Called if one of the sources indicates a heartbeat change
501 void onCurrentSourceChanged();
502
503 // Called if one of the sources reports traffic (position known)
504 void onTrafficFactorWithPosition(const Traffic::TrafficFactorData_WithPosition& factor);
505
506 // Called if one of the sources reports traffic (position unknown)
507 void onTrafficFactorWithoutPosition(const Traffic::TrafficFactorData_DistanceOnly& factor);
508
509 // Resetter method
510 void resetWarning();
511
512 // Save connection infos to file
513 void saveConnectionInfos();
514
515 // Setter method
516 void setWarning(const Traffic::Warning& warning);
517
518private:
519 Q_DISABLE_COPY_MOVE(TrafficDataProvider)
520
521 //
522 // Compute Methods
523 //
524
525
526 QProperty<QString> m_statusString;
527 QString computeStatusString();
528
529 // UDP Socket for ForeFlight Broadcast messages.
530 // See https://www.foreflight.com/connect/spec/
531 QNetworkDatagram foreFlightBroadcastDatagram = {R"({"App":"Enroute Flight Navigation","GDL90":{"port":4000}})", QHostAddress::Broadcast, 63093};
532 QUdpSocket foreFlightBroadcastSocket;
533 QTimer foreFlightBroadcastTimer;
534
535 // Targets
536 QList<Traffic::TrafficFactor_WithPosition *> m_trafficObjects;
537 QPointer<Traffic::TrafficFactor_DistanceOnly> m_trafficObjectWithoutPosition;
538
539 // TrafficData Sources
540 QProperty<QList<QPointer<Traffic::TrafficDataSource_Abstract>>> m_dataSources;
541
542 // Cached, alphabetically sorted view of m_dataSources exposed via the
543 // dataSources property. Recomputed (and dataSourcesChanged emitted) whenever
544 // m_dataSources changes.
545 Q_OBJECT_BINDABLE_PROPERTY(Traffic::TrafficDataProvider, QList<Traffic::TrafficDataSource_Abstract*>, m_dataSourcesCache, &Traffic::TrafficDataProvider::dataSourcesChanged);
546 QList<Traffic::TrafficDataSource_Abstract*> computeDataSources();
547
548 QProperty<QPointer<Traffic::TrafficDataSource_Abstract>> m_currentSource;
549 QPropertyNotifier m_currentSourceNotifier;
550 QPointer<Traffic::TrafficDataSource_Abstract> computeCurrentSource();
551
552 QProperty<bool> m_currentSourceIsInternetService;
553
554 // Property cache
555 Traffic::Warning m_Warning;
556 QTimer m_WarningTimer;
557
558 Q_OBJECT_BINDABLE_PROPERTY(Traffic::TrafficDataProvider, QList<Traffic::ConnectionInfo>, m_connectionInfos, &Traffic::TrafficDataProvider::connectionInfosChanged);
559 QList<Traffic::ConnectionInfo> computeConnectionInfos();
560
561 Q_OBJECT_BINDABLE_PROPERTY(Traffic::TrafficDataProvider, QString, m_trafficReceiverRuntimeError, &Traffic::TrafficDataProvider::trafficReceiverRuntimeErrorChanged);
562 QString computeTrafficReceiverRuntimeError();
563
564 Q_OBJECT_BINDABLE_PROPERTY(Traffic::TrafficDataProvider, QString, m_trafficReceiverSelfTestError, &Traffic::TrafficDataProvider::trafficReceiverSelfTestErrorChanged);
565 QString computeTrafficReceiverSelfTestError();
566
567 QProperty<Positioning::PositionInfo> m_positionInfo;
568 Positioning::PositionInfo computePositionInfo();
569
570 QProperty<Units::Distance> m_pressureAltitude;
571 Units::Distance computePressureAltitude();
572
573 // Reconnect
574 QTimer reconnectionTimer;
575
576 Q_OBJECT_BINDABLE_PROPERTY(Traffic::TrafficDataProvider, bool, m_receivingHeartbeat, &Traffic::TrafficDataProvider::receivingHeartbeatChanged);
577 bool computeReceivingHeartbeat();
578
579 // Standard file name for saveConnectionInfos()
580 QString stdFileName = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + u"/connectionInfos.data"_s;
581};
582
583} // 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.
QList< Traffic::ConnectionInfo > connectionInfos
Connection Infos.
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.
QBindable< bool > bindableCurrentSourceIsInternetService()
Getter method for property with the same name.
QList< Traffic::TrafficDataSource_Abstract * > dataSources
Traffic data sources.
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.
QBindable< QString > bindableStatusString()
Getter method for property with the same name.
void connectionInfosChanged()
Notifier signal.
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.
QBindable< Positioning::PositionInfo > bindablePositionInfo()
Getter method for property with the same name.
bool receivingHeartbeat
Heartbeat indicator.
QString statusString
Source status.
Units::Distance pressureAltitude
Pressure altitude.
QBindable< Units::Distance > bindablePressureAltitude()
Getter method for property with the same name.
void receivingHeartbeatChanged()
Notifier signal.
void connectToTrafficReceiver()
Start attempt to connect to traffic receiver.
void trafficReceiverRuntimeErrorChanged()
Notifier signal.
Q_INVOKABLE QString addDataSource_SerialPort(const QString &portNameOrDescription, ConnectionInfo::BaudRate baudRate, ConnectionInfo::StopBits stopBits, ConnectionInfo::FlowControl flowControl)
Add an additional data source.
void trafficReceiverSelfTestErrorChanged()
Notifier signal.
QString statusString() const
Getter method for property with the same name.
void dataSourcesChanged()
Notifier signal.
Q_INVOKABLE void removeDataSources()
Remove all non-canonical data sources.
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.
Q_INVOKABLE bool hasDataSource_SerialPort(const QString &portNameOrDescription)
Check if serial port connection already exists.
QBindable< bool > bindableReceivingHeartbeat()
Getter method for property with the same name.
bool currentSourceIsInternetService() const
Getter method for property with the same name.
QList< Traffic::TrafficFactor_WithPosition * > trafficObjects
Traffic objects whose position is known.
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.
QBindable< QList< Traffic::ConnectionInfo > > bindableConnectionInfos()
Getter method for property with the same name.
Base class for all traffic receiver data sources.
Traffic factor whose distance is known, but not its bearing.
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
Plain-data record of a traffic factor whose position is not known.
Plain-data record of a traffic factor whose precise position is known.