13 uint64_t persistedTimestamp, const QString& keyName,
bool signOutgoing)
15 if (!key.isEmpty() && !callback) {
16 qCWarning(SigningChannelLog) <<
"[ch" << channel <<
"] callback must be specified when enabling";
22 qCWarning(SigningChannelLog) <<
"[ch" << channel <<
"] invalid channel (no MAVLink status)";
26 QWriteLocker locker(&_lock);
30 status->signing =
nullptr;
31 status->signing_streams =
nullptr;
33 _signing.accept_unsigned_callback =
nullptr;
40 if (key.size() <
static_cast<qsizetype
>(
sizeof(_signing.secret_key))) {
41 qCWarning(SigningChannelLog) <<
"[ch" << channel <<
"] key too short:" << key.size() <<
"bytes (need"
42 <<
sizeof(_signing.secret_key) <<
")";
49 _signing.link_id =
static_cast<uint8_t
>(channel);
50 _signing.flags = signOutgoing ? MAVLINK_SIGNING_FLAG_SIGN_OUTGOING : 0;
51 _signing.accept_unsigned_callback = callback;
52 memcpy(_signing.secret_key, key.constData(),
sizeof(_signing.secret_key));
55 persistedTimestamp + kPersistedTimestampSafetyBumpTicks);
58 status->signing = &_signing;
59 status->signing_streams = &_streams;
66 QReadLocker locker(&_lock);
68 return {0, QString()};
70 return {_signing.timestamp, _keyHint};
75 QWriteLocker locker(&_lock);
79 _signing.accept_unsigned_callback = callback;
83bool SigningChannel::setSignOutgoing(
bool signOutgoing)
85 QWriteLocker locker(&_lock);
90 _signing.flags |= MAVLINK_SIGNING_FLAG_SIGN_OUTGOING;
92 _signing.flags &=
static_cast<uint8_t
>(~MAVLINK_SIGNING_FLAG_SIGN_OUTGOING);
99 QReadLocker locker(&_lock);
105 QReadLocker locker(&_lock);
106 return static_cast<int>(_streams.num_signing_streams);
111 QReadLocker locker(&_lock);
117 QWriteLocker locker(&_lock);
123 return _autoDetectSuspended.load(std::memory_order_acquire);
128 QReadLocker locker(&_lock);
129 return !_detectCooldown.hasExpired();
134 QWriteLocker locker(&_lock);
140 QWriteLocker locker(&_lock);
141 _detectCooldown.setRemainingTime(0);
146 QWriteLocker locker(&_lock);
156 QReadLocker locker(&_lock);
158 snap.
inCooldown = !_detectCooldown.hasExpired();
165 QWriteLocker locker(&_lock);
167 const mavlink_signing_status_t current =
168 (status && status->signing) ? status->signing->last_status : MAVLINK_SIGNING_STATUS_NONE;
169 if (current == _lastTransitionStatus) {
172 _lastTransitionStatus = current;
mavlink_status_t * mavlink_get_channel_status(uint8_t chan)
#define QGC_LOGGING_CATEGORY(name, categoryStr)
Owns MAVLink signing state for one channel: signing/streams structs, key hint, and RW lock.
void setKeyHint(const QString &name)
bool setAcceptUnsignedCallback(mavlink_accept_unsigned_t callback)
Swap the accept-unsigned callback without resetting the key. Returns false if signing isn't enabled.
MAVLinkSigning::DetectSnapshot detectSnapshot() const
Single-lock snapshot; 3 separate reads have TOCTOU window vs MockLink's thread.
void clearDetectCooldown()
bool isAutoDetectSuspended() const
While suspended, tryDetectKey is suppressed to block stale-key installs during pending enable.
bool consumeStatusTransition(mavlink_channel_t channel)
True if last_status changed since previous call; sole transition-detection source.
bool isInDetectCooldown() const
Throttles detect misses; HMAC per packet per key is expensive. Monotonic timer to avoid wall-clock sk...
static constexpr qint64 kDetectCooldownMs
TimestampSnapshot currentTimestampAndName() const
Returns current timestamp and active key name. Returns {0, ""} when signing is not enabled.
uint64_t currentSigningTimestampTicks()
Current signing timestamp in 10µs ticks since 2015-01-01.
void secureZero(void *data, size_t size)
Single-lock snapshot struct; fields populated by SigningChannel::detectSnapshot().