Enroute Flight Navigation
A navigation app for VFR pilots
TrafficDataSource_Ogn.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 <QPointer>
24#include <QTcpSocket>
25#include <string>
26#include <vector>
27
28#include "traffic/TrafficDataSource_AbstractSocket.h"
29#include "OgnFilter.h" // From enrouteOGN library
30#include "OgnParser.h" // From enrouteOGN library
31
32using namespace Qt::Literals::StringLiterals;
33
34namespace Traffic {
35
48
50 Q_OBJECT
51
52public:
63 TrafficDataSource_Ogn(bool isCanonical, QString hostName, quint16 port, QObject *parent = nullptr);
64
65 // Standard destructor
66 ~TrafficDataSource_Ogn() override;
67
68 //
69 // Properties
70 //
71
74 Q_PROPERTY(QString host READ host CONSTANT)
75
76
78 Q_PROPERTY(quint16 port READ port CONSTANT)
79
80 //
81 // Getter Methods
82 //
83
88 [[nodiscard]] QString dataFormat() const override { return u"APRS-IS"_s; }
89
94 [[nodiscard]] QString host() const
95 {
96 return m_hostName;
97 }
98
106 [[nodiscard]] QString icon() const override { return u"/icons/material/ic_wifi.svg"_s; }
107
115 [[nodiscard]] auto sourceName() const -> QString override
116 {
117 return tr("Open Glider Network-Connection");
118 }
119
124 [[nodiscard]] quint16 port() const
125 {
126 return m_port;
127 }
128
129public slots:
136
143
153 void sendPosition(const QGeoCoordinate& coordinate, double course, double speed, double altitude);
154
155private slots:
156
157 // Read lines from the socket's text stream and passes the string on to
158 // processAprsisMessage.
159 void onReadyRead();
160
161private:
162 Q_DISABLE_COPY_MOVE(TrafficDataSource_Ogn)
163
164 QTcpSocket m_socket;
165 QTextStream m_textStream;
166 QString m_hostName;
167 quint16 m_port;
168
169 // True while a connection is wanted. The socket's "disconnected" signal only
170 // triggers an automatic reconnect while this is true, so that
171 // disconnectFromTrafficReceiver() can actually stop the connection — abort()
172 // emits "disconnected", which would otherwise reconnect immediately.
173 bool m_connectionDesired = false;
174
175 QString m_lineBuffer; // Reusable buffer for reading lines
176 Ogn::OgnMessage m_ognMessage; // Reusable message structure
177 Ogn::OgnFilter m_ognFilter; // Deduplication and out-of-order packet filter
178
179 // our own OGN APRS CallSign, like "ENR12345"
180 QString m_callSign;
181
182 // our own AircraftType
184
185 // Radius around the approximate position for which traffic data is requested.
186 static constexpr Units::Distance m_receiveRadius = Units::Distance::fromNM(20.0);
187
188 // Current coordinate and GPS usage
189 QGeoCoordinate m_currentPosition;
190 bool m_usingGps = true;
191
192 // Cached ownship filter data (updated when aircraft settings change)
193 std::u16string m_ownAircraftName;
194 std::vector<std::string> m_ownTransponderCodes;
195
196 // Throttling for filter updates
197 QGeoCoordinate m_lastFilterPosition; // Last coordinate actually sent to OGN server
198 qint64 m_lastFilterUpdateTime = 0;
199 static constexpr qint64 MIN_FILTER_UPDATE_INTERVAL_MS = 1000; // 1 second
200 static constexpr double MIN_FILTER_UPDATE_DISTANCE_KM = 5.0; // 5 km
201
202 // Update filter with throttling logic
203 void setFilter(const QGeoCoordinate& coordinate);
204
205 // Update current coordinate based on GPS and map center availability
206 void updateCurrentCoordinate();
207
208 // Update cached ownship filter data from aircraft settings
209 void updateOwnshipFilterData();
210
211 // Periodic update function called once per minute
212 void periodicUpdate();
213
214 // Process OGN message and emit factorWithPosition signal
215 void processOgnMessage(const QString& data);
216
217 // Send a keep-alive message to the APRS-IS server
218 void sendKeepAlive();
219
220 // Verify the connection to the APRS-IS server and reconnect if necessary
221 void verifyConnection();
222};
223
224} // namespace Traffic
TrafficDataSource_AbstractSocket(bool isCanonical, QObject *parent)
Default constructor.
void connectToTrafficReceiver() override
Start attempt to connect to traffic receiver.
QString dataFormat() const override
Getter function for the property with the same name.
void sendPosition(const QGeoCoordinate &coordinate, double course, double speed, double altitude)
Send position report to APRS-IS server.
void disconnectFromTrafficReceiver() override
Disconnect from traffic receiver.
quint16 port() const
Getter function for the property with the same name.
quint16 port
TCP port of the OGN/APRS-IS server (e.g. 14580).
QString host
Hostname of the OGN/APRS-IS server (e.g. aprs.glidernet.org).
TrafficDataSource_Ogn(bool isCanonical, QString hostName, quint16 port, QObject *parent=nullptr)
Default constructor.
QString host() const
Getter function for the property with the same name.
QString icon() const override
Getter function for the property with the same name.
auto sourceName() const -> QString override
Getter function for the property with the same name.
Convenience class for distance computations.
Definition Distance.h:35
static Q_INVOKABLE constexpr Units::Distance fromNM(double distanceInNM)
Constructs a distance.
Definition Distance.h:82