3#include <QtCore/QMetaEnum>
19 qCDebug(VehicleSigningControllerLog) <<
"VehicleSigningController ctor — vehicle" << _vehicle->id();
21 _retryTimer.setInterval(kRetransmitIntervalMs);
22 connect(&_retryTimer, &QTimer::timeout,
this, &VehicleSigningController::_onRetryTimer);
25 &VehicleSigningController::_onPrimaryLinkChanged);
36 qCDebug(VehicleSigningControllerLog) <<
"VehicleSigningController dtor — vehicle" << _vehicle->
id();
39void VehicleSigningController::_onPrimaryLinkChanged()
52 if (!ctrl || ctrl == _active) {
69 if (ctrl->
state() == SigningController::State::Enabling || ctrl->
state() == SigningController::State::Disabling) {
72 disconnect(ctrl,
nullptr,
this,
nullptr);
73 if (_active == ctrl) {
79void VehicleSigningController::_onSigningStateChanged()
84void VehicleSigningController::_refreshStatus()
86 _signingStatus = _active ? _active->status() :
SigningStatus{};
89void VehicleSigningController::_onSigningAlertRaised(
const QString& detail)
91 qCWarning(VehicleSigningControllerLog) <<
"[veh" << _vehicle->
id() <<
"] signing alert:" << detail;
92 qgcApp()->showAppMessage(tr(
"Vehicle %1: %2").arg(_vehicle->
id()).arg(detail));
95void VehicleSigningController::_onSigningConfirmed(
const QString& confirmedKey)
101 qCDebug(VehicleSigningControllerLog) <<
"[veh" << _vehicle->
id() <<
"] signing confirmed — key"
102 << (confirmedKey.isEmpty() ?
"<disabled>" : confirmedKey);
105void VehicleSigningController::_onSigningFailed(
const SigningFailure& failure)
108 qCWarning(VehicleSigningControllerLog)
109 <<
"[veh" << _vehicle->
id() <<
"] signing failed:"
110 << QMetaEnum::fromType<SigningFailure::Reason>().valueToKey(
static_cast<int>(failure.
reason)) << failure.
detail;
115void VehicleSigningController::_startRetransmit()
120void VehicleSigningController::_stopRetransmit()
124 _pendingHasKey =
false;
127void VehicleSigningController::_onRetryTimer()
129 if (!_active || _active->state() == SigningController::State::On ||
130 _active->state() == SigningController::State::Off) {
138 const QByteArrayView keyView = _pendingHasKey ? QByteArrayView(
reinterpret_cast<const char*
>(_pendingKey.data()),
139 static_cast<qsizetype
>(_pendingKey.size()))
141 (void)_sendSetupSigning(sharedLink, keyView);
142 qCDebug(VehicleSigningControllerLog) <<
"[veh" << _vehicle->
id() <<
"] retransmitted SETUP_SIGNING ("
143 << (_pendingHasKey ?
"enable" :
"disable") <<
")";
146bool VehicleSigningController::_sendSetupSigning(
const SharedLinkInterfacePtr& sharedLink, QByteArrayView keyView)
148 const auto channel =
static_cast<mavlink_channel_t>(sharedLink->mavlinkChannel());
149 const mavlink_system_t targetSystem{
static_cast<uint8_t
>(_vehicle->
id()),
155 qCWarning(VehicleSigningControllerLog)
156 <<
"[veh" << _vehicle->
id() <<
"] failed to encode SETUP_SIGNING (channel" << channel <<
")";
161 for (uint8_t i = 0; i < 2; ++i) {
170 qCWarning(VehicleSigningControllerLog) <<
"[veh" << _vehicle->
id() <<
"] enable: no signing controller";
176 qCWarning(VehicleSigningControllerLog) <<
"[veh" << _vehicle->
id() <<
"] enable: no primary link";
182 qCCritical(VehicleSigningControllerLog)
183 <<
"[veh" << _vehicle->
id() <<
"] enable: unknown signing key:" << keyName;
188 if (
auto fail = _active->tryBeginEnable(
static_cast<uint8_t
>(_vehicle->
id()), keyName, *keyBytes)) {
189 qgcApp()->showAppMessage(fail->detail);
195 Qt::SingleShotConnection);
197 Qt::SingleShotConnection);
199 const QByteArrayView keyView(
reinterpret_cast<const char*
>(keyBytes->data()), keyBytes->size());
200 if (!_sendSetupSigning(sharedLink, keyView)) {
201 _active->cancelPending(tr(
"Failed to transmit SETUP_SIGNING to vehicle"));
205 _pendingKey = *keyBytes;
206 _pendingHasKey =
true;
209 qCDebug(VehicleSigningControllerLog) <<
"[veh" << _vehicle->
id() <<
"] SETUP_SIGNING sent — key" << keyName
210 <<
"awaiting signed HEARTBEAT";
216 qCWarning(VehicleSigningControllerLog) <<
"[veh" << _vehicle->
id() <<
"] disable: no signing controller";
222 qCWarning(VehicleSigningControllerLog) <<
"[veh" << _vehicle->
id() <<
"] disable: no primary link";
226 if (
auto fail = _active->tryBeginDisable(
static_cast<uint8_t
>(_vehicle->
id()))) {
227 qgcApp()->showAppMessage(fail->detail);
233 Qt::SingleShotConnection);
235 Qt::SingleShotConnection);
239 _pendingHasKey =
false;
241 if (!_sendSetupSigning(sharedLink, QByteArrayView{})) {
242 _active->cancelPending(tr(
"Failed to transmit SETUP_SIGNING to vehicle"));
248 qCDebug(VehicleSigningControllerLog) <<
"[veh" << _vehicle->
id()
249 <<
"] disable SETUP_SIGNING sent — awaiting unsigned HEARTBEAT";
std::shared_ptr< LinkInterface > SharedLinkInterfacePtr
struct __mavlink_message mavlink_message_t
#define QGC_LOGGING_CATEGORY(name, categoryStr)
static int getComponentId()
void resetSequenceTracking(LinkInterface *link)
Reset sequence tracking so signing transitions don't inflate loss counters.
static MAVLinkProtocol * instance()
static MAVLinkSigningKeys * instance()
std::optional< MAVLinkSigning::SigningKey > keyBytesByName(const QString &name) const
Key bytes for the key with the given name, or nullopt if not found.
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.
void cancelPending(const QString &detail={})
void alertRaised(const QString &detail)
void keyAutoDetected(const QString &keyName)
void signingFailed(SigningFailure failure)
Emitted exactly once per begin*() on failure (timeout, init error, cancel, re-entry).
Reason a signing operation failed. Used by SigningController error path and Vehicle::signingFailed.
void primaryLinkChanged()
WeakLinkInterfacePtr primaryLink() const
Per-vehicle signing facade. Owns the wiring between Vehicle and the active SigningController (which l...
Q_INVOKABLE void enable(const QString &keyName)
~VehicleSigningController() override
Q_INVOKABLE void disable()
void signingFailed(SigningFailure info)
VehicleLinkManager * vehicleLinkManager()
bool sendMessageOnLinkThreadSafe(LinkInterface *link, mavlink_message_t message)
int defaultComponentId() const
bool encodeSetupSigning(mavlink_channel_t channel, uint8_t srcSysId, uint8_t srcCompId, mavlink_system_t target_system, QByteArrayView keyBytes, mavlink_message_t &message)
void secureZero(void *data, size_t size)