QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
SigningController.h
Go to the documentation of this file.
1#pragma once
2
3#include <QtCore/QMutex>
4#include <QtCore/QObject>
5#include <QtCore/QString>
6#include <QtCore/QTimer>
7#include <chrono>
8#include <optional>
9
11#include "MAVLinkMessageType.h"
12#include "MAVLinkSigning.h"
13#include "SigningChannel.h"
14#include "SigningFailure.h"
15#include "SigningStatus.h"
16
19class SigningController : public QObject
20{
21 Q_OBJECT
22public:
25
26 Q_PROPERTY(State state READ state NOTIFY stateChanged)
27
28 explicit SigningController(mavlink_channel_t channel, QObject* parent = nullptr);
29 ~SigningController() override;
30
31 State state() const;
32 SigningStatus status() const;
33
34 bool isEnabled() const;
35 QString keyName() const;
36 int streamCount() const;
37 QString statusText() const;
38
40 [[nodiscard]] std::optional<SigningFailure> tryBeginEnable(uint8_t expectedSysId, const QString& keyName,
41 const MAVLinkSigning::SigningKey& keyBytes);
42
44 [[nodiscard]] std::optional<SigningFailure> tryBeginDisable(uint8_t expectedSysId);
45
48 void cancelPending(const QString& detail = {});
49
50 bool clearSigning();
51
54 const QString& keyNameHint = {});
55
56 const SigningChannel& channel() const { return _channel; }
57
58 void recordDetectMiss() { _channel.recordDetectMiss(); }
59
61
63 bool processFrame(bool framingOk, const mavlink_message_t& message);
64
65 void resetBadSigBurst();
66
67signals:
69 void keyAutoDetected(const QString& keyName);
70 void alertRaised(const QString& detail);
71
73 void signingConfirmed(const QString& keyName);
74
77
78private:
79 enum class OpKind : uint8_t
80 {
81 None,
82 Enable,
83 Disable
84 };
85
86 struct PendingOp
87 {
88 OpKind kind = OpKind::None;
89 uint8_t expectedSysId = 0;
90 QString keyName;
92 bool unsignedSeen = false;
93 };
94
95 bool _isPendingLocked() const { return _op.kind != OpKind::None; }
96
98 void _handleFsmFrameLocked(const mavlink_message_t& message);
99 void _confirmLocked();
100 void _failLocked(FailReason reason, const QString& detail, bool cancelled = false);
101 void _clearLocked();
102 void _setOpLocked(PendingOp next);
103 void _completeDisableSuccessLocked();
104 void _onTimeout();
105
106 SigningChannel _channel;
107 mavlink_channel_t _mavlinkChannel;
110 mutable QRecursiveMutex _fsmMutex;
111 PendingOp _op;
112 std::optional<QGC::AutoSuspendGuard> _autoDetectGuard;
113 QTimer _timeout;
114
115 static constexpr uint8_t kBadSignatureAlertThreshold = 3;
116 QGC::EdgeTriggeredCounter<uint8_t> _badSigBurst{kBadSignatureAlertThreshold};
117
118 static constexpr auto kTimeout = std::chrono::seconds(5);
119};
mavlink_channel_t
struct __mavlink_message mavlink_message_t
Owns MAVLink signing state for one channel: signing/streams structs, key hint, and RW lock.
Owns MAVLink signing state and the deferred-confirmation state machine for one LinkInterface.
void signingConfirmed(const QString &keyName)
Emitted exactly once per begin*() on success. keyName is the enabled key, or empty for disable.
std::optional< SigningFailure > tryBeginEnable(uint8_t expectedSysId, const QString &keyName, const MAVLinkSigning::SigningKey &keyBytes)
Begin pending-enable. Caller must send SETUP_SIGNING only on nullopt; outcome arrives via signingConf...
std::optional< SigningFailure > tryBeginDisable(uint8_t expectedSysId)
Atomic check-and-commit for disable; same contract as tryBeginEnable.
QString keyName() const
bool initSigningImmediate(QByteArrayView key, MAVLinkSigning::UnsignedAcceptancePolicy policy, const QString &keyNameHint={})
Bypasses the FSM; used by tests and auto-detect. Non-empty keyNameHint seeds the persisted timestamp.
bool processFrame(bool framingOk, const mavlink_message_t &message)
Per-frame entry point; drives burst alerts, auto-detect, and the FSM. Returns true on auto-detect.
QString statusText() const
SigningFailure::Reason FailReason
void cancelPending(const QString &detail={})
void alertRaised(const QString &detail)
~SigningController() override
SigningStatus status() const
void keyAutoDetected(const QString &keyName)
void signingFailed(SigningFailure failure)
Emitted exactly once per begin*() on failure (timeout, init error, cancel, re-entry).
const SigningChannel & channel() const
Reason a signing operation failed. Used by SigningController error path and Vehicle::signingFailed.
std::array< uint8_t, kSigningKeySize > SigningKey
std::array avoids QByteArray COW detach so secureZero() actually wipes the bytes.