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") <<
")";
149 qCWarning(VehicleSigningControllerLog) <<
"[veh" << _vehicle->
id() <<
"]" << op <<
": no signing controller";
154 qCWarning(VehicleSigningControllerLog) <<
"[veh" << _vehicle->
id() <<
"]" << op <<
": no primary link";
159void VehicleSigningController::_wireConfirmHandlers()
162 Qt::SingleShotConnection);
164 Qt::SingleShotConnection);
167bool VehicleSigningController::_sendAndStartRetransmit(
const SharedLinkInterfacePtr& sharedLink, QByteArrayView keyView)
169 if (!_sendSetupSigning(sharedLink, keyView)) {
170 _active->cancelPending(tr(
"Failed to transmit SETUP_SIGNING to vehicle"));
178bool VehicleSigningController::_sendSetupSigning(
const SharedLinkInterfacePtr& sharedLink, QByteArrayView keyView)
180 const auto channel =
static_cast<mavlink_channel_t>(sharedLink->mavlinkChannel());
181 const mavlink_system_t targetSystem{
static_cast<uint8_t
>(_vehicle->
id()),
187 qCWarning(VehicleSigningControllerLog)
188 <<
"[veh" << _vehicle->
id() <<
"] failed to encode SETUP_SIGNING (channel" << channel <<
")";
193 for (uint8_t i = 0; i < 2; ++i) {
208 qCCritical(VehicleSigningControllerLog)
209 <<
"[veh" << _vehicle->
id() <<
"] enable: unknown signing key:" << keyName;
214 if (
auto fail = _active->tryBeginEnable(
static_cast<uint8_t
>(_vehicle->
id()), keyName, *keyBytes)) {
215 qgcApp()->showAppMessage(fail->detail);
220 _pendingKey = *keyBytes;
221 _pendingHasKey =
true;
222 const QByteArrayView keyView(
reinterpret_cast<const char*
>(_pendingKey.data()), _pendingKey.size());
223 _wireConfirmHandlers();
224 if (!_sendAndStartRetransmit(sharedLink, keyView)) {
226 _pendingHasKey =
false;
230 qCDebug(VehicleSigningControllerLog) <<
"[veh" << _vehicle->
id() <<
"] SETUP_SIGNING sent — key" << keyName
231 <<
"awaiting signed HEARTBEAT";
241 if (
auto fail = _active->tryBeginDisable(
static_cast<uint8_t
>(_vehicle->
id()))) {
242 qgcApp()->showAppMessage(fail->detail);
249 _pendingHasKey =
false;
251 _wireConfirmHandlers();
252 if (!_sendAndStartRetransmit(sharedLink, QByteArrayView{})) {
256 qCDebug(VehicleSigningControllerLog) <<
"[veh" << _vehicle->
id()
257 <<
"] 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)