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 //~TrafficDataProvider();
74
75 //
76 // Properties
77 //
78
84 Q_PROPERTY(QList<Traffic::ConnectionInfo> connectionInfos READ connectionInfos BINDABLE bindableConnectionInfos NOTIFY connectionInfosChanged)
85
86
92
99
107 Q_PROPERTY(Positioning::PositionInfo positionInfo READ positionInfo BINDABLE bindablePositionInfo)
108
115
124
131 Q_PROPERTY(QString statusString READ statusString BINDABLE bindableStatusString)
132
141 Q_PROPERTY(QList<Traffic::TrafficFactor_WithPosition*> trafficObjects READ trafficObjects CONSTANT)
142
150
159
168
175 Q_PROPERTY(Traffic::Warning warning READ warning NOTIFY warningChanged)
176
177
178 //
179 // Getter Methods
180 //
181
186 [[nodiscard]] QList<Traffic::ConnectionInfo> connectionInfos() const {return m_connectionInfos.value();}
187
192 [[nodiscard]] QBindable<QList<Traffic::ConnectionInfo>> bindableConnectionInfos() {return &m_connectionInfos;}
193
198 [[nodiscard]] bool currentSourceIsInternetService() const {return m_currentSourceIsInternetService.value();}
199
204 [[nodiscard]] QBindable<bool> bindableCurrentSourceIsInternetService() {return &m_currentSourceIsInternetService;}
205
210 [[nodiscard]] QList<Traffic::TrafficDataSource_Abstract*> dataSources() const;
211
217 {
218 return m_positionInfo.value();
219 }
220
225 [[nodiscard]] QBindable<Positioning::PositionInfo> bindablePositionInfo() {return &m_positionInfo;}
226
231 [[nodiscard]] Units::Distance pressureAltitude() const {return m_pressureAltitude.value();}
232
237 [[nodiscard]] QBindable<Units::Distance> bindablePressureAltitude() {return &m_pressureAltitude;}
238
243 [[nodiscard]] bool receivingHeartbeat() const
244 {
245 return m_receivingHeartbeat.value();
246 }
247
252 [[nodiscard]] QBindable<bool> bindableReceivingHeartbeat() {return &m_receivingHeartbeat;}
253
258 [[nodiscard]] QString statusString() const
259 {
260 return m_statusString.value();
261 }
262
267 [[nodiscard]] QBindable<QString> bindableStatusString() {return &m_statusString;}
268
273 [[nodiscard]] QList<Traffic::TrafficFactor_WithPosition*> trafficObjects() const
274 {
275 return m_trafficObjects;
276 }
277
283 {
284 return m_trafficObjectWithoutPosition;
285 }
286
291 [[nodiscard]] QString trafficReceiverRuntimeError() const
292 {
293 return m_trafficReceiverRuntimeError.value();
294 }
295
300 [[nodiscard]] QString trafficReceiverSelfTestError() const
301 {
302 return m_trafficReceiverSelfTestError.value();
303 }
304
309 [[nodiscard]] Traffic::Warning warning() const
310 {
311 return m_Warning;
312 }
313
314
315 //
316 // Methods
317 //
318
328
338 Q_INVOKABLE QString addDataSource(const Traffic::ConnectionInfo &connectionInfo);
339
348 Q_INVOKABLE QString addDataSource_UDP(quint16 port);
349
365 Q_INVOKABLE QString addDataSource_SerialPort(const QString& portNameOrDescription,
366 ConnectionInfo::BaudRate baudRate,
367 ConnectionInfo::StopBits stopBits,
368 ConnectionInfo::FlowControl flowControl);
369
380 Q_INVOKABLE QString addDataSource_TCP(const QString& host, quint16 port);
381
388 Q_INVOKABLE QString addDataSource_OGN();
389
397 Q_INVOKABLE bool hasDataSource_SerialPort(const QString& portNameOrDescription);
398
407
409 Q_INVOKABLE void removeDataSources();
410
411
412signals:
415
418
426 void passwordRequest(const QString& SSID);
427
434 void passwordStorageRequest(const QString& SSID, const QString& password);
435
438
441
444
447
448public slots:
457
463
474 void setPassword(const QString& SSID, const QString &password);
475
476private slots:
477 // Identical to addDataSource, but handles Bluetooth Classic connections only.
478 QString addDataSource_BluetoothClassic(const Traffic::ConnectionInfo &connectionInfo);
479
480 // Identical to addDataSource, but handles Bluetooth Low Energy connections only.
481 QString addDataSource_BluetoothLowEnergy(const Traffic::ConnectionInfo &connectionInfo);
482
483 // Intializations that are moved out of the constructor, in order to avoid
484 // nested uses of constructors in Global.
485 void deferredInitialization();
486
487 // Sends out foreflight broadcast message See
488 // https://www.foreflight.com/connect/spec/
489 void foreFlightBroadcast();
490
491 // Load connection infos from file and create connections
492 void loadConnectionInfos();
493
494 // Called if one of the sources indicates a heartbeat change
495 void onCurrentSourceChanged();
496
497 // Called if one of the sources reports traffic (position unknown)
498 void onTrafficFactorWithPosition(const Traffic::TrafficFactor_WithPosition& factor);
499
500 // Called if one of the sources reports traffic (position known)
501 void onTrafficFactorWithoutPosition(const Traffic::TrafficFactor_DistanceOnly& factor);
502
503 // Resetter method
504 void resetWarning();
505
506 // Save connection infos to file
507 void saveConnectionInfos();
508
509 // Setter method
510 void setWarning(const Traffic::Warning& warning);
511
512private:
513 //
514 // Compute Methods
515 //
516
517
518 QProperty<QString> m_statusString;
519 QString computeStatusString();
520
521 // UDP Socket for ForeFlight Broadcast messages.
522 // See https://www.foreflight.com/connect/spec/
523 QNetworkDatagram foreFlightBroadcastDatagram {R"({"App":"Enroute Flight Navigation","GDL90":{"port":4000}})", QHostAddress::Broadcast, 63093};
524 QUdpSocket foreFlightBroadcastSocket;
525 QTimer foreFlightBroadcastTimer;
526
527 // Targets
528 QList<Traffic::TrafficFactor_WithPosition *> m_trafficObjects;
529 QPointer<Traffic::TrafficFactor_DistanceOnly> m_trafficObjectWithoutPosition;
530
531 // TrafficData Sources
532 QProperty<QList<QPointer<Traffic::TrafficDataSource_Abstract>>> m_dataSources;
533
534 QProperty<QPointer<Traffic::TrafficDataSource_Abstract>> m_currentSource;
535 QPropertyNotifier m_currentSourceNotifier;
536 QPointer<Traffic::TrafficDataSource_Abstract> computeCurrentSource();
537
538 QProperty<bool> m_currentSourceIsInternetService;
539
540 // Property cache
541 Traffic::Warning m_Warning;
542 QTimer m_WarningTimer;
543
544 Q_OBJECT_BINDABLE_PROPERTY(Traffic::TrafficDataProvider, QList<Traffic::ConnectionInfo>, m_connectionInfos, &Traffic::TrafficDataProvider::connectionInfosChanged);
545 QList<Traffic::ConnectionInfo> computeConnectionInfos();
546
547 Q_OBJECT_BINDABLE_PROPERTY(Traffic::TrafficDataProvider, QString, m_trafficReceiverRuntimeError, &Traffic::TrafficDataProvider::trafficReceiverRuntimeErrorChanged);
548 QString computeTrafficReceiverRuntimeError();
549
550 Q_OBJECT_BINDABLE_PROPERTY(Traffic::TrafficDataProvider, QString, m_trafficReceiverSelfTestError, &Traffic::TrafficDataProvider::trafficReceiverSelfTestErrorChanged);
551 QString computeTrafficReceiverSelfTestError();
552
553 QProperty<Positioning::PositionInfo> m_positionInfo;
554 Positioning::PositionInfo computePositionInfo();
555
556 QProperty<Units::Distance> m_pressureAltitude;
557 Units::Distance computePressureAltitude();
558
559 // Reconnect
560 QTimer reconnectionTimer;
561
562 Q_OBJECT_BINDABLE_PROPERTY(Traffic::TrafficDataProvider, bool, m_receivingHeartbeat, &Traffic::TrafficDataProvider::receivingHeartbeatChanged);
563 bool computeReceivingHeartbeat();
564
565 // Standard file name for saveConnectionInfos()
566 QString stdFileName{QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + u"/connectionInfos.data"_s};
567};
568
569} // 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 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