QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
NTRIPManager.h
Go to the documentation of this file.
1#pragma once
2
3#include <QtCore/QChronoTimer>
4#include <QtCore/QLoggingCategory>
5#include <QtCore/QObject>
6#include <QtCore/QPointer>
7#include <QtQmlIntegration/QtQmlIntegration>
8#include <chrono>
9
11#include "NTRIPGgaProvider.h"
13#include "NTRIPTransport.h"
15#include "UdpForwarder.h"
16
17Q_DECLARE_LOGGING_CATEGORY(NTRIPManagerLog)
18
19class NTRIPSettings;
20class RTCMMavlink;
21class RTCMUdpInput;
22
28class NTRIPManager : public QObject
29{
30 Q_OBJECT
31 friend class NTRIPManagerTest;
32 QML_ELEMENT
33 QML_UNCREATABLE("")
34 Q_MOC_INCLUDE("NTRIPConnectionStats.h")
35 Q_MOC_INCLUDE("NTRIPSourceTableController.h")
36 Q_MOC_INCLUDE("RTCMMavlink.h")
38 Q_PROPERTY(QString statusMessage READ statusMessage NOTIFY statusMessageChanged)
39 Q_PROPERTY(QString securityWarning READ securityWarning NOTIFY securityWarningChanged)
41 Q_PROPERTY(QString ggaSource READ ggaSource NOTIFY ggaSourceChanged)
44 // CONSTANT is safe: rtcmMavlink is established once in init() (or injected for
45 // tests) before any QML binds, and is never reassigned thereafter.
46 Q_PROPERTY(RTCMMavlink* rtcmMavlink READ rtcmMavlink CONSTANT)
47
48public:
51 {
52 Disconnected = 0,
53 Connecting = 1,
54 Connected = 2,
55 Reconnecting = 3,
56 Error = 4
57 };
58 Q_ENUM(ConnectionStatus)
59
60 enum class CasterStatus
61 {
65 };
66 Q_ENUM(CasterStatus)
67
68
85
86 explicit NTRIPManager(QObject* parent = nullptr);
87 ~NTRIPManager() override;
88
89 static NTRIPManager* instance();
90
94 void init();
95
96 ConnectionStatus connectionStatus() const { return _connectionStatus; }
97
98 QString statusMessage() const { return _statusMessage; }
99
100 QString securityWarning() const { return _securityWarning; }
101
102 CasterStatus casterStatus() const { return _casterStatus; }
103
104 QString ggaSource() const { return _ggaProvider.currentSource(); }
105
106 NTRIPSourceTableController* sourceTableController() { return &_sourceTableController; }
107
109
112 RTCMMavlink* rtcmMavlink() const;
113
114 Q_INVOKABLE void fetchMountpoints();
115
116 Q_INVOKABLE void selectMountpoint(const QString& mountpoint)
117 {
118 _sourceTableController.selectMountpoint(mountpoint);
119 }
120
123 void setTransportForTest(NTRIPTransport* transport) { _injectedTransport = transport; }
124
125 void setRtcmMavlink(RTCMMavlink* mavlink);
126
127 void startNTRIP();
128 void stopNTRIP();
129
130signals:
136
137private:
140 bool _dispatch(Event ev, const QString& detail = {});
141
145 void _enterState(ConnectionStatus to, const QString& detail);
146
148 void _onEnterState(ConnectionStatus from, ConnectionStatus to);
149
151 static QString _defaultMessageFor(ConnectionStatus state);
152
153 void _startTransport();
154 void _teardownTransport();
155
156 // Reconnect backoff (inlined; was NTRIPReconnectPolicy). The single-shot
157 // timer fires reconnectRequested → ReconnectDue; exhausting the attempt
158 // ceiling fires ReconnectGaveUp instead.
159 static constexpr int kMinReconnectMs = 1000;
160 static constexpr int kMaxReconnectMs = 30000;
161 static constexpr int kMaxReconnectAttempts = 100;
162
163 void _scheduleReconnect();
164
165 void _cancelReconnect() { _reconnectTimer.stop(); }
166
167 void _resetReconnectAttempts() { _reconnectAttempts = 0; }
168
169 int _reconnectBackoffMs() const;
170
171 bool _reconnectExhausted() const { return _reconnectAttempts >= kMaxReconnectAttempts; }
172
175 void _applyUdpForwarderConfig(const NTRIPTransportConfig& config);
176
177 void _onTransportError(NTRIPError code, const QString& detail);
178 void _onPlaintextCredentialsWarning();
179 void _setSecurityWarning(const QString& warning);
180 void _rtcmDataReceived(const QByteArray& data, int messageId);
181 void _onSettingChanged();
182 bool _isEnabled() const;
183
186 void _setupRtcmUdpInput();
187
188 NTRIPGgaProvider _ggaProvider{this};
189 NTRIPConnectionStats _stats{this};
190 UdpForwarder _udpForwarder{this};
191
193 QString _statusMessage;
194 QString _securityWarning;
196
197 QPointer<NTRIPTransport> _injectedTransport;
198 QPointer<NTRIPTransport> _transport;
199
200 QPointer<RTCMMavlink> _rtcmMavlink;
201 RTCMUdpInput* _rtcmUdpInput = nullptr;
202
203 NTRIPTransportConfig _runningConfig;
204 NTRIPSettings* _settings = nullptr;
205
206 NTRIPSourceTableController _sourceTableController{this};
207
208 static constexpr std::chrono::milliseconds kSettingsDebounceMs{250};
209 QChronoTimer _settingsDebounceTimer{this};
210 QChronoTimer _reconnectTimer{this};
211 int _reconnectAttempts = 0;
212 bool _initialized = false;
213};
Config config
QString currentSource() const
void statusMessageChanged()
ConnectionStatus connectionStatus() const
void setRtcmMavlink(RTCMMavlink *mavlink)
void casterStatusChanged(CasterStatus status)
Q_INVOKABLE void selectMountpoint(const QString &mountpoint)
ConnectionStatus
Public connection status. Numeric values are stable — QML binds against them.
void setTransportForTest(NTRIPTransport *transport)
Q_INVOKABLE void fetchMountpoints()
QString securityWarning() const
static NTRIPManager * instance()
NTRIPSourceTableController * sourceTableController()
void ggaSourceChanged()
RTCMMavlink * rtcmMavlink() const
CasterStatus casterStatus() const
void securityWarningChanged()
QString statusMessage() const
@ StartRequested
startNTRIP() called or settings enable went true.
@ ReconnectGaveUp
NTRIPReconnectPolicy fired gaveUp().
@ HotReconfigure
Transport-affecting setting changed while connected; reconnect in place.
@ TransportFatalError
NTRIPTransport emitted a non-retryable error.
@ RTCMBeforeConnected
RTCM data arrived before the connected() signal was processed.
@ ConfigInvalid
NTRIPTransportConfig::isValid() returned false.
@ TransportError
NTRIPTransport emitted a retryable error.
@ TransportConnected
NTRIPTransport emitted connected().
@ StopRequested
stopNTRIP() called or settings enable went false.
@ ReconnectDue
NTRIPReconnectPolicy fired reconnectRequested().
QString ggaSource() const
~NTRIPManager() override
void connectionStatusChanged()
NTRIPConnectionStats * connectionStats()
friend class NTRIPManagerTest
Q_INVOKABLE void selectMountpoint(const QString &mountpoint)
Listens on a UDP port for raw RTCM3 correction data and emits it for forwarding to connected vehicles...