3#include <QtCore/QMutex>
4#include <QtCore/QObject>
5#include <QtCore/QString>
6#include <QtCore/QTimer>
39 [[nodiscard]] std::optional<SigningFailure>
tryBeginEnable(uint8_t expectedSysId,
const QString&
keyName,
43 [[nodiscard]] std::optional<SigningFailure>
tryBeginDisable(uint8_t expectedSysId);
53 const QString& keyNameHint = {});
87 enum class OpKind : uint8_t
96 OpKind kind = OpKind::None;
97 uint8_t expectedSysId = 0;
100 bool unsignedSeen =
false;
103 bool _isPendingLocked()
const {
return _op.kind != OpKind::None; }
107 void _confirmLocked();
108 void _failLocked(
FailReason reason,
const QString& detail,
bool cancelled =
false);
110 void _setOpLocked(PendingOp next);
111 void _completeDisableSuccessLocked();
114 void _setWallClockRefresh(
bool on);
120 mutable QRecursiveMutex _fsmMutex;
122 std::optional<QGC::AutoSuspendGuard> _autoDetectGuard;
127 QTimer _wallClockRefresh;
129 static constexpr uint8_t kBadSignatureAlertThreshold = 3;
132 static constexpr auto kTimeout = std::chrono::seconds(5);
133 static std::chrono::milliseconds _effectiveTimeout()
135 return _timeoutOverride > std::chrono::milliseconds::zero() ? _timeoutOverride
136 : std::chrono::milliseconds(kTimeout);
138 static inline std::chrono::milliseconds _timeoutOverride{0};
140 static constexpr auto kWallClockRefreshInterval = std::chrono::seconds(1);
struct __mavlink_message mavlink_message_t
Owns MAVLink signing state for one channel: signing/streams structs, key hint, and RW lock.
bool signOutgoing(mavlink_message_t &message)
void clearDetectCooldown()
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.
static void setTimeoutForTesting(std::chrono::milliseconds timeout)
Test-only override for the vehicle-confirmation timeout, read at each begin*(); zero restores the def...
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...
void clearDetectCooldown()
std::optional< SigningFailure > tryBeginDisable(uint8_t expectedSysId)
Atomic check-and-commit for disable; same contract as tryBeginEnable.
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
bool wallClockRefreshActiveForTesting() const
bool signOutgoing(mavlink_message_t &message)
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.