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 QWriteLocker locker(&_lock);
71 if (now <= _signing.timestamp) {
74 _signing.timestamp = now;
80 QWriteLocker locker(&_lock);
81 if (!_enabled || !(_signing.flags & MAVLINK_SIGNING_FLAG_SIGN_OUTGOING)) {
86 const QByteArrayView key(
reinterpret_cast<const char*
>(_signing.secret_key),
sizeof(_signing.secret_key));
95 QReadLocker locker(&_lock);
97 return {0, QString()};
99 return {_signing.timestamp, _keyHint};
104 QWriteLocker locker(&_lock);
108 _signing.accept_unsigned_callback = callback;
112bool SigningChannel::setSignOutgoing(
bool signOutgoing)
114 QWriteLocker locker(&_lock);
119 _signing.flags |= MAVLINK_SIGNING_FLAG_SIGN_OUTGOING;
121 _signing.flags &=
static_cast<uint8_t
>(~MAVLINK_SIGNING_FLAG_SIGN_OUTGOING);
128 QReadLocker locker(&_lock);
134 QReadLocker locker(&_lock);
135 return static_cast<int>(_streams.num_signing_streams);
140 QReadLocker locker(&_lock);
146 QWriteLocker locker(&_lock);
152 return _autoDetectSuspended.load(std::memory_order_acquire);
157 QReadLocker locker(&_lock);
158 return !_detectCooldown.hasExpired();
163 QWriteLocker locker(&_lock);
169 QWriteLocker locker(&_lock);
170 _detectCooldown.setRemainingTime(0);
175 QWriteLocker locker(&_lock);
185 QReadLocker locker(&_lock);
187 snap.
inCooldown = !_detectCooldown.hasExpired();
194 QWriteLocker locker(&_lock);
196 const mavlink_signing_status_t current =
197 (status && status->signing) ? status->signing->last_status : MAVLINK_SIGNING_STATUS_NONE;
198 if (current == _lastTransitionStatus) {
201 _lastTransitionStatus = current;
mavlink_status_t * mavlink_get_channel_status(uint8_t chan)
struct __mavlink_message mavlink_message_t
#define QGC_LOGGING_CATEGORY(name, categoryStr)
Owns MAVLink signing state for one channel: signing/streams structs, key hint, and RW lock.
bool refreshOutgoingTimestamp()
bool signOutgoing(mavlink_message_t &message)
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.
void signMessage(QByteArrayView key, uint8_t linkId, uint64_t timestamp, mavlink_message_t &message)
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().