diff --git a/src/AirLink/AirlinkLink.cc b/src/AirLink/AirlinkLink.cc index 6d6ffff151f5..894c735fb22f 100644 --- a/src/AirLink/AirlinkLink.cc +++ b/src/AirLink/AirlinkLink.cc @@ -130,9 +130,8 @@ bool AirlinkLink::_connect() pendingTimer->deleteLater(); } }); - MAVLinkProtocol *mavlink = qgcApp()->toolbox()->mavlinkProtocol(); auto conn = std::make_shared(); - *conn = connect(mavlink, &MAVLinkProtocol::messageReceived, [this, conn] (LinkInterface* linkSrc, mavlink_message_t message) { + *conn = connect(MAVLinkProtocol::instance(), &MAVLinkProtocol::messageReceived, [this, conn] (LinkInterface* linkSrc, mavlink_message_t message) { if (this != linkSrc || message.msgid != MAVLINK_MSG_ID_AIRLINK_AUTH_RESPONSE) { return; } diff --git a/src/AnalyzeView/LogDownloadController.cc b/src/AnalyzeView/LogDownloadController.cc index 1070cffd4495..59d6e1f8585a 100644 --- a/src/AnalyzeView/LogDownloadController.cc +++ b/src/AnalyzeView/LogDownloadController.cc @@ -394,8 +394,8 @@ LogDownloadController::_requestLogData(uint16_t id, uint32_t offset, uint32_t co qCDebug(LogDownloadControllerLog) << "Request log data (id:" << id << "offset:" << offset << "size:" << count << "retryCount" << retryCount << ")"; mavlink_message_t msg; mavlink_msg_log_request_data_pack_chan( - qgcApp()->toolbox()->mavlinkProtocol()->getSystemId(), - qgcApp()->toolbox()->mavlinkProtocol()->getComponentId(), + MAVLinkProtocol::instance()->getSystemId(), + MAVLinkProtocol::instance()->getComponentId(), sharedLink->mavlinkChannel(), &msg, _vehicle->id(), _vehicle->defaultComponentId(), @@ -425,8 +425,8 @@ LogDownloadController::_requestLogList(uint32_t start, uint32_t end) if (sharedLink) { mavlink_message_t msg; mavlink_msg_log_request_list_pack_chan( - qgcApp()->toolbox()->mavlinkProtocol()->getSystemId(), - qgcApp()->toolbox()->mavlinkProtocol()->getComponentId(), + MAVLinkProtocol::instance()->getSystemId(), + MAVLinkProtocol::instance()->getComponentId(), sharedLink->mavlinkChannel(), &msg, _vehicle->id(), @@ -596,8 +596,8 @@ LogDownloadController::eraseAll(void) if (sharedLink) { mavlink_message_t msg; mavlink_msg_log_erase_pack_chan( - qgcApp()->toolbox()->mavlinkProtocol()->getSystemId(), - qgcApp()->toolbox()->mavlinkProtocol()->getComponentId(), + MAVLinkProtocol::instance()->getSystemId(), + MAVLinkProtocol::instance()->getComponentId(), sharedLink->mavlinkChannel(), &msg, qgcApp()->toolbox()->multiVehicleManager()->activeVehicle()->id(), qgcApp()->toolbox()->multiVehicleManager()->activeVehicle()->defaultComponentId()); diff --git a/src/AnalyzeView/MAVLinkConsoleController.cc b/src/AnalyzeView/MAVLinkConsoleController.cc index 13e73e3d4815..f85d1b2a4d91 100644 --- a/src/AnalyzeView/MAVLinkConsoleController.cc +++ b/src/AnalyzeView/MAVLinkConsoleController.cc @@ -155,12 +155,11 @@ MAVLinkConsoleController::_sendSerialData(QByteArray data, bool close) chunk.append(MAVLINK_MSG_SERIAL_CONTROL_FIELD_DATA_LEN - chunk.size(), '\0'); uint8_t flags = SERIAL_CONTROL_FLAG_EXCLUSIVE | SERIAL_CONTROL_FLAG_RESPOND | SERIAL_CONTROL_FLAG_MULTI; if (close) flags = 0; - auto protocol = qgcApp()->toolbox()->mavlinkProtocol(); auto link = _vehicle->vehicleLinkManager()->primaryLink(); mavlink_message_t msg; mavlink_msg_serial_control_pack_chan( - protocol->getSystemId(), - protocol->getComponentId(), + MAVLinkProtocol::instance()->getSystemId(), + MAVLinkProtocol::instance()->getComponentId(), sharedLink->mavlinkChannel(), &msg, SERIAL_CONTROL_DEV_SHELL, diff --git a/src/AnalyzeView/MAVLinkInspectorController.cc b/src/AnalyzeView/MAVLinkInspectorController.cc index 290da65c7a62..9fb2e66f6d2b 100644 --- a/src/AnalyzeView/MAVLinkInspectorController.cc +++ b/src/AnalyzeView/MAVLinkInspectorController.cc @@ -28,8 +28,7 @@ MAVLinkInspectorController::MAVLinkInspectorController() connect(multiVehicleManager, &MultiVehicleManager::vehicleAdded, this, &MAVLinkInspectorController::_vehicleAdded); connect(multiVehicleManager, &MultiVehicleManager::vehicleRemoved, this, &MAVLinkInspectorController::_vehicleRemoved); connect(multiVehicleManager, &MultiVehicleManager::activeVehicleChanged, this, &MAVLinkInspectorController::_setActiveVehicle); - MAVLinkProtocol* mavlinkProtocol = qgcApp()->toolbox()->mavlinkProtocol(); - connect(mavlinkProtocol, &MAVLinkProtocol::messageReceived, this, &MAVLinkInspectorController::_receiveMessage); + connect(MAVLinkProtocol::instance(), &MAVLinkProtocol::messageReceived, this, &MAVLinkInspectorController::_receiveMessage); connect(&_updateFrequencyTimer, &QTimer::timeout, this, &MAVLinkInspectorController::_refreshFrequency); _updateFrequencyTimer.start(1000); _timeScaleSt.append(new TimeScale_st(this, tr("5 Sec"), 5 * 1000)); diff --git a/src/AutoPilotPlugins/APM/APMSensorsComponentController.cc b/src/AutoPilotPlugins/APM/APMSensorsComponentController.cc index a59852f2cb02..0124e369ff70 100644 --- a/src/AutoPilotPlugins/APM/APMSensorsComponentController.cc +++ b/src/AutoPilotPlugins/APM/APMSensorsComponentController.cc @@ -103,7 +103,7 @@ void APMSensorsComponentController::_startLogCalibration(void) } _cancelButton->setEnabled(_calTypeInProgress == QGCMAVLink::CalibrationMag); - connect(qgcApp()->toolbox()->mavlinkProtocol(), &MAVLinkProtocol::messageReceived, this, &APMSensorsComponentController::_mavlinkMessageReceived); + connect(MAVLinkProtocol::instance(), &MAVLinkProtocol::messageReceived, this, &APMSensorsComponentController::_mavlinkMessageReceived); } void APMSensorsComponentController::_startVisualCalibration(void) @@ -116,7 +116,7 @@ void APMSensorsComponentController::_startVisualCalibration(void) _progressBar->setProperty("value", 0); - connect(qgcApp()->toolbox()->mavlinkProtocol(), &MAVLinkProtocol::messageReceived, this, &APMSensorsComponentController::_mavlinkMessageReceived); + connect(MAVLinkProtocol::instance(), &MAVLinkProtocol::messageReceived, this, &APMSensorsComponentController::_mavlinkMessageReceived); } void APMSensorsComponentController::_resetInternalState(void) @@ -147,7 +147,7 @@ void APMSensorsComponentController::_resetInternalState(void) void APMSensorsComponentController::_stopCalibration(APMSensorsComponentController::StopCalibrationCode code) { - disconnect(qgcApp()->toolbox()->mavlinkProtocol(), &MAVLinkProtocol::messageReceived, this, &APMSensorsComponentController::_mavlinkMessageReceived); + disconnect(MAVLinkProtocol::instance(), &MAVLinkProtocol::messageReceived, this, &APMSensorsComponentController::_mavlinkMessageReceived); _vehicle->vehicleLinkManager()->setCommunicationLostEnabled(true); disconnect(_vehicle, &Vehicle::textMessageReceived, this, &APMSensorsComponentController::_handleUASTextMessage); @@ -462,8 +462,8 @@ void APMSensorsComponentController::nextClicked(void) if (sharedLink) { mavlink_message_t msg; - mavlink_msg_command_ack_pack_chan(qgcApp()->toolbox()->mavlinkProtocol()->getSystemId(), - qgcApp()->toolbox()->mavlinkProtocol()->getComponentId(), + mavlink_msg_command_ack_pack_chan(MAVLinkProtocol::instance()->getSystemId(), + MAVLinkProtocol::instance()->getComponentId(), sharedLink->mavlinkChannel(), &msg, 0, // command diff --git a/src/Camera/QGCCameraIO.cc b/src/Camera/QGCCameraIO.cc index 52da8bd2b43c..f3e40159c6aa 100644 --- a/src/Camera/QGCCameraIO.cc +++ b/src/Camera/QGCCameraIO.cc @@ -10,8 +10,6 @@ #include "MavlinkCameraControl.h" #include "QGCCameraIO.h" #include "QGCLoggingCategory.h" -#include "QGCApplication.h" -#include "QGCToolbox.h" #include "LinkInterface.h" #include "MAVLinkProtocol.h" #include "Vehicle.h" @@ -47,7 +45,6 @@ QGCCameraParamIO::QGCCameraParamIO(MavlinkCameraControl *control, Fact* fact, Ve connect(&_paramWriteTimer, &QTimer::timeout, this, &QGCCameraParamIO::_paramWriteTimeout); connect(_fact, &Fact::rawValueChanged, this, &QGCCameraParamIO::_factChanged); connect(_fact, &Fact::_containerRawValueChanged, this, &QGCCameraParamIO::_containerRawValueChanged); - _pMavlink = qgcApp()->toolbox()->mavlinkProtocol(); //-- TODO: Even though we don't use anything larger than 32-bit, this should // probably be updated. switch (_fact->type()) { @@ -196,8 +193,8 @@ QGCCameraParamIO::_sendParameter() p.target_component = static_cast(_control->compID()); strncpy(p.param_id, _fact->name().toStdString().c_str(), MAVLINK_MSG_PARAM_EXT_SET_FIELD_PARAM_ID_LEN); mavlink_msg_param_ext_set_encode_chan( - static_cast(_pMavlink->getSystemId()), - static_cast(_pMavlink->getComponentId()), + static_cast(MAVLinkProtocol::instance()->getSystemId()), + static_cast(MAVLinkProtocol::instance()->getComponentId()), sharedLink->mavlinkChannel(), &msg, &p); @@ -369,8 +366,8 @@ QGCCameraParamIO::paramRequest(bool reset) strncpy(param_id, _fact->name().toStdString().c_str(), MAVLINK_MSG_PARAM_EXT_REQUEST_READ_FIELD_PARAM_ID_LEN); mavlink_message_t msg; mavlink_msg_param_ext_request_read_pack_chan( - static_cast(_pMavlink->getSystemId()), - static_cast(_pMavlink->getComponentId()), + static_cast(MAVLinkProtocol::instance()->getSystemId()), + static_cast(MAVLinkProtocol::instance()->getComponentId()), sharedLink->mavlinkChannel(), &msg, static_cast(_vehicle->id()), diff --git a/src/Camera/QGCCameraIO.h b/src/Camera/QGCCameraIO.h index 5d2ce7ef97fd..bd61fb43092b 100644 --- a/src/Camera/QGCCameraIO.h +++ b/src/Camera/QGCCameraIO.h @@ -15,7 +15,6 @@ class MavlinkCameraControl; class Fact; class Vehicle; -class MAVLinkProtocol; Q_DECLARE_LOGGING_CATEGORY(CameraIOLog) Q_DECLARE_LOGGING_CATEGORY(CameraIOLogVerbose) @@ -77,7 +76,6 @@ private slots: bool _done; bool _updateOnSet; MAV_PARAM_EXT_TYPE _mavParamType; - MAVLinkProtocol* _pMavlink; bool _forceUIUpdate; }; diff --git a/src/Camera/VehicleCameraControl.cc b/src/Camera/VehicleCameraControl.cc index e83e06ade72b..9dab8d2a5288 100644 --- a/src/Camera/VehicleCameraControl.cc +++ b/src/Camera/VehicleCameraControl.cc @@ -1155,11 +1155,10 @@ VehicleCameraControl::_requestAllParameters() } SharedLinkInterfacePtr sharedLink = _vehicle->vehicleLinkManager()->primaryLink().lock(); if (sharedLink) { - MAVLinkProtocol* mavlink = qgcApp()->toolbox()->mavlinkProtocol(); mavlink_message_t msg; mavlink_msg_param_ext_request_list_pack_chan( - static_cast(mavlink->getSystemId()), - static_cast(mavlink->getComponentId()), + static_cast(MAVLinkProtocol::instance()->getSystemId()), + static_cast(MAVLinkProtocol::instance()->getComponentId()), sharedLink->mavlinkChannel(), &msg, static_cast(_vehicle->id()), diff --git a/src/Comms/LinkManager.cc b/src/Comms/LinkManager.cc index 43df54e8d387..0f55735552c9 100644 --- a/src/Comms/LinkManager.cc +++ b/src/Comms/LinkManager.cc @@ -87,7 +87,6 @@ void LinkManager::setToolbox(QGCToolbox *toolbox) QGCTool::setToolbox(toolbox); _autoConnectSettings = toolbox->settingsManager()->autoConnectSettings(); - _mavlinkProtocol = _toolbox->mavlinkProtocol(); if (!qgcApp()->runningUnitTests()) { (void) connect(_portListTimer, &QTimer::timeout, this, &LinkManager::_updateAutoConnectLinks); @@ -161,12 +160,12 @@ bool LinkManager::createConnectedLink(SharedLinkConfigurationPtr &config) config->setLink(link); (void) connect(link.get(), &LinkInterface::communicationError, _app, &QGCApplication::criticalMessageBoxOnMainThread); - (void) connect(link.get(), &LinkInterface::bytesReceived, _mavlinkProtocol, &MAVLinkProtocol::receiveBytes); - (void) connect(link.get(), &LinkInterface::bytesSent, _mavlinkProtocol, &MAVLinkProtocol::logSentBytes); + (void) connect(link.get(), &LinkInterface::bytesReceived, MAVLinkProtocol::instance(), &MAVLinkProtocol::receiveBytes); + (void) connect(link.get(), &LinkInterface::bytesSent, MAVLinkProtocol::instance(), &MAVLinkProtocol::logSentBytes); (void) connect(link.get(), &LinkInterface::disconnected, this, &LinkManager::_linkDisconnected); - _mavlinkProtocol->resetMetadataForLink(link.get()); - _mavlinkProtocol->setVersion(_mavlinkProtocol->getCurrentVersion()); + MAVLinkProtocol::instance()->resetMetadataForLink(link.get()); + MAVLinkProtocol::instance()->setVersion(MAVLinkProtocol::instance()->getCurrentVersion()); if (!link->_connect()) { link->_freeMavlinkChannel(); @@ -219,8 +218,8 @@ void LinkManager::_linkDisconnected() } (void) disconnect(link, &LinkInterface::communicationError, _app, &QGCApplication::criticalMessageBoxOnMainThread); - (void) disconnect(link, &LinkInterface::bytesReceived, _mavlinkProtocol, &MAVLinkProtocol::receiveBytes); - (void) disconnect(link, &LinkInterface::bytesSent, _mavlinkProtocol, &MAVLinkProtocol::logSentBytes); + (void) disconnect(link, &LinkInterface::bytesReceived, MAVLinkProtocol::instance(), &MAVLinkProtocol::receiveBytes); + (void) disconnect(link, &LinkInterface::bytesSent, MAVLinkProtocol::instance(), &MAVLinkProtocol::logSentBytes); (void) disconnect(link, &LinkInterface::disconnected, this, &LinkManager::_linkDisconnected); link->_freeMavlinkChannel(); diff --git a/src/Comms/LinkManager.h b/src/Comms/LinkManager.h index 59359d7a69dd..6a94b63cf7ac 100644 --- a/src/Comms/LinkManager.h +++ b/src/Comms/LinkManager.h @@ -149,7 +149,6 @@ private slots: QString _connectionsSuspendedReason; ///< User visible reason for suspension AutoConnectSettings *_autoConnectSettings = nullptr; - MAVLinkProtocol *_mavlinkProtocol = nullptr; QTimer *_portListTimer = nullptr; QmlObjectListModel *_qmlConfigurations = nullptr; diff --git a/src/Comms/LogReplayLink.cc b/src/Comms/LogReplayLink.cc index 53a86112d1da..ffb8155d9ee1 100644 --- a/src/Comms/LogReplayLink.cc +++ b/src/Comms/LogReplayLink.cc @@ -360,7 +360,7 @@ void LogReplayLink::_play(void) { qgcApp()->toolbox()->linkManager()->setConnectionsSuspended(tr("Connect not allowed during Flight Data replay.")); #ifndef __mobile__ - qgcApp()->toolbox()->mavlinkProtocol()->suspendLogForReplay(true); + MAVLinkProtocol::instance()->suspendLogForReplay(true); #endif // Make sure we aren't at the end of the file, if we are, reset to the beginning and play from there. @@ -379,7 +379,7 @@ void LogReplayLink::_pause(void) { qgcApp()->toolbox()->linkManager()->setConnectionsAllowed(); #ifndef __mobile__ - qgcApp()->toolbox()->mavlinkProtocol()->suspendLogForReplay(false); + MAVLinkProtocol::instance()->suspendLogForReplay(false); #endif _readTickTimer.stop(); diff --git a/src/Comms/MAVLinkProtocol.cc b/src/Comms/MAVLinkProtocol.cc index 4653333e1cd5..6232954abbf2 100644 --- a/src/Comms/MAVLinkProtocol.cc +++ b/src/Comms/MAVLinkProtocol.cc @@ -8,530 +8,411 @@ ****************************************************************************/ #include "MAVLinkProtocol.h" +#include "LinkInterface.h" #include "LinkManager.h" -#include "QGCApplication.h" #include "MultiVehicleManager.h" -#include "SettingsManager.h" +#include "QGCApplication.h" #include "QGCLoggingCategory.h" +#include "QGCTemporaryFile.h" +#include "QGCToolbox.h" +#include "SettingsManager.h" -#include -#include -#include #include #include +#include +#include +#include #include -Q_DECLARE_METATYPE(mavlink_message_t) +QGC_LOGGING_CATEGORY(MAVLinkProtocolLog, "qgc.comms.mavlinkprotocol") -QGC_LOGGING_CATEGORY(MAVLinkProtocolLog, "MAVLinkProtocolLog") +Q_APPLICATION_STATIC(MAVLinkProtocol, _mavlinkProtocol); -static QObject* mavlinkSingletonFactory(QQmlEngine*, QJSEngine*) +MAVLinkProtocol::MAVLinkProtocol(QObject *parent) + : QObject(parent) + , _tempLogFile(new QGCTemporaryFile(QStringLiteral("%2.%3").arg(_tempLogFileTemplate, _logFileExtension))) { - return new QGCMAVLink(); -} + // qCDebug(MAVLinkProtocolLog) << Q_FUNC_INFO << this; -/** - * The default constructor will create a new MAVLink object sending heartbeats at - * the MAVLINK_HEARTBEAT_DEFAULT_RATE to all connected links. - */ -MAVLinkProtocol::MAVLinkProtocol(QGCApplication* app, QGCToolbox* toolbox) - : QGCTool(app, toolbox) - , _enable_version_check(true) - , _message({}) - , _status({}) - , versionMismatchIgnore(false) - , systemId(255) - , _current_version(100) - , _radio_version_mismatch_count(0) - , _logSuspendError(false) - , _logSuspendReplay(false) - , _vehicleWasArmed(false) - , _tempLogFile(QString("%2.%3").arg(_tempLogFileTemplate).arg(_logFileExtension)) - , _linkMgr(nullptr) - , _multiVehicleManager(nullptr) -{ - memset(totalReceiveCounter, 0, sizeof(totalReceiveCounter)); - memset(totalLossCounter, 0, sizeof(totalLossCounter)); - memset(runningLossPercent, 0, sizeof(runningLossPercent)); - memset(firstMessage, 1, sizeof(firstMessage)); - memset(&_status, 0, sizeof(_status)); - memset(&_message, 0, sizeof(_message)); + (void) memset(_firstMessage, 1, sizeof(_firstMessage)); + + (void) connect(this, &MAVLinkProtocol::protocolStatusMessage, qgcApp(), &QGCApplication::criticalMessageBoxOnMainThread); + (void) connect(this, &MAVLinkProtocol::saveTelemetryLog, qgcApp(), &QGCApplication::saveTelemetryLogOnMainThread); + (void) connect(this, &MAVLinkProtocol::checkTelemetrySavePath, qgcApp(), &QGCApplication::checkTelemetrySavePathOnMainThread); + + (void) connect(qgcApp()->toolbox()->multiVehicleManager(), &MultiVehicleManager::vehicleAdded, this, &MAVLinkProtocol::_vehicleCountChanged); + (void) connect(qgcApp()->toolbox()->multiVehicleManager(), &MultiVehicleManager::vehicleRemoved, this, &MAVLinkProtocol::_vehicleCountChanged); + + enableVersionCheck(true); + + loadSettings(); } MAVLinkProtocol::~MAVLinkProtocol() { storeSettings(); _closeLogFile(); + + // qCDebug(MAVLinkProtocolLog) << Q_FUNC_INFO << this; } -void MAVLinkProtocol::setVersion(unsigned version) +MAVLinkProtocol *MAVLinkProtocol::instance() { - QList sharedLinks = _linkMgr->links(); - - for (int i = 0; i < sharedLinks.length(); i++) { - mavlink_status_t* mavlinkStatus = mavlink_get_channel_status(sharedLinks[i].get()->mavlinkChannel()); - - // Set flags for version - if (version < 200) { - mavlinkStatus->flags |= MAVLINK_STATUS_FLAG_OUT_MAVLINK1; - } else { - mavlinkStatus->flags &= ~MAVLINK_STATUS_FLAG_OUT_MAVLINK1; - } - } - - _current_version = version; + return _mavlinkProtocol(); } -void MAVLinkProtocol::setToolbox(QGCToolbox *toolbox) +void MAVLinkProtocol::setVersion(uint16_t version) { - QGCTool::setToolbox(toolbox); - - _linkMgr = _toolbox->linkManager(); - _multiVehicleManager = _toolbox->multiVehicleManager(); - - qmlRegisterSingletonType("MAVLink", 1, 0, "MAVLink", mavlinkSingletonFactory); - qRegisterMetaType("mavlink_message_t"); - - loadSettings(); - - // All the *Counter variables are not initialized here, as they should be initialized - // on a per-link basis before those links are used. @see resetMetadataForLink(). - - connect(this, &MAVLinkProtocol::protocolStatusMessage, _app, &QGCApplication::criticalMessageBoxOnMainThread); - connect(this, &MAVLinkProtocol::saveTelemetryLog, _app, &QGCApplication::saveTelemetryLogOnMainThread); - connect(this, &MAVLinkProtocol::checkTelemetrySavePath, _app, &QGCApplication::checkTelemetrySavePathOnMainThread); - - connect(_multiVehicleManager, &MultiVehicleManager::vehicleAdded, this, &MAVLinkProtocol::_vehicleCountChanged); - connect(_multiVehicleManager, &MultiVehicleManager::vehicleRemoved, this, &MAVLinkProtocol::_vehicleCountChanged); + const QList sharedLinks = qgcApp()->toolbox()->linkManager()->links(); + for (const SharedLinkInterfacePtr &interface : sharedLinks) { + mavlink_set_proto_version(interface.get()->mavlinkChannel(), version); + } - emit versionCheckChanged(_enable_version_check); + _currentVersion = version; } void MAVLinkProtocol::loadSettings() { - // Load defaults from settings QSettings settings; settings.beginGroup("QGC_MAVLINK_PROTOCOL"); - enableVersionCheck(settings.value("VERSION_CHECK_ENABLED", _enable_version_check).toBool()); + enableVersionCheck(settings.value("VERSION_CHECK_ENABLED", versionCheckEnabled()).toBool()); - // Only set system id if it was valid - int temp = settings.value("GCS_SYSTEM_ID", systemId).toInt(); - if (temp > 0 && temp < 256) - { - systemId = temp; + bool ok = false; + const uint temp = settings.value("GCS_SYSTEM_ID", getSystemId()).toUInt(&ok); + if (ok && (temp > 0) && (temp < 256)) { + setSystemId(temp); } + settings.endGroup(); } void MAVLinkProtocol::storeSettings() { - // Store settings QSettings settings; settings.beginGroup("QGC_MAVLINK_PROTOCOL"); - settings.setValue("VERSION_CHECK_ENABLED", _enable_version_check); - settings.setValue("GCS_SYSTEM_ID", systemId); - // Parameter interface settings + + settings.setValue("VERSION_CHECK_ENABLED", versionCheckEnabled()); + settings.setValue("GCS_SYSTEM_ID", getSystemId()); + + settings.endGroup(); } void MAVLinkProtocol::resetMetadataForLink(LinkInterface *link) { - int channel = link->mavlinkChannel(); - totalReceiveCounter[channel] = 0; - totalLossCounter[channel] = 0; - runningLossPercent[channel] = 0.0f; - for(int i = 0; i < 256; i++) { - firstMessage[channel][i] = 1; + const uint8_t channel = link->mavlinkChannel(); + _totalReceiveCounter[channel] = 0; + _totalLossCounter[channel] = 0; + _runningLossPercent[channel] = 0.f; + for (uint16_t i = 0; i < 256; i++) { + _firstMessage[channel][i] = 1; } link->setDecodedFirstMavlinkPacket(false); } -/** - * This method parses all outcoming bytes and log a MAVLink packet. - * @param link The interface to read from - * @see LinkInterface - **/ - -void MAVLinkProtocol::logSentBytes(LinkInterface* link, QByteArray b){ - - uint8_t bytes_time[sizeof(quint64)]; - +void MAVLinkProtocol::logSentBytes(LinkInterface *link, const QByteArray &data) +{ Q_UNUSED(link); - if (!_logSuspendError && !_logSuspendReplay && _tempLogFile.isOpen()) { - - quint64 time = static_cast(QDateTime::currentMSecsSinceEpoch() * 1000); - qToBigEndian(time,bytes_time); - - b.insert(0,QByteArray((const char*)bytes_time,sizeof(bytes_time))); - - int len = b.length(); - - if(_tempLogFile.write(b) != len) - { - // If there's an error logging data, raise an alert and stop logging. - emit protocolStatusMessage(tr("MAVLink Protocol"), tr("MAVLink Logging failed. Could not write to file %1, logging disabled.").arg(_tempLogFile.fileName())); + uint8_t bytes_time[sizeof(qint64)]; + if (!_logSuspendError && !_logSuspendReplay && _tempLogFile->isOpen()) { + const qint64 time = QDateTime::currentMSecsSinceEpoch() * 1000; + qToBigEndian(time, bytes_time); + QByteArray logData = QByteArray(); + (void) logData.insert(0, QByteArray(reinterpret_cast(bytes_time), sizeof(bytes_time))); + + const qsizetype len = logData.length(); + if (_tempLogFile->write(logData) != logData.length()) { + const QString message = QStringLiteral("MAVLink Logging failed. Could not write to file %1, logging disabled.").arg(_tempLogFile->fileName()); + emit protocolStatusMessage(getName(), message); _stopLogging(); _logSuspendError = true; } } - } -/** - * This method parses all incoming bytes and constructs a MAVLink packet. - * It can handle multiple links in parallel, as each link has it's own buffer/ - * parsing state machine. - * @param link The interface to read from - * @see LinkInterface - **/ - -void MAVLinkProtocol::receiveBytes(LinkInterface* link, QByteArray b) +void MAVLinkProtocol::receiveBytes(LinkInterface *link, const QByteArray &data) { - // Since receiveBytes signals cross threads we can end up with signals in the queue - // that come through after the link is disconnected. For these we just drop the data - // since the link is closed. - SharedLinkInterfacePtr linkPtr = _linkMgr->sharedLinkInterfacePointerForLink(link); + const SharedLinkInterfacePtr linkPtr = qgcApp()->toolbox()->linkManager()->sharedLinkInterfacePointerForLink(link); if (!linkPtr) { - qCDebug(MAVLinkProtocolLog) << "receiveBytes: link gone!" << b.size() << " bytes arrived too late"; + qCDebug(MAVLinkProtocolLog) << "receiveBytes: link gone!" << data.size() << " bytes arrived too late"; return; } - uint8_t mavlinkChannel = link->mavlinkChannel(); - - for (int position = 0; position < b.size(); position++) { - if (mavlink_parse_char(mavlinkChannel, static_cast(b[position]), &_message, &_status)) { - // Got a valid message - if (!link->decodedFirstMavlinkPacket()) { - link->setDecodedFirstMavlinkPacket(true); - mavlink_status_t* mavlinkStatus = mavlink_get_channel_status(mavlinkChannel); - if (!(mavlinkStatus->flags & MAVLINK_STATUS_FLAG_IN_MAVLINK1) && (mavlinkStatus->flags & MAVLINK_STATUS_FLAG_OUT_MAVLINK1)) { - qCDebug(MAVLinkProtocolLog) << "Switching outbound to mavlink 2.0 due to incoming mavlink 2.0 packet:" << mavlinkStatus << mavlinkChannel << mavlinkStatus->flags; - mavlinkStatus->flags &= ~MAVLINK_STATUS_FLAG_OUT_MAVLINK1; - // Set all links to v2 - setVersion(200); - } - } - - //----------------------------------------------------------------- - // MAVLink Status - uint8_t lastSeq = lastIndex[_message.sysid][_message.compid]; - uint8_t expectedSeq = lastSeq + 1; - // Increase receive counter - totalReceiveCounter[mavlinkChannel]++; - // Determine what the next expected sequence number is, accounting for - // never having seen a message for this system/component pair. - if(firstMessage[_message.sysid][_message.compid]) { - firstMessage[_message.sysid][_message.compid] = 0; - lastSeq = _message.seq; - expectedSeq = _message.seq; - } - // And if we didn't encounter that sequence number, record the error - //int foo = 0; - if (_message.seq != expectedSeq) - { - //foo = 1; - int lostMessages = 0; - //-- Account for overflow during packet loss - if(_message.seq < expectedSeq) { - lostMessages = (_message.seq + 255) - expectedSeq; - } else { - lostMessages = _message.seq - expectedSeq; - } - // Log how many were lost - totalLossCounter[mavlinkChannel] += static_cast(lostMessages); - } - - // And update the last sequence number for this system/component pair - lastIndex[_message.sysid][_message.compid] = _message.seq;; - // Calculate new loss ratio - uint64_t totalSent = totalReceiveCounter[mavlinkChannel] + totalLossCounter[mavlinkChannel]; - float receiveLossPercent = static_cast(static_cast(totalLossCounter[mavlinkChannel]) / static_cast(totalSent)); - receiveLossPercent *= 100.0f; - receiveLossPercent = (receiveLossPercent * 0.5f) + (runningLossPercent[mavlinkChannel] * 0.5f); - runningLossPercent[mavlinkChannel] = receiveLossPercent; - - //qDebug() << foo << _message.seq << expectedSeq << lastSeq << totalLossCounter[mavlinkChannel] << totalReceiveCounter[mavlinkChannel] << totalSentCounter[mavlinkChannel] << "(" << _message.sysid << _message.compid << ")"; - - //----------------------------------------------------------------- - // MAVLink forwarding - bool forwardingEnabled = _app->toolbox()->settingsManager()->appSettings()->forwardMavlink()->rawValue().toBool(); - if (_message.msgid == MAVLINK_MSG_ID_SETUP_SIGNING) { - forwardingEnabled = false; - } - if (forwardingEnabled) { - SharedLinkInterfacePtr forwardingLink = _linkMgr->mavlinkForwardingLink(); - - if (forwardingLink) { - uint8_t buf[MAVLINK_MAX_PACKET_LEN]; - int len = mavlink_msg_to_send_buffer(buf, &_message); - forwardingLink->writeBytesThreadSafe((const char*)buf, len); - } - } - - // MAVLink forwarding support - bool forwardingSupportEnabled = _linkMgr->mavlinkSupportForwardingEnabled(); - if (_message.msgid == MAVLINK_MSG_ID_SETUP_SIGNING) { - forwardingSupportEnabled = false; - } - if (forwardingSupportEnabled) { - SharedLinkInterfacePtr forwardingSupportLink = _linkMgr->mavlinkForwardingSupportLink(); - - if (forwardingSupportLink) { - uint8_t buf[MAVLINK_MAX_PACKET_LEN]; - int len = mavlink_msg_to_send_buffer(buf, &_message); - forwardingSupportLink->writeBytesThreadSafe((const char*)buf, len); - } - } - - //----------------------------------------------------------------- - // Log data - if (!_logSuspendError && !_logSuspendReplay && _tempLogFile.isOpen()) { - uint8_t buf[MAVLINK_MAX_PACKET_LEN+sizeof(quint64)]; - - // Write the uint64 time in microseconds in big endian format before the message. - // This timestamp is saved in UTC time. We are only saving in ms precision because - // getting more than this isn't possible with Qt without a ton of extra code. - quint64 time = static_cast(QDateTime::currentMSecsSinceEpoch() * 1000); - qToBigEndian(time, buf); - - // Then write the message to the buffer - int len = mavlink_msg_to_send_buffer(buf + sizeof(quint64), &_message); - - // Determine how many bytes were written by adding the timestamp size to the message size - len += sizeof(quint64); - - // Now write this timestamp/message pair to the log. - QByteArray b(reinterpret_cast(buf), len); - if(_tempLogFile.write(b) != len) - { - // If there's an error logging data, raise an alert and stop logging. - emit protocolStatusMessage(tr("MAVLink Protocol"), tr("MAVLink Logging failed. Could not write to file %1, logging disabled.").arg(_tempLogFile.fileName())); - _stopLogging(); - _logSuspendError = true; - } - - // Check for the vehicle arming going by. This is used to trigger log save. - if (!_vehicleWasArmed && _message.msgid == MAVLINK_MSG_ID_HEARTBEAT) { - mavlink_heartbeat_t state; - mavlink_msg_heartbeat_decode(&_message, &state); - if (state.base_mode & MAV_MODE_FLAG_DECODE_POSITION_SAFETY) { - _vehicleWasArmed = true; - } - } - } - - if (_message.msgid == MAVLINK_MSG_ID_HEARTBEAT) { - _startLogging(); - mavlink_heartbeat_t heartbeat; - mavlink_msg_heartbeat_decode(&_message, &heartbeat); - emit vehicleHeartbeatInfo(link, _message.sysid, _message.compid, heartbeat.autopilot, heartbeat.type); - } else if (_message.msgid == MAVLINK_MSG_ID_HIGH_LATENCY) { - _startLogging(); - mavlink_high_latency_t highLatency; - mavlink_msg_high_latency_decode(&_message, &highLatency); - // HIGH_LATENCY does not provide autopilot or type information, generic is our safest bet - emit vehicleHeartbeatInfo(link, _message.sysid, _message.compid, MAV_AUTOPILOT_GENERIC, MAV_TYPE_GENERIC); - } else if (_message.msgid == MAVLINK_MSG_ID_HIGH_LATENCY2) { - _startLogging(); - mavlink_high_latency2_t highLatency2; - mavlink_msg_high_latency2_decode(&_message, &highLatency2); - emit vehicleHeartbeatInfo(link, _message.sysid, _message.compid, highLatency2.autopilot, highLatency2.type); + const uint8_t mavlinkChannel = link->mavlinkChannel(); + for (const uint8_t &byte: data) { + if (mavlink_parse_char(mavlinkChannel, byte, &_message, &_status) == MAVLINK_FRAMING_OK) { + _updateVersion(link, mavlinkChannel); + _updateCounters(mavlinkChannel); + _forward(); + _forwardSupport(); + _logData(link); + if (!_updateStatus(link, linkPtr, mavlinkChannel)) { + break; } + } + } +} -#if 0 - // Given the current state of SiK Radio firmwares there is no way to make the code below work. - // The ArduPilot implementation of SiK Radio firmware always sends MAVLINK_MSG_ID_RADIO_STATUS as a mavlink 1 - // packet even if the vehicle is sending Mavlink 2. - - // Detect if we are talking to an old radio not supporting v2 - mavlink_status_t* mavlinkStatus = mavlink_get_channel_status(mavlinkChannel); - if (_message.msgid == MAVLINK_MSG_ID_RADIO_STATUS && _radio_version_mismatch_count != -1) { - if ((mavlinkStatus->flags & MAVLINK_STATUS_FLAG_IN_MAVLINK1) - && !(mavlinkStatus->flags & MAVLINK_STATUS_FLAG_OUT_MAVLINK1)) { - _radio_version_mismatch_count++; - } - } +bool MAVLinkProtocol::_updateStatus(LinkInterface *link, SharedLinkInterfacePtr linkPtr, uint8_t mavlinkChannel) +{ + if ((_totalReceiveCounter[mavlinkChannel] % 32) == 0) { + const uint64_t totalSent = _totalReceiveCounter[mavlinkChannel] + _totalLossCounter[mavlinkChannel]; + emit mavlinkMessageStatus(_message.sysid, totalSent, _totalReceiveCounter[mavlinkChannel], _totalLossCounter[mavlinkChannel], _runningLossPercent[mavlinkChannel]); + } - if (_radio_version_mismatch_count == 5) { - // Warn the user if the radio continues to send v1 while the link uses v2 - emit protocolStatusMessage(tr("MAVLink Protocol"), tr("Detected radio still using MAVLink v1.0 on a link with MAVLink v2.0 enabled. Please upgrade the radio firmware.")); - // Set to flag warning already shown - _radio_version_mismatch_count = -1; - // Flick link back to v1 - qDebug() << "Switching outbound to mavlink 1.0 due to incoming mavlink 1.0 packet:" << mavlinkStatus << mavlinkChannel << mavlinkStatus->flags; - mavlinkStatus->flags |= MAVLINK_STATUS_FLAG_OUT_MAVLINK1; - } -#endif + emit messageReceived(link, _message); - // Update MAVLink status on every 32th packet - if ((totalReceiveCounter[mavlinkChannel] & 0x1F) == 0) { - emit mavlinkMessageStatus(_message.sysid, totalSent, totalReceiveCounter[mavlinkChannel], totalLossCounter[mavlinkChannel], receiveLossPercent); - } + if (linkPtr.use_count() == 1) { + return false; + } - // The packet is emitted as a whole, as it is only 255 - 261 bytes short - // kind of inefficient, but no issue for a groundstation pc. - // It buys as reentrancy for the whole code over all threads - emit messageReceived(link, _message); + (void) memset(&_status, 0, sizeof(_status)); + (void) memset(&_message, 0, sizeof(_message)); - // Anyone handling the message could close the connection, which deletes the link, - // so we check if it's expired - if (1 == linkPtr.use_count()) { - break; - } + return true; +} - // Reset message parsing - memset(&_status, 0, sizeof(_status)); - memset(&_message, 0, sizeof(_message)); +void MAVLinkProtocol::_updateVersion(LinkInterface *link, uint8_t mavlinkChannel) +{ + if (!link->decodedFirstMavlinkPacket()) { + link->setDecodedFirstMavlinkPacket(true); + mavlink_status_t* const mavlinkStatus = mavlink_get_channel_status(mavlinkChannel); + if ((!(mavlinkStatus->flags & MAVLINK_STATUS_FLAG_IN_MAVLINK1)) && (mavlinkStatus->flags & MAVLINK_STATUS_FLAG_OUT_MAVLINK1)) { + qCDebug(MAVLinkProtocolLog) << QStringLiteral("Switching outbound to mavlink 2.0 due to incoming mavlink 2.0 packet:") << mavlinkChannel; + mavlinkStatus->flags &= ~MAVLINK_STATUS_FLAG_OUT_MAVLINK1; + setVersion(2); } } } -/** - * @return The name of this protocol - **/ -QString MAVLinkProtocol::getName() +void MAVLinkProtocol::_updateCounters(uint8_t mavlinkChannel) { - return tr("MAVLink protocol"); + uint8_t lastSeq = _lastIndex[_message.sysid][_message.compid]; + uint8_t expectedSeq = lastSeq + 1; + _totalReceiveCounter[mavlinkChannel]++; + if (_firstMessage[_message.sysid][_message.compid] != 0) { + _firstMessage[_message.sysid][_message.compid] = 0; + lastSeq = _message.seq; + expectedSeq = _message.seq; + } + + if (_message.seq != expectedSeq) + { + uint64_t lostMessages = _message.seq; + if (lostMessages < expectedSeq) { + lostMessages += 255; + } + lostMessages -= expectedSeq; + _totalLossCounter[mavlinkChannel] += lostMessages; + } + + _lastIndex[_message.sysid][_message.compid] = _message.seq; + const uint64_t totalSent = _totalReceiveCounter[mavlinkChannel] + _totalLossCounter[mavlinkChannel]; + float receiveLossPercent = static_cast(static_cast(_totalLossCounter[mavlinkChannel]) / static_cast(totalSent)); + receiveLossPercent *= 100.0f; + receiveLossPercent *= 0.5f; + receiveLossPercent += (_runningLossPercent[mavlinkChannel] * 0.5f); + _runningLossPercent[mavlinkChannel] = receiveLossPercent; } -/** @return System id of this application */ -int MAVLinkProtocol::getSystemId() const +void MAVLinkProtocol::_forward() { - return systemId; + bool forwardingEnabled = qgcApp()->toolbox()->settingsManager()->appSettings()->forwardMavlink()->rawValue().toBool(); + if (_message.msgid == MAVLINK_MSG_ID_SETUP_SIGNING) { + forwardingEnabled = false; + } + if (forwardingEnabled) { + SharedLinkInterfacePtr forwardingLink = qgcApp()->toolbox()->linkManager()->mavlinkForwardingLink(); + if (forwardingLink) { + uint8_t buf[MAVLINK_MAX_PACKET_LEN]; + const uint16_t len = mavlink_msg_to_send_buffer(buf, &_message); + forwardingLink->writeBytesThreadSafe(reinterpret_cast(buf), len); + } + } } -void MAVLinkProtocol::setSystemId(int id) +void MAVLinkProtocol::_forwardSupport() { - systemId = id; + LinkManager *linkManager = qgcApp()->toolbox()->linkManager(); + bool forwardingSupportEnabled = linkManager->mavlinkSupportForwardingEnabled(); + if (_message.msgid == MAVLINK_MSG_ID_SETUP_SIGNING) { + forwardingSupportEnabled = false; + } + if (forwardingSupportEnabled) { + SharedLinkInterfacePtr forwardingSupportLink = linkManager->mavlinkForwardingSupportLink(); + if (forwardingSupportLink) { + uint8_t buf[MAVLINK_MAX_PACKET_LEN]; + const uint16_t len = mavlink_msg_to_send_buffer(buf, &_message); + forwardingSupportLink->writeBytesThreadSafe(reinterpret_cast(buf), len); + } + } } -/** @return Component id of this application */ -int MAVLinkProtocol::getComponentId() const +void MAVLinkProtocol::_logData(LinkInterface *link) { - return MAV_COMP_ID_MISSIONPLANNER; + if (!_logSuspendError && !_logSuspendReplay && _tempLogFile->isOpen()) { + const qint64 timestamp = QDateTime::currentMSecsSinceEpoch() * 1000; + uint8_t buf[MAVLINK_MAX_PACKET_LEN + sizeof(timestamp)]; + qToBigEndian(timestamp, buf); + + const qsizetype len = mavlink_msg_to_send_buffer(buf + sizeof(timestamp), &_message) + sizeof(timestamp); + const QByteArray log_data(reinterpret_cast(buf), len); + if (_tempLogFile->write(log_data) != len) { + const QString message = QStringLiteral("MAVLink Logging failed. Could not write to file %1, logging disabled.").arg(_tempLogFile->fileName()); + emit protocolStatusMessage(getName(), message); + _stopLogging(); + _logSuspendError = true; + } + + if (!_vehicleWasArmed && (_message.msgid == MAVLINK_MSG_ID_HEARTBEAT)) { + mavlink_heartbeat_t state; + mavlink_msg_heartbeat_decode(&_message, &state); + if (state.base_mode & MAV_MODE_FLAG_DECODE_POSITION_SAFETY) { + _vehicleWasArmed = true; + } + } + } + + switch (_message.msgid) { + case MAVLINK_MSG_ID_HEARTBEAT: + _startLogging(); + mavlink_heartbeat_t heartbeat; + mavlink_msg_heartbeat_decode(&_message, &heartbeat); + emit vehicleHeartbeatInfo(link, _message.sysid, _message.compid, static_cast(heartbeat.autopilot), static_cast(heartbeat.type)); + break; + case MAVLINK_MSG_ID_HIGH_LATENCY: + _startLogging(); + mavlink_high_latency_t highLatency; + mavlink_msg_high_latency_decode(&_message, &highLatency); + // HIGH_LATENCY does not provide autopilot or type information, generic is our safest bet + emit vehicleHeartbeatInfo(link, _message.sysid, _message.compid, MAV_AUTOPILOT_GENERIC, MAV_TYPE_GENERIC); + break; + case MAVLINK_MSG_ID_HIGH_LATENCY2: + _startLogging(); + mavlink_high_latency2_t highLatency2; + mavlink_msg_high_latency2_decode(&_message, &highLatency2); + emit vehicleHeartbeatInfo(link, _message.sysid, _message.compid, static_cast(highLatency2.autopilot), static_cast(highLatency2.type)); + break; + default: + break; + } } void MAVLinkProtocol::enableVersionCheck(bool enabled) { - _enable_version_check = enabled; - emit versionCheckChanged(enabled); + if (enabled != _enableVersionCheck) { + _enableVersionCheck = enabled; + emit versionCheckChanged(enabled); + } } -void MAVLinkProtocol::_vehicleCountChanged(void) +void MAVLinkProtocol::_vehicleCountChanged() { - int count = _multiVehicleManager->vehicles()->count(); - if (count == 0) { - // Last vehicle is gone, close out logging + if (qgcApp()->toolbox()->multiVehicleManager()->vehicles()->count() == 0) { _stopLogging(); - _radio_version_mismatch_count = 0; + // _radioVersionMismatchCount = 0; } } -/// @brief Closes the log file if it is open -bool MAVLinkProtocol::_closeLogFile(void) +bool MAVLinkProtocol::_closeLogFile() { - if (_tempLogFile.isOpen()) { - if (_tempLogFile.size() == 0) { - // Don't save zero byte files - _tempLogFile.remove(); - return false; - } else { - _tempLogFile.flush(); - _tempLogFile.close(); - return true; - } + if (!_tempLogFile->isOpen()) { + return false; + } + + if (_tempLogFile->size() == 0) { + _tempLogFile->remove(); + return false; + } else { + _tempLogFile->flush(); + _tempLogFile->close(); + return true; } - return false; } -void MAVLinkProtocol::_startLogging(void) +void MAVLinkProtocol::_startLogging() { - //-- Are we supposed to write logs? if (qgcApp()->runningUnitTests()) { return; } - AppSettings* appSettings = _app->toolbox()->settingsManager()->appSettings(); - if(appSettings->disableAllPersistence()->rawValue().toBool()) { + + AppSettings* const appSettings = qgcApp()->toolbox()->settingsManager()->appSettings(); + if (appSettings->disableAllPersistence()->rawValue().toBool()) { return; } -#ifdef __mobile__ - //-- Mobile build don't write to /tmp unless told to do so + +#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) if (!appSettings->telemetrySave()->rawValue().toBool()) { return; } #endif - //-- Log is always written to a temp file. If later the user decides they want - // it, it's all there for them. - if (!_tempLogFile.isOpen()) { - if (!_logSuspendReplay) { - if (!_tempLogFile.open()) { - emit protocolStatusMessage(tr("MAVLink Protocol"), tr("Opening Flight Data file for writing failed. " - "Unable to write to %1. Please choose a different file location.").arg(_tempLogFile.fileName())); - _closeLogFile(); - _logSuspendError = true; - return; - } - qCDebug(MAVLinkProtocolLog) << "Temp log" << _tempLogFile.fileName(); - emit checkTelemetrySavePath(); + if (_tempLogFile->isOpen()) { + return; + } - _logSuspendError = false; - } + if (_logSuspendReplay) { + return; + } + + if (!_tempLogFile->open()) { + const QString message = QStringLiteral("Opening Flight Data file for writing failed. Unable to write to %1. Please choose a different file location.").arg(_tempLogFile->fileName()); + emit protocolStatusMessage(getName(), message); + _closeLogFile(); + _logSuspendError = true; + return; } + + qCDebug(MAVLinkProtocolLog) << "Temp log" << _tempLogFile->fileName(); + emit checkTelemetrySavePath(); + + _logSuspendError = false; } -void MAVLinkProtocol::_stopLogging(void) +void MAVLinkProtocol::_stopLogging() { - if (_tempLogFile.isOpen()) { + if (_tempLogFile->isOpen()) { if (_closeLogFile()) { - if ((_vehicleWasArmed || _app->toolbox()->settingsManager()->appSettings()->telemetrySaveNotArmed()->rawValue().toBool()) && - _app->toolbox()->settingsManager()->appSettings()->telemetrySave()->rawValue().toBool() && - !_app->toolbox()->settingsManager()->appSettings()->disableAllPersistence()->rawValue().toBool()) { - emit saveTelemetryLog(_tempLogFile.fileName()); + AppSettings* const appSettings = qgcApp()->toolbox()->settingsManager()->appSettings(); + if ((_vehicleWasArmed || appSettings->telemetrySaveNotArmed()->rawValue().toBool()) && + appSettings->telemetrySave()->rawValue().toBool() && + !appSettings->disableAllPersistence()->rawValue().toBool()) { + emit saveTelemetryLog(_tempLogFile->fileName()); } else { - QFile::remove(_tempLogFile.fileName()); + (void) QFile::remove(_tempLogFile->fileName()); } } } + _vehicleWasArmed = false; } -/// @brief Checks the temp directory for log files which may have been left there. -/// This could happen if QGC crashes without the temp log file being saved. -/// Give the user an option to save these orphaned files. -void MAVLinkProtocol::checkForLostLogFiles(void) +void MAVLinkProtocol::checkForLostLogFiles() { - QDir tempDir(QStandardPaths::writableLocation(QStandardPaths::TempLocation)); + static const QDir tempDir(QStandardPaths::writableLocation(QStandardPaths::TempLocation)); + static const QString filter(QStringLiteral("*.%1").arg(_logFileExtension)); + const QFileInfoList fileInfoList = tempDir.entryInfoList(QStringList(filter), QDir::Files); + qCDebug(MAVLinkProtocolLog) << "Orphaned log file count" << fileInfoList.count(); - QString filter(QString("*.%1").arg(_logFileExtension)); - QFileInfoList fileInfoList = tempDir.entryInfoList(QStringList(filter), QDir::Files); - //qDebug() << "Orphaned log file count" << fileInfoList.count(); - - for(const QFileInfo& fileInfo: fileInfoList) { - //qDebug() << "Orphaned log file" << fileInfo.filePath(); + for(const QFileInfo &fileInfo: fileInfoList) { + qCDebug(MAVLinkProtocolLog) << "Orphaned log file" << fileInfo.filePath(); if (fileInfo.size() == 0) { - // Delete all zero length files - QFile::remove(fileInfo.filePath()); + (void) QFile::remove(fileInfo.filePath()); continue; } emit saveTelemetryLog(fileInfo.filePath()); } } -void MAVLinkProtocol::suspendLogForReplay(bool suspend) -{ - _logSuspendReplay = suspend; -} - -void MAVLinkProtocol::deleteTempLogFiles(void) +void MAVLinkProtocol::deleteTempLogFiles() { - QDir tempDir(QStandardPaths::writableLocation(QStandardPaths::TempLocation)); - - QString filter(QString("*.%1").arg(_logFileExtension)); - QFileInfoList fileInfoList = tempDir.entryInfoList(QStringList(filter), QDir::Files); - - for (const QFileInfo& fileInfo: fileInfoList) { - QFile::remove(fileInfo.filePath()); + static const QDir tempDir(QStandardPaths::writableLocation(QStandardPaths::TempLocation)); + static const QString filter(QStringLiteral("*.%1").arg(_logFileExtension)); + const QFileInfoList fileInfoList = tempDir.entryInfoList(QStringList(filter), QDir::Files); + qCDebug(MAVLinkProtocolLog) << "Temp log file count" << fileInfoList.count(); + + for (const QFileInfo &fileInfo: fileInfoList) { + qCDebug(MAVLinkProtocolLog) << "Temp log file" << fileInfo.filePath(); + (void) QFile::remove(fileInfo.filePath()); } } - diff --git a/src/Comms/MAVLinkProtocol.h b/src/Comms/MAVLinkProtocol.h index 5f6d5968d8d9..888b3be21e01 100644 --- a/src/Comms/MAVLinkProtocol.h +++ b/src/Comms/MAVLinkProtocol.h @@ -9,160 +9,164 @@ #pragma once -#include "LinkInterface.h" -#include "QGCMAVLink.h" -#include "QGCTemporaryFile.h" -#include "QGCToolbox.h" - -#include #include #include +#include +#include + +#include "LinkInterface.h" +#include "MAVLinkLib.h" -class LinkManager; -class MultiVehicleManager; -class QGCApplication; +class LinkInterface; +class QGCTemporaryFile; Q_DECLARE_LOGGING_CATEGORY(MAVLinkProtocolLog) -/** - * @brief MAVLink micro air vehicle protocol reference implementation. - * - * MAVLink is a generic communication protocol for micro air vehicles. - * for more information, please see the official website: https://mavlink.io - **/ -class MAVLinkProtocol : public QGCTool +/// MAVLink micro air vehicle protocol reference implementation. +/// MAVLink is a generic communication protocol for micro air vehicles. +/// for more information, please see the official website: https://mavlink.io +class MAVLinkProtocol : public QObject { Q_OBJECT + // QML_ELEMENT + // QML_UNCREATABLE("") + // QML_SINGLETON + Q_MOC_INCLUDE("LinkInterface.h") public: - MAVLinkProtocol(QGCApplication* app, QGCToolbox* toolbox); + MAVLinkProtocol(QObject *parent = nullptr); ~MAVLinkProtocol(); - /** @brief Get the human-friendly name of this protocol */ - QString getName(); - /** @brief Get the system id of this application */ - int getSystemId() const; - /** @brief Get the component id of this application */ - int getComponentId() const; - - /** @brief Get protocol version check state */ - bool versionCheckEnabled() const { - return _enable_version_check; - } - /** @brief Get the protocol version */ - int getVersion() { - return MAVLINK_VERSION; - } - /** @brief Get the currently configured protocol version */ - unsigned getCurrentVersion() const{ - return _current_version; - } - /** - * Reset the counters for all metadata for this link. - */ - virtual void resetMetadataForLink(LinkInterface *link); + static MAVLinkProtocol *instance(); - /// Suspend/Restart logging during replay. - void suspendLogForReplay(bool suspend); + /// Get the human-friendly name of this protocol + static QString getName() { return QStringLiteral("MAVLink protocol"); } - /// Set protocol version - void setVersion(unsigned version); + /// Get the system id of this application + uint8_t getSystemId() const { return _systemId; } - // Override from QGCTool - virtual void setToolbox(QGCToolbox *toolbox); + /// Get the component id of this application + static int getComponentId() { return MAV_COMP_ID_MISSIONPLANNER; } -public slots: - /** @brief Receive bytes from a communication interface */ - void receiveBytes(LinkInterface* link, QByteArray b); + /// Get protocol version check state + bool versionCheckEnabled() const { return _enableVersionCheck; } - /** @brief Log bytes sent from a communication interface */ - void logSentBytes(LinkInterface* link, QByteArray b); + /// Get the protocol version + static uint8_t getVersion() { return MAVLINK_VERSION; } - /** @brief Set the system id of this application */ - void setSystemId(int id); + /// Get the currently configured protocol version + uint8_t getCurrentVersion() const { return _currentVersion; } - /** @brief Enable / disable version check */ - void enableVersionCheck(bool enabled); + /// Reset the counters for all metadata for this link. + void resetMetadataForLink(LinkInterface *link); - /** @brief Load protocol settings */ - void loadSettings(); - /** @brief Store protocol settings */ - void storeSettings(); + /// Suspend/Restart logging during replay. + void suspendLogForReplay(bool suspend) { _logSuspendReplay = suspend; } - /// @brief Deletes any log files which are in the temp directory - static void deleteTempLogFiles(void); + /// Set protocol version + void setVersion(uint16_t version); - /// Checks for lost log files - void checkForLostLogFiles(void); +signals: + /// Heartbeat received on link + void vehicleHeartbeatInfo(LinkInterface *link, uint8_t vehicleId, uint8_t componentId, MAV_AUTOPILOT vehicleFirmwareType, MAV_TYPE vehicleType); -protected: - bool _enable_version_check; ///< Enable checking of version match of MAV and QGC - uint8_t lastIndex[256][256]; ///< Store the last received sequence ID for each system/componenet pair - uint8_t firstMessage[256][256]; ///< First message flag - uint64_t totalReceiveCounter[MAVLINK_COMM_NUM_BUFFERS]; ///< The total number of successfully received messages - uint64_t totalLossCounter[MAVLINK_COMM_NUM_BUFFERS]; ///< Total messages lost during transmission. - float runningLossPercent[MAVLINK_COMM_NUM_BUFFERS]; ///< Loss rate + /// Message received and directly copied via signal + void messageReceived(LinkInterface *link, mavlink_message_t message); - mavlink_message_t _message; - mavlink_status_t _status; + /// Emitted if version check is enabled/disabled + void versionCheckChanged(bool enabled); - bool versionMismatchIgnore; - int systemId; - unsigned _current_version; - int _radio_version_mismatch_count; + /// Emitted if a message from the protocol should reach the user + void protocolStatusMessage(const QString &title, const QString &message); -signals: - /// Heartbeat received on link - void vehicleHeartbeatInfo(LinkInterface* link, int vehicleId, int componentId, int vehicleFirmwareType, int vehicleType); + /// Emitted if a new system ID was set + void systemIdChanged(uint8_t systemId); - /** @brief Message received and directly copied via signal */ - void messageReceived(LinkInterface* link, mavlink_message_t message); - /** @brief Emitted if version check is enabled / disabled */ - void versionCheckChanged(bool enabled); - /** @brief Emitted if a message from the protocol should reach the user */ - void protocolStatusMessage(const QString& title, const QString& message); - /** @brief Emitted if a new system ID was set */ - void systemIdChanged(int systemId); - - void mavlinkMessageStatus(int uasId, uint64_t totalSent, uint64_t totalReceived, uint64_t totalLoss, float lossPercent); - - /** - * @brief Emitted if a new radio status packet received - * - * @param rxerrors receive errors - * @param fixed count of error corrected packets - * @param rssi local signal strength in dBm - * @param remrssi remote signal strength in dBm - * @param txbuf how full the tx buffer is as a percentage - * @param noise background noise level - * @param remnoise remote background noise level - */ - void radioStatusChanged(LinkInterface* link, unsigned rxerrors, unsigned fixed, int rssi, int remrssi, - unsigned txbuf, unsigned noise, unsigned remnoise); + void mavlinkMessageStatus(uint8_t sysid, uint64_t totalSent, uint64_t totalReceived, uint64_t totalLoss, float lossPercent); + + /// Emitted if a new radio status packet received + /// @param rxerrors receive errors + /// @param fixed count of error corrected packets + /// @param rssi local signal strength in dBm + /// @param remrssi remote signal strength in dBm + /// @param txbuf how full the tx buffer is as a percentage + /// @param noise background noise level + /// @param remnoise remote background noise level + void radioStatusChanged(LinkInterface *link, uint32_t rxerrors, uint32_t fixed, int rssi, int remrssi, uint32_t txbuf, uint32_t noise, uint32_t remnoise); /// Emitted when a temporary telemetry log file is ready for saving - void saveTelemetryLog(QString tempLogfile); + void saveTelemetryLog(const QString &tempLogfile); /// Emitted when a telemetry log is started to save. - void checkTelemetrySavePath(void); + void checkTelemetrySavePath(); + +public slots: + /// Receive bytes from a communication interface and constructs a MAVLink packet + /// @param link The interface to read from + void receiveBytes(LinkInterface *link, const QByteArray &data); + + /// Log bytes sent from a communication interface and logs a MAVLink packet. + /// It can handle multiple links in parallel, as each link has it's own buffer/parsing state machine. + /// @param link The interface to read from + void logSentBytes(LinkInterface *link, const QByteArray &data); + + /// Set the system id of this application + void setSystemId(uint8_t id) { _systemId = id; } + + /// Enable/Disable version check + void enableVersionCheck(bool enabled); + + /// Load protocol settings + void loadSettings(); + + /// Store protocol settings + void storeSettings(); + + /// Deletes any log files which are in the temp directory + static void deleteTempLogFiles(); + + /// Checks the temp directory for log files which may have been left there. + /// This could happen if QGC crashes without the temp log file being saved. + /// Give the user an option to save these orphaned files. + void checkForLostLogFiles(); private slots: - void _vehicleCountChanged(void); + void _vehicleCountChanged(); + +protected: + bool _enableVersionCheck = false; ///< Enable checking of version match of MAV and QGC + uint8_t _lastIndex[256][256]{}; ///< Store the last received sequence ID for each system/componenet pair + uint8_t _firstMessage[256][256]{}; ///< First message flag + uint64_t _totalReceiveCounter[MAVLINK_COMM_NUM_BUFFERS]{}; ///< The total number of successfully received messages + uint64_t _totalLossCounter[MAVLINK_COMM_NUM_BUFFERS]{}; ///< Total messages lost during transmission. + float _runningLossPercent[MAVLINK_COMM_NUM_BUFFERS]{}; ///< Loss rate + + mavlink_message_t _message{}; + mavlink_status_t _status{}; + + uint8_t _systemId = 255; + uint16_t _currentVersion = 1; + // uint32_t _radioVersionMismatchCount = 0; private: - bool _closeLogFile(void); - void _startLogging(void); - void _stopLogging(void); + void _logData(LinkInterface *link); + bool _closeLogFile(); + void _startLogging(); + void _stopLogging(); - bool _logSuspendError; ///< true: Logging suspended due to error - bool _logSuspendReplay; ///< true: Logging suspended due to replay - bool _vehicleWasArmed; ///< true: Vehicle was armed during log sequence + void _forward(); + void _forwardSupport(); - QGCTemporaryFile _tempLogFile; ///< File to log to - static constexpr const char* _tempLogFileTemplate = "FlightDataXXXXXX"; ///< Template for temporary log file - static constexpr const char* _logFileExtension = "mavlink"; ///< Extension for log files + void _updateCounters(uint8_t mavlinkChannel); + bool _updateStatus(LinkInterface *link, SharedLinkInterfacePtr linkPtr, uint8_t mavlinkChannel); + void _updateVersion(LinkInterface *link, uint8_t mavlinkChannel); - LinkManager* _linkMgr; - MultiVehicleManager* _multiVehicleManager; -}; + bool _logSuspendError = false; ///< true: Logging suspended due to error + bool _logSuspendReplay = false; ///< true: Logging suspended due to replay + bool _vehicleWasArmed = false; ///< true: Vehicle was armed during log sequence + QGCTemporaryFile *_tempLogFile = nullptr; + + static constexpr const char *_tempLogFileTemplate = "FlightDataXXXXXX"; ///< Template for temporary log file + static constexpr const char *_logFileExtension = "mavlink"; ///< Extension for log files +}; diff --git a/src/Comms/MockLink/MockLink.cc b/src/Comms/MockLink/MockLink.cc index 48b9010ec383..cd65e342a4c6 100644 --- a/src/Comms/MockLink/MockLink.cc +++ b/src/Comms/MockLink/MockLink.cc @@ -11,6 +11,7 @@ #include "QGCLoggingCategory.h" #include "QGCApplication.h" #include "LinkManager.h" +#include "MAVLinkProtocol.h" #include "QGCLoggingCategory.h" #include @@ -45,7 +46,7 @@ static_assert(LinkManager::invalidMavlinkChannel() == std::numeric_limitstoolbox()->mavlinkProtocol()) + , _missionItemHandler (this, MAVLinkProtocol::instance()) , _name ("MockLink") , _connected (false) , _vehicleComponentId (MAV_COMP_ID_AUTOPILOT1) diff --git a/src/FactSystem/ParameterManager.cc b/src/FactSystem/ParameterManager.cc index 23919ef7477d..50609a379b5d 100644 --- a/src/FactSystem/ParameterManager.cc +++ b/src/FactSystem/ParameterManager.cc @@ -68,7 +68,6 @@ const QHash _mavlinkCompIdHash { ParameterManager::ParameterManager(Vehicle* vehicle) : QObject (vehicle) , _vehicle (vehicle) - , _mavlink (nullptr) , _loadProgress (0.0) , _parametersReady (false) , _missingParameters (false) @@ -91,8 +90,6 @@ ParameterManager::ParameterManager(Vehicle* vehicle) return; } - _mavlink = qgcApp()->toolbox()->mavlinkProtocol(); - _initialRequestTimeoutTimer.setSingleShot(true); _initialRequestTimeoutTimer.setInterval(5000); connect(&_initialRequestTimeoutTimer, &QTimer::timeout, this, &ParameterManager::_initialRequestTimeout); @@ -544,11 +541,10 @@ void ParameterManager::refreshAllParameters(uint8_t componentId) _waitingReadParamIndexMap[cid][waitingIndex] = 0; } } - MAVLinkProtocol* mavlink = qgcApp()->toolbox()->mavlinkProtocol(); mavlink_message_t msg; - mavlink_msg_param_request_list_pack_chan(mavlink->getSystemId(), - mavlink->getComponentId(), + mavlink_msg_param_request_list_pack_chan(MAVLinkProtocol::instance()->getSystemId(), + MAVLinkProtocol::instance()->getComponentId(), sharedLink->mavlinkChannel(), &msg, _vehicle->id(), @@ -789,8 +785,8 @@ void ParameterManager::_readParameterRaw(int componentId, const QString& paramNa strncpy(fixedParamName, paramName.toStdString().c_str(), sizeof(fixedParamName)); - mavlink_msg_param_request_read_pack_chan(_mavlink->getSystemId(), // QGC system id - _mavlink->getComponentId(), // QGC component id + mavlink_msg_param_request_read_pack_chan(MAVLinkProtocol::instance()->getSystemId(), // QGC system id + MAVLinkProtocol::instance()->getComponentId(), // QGC component id sharedLink->mavlinkChannel(), &msg, // Pack into this mavlink_message_t _vehicle->id(), // Target system id @@ -853,8 +849,8 @@ void ParameterManager::_sendParamSetToVehicle(int componentId, const QString& pa strncpy(p.param_id, paramName.toStdString().c_str(), sizeof(p.param_id)); mavlink_message_t msg; - mavlink_msg_param_set_encode_chan(_mavlink->getSystemId(), - _mavlink->getComponentId(), + mavlink_msg_param_set_encode_chan(MAVLinkProtocol::instance()->getSystemId(), + MAVLinkProtocol::instance()->getComponentId(), sharedLink->mavlinkChannel(), &msg, &p); @@ -951,8 +947,8 @@ void ParameterManager::_tryCacheHashLoad(int vehicleId, int componentId, QVarian p.target_system = (uint8_t)_vehicle->id(); p.target_component = (uint8_t)componentId; mavlink_message_t msg; - mavlink_msg_param_set_encode_chan(_mavlink->getSystemId(), - _mavlink->getComponentId(), + mavlink_msg_param_set_encode_chan(MAVLinkProtocol::instance()->getSystemId(), + MAVLinkProtocol::instance()->getComponentId(), sharedLink->mavlinkChannel(), &msg, &p); diff --git a/src/FactSystem/ParameterManager.h b/src/FactSystem/ParameterManager.h index ca099ea825b7..a6a4fc724226 100644 --- a/src/FactSystem/ParameterManager.h +++ b/src/FactSystem/ParameterManager.h @@ -26,7 +26,6 @@ Q_DECLARE_LOGGING_CATEGORY(ParameterManagerDebugCacheFailureLog) class ParameterEditorController; class Vehicle; -class MAVLinkProtocol; class ParameterManager : public QObject { @@ -134,7 +133,6 @@ private slots: static QVariant _stringToTypedVariant(const QString& string, FactMetaData::ValueType_t type, bool failOk = false); Vehicle* _vehicle; - MAVLinkProtocol* _mavlink; QMap> _mapCompId2FactMap; diff --git a/src/FirmwarePlugin/APM/APMFirmwarePlugin.cc b/src/FirmwarePlugin/APM/APMFirmwarePlugin.cc index c54d13965776..82a2510e06b0 100644 --- a/src/FirmwarePlugin/APM/APMFirmwarePlugin.cc +++ b/src/FirmwarePlugin/APM/APMFirmwarePlugin.cc @@ -874,10 +874,9 @@ void APMFirmwarePlugin::guidedModeChangeAltitude(Vehicle* vehicle, double altitu cmd.y = 0.0f; cmd.z = static_cast(-(altitudeChange)); - MAVLinkProtocol* mavlink = qgcApp()->toolbox()->mavlinkProtocol(); mavlink_msg_set_position_target_local_ned_encode_chan( - static_cast(mavlink->getSystemId()), - static_cast(mavlink->getComponentId()), + static_cast(MAVLinkProtocol::instance()->getSystemId()), + static_cast(MAVLinkProtocol::instance()->getComponentId()), sharedLink->mavlinkChannel(), &msg, &cmd); @@ -1083,10 +1082,9 @@ void APMFirmwarePlugin::_handleRCChannels(Vehicle* vehicle, mavlink_message_t* m if(channels.rssi && channels.rssi != 255) { channels.rssi = static_cast(static_cast(channels.rssi) / 254.0 * 100.0); } - MAVLinkProtocol* mavlink = qgcApp()->toolbox()->mavlinkProtocol(); mavlink_msg_rc_channels_encode_chan( - static_cast(mavlink->getSystemId()), - static_cast(mavlink->getComponentId()), + static_cast(MAVLinkProtocol::instance()->getSystemId()), + static_cast(MAVLinkProtocol::instance()->getComponentId()), sharedLink->mavlinkChannel(), message, &channels); @@ -1104,10 +1102,9 @@ void APMFirmwarePlugin::_handleRCChannelsRaw(Vehicle* vehicle, mavlink_message_t if(channels.rssi) { channels.rssi = static_cast(static_cast(channels.rssi) / 255.0 * 100.0); } - MAVLinkProtocol* mavlink = qgcApp()->toolbox()->mavlinkProtocol(); mavlink_msg_rc_channels_raw_encode_chan( - static_cast(mavlink->getSystemId()), - static_cast(mavlink->getComponentId()), + static_cast(MAVLinkProtocol::instance()->getSystemId()), + static_cast(MAVLinkProtocol::instance()->getComponentId()), sharedLink->mavlinkChannel(), message, &channels); @@ -1142,7 +1139,6 @@ void APMFirmwarePlugin::sendGCSMotionReport(Vehicle *vehicle, FollowMe::GCSMotio return; } - const MAVLinkProtocol* const mavlinkProtocol = qgcApp()->toolbox()->mavlinkProtocol(); const mavlink_global_position_int_t globalPositionInt = { static_cast(qgcApp()->msecsSinceBoot()), /*< [ms] Timestamp (time since system boot).*/ motionReport.lat_int, /*< [degE7] Latitude, expressed*/ @@ -1157,8 +1153,8 @@ void APMFirmwarePlugin::sendGCSMotionReport(Vehicle *vehicle, FollowMe::GCSMotio mavlink_message_t message; (void) mavlink_msg_global_position_int_encode_chan( - static_cast(mavlinkProtocol->getSystemId()), - static_cast(mavlinkProtocol->getComponentId()), + static_cast(MAVLinkProtocol::instance()->getSystemId()), + static_cast(MAVLinkProtocol::instance()->getComponentId()), sharedLink->mavlinkChannel(), &message, &globalPositionInt diff --git a/src/FirmwarePlugin/FirmwarePlugin.cc b/src/FirmwarePlugin/FirmwarePlugin.cc index 739061ebba68..c6ec48a3618f 100644 --- a/src/FirmwarePlugin/FirmwarePlugin.cc +++ b/src/FirmwarePlugin/FirmwarePlugin.cc @@ -1125,7 +1125,6 @@ void FirmwarePlugin::sendGCSMotionReport(Vehicle *vehicle, FollowMe::GCSMotionRe return; } - const MAVLinkProtocol* const mavlinkProtocol = qgcApp()->toolbox()->mavlinkProtocol(); mavlink_follow_target_t follow_target{0}; follow_target.timestamp = qgcApp()->msecsSinceBoot(); @@ -1140,8 +1139,8 @@ void FirmwarePlugin::sendGCSMotionReport(Vehicle *vehicle, FollowMe::GCSMotionRe mavlink_message_t message; mavlink_msg_follow_target_encode_chan( - static_cast(mavlinkProtocol->getSystemId()), - static_cast(mavlinkProtocol->getComponentId()), + static_cast(MAVLinkProtocol::instance()->getSystemId()), + static_cast(MAVLinkProtocol::instance()->getComponentId()), sharedLink->mavlinkChannel(), &message, &follow_target diff --git a/src/GPS/RTCMMavlink.cc b/src/GPS/RTCMMavlink.cc index 53272c8b836e..46f9fb637e13 100644 --- a/src/GPS/RTCMMavlink.cc +++ b/src/GPS/RTCMMavlink.cc @@ -61,7 +61,6 @@ void RTCMMavlink::RTCMDataUpdate(QByteArray message) void RTCMMavlink::sendMessageToVehicle(const mavlink_gps_rtcm_data_t& msg) { QmlObjectListModel& vehicles = *_toolbox.multiVehicleManager()->vehicles(); - MAVLinkProtocol* mavlinkProtocol = _toolbox.mavlinkProtocol(); for (int i = 0; i < vehicles.count(); i++) { Vehicle* vehicle = qobject_cast(vehicles[i]); SharedLinkInterfacePtr sharedLink = vehicle->vehicleLinkManager()->primaryLink().lock(); @@ -69,8 +68,8 @@ void RTCMMavlink::sendMessageToVehicle(const mavlink_gps_rtcm_data_t& msg) if (sharedLink) { mavlink_message_t message; - mavlink_msg_gps_rtcm_data_encode_chan(mavlinkProtocol->getSystemId(), - mavlinkProtocol->getComponentId(), + mavlink_msg_gps_rtcm_data_encode_chan(MAVLinkProtocol::instance()->getSystemId(), + MAVLinkProtocol::instance()->getComponentId(), sharedLink->mavlinkChannel(), &message, &msg); diff --git a/src/MAVLink/QGCMAVLink.cc b/src/MAVLink/QGCMAVLink.cc index bb61af2b1912..76b0e11b11ee 100644 --- a/src/MAVLink/QGCMAVLink.cc +++ b/src/MAVLink/QGCMAVLink.cc @@ -8,8 +8,7 @@ ****************************************************************************/ #include "QGCMAVLink.h" -#include "MAVLinkLib.h" -#include +#include "QGCLoggingCategory.h" #include @@ -38,6 +37,10 @@ QGCMAVLink::QGCMAVLink(QObject *parent) : QObject(parent) { // qCDebug(StatusTextHandlerLog) << Q_FUNC_INFO << this; + + qRegisterMetaType("mavlink_message_t"); + qRegisterMetaType("MAV_TYPE"); + qRegisterMetaType("MAV_AUTOPILOT"); } QGCMAVLink::~QGCMAVLink() diff --git a/src/MAVLink/QGCMAVLink.h b/src/MAVLink/QGCMAVLink.h index ad345a9c1fce..cf4da6f6762a 100644 --- a/src/MAVLink/QGCMAVLink.h +++ b/src/MAVLink/QGCMAVLink.h @@ -9,15 +9,18 @@ #pragma once -#include -#include #include #include +#include +#include #include #include "MAVLinkLib.h" Q_DECLARE_LOGGING_CATEGORY(QGCMAVLinkLog) +// Q_DECLARE_METATYPE(mavlink_message_t) +Q_DECLARE_METATYPE(MAV_TYPE) +Q_DECLARE_METATYPE(MAV_AUTOPILOT) // TODO: Q_NAMESPACE class QGCMAVLink : public QObject diff --git a/src/MissionManager/MissionManager.cc b/src/MissionManager/MissionManager.cc index 3b8ef5fc9351..f88a01cfcdd1 100644 --- a/src/MissionManager/MissionManager.cc +++ b/src/MissionManager/MissionManager.cc @@ -61,8 +61,8 @@ void MissionManager::writeArduPilotGuidedMissionItem(const QGeoCoordinate& gotoC missionItem.current = altChangeOnly ? 3 : 2; missionItem.autocontinue = true; - mavlink_msg_mission_item_encode_chan(qgcApp()->toolbox()->mavlinkProtocol()->getSystemId(), - qgcApp()->toolbox()->mavlinkProtocol()->getComponentId(), + mavlink_msg_mission_item_encode_chan(MAVLinkProtocol::instance()->getSystemId(), + MAVLinkProtocol::instance()->getComponentId(), sharedLink->mavlinkChannel(), &messageOut, &missionItem); diff --git a/src/MissionManager/PlanManager.cc b/src/MissionManager/PlanManager.cc index 9174a40b7838..9e8c4f461c58 100644 --- a/src/MissionManager/PlanManager.cc +++ b/src/MissionManager/PlanManager.cc @@ -108,8 +108,8 @@ void PlanManager::_writeMissionCount(void) mavlink_message_t message; mavlink_msg_mission_count_pack_chan( - qgcApp()->toolbox()->mavlinkProtocol()->getSystemId(), - qgcApp()->toolbox()->mavlinkProtocol()->getComponentId(), + MAVLinkProtocol::instance()->getSystemId(), + MAVLinkProtocol::instance()->getComponentId(), sharedLink->mavlinkChannel(), &message, _vehicle->id(), @@ -154,8 +154,8 @@ void PlanManager::_requestList(void) SharedLinkInterfacePtr sharedLink = _vehicle->vehicleLinkManager()->primaryLink().lock(); if (sharedLink){ mavlink_message_t message; - mavlink_msg_mission_request_list_pack_chan(qgcApp()->toolbox()->mavlinkProtocol()->getSystemId(), - qgcApp()->toolbox()->mavlinkProtocol()->getComponentId(), + mavlink_msg_mission_request_list_pack_chan(MAVLinkProtocol::instance()->getSystemId(), + MAVLinkProtocol::instance()->getComponentId(), sharedLink->mavlinkChannel(), &message, _vehicle->id(), @@ -297,8 +297,8 @@ void PlanManager::_readTransactionComplete(void) mavlink_message_t message; mavlink_msg_mission_ack_pack_chan( - qgcApp()->toolbox()->mavlinkProtocol()->getSystemId(), - qgcApp()->toolbox()->mavlinkProtocol()->getComponentId(), + MAVLinkProtocol::instance()->getSystemId(), + MAVLinkProtocol::instance()->getComponentId(), sharedLink->mavlinkChannel(), &message, _vehicle->id(), @@ -360,8 +360,8 @@ void PlanManager::_requestNextMissionItem(void) if (sharedLink) { mavlink_message_t message; - mavlink_msg_mission_request_int_pack_chan(qgcApp()->toolbox()->mavlinkProtocol()->getSystemId(), - qgcApp()->toolbox()->mavlinkProtocol()->getComponentId(), + mavlink_msg_mission_request_int_pack_chan(MAVLinkProtocol::instance()->getSystemId(), + MAVLinkProtocol::instance()->getComponentId(), sharedLink->mavlinkChannel(), &message, _vehicle->id(), @@ -529,8 +529,8 @@ void PlanManager::_handleMissionRequest(const mavlink_message_t& message) if (sharedLink) { mavlink_message_t messageOut; - mavlink_msg_mission_item_int_pack_chan(qgcApp()->toolbox()->mavlinkProtocol()->getSystemId(), - qgcApp()->toolbox()->mavlinkProtocol()->getComponentId(), + mavlink_msg_mission_item_int_pack_chan(MAVLinkProtocol::instance()->getSystemId(), + MAVLinkProtocol::instance()->getComponentId(), sharedLink->mavlinkChannel(), &messageOut, _vehicle->id(), @@ -879,8 +879,8 @@ void PlanManager::_removeAllWorker(void) if (sharedLink) { mavlink_message_t message; - mavlink_msg_mission_clear_all_pack_chan(qgcApp()->toolbox()->mavlinkProtocol()->getSystemId(), - qgcApp()->toolbox()->mavlinkProtocol()->getComponentId(), + mavlink_msg_mission_clear_all_pack_chan(MAVLinkProtocol::instance()->getSystemId(), + MAVLinkProtocol::instance()->getComponentId(), sharedLink->mavlinkChannel(), &message, _vehicle->id(), diff --git a/src/QGCApplication.cc b/src/QGCApplication.cc index fbdb956f99d7..11cf7927f8ce 100644 --- a/src/QGCApplication.cc +++ b/src/QGCApplication.cc @@ -27,7 +27,6 @@ #include #include -#include "Audio/AudioOutput.h" #include "QGCConfig.h" #include "QGCApplication.h" #include "CmdLineOptParser.h" @@ -138,6 +137,11 @@ static QObject* shapeFileHelperSingletonFactory(QQmlEngine*, QJSEngine*) return new ShapeFileHelper; } +static QObject *mavlinkSingletonFactory(QQmlEngine*, QJSEngine*) +{ + return new QGCMAVLink(); +} + QGCApplication::QGCApplication(int &argc, char* argv[], bool unitTesting) : QApplication(argc, argv) , _runningUnitTests(unitTesting) @@ -389,6 +393,8 @@ void QGCApplication::init() qmlRegisterSingletonType("QGroundControl.ShapeFileHelper", 1, 0, "ShapeFileHelper", shapeFileHelperSingletonFactory); + qmlRegisterSingletonType("MAVLink", 1, 0, "MAVLink", mavlinkSingletonFactory); + // Although this should really be in _initForNormalAppBoot putting it here allowws us to create unit tests which pop up more easily if(QFontDatabase::addApplicationFont(":/fonts/opensans") < 0) { @@ -460,7 +466,7 @@ void QGCApplication::_initForNormalAppBoot() #endif // Now that main window is up check for lost log files - connect(this, &QGCApplication::checkForLostLogFiles, _toolbox->mavlinkProtocol(), &MAVLinkProtocol::checkForLostLogFiles); + connect(this, &QGCApplication::checkForLostLogFiles, MAVLinkProtocol::instance(), &MAVLinkProtocol::checkForLostLogFiles); emit checkForLostLogFiles(); // Load known link configurations diff --git a/src/QGCToolbox.cc b/src/QGCToolbox.cc index 09e933c72127..a51d476dd2ad 100644 --- a/src/QGCToolbox.cc +++ b/src/QGCToolbox.cc @@ -14,7 +14,6 @@ #endif #include "JoystickManager.h" #include "LinkManager.h" -#include "MAVLinkProtocol.h" #include "MissionCommandTree.h" #include "MultiVehicleManager.h" #include "PositionManager.h" @@ -49,7 +48,6 @@ QGCToolbox::QGCToolbox(QGCApplication* app) #endif _joystickManager = new JoystickManager (app, this); _linkManager = new LinkManager (app, this); - _mavlinkProtocol = new MAVLinkProtocol (app, this); _missionCommandTree = new MissionCommandTree (app, this); _multiVehicleManager = new MultiVehicleManager (app, this); _qgcPositionManager = new QGCPositionManager (app, this); @@ -76,7 +74,6 @@ void QGCToolbox::setChildToolboxes(void) #endif _joystickManager->setToolbox(this); _linkManager->setToolbox(this); - _mavlinkProtocol->setToolbox(this); _missionCommandTree->setToolbox(this); _multiVehicleManager->setToolbox(this); _qgcPositionManager->setToolbox(this); diff --git a/src/QGCToolbox.h b/src/QGCToolbox.h index 634ee38d2135..8f645cf7adc8 100644 --- a/src/QGCToolbox.h +++ b/src/QGCToolbox.h @@ -17,7 +17,6 @@ class FirmwarePluginManager; class GPSManager; class JoystickManager; class LinkManager; -class MAVLinkProtocol; class MissionCommandTree; class MultiVehicleManager; class QGCApplication; @@ -43,7 +42,6 @@ class QGCToolbox : public QObject { FirmwarePluginManager* firmwarePluginManager () { return _firmwarePluginManager; } JoystickManager* joystickManager () { return _joystickManager; } LinkManager* linkManager () { return _linkManager; } - MAVLinkProtocol* mavlinkProtocol () { return _mavlinkProtocol; } MissionCommandTree* missionCommandTree () { return _missionCommandTree; } MultiVehicleManager* multiVehicleManager () { return _multiVehicleManager; } QGCPositionManager* qgcPositionManager () { return _qgcPositionManager; } @@ -71,7 +69,6 @@ class QGCToolbox : public QObject { #endif JoystickManager* _joystickManager = nullptr; LinkManager* _linkManager = nullptr; - MAVLinkProtocol* _mavlinkProtocol = nullptr; MissionCommandTree* _missionCommandTree = nullptr; MultiVehicleManager* _multiVehicleManager = nullptr; QGCPositionManager* _qgcPositionManager = nullptr; diff --git a/src/QmlControls/QGroundControlQmlGlobal.cc b/src/QmlControls/QGroundControlQmlGlobal.cc index ffd7923a57b3..1895651ace0e 100644 --- a/src/QmlControls/QGroundControlQmlGlobal.cc +++ b/src/QmlControls/QGroundControlQmlGlobal.cc @@ -196,13 +196,13 @@ void QGroundControlQmlGlobal::stopOneMockLink(void) void QGroundControlQmlGlobal::setIsVersionCheckEnabled(bool enable) { - _toolbox->mavlinkProtocol()->enableVersionCheck(enable); + MAVLinkProtocol::instance()->enableVersionCheck(enable); emit isVersionCheckEnabledChanged(enable); } void QGroundControlQmlGlobal::setMavlinkSystemID(int id) { - _toolbox->mavlinkProtocol()->setSystemId(id); + MAVLinkProtocol::instance()->setSystemId(id); emit mavlinkSystemIDChanged(id); } @@ -325,12 +325,12 @@ QString QGroundControlQmlGlobal::altitudeModeShortDescription(AltMode altMode) bool QGroundControlQmlGlobal::isVersionCheckEnabled() { - return _toolbox->mavlinkProtocol()->versionCheckEnabled(); + return MAVLinkProtocol::instance()->versionCheckEnabled(); } int QGroundControlQmlGlobal::mavlinkSystemID() { - return _toolbox->mavlinkProtocol()->getSystemId(); + return MAVLinkProtocol::instance()->getSystemId(); } QString QGroundControlQmlGlobal::elevationProviderName() diff --git a/src/Vehicle/FTPManager.cc b/src/Vehicle/FTPManager.cc index 6ca95bbda430..924da502cfcf 100644 --- a/src/Vehicle/FTPManager.cc +++ b/src/Vehicle/FTPManager.cc @@ -11,6 +11,7 @@ #include "MAVLinkProtocol.h" #include "Vehicle.h" #include "QGCApplication.h" +#include "QGCToolbox.h" #include "QGCLoggingCategory.h" #include @@ -230,7 +231,7 @@ void FTPManager::_mavlinkMessageReceived(const mavlink_message_t& message) mavlink_msg_file_transfer_protocol_decode(&message, &data); // Make sure we are the target system - int qgcId = qgcApp()->toolbox()->mavlinkProtocol()->getSystemId(); + int qgcId = MAVLinkProtocol::instance()->getSystemId(); if (data.target_system != qgcId) { return; } @@ -738,8 +739,8 @@ void FTPManager::_sendRequestExpectAck(MavlinkFTP::Request* request) qCDebug(FTPManagerLog) << "_sendRequestExpectAck opcode:" << MavlinkFTP::opCodeToString(static_cast(request->hdr.opcode)) << "seqNumber:" << request->hdr.seqNumber; mavlink_message_t message; - mavlink_msg_file_transfer_protocol_pack_chan(qgcApp()->toolbox()->mavlinkProtocol()->getSystemId(), - qgcApp()->toolbox()->mavlinkProtocol()->getComponentId(), + mavlink_msg_file_transfer_protocol_pack_chan(MAVLinkProtocol::instance()->getSystemId(), + MAVLinkProtocol::instance()->getComponentId(), sharedLink->mavlinkChannel(), &message, 0, // Target network, 0=broadcast? diff --git a/src/Vehicle/InitialConnectStateMachine.cc b/src/Vehicle/InitialConnectStateMachine.cc index 8751517b4659..277c7a8f4352 100644 --- a/src/Vehicle/InitialConnectStateMachine.cc +++ b/src/Vehicle/InitialConnectStateMachine.cc @@ -168,7 +168,7 @@ void InitialConnectStateMachine::_autopilotVersionRequestMessageHandler(void* re if (failureCode != Vehicle::RequestMessageNoFailure) { qCDebug(InitialConnectStateMachineLog) << "REQUEST_MESSAGE:AUTOPILOT_VERSION failed. Setting no capabilities"; uint64_t assumedCapabilities = 0; - if (vehicle->_mavlinkProtocolRequestMaxProtoVersion >= 200) { + if (vehicle->_mavlinkProtocolRequestMaxProtoVersion >= 2) { // Link already running mavlink 2 assumedCapabilities |= MAV_PROTOCOL_CAPABILITY_MAVLINK2; } @@ -220,7 +220,7 @@ void InitialConnectStateMachine::_protocolVersionRequestMessageHandler(void* res mavlink_msg_protocol_version_decode(&message, &protoVersion); qCDebug(InitialConnectStateMachineLog) << "PROTOCOL_VERSION received mav_version:" << protoVersion.max_version; - vehicle->_mavlinkProtocolRequestMaxProtoVersion = protoVersion.max_version; + vehicle->_mavlinkProtocolRequestMaxProtoVersion = protoVersion.max_version / 100; vehicle->_mavlinkProtocolRequestComplete = true; vehicle->_setMaxProtoVersionFromBothSources(); } @@ -243,7 +243,7 @@ void InitialConnectStateMachine::_protocolVersionRequestMessageHandler(void* res // Either the PROTOCOL_VERSION message didn't make it through the pipe from Vehicle->QGC because the pipe is mavlink 1. // Or the PROTOCOL_VERSION message was lost on a noisy connection. Either way the best we can do is fall back to mavlink 1. qCDebug(InitialConnectStateMachineLog) << QStringLiteral("Setting _maxProtoVersion to 100 due to timeout on receiving PROTOCOL_VERSION message."); - vehicle->_mavlinkProtocolRequestMaxProtoVersion = 100; + vehicle->_mavlinkProtocolRequestMaxProtoVersion = 1; vehicle->_mavlinkProtocolRequestComplete = true; vehicle->_setMaxProtoVersionFromBothSources(); } diff --git a/src/Vehicle/MultiVehicleManager.cc b/src/Vehicle/MultiVehicleManager.cc index d5bbb22046d6..e5aba05d4803 100644 --- a/src/Vehicle/MultiVehicleManager.cc +++ b/src/Vehicle/MultiVehicleManager.cc @@ -23,6 +23,11 @@ #include +#define PX4_FLOW_SYS_ID 81 +#define PX4_FLOW_SYS_COMP_ID MAV_COMP_ID_USER26 +#define PX4_FLOW_MAV_TYPE MAV_TYPE_GENERIC +#define PX4_FLOW_AUTOPILOT_TYPE MAV_AUTOPILOT_GENERIC + QGC_LOGGING_CATEGORY(MultiVehicleManagerLog, "MultiVehicleManagerLog") MultiVehicleManager::MultiVehicleManager(QGCApplication* app, QGCToolbox* toolbox) @@ -33,7 +38,6 @@ MultiVehicleManager::MultiVehicleManager(QGCApplication* app, QGCToolbox* toolbo , _offlineEditingVehicle(nullptr) , _firmwarePluginManager(nullptr) , _joystickManager(nullptr) - , _mavlinkProtocol(nullptr) , _gcsHeartbeatEnabled(true) { QSettings settings; @@ -48,7 +52,6 @@ void MultiVehicleManager::setToolbox(QGCToolbox *toolbox) _firmwarePluginManager = _toolbox->firmwarePluginManager(); _joystickManager = _toolbox->joystickManager(); - _mavlinkProtocol = _toolbox->mavlinkProtocol(); QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership); qmlRegisterUncreatableType("QGroundControl.MultiVehicleManager", 1, 0, "MultiVehicleManager", "Reference only"); @@ -57,7 +60,7 @@ void MultiVehicleManager::setToolbox(QGCToolbox *toolbox) qRegisterMetaType("MavCmdResultFailureCode_t"); - connect(_mavlinkProtocol, &MAVLinkProtocol::vehicleHeartbeatInfo, this, &MultiVehicleManager::_vehicleHeartbeatInfo); + connect(MAVLinkProtocol::instance(), &MAVLinkProtocol::vehicleHeartbeatInfo, this, &MultiVehicleManager::_vehicleHeartbeatInfo); connect(&_gcsHeartbeatTimer, &QTimer::timeout, this, &MultiVehicleManager::_sendGCSHeartbeat); if (_gcsHeartbeatEnabled) { @@ -67,7 +70,7 @@ void MultiVehicleManager::setToolbox(QGCToolbox *toolbox) _offlineEditingVehicle = new Vehicle(Vehicle::MAV_AUTOPILOT_TRACK, Vehicle::MAV_TYPE_TRACK, _firmwarePluginManager, this); } -void MultiVehicleManager::_vehicleHeartbeatInfo(LinkInterface* link, int vehicleId, int componentId, int vehicleFirmwareType, int vehicleType) +void MultiVehicleManager::_vehicleHeartbeatInfo(LinkInterface* link, uint8_t vehicleId, uint8_t componentId, MAV_AUTOPILOT vehicleFirmwareType, MAV_TYPE vehicleType) { if (componentId != MAV_COMP_ID_AUTOPILOT1) { // Don't create vehicles for components other than the autopilot @@ -84,7 +87,7 @@ void MultiVehicleManager::_vehicleHeartbeatInfo(LinkInterface* link, int vehicle // When you flash a new ArduCopter it does not set a FRAME_CLASS for some reason. This is the only ArduPilot variant which // works this way. Because of this the vehicle type is not known at first connection. In order to make QGC work reasonably // we assume ArduCopter for this case. - if (vehicleType == 0 && vehicleFirmwareType == MAV_AUTOPILOT_ARDUPILOTMEGA) { + if ((vehicleType == MAV_TYPE_GENERIC) && (vehicleFirmwareType == MAV_AUTOPILOT_ARDUPILOTMEGA)) { vehicleType = MAV_TYPE_QUADROTOR; } #endif @@ -115,11 +118,11 @@ void MultiVehicleManager::_vehicleHeartbeatInfo(LinkInterface* link, int vehicle << vehicleFirmwareType << vehicleType; - if (vehicleId == _mavlinkProtocol->getSystemId()) { + if (vehicleId == MAVLinkProtocol::instance()->getSystemId()) { _app->showAppMessage(tr("Warning: A vehicle is using the same system id as %1: %2").arg(QCoreApplication::applicationName()).arg(vehicleId)); } - Vehicle* vehicle = new Vehicle(link, vehicleId, componentId, (MAV_AUTOPILOT)vehicleFirmwareType, (MAV_TYPE)vehicleType, _firmwarePluginManager, _joystickManager, this); + Vehicle* vehicle = new Vehicle(link, vehicleId, componentId, vehicleFirmwareType, vehicleType, _firmwarePluginManager, _joystickManager, this); connect(vehicle, &Vehicle::requestProtocolVersion, this, &MultiVehicleManager::_requestProtocolVersion); connect(vehicle->vehicleLinkManager(), &VehicleLinkManager::allLinksRemoved, this, &MultiVehicleManager::_deleteVehiclePhase1); connect(vehicle->parameterManager(), &ParameterManager::parametersReadyChanged, this, &MultiVehicleManager::_vehicleParametersReadyChanged); @@ -151,12 +154,12 @@ void MultiVehicleManager::_vehicleHeartbeatInfo(LinkInterface* link, int vehicle /// This slot is connected to the Vehicle::requestProtocolVersion signal such that the vehicle manager /// tries to switch MAVLink to v2 if all vehicles support it -void MultiVehicleManager::_requestProtocolVersion(unsigned version) +void MultiVehicleManager::_requestProtocolVersion(uint8_t version) { - unsigned maxversion = 0; + uint8_t maxversion = 0; if (_vehicles.count() == 0) { - _mavlinkProtocol->setVersion(version); + MAVLinkProtocol::instance()->setVersion(version); return; } @@ -168,8 +171,8 @@ void MultiVehicleManager::_requestProtocolVersion(unsigned version) } } - if (_mavlinkProtocol->getCurrentVersion() != maxversion) { - _mavlinkProtocol->setVersion(maxversion); + if (MAVLinkProtocol::instance()->getCurrentVersion() != maxversion) { + MAVLinkProtocol::instance()->setVersion(maxversion); } } @@ -369,8 +372,8 @@ void MultiVehicleManager::_sendGCSHeartbeat(void) auto linkConfiguration = link->linkConfiguration(); if (link->isConnected() && linkConfiguration && !linkConfiguration->isHighLatency()) { mavlink_message_t message; - mavlink_msg_heartbeat_pack_chan(_mavlinkProtocol->getSystemId(), - _mavlinkProtocol->getComponentId(), + mavlink_msg_heartbeat_pack_chan(MAVLinkProtocol::instance()->getSystemId(), + MAVLinkProtocol::instance()->getComponentId(), link->mavlinkChannel(), &message, MAV_TYPE_GCS, // MAV_TYPE diff --git a/src/Vehicle/MultiVehicleManager.h b/src/Vehicle/MultiVehicleManager.h index 70d66c6061b7..46305fccd522 100644 --- a/src/Vehicle/MultiVehicleManager.h +++ b/src/Vehicle/MultiVehicleManager.h @@ -19,11 +19,11 @@ #include "QGCToolbox.h" #include "QmlObjectListModel.h" +#include "MAVLinkLib.h" class FirmwarePluginManager; class JoystickManager; class QGCApplication; -class MAVLinkProtocol; class LinkInterface; class Vehicle; @@ -91,8 +91,8 @@ private slots: void _setActiveVehiclePhase2 (void); void _vehicleParametersReadyChanged (bool parametersReady); void _sendGCSHeartbeat (void); - void _vehicleHeartbeatInfo (LinkInterface* link, int vehicleId, int componentId, int vehicleFirmwareType, int vehicleType); - void _requestProtocolVersion (unsigned version); + void _vehicleHeartbeatInfo (LinkInterface* link, uint8_t vehicleId, uint8_t componentId, MAV_AUTOPILOT vehicleFirmwareType, MAV_TYPE vehicleType); + void _requestProtocolVersion (uint8_t version); void _coordinateChanged (QGeoCoordinate coordinate); private: @@ -112,7 +112,6 @@ private slots: FirmwarePluginManager* _firmwarePluginManager; JoystickManager* _joystickManager; - MAVLinkProtocol* _mavlinkProtocol; QGeoCoordinate _lastKnownLocation; QTimer _gcsHeartbeatTimer; ///< Timer to emit heartbeats diff --git a/src/Vehicle/RemoteIDManager.cc b/src/Vehicle/RemoteIDManager.cc index 19d5062d194c..36195fb715d9 100644 --- a/src/Vehicle/RemoteIDManager.cc +++ b/src/Vehicle/RemoteIDManager.cc @@ -28,7 +28,6 @@ const uint8_t* RemoteIDManager::_id_or_mac_unknown = new uint8_t[MAVLINK_MSG_OPE RemoteIDManager::RemoteIDManager(Vehicle* vehicle) : QObject (vehicle) - , _mavlink (nullptr) , _vehicle (vehicle) , _settings (nullptr) , _armStatusGood (false) @@ -42,7 +41,6 @@ RemoteIDManager::RemoteIDManager(Vehicle* vehicle) , _targetComponent (0) // By default 0 means broadcast , _enforceSendingSelfID (false) { - _mavlink = qgcApp()->toolbox()->mavlinkProtocol(); _settings = qgcApp()->toolbox()->settingsManager()->remoteIDSettings(); _positionManager = qgcApp()->toolbox()->qgcPositionManager(); @@ -197,8 +195,8 @@ void RemoteIDManager::_sendSelfIDMsg() if (sharedLink) { mavlink_message_t msg; - mavlink_msg_open_drone_id_self_id_pack_chan(_mavlink->getSystemId(), - _mavlink->getComponentId(), + mavlink_msg_open_drone_id_self_id_pack_chan(MAVLinkProtocol::instance()->getSystemId(), + MAVLinkProtocol::instance()->getComponentId(), sharedLink->mavlinkChannel(), &msg, _targetSystem, @@ -251,8 +249,8 @@ void RemoteIDManager::_sendOperatorID() bytesOperatorID.resize(MAVLINK_MSG_OPEN_DRONE_ID_OPERATOR_ID_FIELD_OPERATOR_ID_LEN); mavlink_msg_open_drone_id_operator_id_pack_chan( - _mavlink->getSystemId(), - _mavlink->getComponentId(), + MAVLinkProtocol::instance()->getSystemId(), + MAVLinkProtocol::instance()->getComponentId(), sharedLink->mavlinkChannel(), &msg, _targetSystem, @@ -333,8 +331,8 @@ void RemoteIDManager::_sendSystem() if (sharedLink) { mavlink_message_t msg; - mavlink_msg_open_drone_id_system_pack_chan(_mavlink->getSystemId(), - _mavlink->getComponentId(), + mavlink_msg_open_drone_id_system_pack_chan(MAVLinkProtocol::instance()->getSystemId(), + MAVLinkProtocol::instance()->getComponentId(), sharedLink->mavlinkChannel(), &msg, _targetSystem, @@ -377,8 +375,8 @@ void RemoteIDManager::_sendBasicID() // To make sure the buffer is large enough to fit the message. It will add padding bytes if smaller, or exclude the extra ones if bigger ba.resize(MAVLINK_MSG_OPEN_DRONE_ID_BASIC_ID_FIELD_UAS_ID_LEN); - mavlink_msg_open_drone_id_basic_id_pack_chan(_mavlink->getSystemId(), - _mavlink->getComponentId(), + mavlink_msg_open_drone_id_basic_id_pack_chan(MAVLinkProtocol::instance()->getSystemId(), + MAVLinkProtocol::instance()->getComponentId(), sharedLink->mavlinkChannel(), &msg, _targetSystem, diff --git a/src/Vehicle/RemoteIDManager.h b/src/Vehicle/RemoteIDManager.h index 4c13cd85b1f0..306730e5da21 100644 --- a/src/Vehicle/RemoteIDManager.h +++ b/src/Vehicle/RemoteIDManager.h @@ -22,7 +22,6 @@ Q_DECLARE_LOGGING_CATEGORY(RemoteIDManagerLog) class RemoteIDSettings; class QGCPositionManager; class Vehicle; -class MAVLinkProtocol; // Supporting Open Drone ID protocol class RemoteIDManager : public QObject @@ -106,7 +105,6 @@ private slots: bool _isEUOperatorIDValid(const QString& operatorID) const; QChar _calculateLuhnMod36(const QString& input) const; - MAVLinkProtocol* _mavlink; Vehicle* _vehicle; RemoteIDSettings* _settings; QGCPositionManager* _positionManager; diff --git a/src/Vehicle/TerrainProtocolHandler.cc b/src/Vehicle/TerrainProtocolHandler.cc index d1386993ef06..f55f5e167df3 100644 --- a/src/Vehicle/TerrainProtocolHandler.cc +++ b/src/Vehicle/TerrainProtocolHandler.cc @@ -144,8 +144,8 @@ void TerrainProtocolHandler::_sendTerrainData(const QGeoCoordinate& swCorner, ui mavlink_message_t msg; mavlink_msg_terrain_data_pack_chan( - qgcApp()->toolbox()->mavlinkProtocol()->getSystemId(), - qgcApp()->toolbox()->mavlinkProtocol()->getComponentId(), + MAVLinkProtocol::instance()->getSystemId(), + MAVLinkProtocol::instance()->getComponentId(), sharedLink->mavlinkChannel(), &msg, _currentTerrainRequest.lat, diff --git a/src/Vehicle/Vehicle.cc b/src/Vehicle/Vehicle.cc index 27145ba2df88..7a70b51a21fb 100644 --- a/src/Vehicle/Vehicle.cc +++ b/src/Vehicle/Vehicle.cc @@ -119,11 +119,10 @@ Vehicle::Vehicle(LinkInterface* link, connect(_joystickManager, &JoystickManager::activeJoystickChanged, this, &Vehicle::_loadJoystickSettings); connect(qgcApp()->toolbox()->multiVehicleManager(), &MultiVehicleManager::activeVehicleChanged, this, &Vehicle::_activeVehicleChanged); - _mavlink = _toolbox->mavlinkProtocol(); - qCDebug(VehicleLog) << "Link started with Mavlink " << (_mavlink->getCurrentVersion() >= 200 ? "V2" : "V1"); + qCDebug(VehicleLog) << "Link started with Mavlink " << (MAVLinkProtocol::instance()->getCurrentVersion() >= 2 ? "V2" : "V1"); - connect(_mavlink, &MAVLinkProtocol::messageReceived, this, &Vehicle::_mavlinkMessageReceived); - connect(_mavlink, &MAVLinkProtocol::mavlinkMessageStatus, this, &Vehicle::_mavlinkMessageStatus); + connect(MAVLinkProtocol::instance(), &MAVLinkProtocol::messageReceived, this, &Vehicle::_mavlinkMessageReceived); + connect(MAVLinkProtocol::instance(), &MAVLinkProtocol::mavlinkMessageStatus, this, &Vehicle::_mavlinkMessageStatus); connect(this, &Vehicle::flightModeChanged, this, &Vehicle::_handleFlightModeChanged); connect(this, &Vehicle::armedChanged, this, &Vehicle::_announceArmedChanged); @@ -213,7 +212,7 @@ Vehicle::Vehicle(MAV_AUTOPILOT firmwareType, , _defaultCruiseSpeed (_settingsManager->appSettings()->offlineEditingCruiseSpeed()->rawValue().toDouble()) , _defaultHoverSpeed (_settingsManager->appSettings()->offlineEditingHoverSpeed()->rawValue().toDouble()) , _mavlinkProtocolRequestComplete (true) - , _maxProtoVersion (200) + , _maxProtoVersion (2) , _capabilityBitsKnown (true) , _capabilityBits (MAV_PROTOCOL_CAPABILITY_MISSION_FENCE | MAV_PROTOCOL_CAPABILITY_MISSION_RALLY) , _firmwarePluginManager (firmwarePluginManager) @@ -371,7 +370,7 @@ void Vehicle::_commonInit() // enable Joystick if appropriate _loadJoystickSettings(); - _gimbalController = new GimbalController(_mavlink, this); + _gimbalController = new GimbalController(MAVLinkProtocol::instance(), this); } Vehicle::~Vehicle() @@ -472,8 +471,8 @@ void Vehicle::resetCounters() void Vehicle::_mavlinkMessageReceived(LinkInterface* link, mavlink_message_t message) { // If the link is already running at Mavlink V2 set our max proto version to it. - unsigned mavlinkVersion = _mavlink->getCurrentVersion(); - if (_maxProtoVersion != mavlinkVersion && mavlinkVersion >= 200) { + uint8_t mavlinkVersion = MAVLinkProtocol::instance()->getCurrentVersion(); + if ((_maxProtoVersion != mavlinkVersion) && (mavlinkVersion >= 2)) { _maxProtoVersion = mavlinkVersion; qCDebug(VehicleLog) << "_mavlinkMessageReceived Link already running Mavlink v2. Setting _maxProtoVersion" << _maxProtoVersion; } @@ -896,10 +895,10 @@ void Vehicle::_setCapabilities(uint64_t capabilityBits) _setMaxProtoVersionFromBothSources(); } -void Vehicle::_setMaxProtoVersion(unsigned version) { +void Vehicle::_setMaxProtoVersion(uint8_t version) { // Set only once or if we need to reduce the max version - if (_maxProtoVersion == 0 || version < _maxProtoVersion) { + if ((_maxProtoVersion == 0) || (version < _maxProtoVersion)) { qCDebug(VehicleLog) << "_setMaxProtoVersion before:after" << _maxProtoVersion << version; _maxProtoVersion = version; emit requestProtocolVersion(_maxProtoVersion); @@ -914,7 +913,7 @@ void Vehicle::_setMaxProtoVersionFromBothSources() _setMaxProtoVersion(_mavlinkProtocolRequestMaxProtoVersion); } else { qCDebug(VehicleLog) << "_setMaxProtoVersionFromBothSources using capability bits"; - _setMaxProtoVersion(capabilityBits() & MAV_PROTOCOL_CAPABILITY_MAVLINK2 ? 200 : 100); + _setMaxProtoVersion(capabilityBits() & MAV_PROTOCOL_CAPABILITY_MAVLINK2 ? 2 : 1); } } } @@ -1148,8 +1147,8 @@ void Vehicle::_handlePing(LinkInterface* link, mavlink_message_t& message) if ((ping.target_system == 0) && (ping.target_component == 0)) { // Mavlink defines a ping request as a MSG_ID_PING which contains target_system = 0 and target_component = 0 // So only send a ping response when you receive a valid ping request - mavlink_msg_ping_pack_chan(static_cast(_mavlink->getSystemId()), - static_cast(_mavlink->getComponentId()), + mavlink_msg_ping_pack_chan(static_cast(MAVLinkProtocol::instance()->getSystemId()), + static_cast(MAVLinkProtocol::instance()->getComponentId()), sharedLink->mavlinkChannel(), &msg, ping.time_usec, @@ -1242,8 +1241,8 @@ EventHandler& Vehicle::_eventHandler(uint8_t compid) SharedLinkInterfacePtr sharedLink = vehicleLinkManager()->primaryLink().lock(); if (sharedLink) { mavlink_message_t message; - mavlink_msg_request_event_encode_chan(_mavlink->getSystemId(), - _mavlink->getComponentId(), + mavlink_msg_request_event_encode_chan(MAVLinkProtocol::instance()->getSystemId(), + MAVLinkProtocol::instance()->getComponentId(), sharedLink->mavlinkChannel(), &message, &msg); @@ -1256,7 +1255,7 @@ EventHandler& Vehicle::_eventHandler(uint8_t compid) QSharedPointer eventHandler{new EventHandler(this, profile, std::bind(&Vehicle::_handleEvent, this, compid, std::placeholders::_1), sendRequestEventMessageCB, - _mavlink->getSystemId(), _mavlink->getComponentId(), _id, compid)}; + MAVLinkProtocol::instance()->getSystemId(), MAVLinkProtocol::instance()->getComponentId(), _id, compid)}; eventData = _events.insert(compid, eventHandler); // connect health and arming check updates @@ -1670,8 +1669,8 @@ void Vehicle::setFlightMode(const QString& flightMode) custom_mode); } else { mavlink_message_t msg; - mavlink_msg_set_mode_pack_chan(_mavlink->getSystemId(), - _mavlink->getComponentId(), + mavlink_msg_set_mode_pack_chan(MAVLinkProtocol::instance()->getSystemId(), + MAVLinkProtocol::instance()->getComponentId(), sharedLink->mavlinkChannel(), &msg, id(), @@ -1714,8 +1713,8 @@ void Vehicle::requestDataStream(MAV_DATA_STREAM stream, uint16_t rate, bool send dataStream.target_system = id(); dataStream.target_component = _defaultComponentId; - mavlink_msg_request_data_stream_encode_chan(_mavlink->getSystemId(), - _mavlink->getComponentId(), + mavlink_msg_request_data_stream_encode_chan(MAVLinkProtocol::instance()->getSystemId(), + MAVLinkProtocol::instance()->getComponentId(), sharedLink->mavlinkChannel(), &msg, &dataStream); @@ -1869,8 +1868,8 @@ void Vehicle::_sendQGCTimeToVehicle() cmd.time_unix_usec = QDateTime::currentDateTime().currentMSecsSinceEpoch()*1000; // Timestamp of the component clock since boot time in milliseconds (Not necessary). cmd.time_boot_ms = 0; - mavlink_msg_system_time_encode_chan(_mavlink->getSystemId(), - _mavlink->getComponentId(), + mavlink_msg_system_time_encode_chan(MAVLinkProtocol::instance()->getSystemId(), + MAVLinkProtocol::instance()->getComponentId(), sharedLink->mavlinkChannel(), &msg, &cmd); @@ -2367,8 +2366,8 @@ void Vehicle::setCurrentMissionSequence(int seq) seq--; } mavlink_msg_mission_set_current_pack_chan( - static_cast(_mavlink->getSystemId()), - static_cast(_mavlink->getComponentId()), + static_cast(MAVLinkProtocol::instance()->getSystemId()), + static_cast(MAVLinkProtocol::instance()->getComponentId()), sharedLink->mavlinkChannel(), &msg, static_cast(id()), @@ -2625,8 +2624,8 @@ void Vehicle::_sendMavCommandFromList(int index) cmd.x = commandEntry.frame == MAV_FRAME_MISSION ? commandEntry.rgParam5 : commandEntry.rgParam5 * 1e7; cmd.y = commandEntry.frame == MAV_FRAME_MISSION ? commandEntry.rgParam6 : commandEntry.rgParam6 * 1e7; cmd.z = commandEntry.rgParam7; - mavlink_msg_command_int_encode_chan(_mavlink->getSystemId(), - _mavlink->getComponentId(), + mavlink_msg_command_int_encode_chan(MAVLinkProtocol::instance()->getSystemId(), + MAVLinkProtocol::instance()->getComponentId(), sharedLink->mavlinkChannel(), &msg, &cmd); @@ -2645,8 +2644,8 @@ void Vehicle::_sendMavCommandFromList(int index) cmd.param5 = static_cast(commandEntry.rgParam5); cmd.param6 = static_cast(commandEntry.rgParam6); cmd.param7 = commandEntry.rgParam7; - mavlink_msg_command_long_encode_chan(_mavlink->getSystemId(), - _mavlink->getComponentId(), + mavlink_msg_command_long_encode_chan(MAVLinkProtocol::instance()->getSystemId(), + MAVLinkProtocol::instance()->getComponentId(), sharedLink->mavlinkChannel(), &msg, &cmd); @@ -3029,8 +3028,8 @@ void Vehicle::startCalibration(QGCMAVLink::CalibrationType calType) // We can't use sendMavCommand here since we have no idea how long it will be before the command returns a result. This in turn // causes the retry logic to break down. mavlink_message_t msg; - mavlink_msg_command_long_pack_chan(_mavlink->getSystemId(), - _mavlink->getComponentId(), + mavlink_msg_command_long_pack_chan(MAVLinkProtocol::instance()->getSystemId(), + MAVLinkProtocol::instance()->getComponentId(), sharedLink->mavlinkChannel(), &msg, id(), @@ -3140,8 +3139,8 @@ void Vehicle::_ackMavlinkLogData(uint16_t sequence) ack.target_component = _defaultComponentId; ack.target_system = id(); mavlink_msg_logging_ack_encode_chan( - _mavlink->getSystemId(), - _mavlink->getComponentId(), + MAVLinkProtocol::instance()->getSystemId(), + MAVLinkProtocol::instance()->getComponentId(), sharedLink->mavlinkChannel(), &msg, &ack); @@ -3428,9 +3427,9 @@ void Vehicle::_vehicleParamLoaded(bool ready) } } -void Vehicle::_mavlinkMessageStatus(int uasId, uint64_t totalSent, uint64_t totalReceived, uint64_t totalLoss, float lossPercent) +void Vehicle::_mavlinkMessageStatus(uint8_t sysid, uint64_t totalSent, uint64_t totalReceived, uint64_t totalLoss, float lossPercent) { - if(uasId == _id) { + if(sysid == _id) { _mavlinkSentCount = totalSent; _mavlinkReceivedCount = totalReceived; _mavlinkLossCount = totalLoss; @@ -3741,8 +3740,8 @@ void Vehicle::sendParamMapRC(const QString& paramName, double scale, double cent } } - mavlink_msg_param_map_rc_pack_chan(static_cast(_mavlink->getSystemId()), - static_cast(_mavlink->getComponentId()), + mavlink_msg_param_map_rc_pack_chan(static_cast(MAVLinkProtocol::instance()->getSystemId()), + static_cast(MAVLinkProtocol::instance()->getComponentId()), sharedLink->mavlinkChannel(), &message, _id, @@ -3769,8 +3768,8 @@ void Vehicle::clearAllParamMapRC(void) for (int i = 0; i < 3; i++) { mavlink_message_t message; - mavlink_msg_param_map_rc_pack_chan(static_cast(_mavlink->getSystemId()), - static_cast(_mavlink->getComponentId()), + mavlink_msg_param_map_rc_pack_chan(static_cast(MAVLinkProtocol::instance()->getSystemId()), + static_cast(MAVLinkProtocol::instance()->getComponentId()), sharedLink->mavlinkChannel(), &message, _id, @@ -3805,8 +3804,8 @@ void Vehicle::sendJoystickDataThreadSafe(float roll, float pitch, float yaw, flo float newThrustCommand = thrust * axesScaling; mavlink_msg_manual_control_pack_chan( - static_cast(_mavlink->getSystemId()), - static_cast(_mavlink->getComponentId()), + static_cast(MAVLinkProtocol::instance()->getSystemId()), + static_cast(MAVLinkProtocol::instance()->getComponentId()), sharedLink->mavlinkChannel(), &message, static_cast(_id), @@ -3869,8 +3868,8 @@ void Vehicle::setEstimatorOrigin(const QGeoCoordinate& centerCoord) mavlink_message_t msg; mavlink_msg_set_gps_global_origin_pack_chan( - _mavlink->getSystemId(), - _mavlink->getComponentId(), + MAVLinkProtocol::instance()->getSystemId(), + MAVLinkProtocol::instance()->getComponentId(), sharedLink->mavlinkChannel(), &msg, id(), @@ -4081,7 +4080,7 @@ void Vehicle::sendSetupSigning() MAVLinkSigning::createSetupSigning(channel, target_system, setup_signing); mavlink_message_t msg; - (void) mavlink_msg_setup_signing_encode_chan(_mavlink->getSystemId(), _mavlink->getComponentId(), channel, &msg, &setup_signing); + (void) mavlink_msg_setup_signing_encode_chan(MAVLinkProtocol::instance()->getSystemId(), MAVLinkProtocol::instance()->getComponentId(), channel, &msg, &setup_signing); // Since we don't get an ack back that the message was received send twice to try to make sure it makes it to the vehicle for (uint8_t i = 0; i < 2; ++i) { diff --git a/src/Vehicle/Vehicle.h b/src/Vehicle/Vehicle.h index 23f65549eb6d..4b7eb6d72d23 100644 --- a/src/Vehicle/Vehicle.h +++ b/src/Vehicle/Vehicle.h @@ -61,7 +61,6 @@ class Joystick; class JoystickManager; class LinkInterface; class LinkManager; -class MAVLinkProtocol; class MissionManager; class ParameterManager; class QGCCameraManager; @@ -585,7 +584,7 @@ class Vehicle : public VehicleFactGroup /// Get the maximum MAVLink protocol version supported /// @return the maximum version - unsigned maxProtoVersion () const { return _maxProtoVersion; } + uint8_t maxProtoVersion () const { return _maxProtoVersion; } bool mavlinkSigning () const { return _mavlinkSigning; } @@ -779,7 +778,7 @@ class Vehicle : public VehicleFactGroup void _setFlying(bool flying); void _setLanding(bool landing); void _setHomePosition(QGeoCoordinate& homeCoord); - void _setMaxProtoVersion(unsigned version); + void _setMaxProtoVersion(uint8_t version); void _setMaxProtoVersionFromBothSources(); /// Vehicle is about to be deleted @@ -931,7 +930,7 @@ private slots: void _updateHobbsMeter (); void _vehicleParamLoaded (bool ready); void _sendQGCTimeToVehicle (); - void _mavlinkMessageStatus (int uasId, uint64_t totalSent, uint64_t totalReceived, uint64_t totalLoss, float lossPercent); + void _mavlinkMessageStatus (uint8_t sysid, uint64_t totalSent, uint64_t totalReceived, uint64_t totalLoss, float lossPercent); void _orbitTelemetryTimeout (); void _updateFlightTime (); void _gotProgressUpdate (float progressValue); @@ -1000,7 +999,6 @@ private slots: FirmwarePlugin* _firmwarePlugin = nullptr; QObject* _firmwarePluginInstanceData = nullptr; AutoPilotPlugin* _autopilotPlugin = nullptr; - MAVLinkProtocol* _mavlink = nullptr; bool _soloFirmware = false; QGCToolbox* _toolbox = nullptr; SettingsManager* _settingsManager = nullptr; @@ -1040,8 +1038,8 @@ private slots: int _telemetryLNoise = 0; int _telemetryRNoise = 0; bool _mavlinkProtocolRequestComplete = false; - unsigned _mavlinkProtocolRequestMaxProtoVersion = 0; - unsigned _maxProtoVersion = 0; + uint8_t _mavlinkProtocolRequestMaxProtoVersion = 0; + uint8_t _maxProtoVersion = 0; bool _capabilityBitsKnown = false; uint64_t _capabilityBits = 0; CheckList _checkListState = CheckListNotSetup; diff --git a/test/AnalyzeView/MavlinkLogTest.cc b/test/AnalyzeView/MavlinkLogTest.cc index 2328e2a91290..d5291e02a58d 100644 --- a/test/AnalyzeView/MavlinkLogTest.cc +++ b/test/AnalyzeView/MavlinkLogTest.cc @@ -78,7 +78,7 @@ void MavlinkLogTest::_bootLogDetectionCancel_test(void) setExpectedFileDialog(getSaveFileName, QStringList()); // Kick the protocol to check for lost log files and wait for signals to move through - connect(this, &MavlinkLogTest::checkForLostLogFiles, qgcApp()->toolbox()->mavlinkProtocol(), &MAVLinkProtocol::checkForLostLogFiles); + connect(this, &MavlinkLogTest::checkForLostLogFiles, MAVLinkProtocol::instance(), &MAVLinkProtocol::checkForLostLogFiles); emit checkForLostLogFiles(); QTest::qWait(1000); @@ -98,7 +98,7 @@ void MavlinkLogTest::_bootLogDetectionSave_test(void) setExpectedFileDialog(getSaveFileName, QStringList(logSaveFile)); // Kick the protocol to check for lost log files and wait for signals to move through - connect(this, &MavlinkLogTest::checkForLostLogFiles, qgcApp()->toolbox()->mavlinkProtocol(), &MAVLinkProtocol::checkForLostLogFiles); + connect(this, &MavlinkLogTest::checkForLostLogFiles, MAVLinkProtocol::instance(), &MAVLinkProtocol::checkForLostLogFiles); emit checkForLostLogFiles(); QTest::qWait(1000); @@ -115,7 +115,7 @@ void MavlinkLogTest::_bootLogDetectionZeroLength_test(void) _createTempLogFile(true); // Kick the protocol to check for lost log files and wait for signals to move through - connect(this, &MavlinkLogTest::checkForLostLogFiles, qgcApp()->toolbox()->mavlinkProtocol(), &MAVLinkProtocol::checkForLostLogFiles); + connect(this, &MavlinkLogTest::checkForLostLogFiles, MAVLinkProtocol::instance(), &MAVLinkProtocol::checkForLostLogFiles); emit checkForLostLogFiles(); QTest::qWait(1000);