From 174c8148f24ad40a111c178f284f76109ec4d077 Mon Sep 17 00:00:00 2001 From: Holden Date: Sat, 9 Nov 2024 12:49:22 -0500 Subject: [PATCH] Convert MAVLinkLogManager to Singleton --- src/QGCToolbox.cc | 3 - src/QGCToolbox.h | 3 - src/QmlControls/QGroundControlQmlGlobal.cc | 3 +- src/QmlControls/QGroundControlQmlGlobal.h | 2 +- src/Vehicle/MAVLinkLogManager.cc | 1110 ++++++++++---------- src/Vehicle/MAVLinkLogManager.h | 409 ++++---- test/CMakeLists.txt | 1 + test/UnitTestList.cc | 2 + test/Vehicle/CMakeLists.txt | 4 + test/Vehicle/MAVLinkLogManagerTest.cc | 18 + test/Vehicle/MAVLinkLogManagerTest.h | 20 + 11 files changed, 813 insertions(+), 762 deletions(-) create mode 100644 test/Vehicle/MAVLinkLogManagerTest.cc create mode 100644 test/Vehicle/MAVLinkLogManagerTest.h diff --git a/src/QGCToolbox.cc b/src/QGCToolbox.cc index 24b6f26d12f..636e0d2d739 100644 --- a/src/QGCToolbox.cc +++ b/src/QGCToolbox.cc @@ -12,7 +12,6 @@ #include "MAVLinkProtocol.h" #include "MultiVehicleManager.h" #include "VideoManager.h" -#include "MAVLinkLogManager.h" #include "QGCCorePlugin.h" #include "SettingsManager.h" #include "QGCApplication.h" @@ -41,7 +40,6 @@ QGCToolbox::QGCToolbox(QGCApplication* app) _multiVehicleManager = new MultiVehicleManager (app, this); _videoManager = new VideoManager (app, this); - _mavlinkLogManager = new MAVLinkLogManager (app, this); #ifndef QGC_AIRLINK_DISABLED _airlinkManager = new AirLinkManager (app, this); #endif @@ -60,7 +58,6 @@ void QGCToolbox::setChildToolboxes(void) _mavlinkProtocol->setToolbox(this); _multiVehicleManager->setToolbox(this); _videoManager->setToolbox(this); - _mavlinkLogManager->setToolbox(this); #ifndef QGC_AIRLINK_DISABLED _airlinkManager->setToolbox(this); #endif diff --git a/src/QGCToolbox.h b/src/QGCToolbox.h index 1ba8dcc66ee..0162ccd2ddc 100644 --- a/src/QGCToolbox.h +++ b/src/QGCToolbox.h @@ -18,7 +18,6 @@ class MAVLinkProtocol; class MultiVehicleManager; class QGCApplication; class VideoManager; -class MAVLinkLogManager; class QGCCorePlugin; class SettingsManager; #ifndef QGC_AIRLINK_DISABLED @@ -39,7 +38,6 @@ class QGCToolbox : public QObject { MAVLinkProtocol* mavlinkProtocol () { return _mavlinkProtocol; } MultiVehicleManager* multiVehicleManager () { return _multiVehicleManager; } VideoManager* videoManager () { return _videoManager; } - MAVLinkLogManager* mavlinkLogManager () { return _mavlinkLogManager; } QGCCorePlugin* corePlugin () { return _corePlugin; } SettingsManager* settingsManager () { return _settingsManager; } #ifndef QGC_AIRLINK_DISABLED @@ -57,7 +55,6 @@ class QGCToolbox : public QObject { MAVLinkProtocol* _mavlinkProtocol = nullptr; MultiVehicleManager* _multiVehicleManager = nullptr; VideoManager* _videoManager = nullptr; - MAVLinkLogManager* _mavlinkLogManager = nullptr; QGCCorePlugin* _corePlugin = nullptr; SettingsManager* _settingsManager = nullptr; #ifndef QGC_AIRLINK_DISABLED diff --git a/src/QmlControls/QGroundControlQmlGlobal.cc b/src/QmlControls/QGroundControlQmlGlobal.cc index af0c7530133..841a4e07c6e 100644 --- a/src/QmlControls/QGroundControlQmlGlobal.cc +++ b/src/QmlControls/QGroundControlQmlGlobal.cc @@ -18,6 +18,7 @@ #include "QGCMapEngineManager.h" #include "ADSBVehicleManager.h" #include "MissionCommandTree.h" +#include "MAVLinkLogManager.h" #ifndef NO_SERIAL_LINK #include "GPSManager.h" #include "GPSRtk.h" @@ -39,6 +40,7 @@ QGroundControlQmlGlobal::QGroundControlQmlGlobal(QGCApplication* app, QGCToolbox , _adsbVehicleManager(ADSBVehicleManager::instance()) , _qgcPositionManager(QGCPositionManager::instance()) , _missionCommandTree(MissionCommandTree::instance()) + , _mavlinkLogManager(MAVLinkLogManager::instance()) { // We clear the parent on this object since we run into shutdown problems caused by hybrid qml app. Instead we let it leak on shutdown. // setParent(nullptr); @@ -82,7 +84,6 @@ void QGroundControlQmlGlobal::setToolbox(QGCToolbox* toolbox) _linkManager = toolbox->linkManager(); _multiVehicleManager = toolbox->multiVehicleManager(); _videoManager = toolbox->videoManager(); - _mavlinkLogManager = toolbox->mavlinkLogManager(); _corePlugin = toolbox->corePlugin(); _settingsManager = toolbox->settingsManager(); #ifndef NO_SERIAL_LINK diff --git a/src/QmlControls/QGroundControlQmlGlobal.h b/src/QmlControls/QGroundControlQmlGlobal.h index 71b9a1ef8f0..9262ef0b553 100644 --- a/src/QmlControls/QGroundControlQmlGlobal.h +++ b/src/QmlControls/QGroundControlQmlGlobal.h @@ -261,12 +261,12 @@ class QGroundControlQmlGlobal : public QGCTool ADSBVehicleManager* _adsbVehicleManager = nullptr; QGCPositionManager* _qgcPositionManager = nullptr; MissionCommandTree* _missionCommandTree = nullptr; + MAVLinkLogManager* _mavlinkLogManager = nullptr; double _flightMapInitialZoom = 17.0; LinkManager* _linkManager = nullptr; MultiVehicleManager* _multiVehicleManager = nullptr; VideoManager* _videoManager = nullptr; - MAVLinkLogManager* _mavlinkLogManager = nullptr; QGCCorePlugin* _corePlugin = nullptr; SettingsManager* _settingsManager = nullptr; #ifndef NO_SERIAL_LINK diff --git a/src/Vehicle/MAVLinkLogManager.cc b/src/Vehicle/MAVLinkLogManager.cc index c4a7ece22cd..2d12dd5c56f 100644 --- a/src/Vehicle/MAVLinkLogManager.cc +++ b/src/Vehicle/MAVLinkLogManager.cc @@ -8,299 +8,307 @@ ****************************************************************************/ #include "MAVLinkLogManager.h" +#include "MultiVehicleManager.h" #include "QGCApplication.h" +#include "QGCLoggingCategory.h" +#include "QmlObjectListModel.h" #include "SettingsManager.h" -#include "MultiVehicleManager.h" #include "Vehicle.h" -#include "QGCLoggingCategory.h" -#include -#include -#include -#include -#include +#include #include #include #include +#include +#include +#include +#include -QGC_LOGGING_CATEGORY(MAVLinkLogManagerLog, "MAVLinkLogManagerLog") +QGC_LOGGING_CATEGORY(MAVLinkLogManagerLog, "qgc.vehicle.mavlinklogmanager") -static constexpr const char* kSidecarExtension = ".uploaded"; +static constexpr const char *kSidecarExtension = ".uploaded"; -//----------------------------------------------------------------------------- -MAVLinkLogFiles::MAVLinkLogFiles(MAVLinkLogManager* manager, const QString& filePath, bool newFile) - : _manager(manager) - , _size(0) - , _selected(false) - , _uploading(false) - , _progress(0) - , _writing(false) - , _uploaded(false) +Q_APPLICATION_STATIC(MAVLinkLogManager, _mavlinkLogManagerInstance); + +MAVLinkLogFiles::MAVLinkLogFiles(MAVLinkLogManager *manager, const QString &filePath, bool newFile) + : QObject(manager) { - QFileInfo fi(filePath); + // qCDebug(MAVLinkLogManagerLog) << Q_FUNC_INFO << this; + + (void) connect(this, &MAVLinkLogFiles::selectedChanged, manager, &MAVLinkLogManager::selectedCountChanged); + + const QFileInfo fi(filePath); _name = fi.baseName(); - if(!newFile) { - _size = (quint32)fi.size(); + if (!newFile) { + _size = fi.size(); QString sideCar = filePath; - sideCar.replace(manager->logExtension(), kSidecarExtension); - QFileInfo sc(sideCar); + sideCar = sideCar.replace(manager->logExtension(), kSidecarExtension); + const QFileInfo sc(sideCar); _uploaded = sc.exists(); } } -//----------------------------------------------------------------------------- -void -MAVLinkLogFiles::setSize(quint32 size) +MAVLinkLogFiles::~MAVLinkLogFiles() { - _size = size; - emit sizeChanged(); + // qCDebug(MAVLinkLogManagerLog) << Q_FUNC_INFO << this; } -//----------------------------------------------------------------------------- -void -MAVLinkLogFiles::setSelected(bool selected) +void MAVLinkLogFiles::setSize(quint32 size) { - _selected = selected; - emit selectedChanged(); - emit _manager->selectedCountChanged(); + if (size != _size) { + _size = size; + emit sizeChanged(); + } } -//----------------------------------------------------------------------------- -void -MAVLinkLogFiles::setUploading(bool uploading) +void MAVLinkLogFiles::setSelected(bool selected) { - _uploading = uploading; - emit uploadingChanged(); + if (selected != _selected) { + _selected = selected; + emit selectedChanged(); + } +} + +void MAVLinkLogFiles::setUploading(bool uploading) +{ + if (uploading != _uploading) { + _uploading = uploading; + emit uploadingChanged(); + } } -//----------------------------------------------------------------------------- -void -MAVLinkLogFiles::setProgress(qreal progress) +void MAVLinkLogFiles::setProgress(qreal progress) { - _progress = progress; - emit progressChanged(); + if (progress != _progress) { + _progress = progress; + emit progressChanged(); + } } -//----------------------------------------------------------------------------- -void -MAVLinkLogFiles::setWriting(bool writing) +void MAVLinkLogFiles::setWriting(bool writing) { - _writing = writing; - emit writingChanged(); + if (writing != _writing) { + _writing = writing; + emit writingChanged(); + } } -//----------------------------------------------------------------------------- -void -MAVLinkLogFiles::setUploaded(bool uploaded) +void MAVLinkLogFiles::setUploaded(bool uploaded) { - _uploaded = uploaded; - emit uploadedChanged(); + if (uploaded != _uploaded) { + _uploaded = uploaded; + emit uploadedChanged(); + } } -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- +/*===========================================================================*/ + MAVLinkLogProcessor::MAVLinkLogProcessor() - : _fd(nullptr) - , _written(0) - , _sequence(-1) - , _numDrops(0) - , _gotHeader(false) - , _error(false) - , _record(nullptr) { + // qCDebug(MAVLinkLogManagerLog) << Q_FUNC_INFO << this; } -//----------------------------------------------------------------------------- MAVLinkLogProcessor::~MAVLinkLogProcessor() { close(); + + // qCDebug(MAVLinkLogManagerLog) << Q_FUNC_INFO << this; } -//----------------------------------------------------------------------------- -void -MAVLinkLogProcessor::close() +void MAVLinkLogProcessor::close() { - if(_fd) { - fclose(_fd); - _fd = nullptr; + if (_file.isOpen()) { + _file.close(); } } -//----------------------------------------------------------------------------- -bool -MAVLinkLogProcessor::valid() +bool MAVLinkLogProcessor::create(MAVLinkLogManager *manager, QStringView path, uint8_t id) { - return (_fd != nullptr) && (_record != nullptr); -} + _fileName = _fileName.asprintf( + "%s/%03d-%s%s", + path.toLatin1().constData(), + id, + QDateTime::currentDateTime().toString("yyyy-MM-dd-hh-mm-ss-zzz").toLocal8Bit().constData(), + manager->logExtension().toLocal8Bit().constData() + ); -//----------------------------------------------------------------------------- -bool -MAVLinkLogProcessor::create(MAVLinkLogManager* manager, const QString path, uint8_t id) -{ - _fileName = _fileName.asprintf("%s/%03d-%s%s", - path.toLatin1().data(), - id, - QDateTime::currentDateTime().toString("yyyy-MM-dd-hh-mm-ss-zzz").toLocal8Bit().data(), - manager->logExtension().toLocal8Bit().data()); - _fd = fopen(_fileName.toLocal8Bit().data(), "wb"); - if(_fd) { - _record = new MAVLinkLogFiles(manager, _fileName, true); - _record->setWriting(true); - _sequence = -1; - return true; + _file.setFileName(_fileName); + if (!_file.open(QIODevice::WriteOnly)) { + qCWarning(MAVLinkLogManagerLog) << "Failed to open file for writing:" << _file.errorString(); + return false; } - return false; + + _record = new MAVLinkLogFiles(manager, _fileName, true); + _record->setWriting(true); + _sequence = -1; + + return true; } -//----------------------------------------------------------------------------- -bool -MAVLinkLogProcessor::_checkSequence(uint16_t seq, int& num_drops) +bool MAVLinkLogProcessor::_checkSequence(uint16_t seq, int &num_drops) { num_drops = 0; //-- Check if a sequence is newer than the one previously received and if // there were dropped messages between the last one and this. - if(_sequence == -1) { + if (_sequence == -1) { _sequence = seq; return true; } - if((uint16_t)_sequence == seq) { + + if (static_cast(_sequence) == seq) { return false; } - if(seq > (uint16_t)_sequence) { + + if (seq > static_cast(_sequence)) { // Account for wrap-arounds, sequence is 2 bytes - if((seq - _sequence) > (1 << 15)) { // Assume reordered + if ((seq - _sequence) > kSequenceSize) { // Assume reordered return false; } + num_drops = seq - _sequence - 1; _numDrops += num_drops; _sequence = seq; return true; - } else { - if((_sequence - seq) > (1 << 15)) { - num_drops = (1 << 16) - _sequence - 1 + seq; - _numDrops += num_drops; - _sequence = seq; - return true; - } - return false; } + + if ((_sequence - seq) > kSequenceSize) { + num_drops = (1 << 16) - _sequence - 1 + seq; + _numDrops += num_drops; + _sequence = seq; + return true; + } + + return false; } -//----------------------------------------------------------------------------- -void -MAVLinkLogProcessor::_writeData(void* data, int len) +void MAVLinkLogProcessor::_writeData(const void *data, int len) { - if(!_error) { - _error = fwrite(data, 1, len, _fd) != (size_t)len; - if(!_error) { - _written += len; - if(_record) { - _record->setSize(_written); - } - } else { - qCDebug(MAVLinkLogManagerLog) << "File IO error:" << len << "bytes into" << _fileName; - } + if (_error) { + return; + } + + const qint64 bytesWritten = _file.write(reinterpret_cast(data), len); + if (bytesWritten != len) { + _error = true; + qCDebug(MAVLinkLogManagerLog) << "File IO error:" << len << "bytes into" << _fileName; + return; + } + + _written += len; + if (_record) { + _record->setSize(_written); } } -//----------------------------------------------------------------------------- -QByteArray -MAVLinkLogProcessor::_writeUlogMessage(QByteArray& data) +QByteArray MAVLinkLogProcessor::_writeUlogMessage(QByteArray &data) { - //-- Write ulog data w/o integrity checking, assuming data starts with a - // valid ulog message. returns the remaining data at the end. - while(data.length() > 2) { - uint8_t* ptr = (uint8_t*)data.data(); - int message_length = ptr[0] + (ptr[1] * 256) + 3; // 3 = ULog msg header - if(message_length > data.length()) + // Write ulog data w/o integrity checking, assuming data starts with a + // valid ulog message. returns the remaining data at the end. + while (data.length() > 2) { + const uint8_t *const ptr = reinterpret_cast(data.constData()); + const int message_length = ptr[0] + (ptr[1] * 256) + kUlogMessageHeader; + if (message_length > data.length()) { break; - _writeData(data.data(), message_length); - data.remove(0, message_length); + } + + _writeData(data.constData(), message_length); + (void) data.remove(0, message_length); } + return data; } -//----------------------------------------------------------------------------- -bool -MAVLinkLogProcessor::processStreamData(uint16_t sequence, uint8_t first_message, QByteArray data) +bool MAVLinkLogProcessor::processStreamData(uint16_t sequence, uint8_t first_message, const QByteArray &in) { int num_drops = 0; _error = false; - while(_checkSequence(sequence, num_drops)) { - //-- The first 16 bytes need special treatment (this sounds awfully brittle) - if(!_gotHeader) { - if(data.size() < 16) { - //-- Shouldn't happen but if it does, we might as well close shop. + + QByteArray data(in); + while (_checkSequence(sequence, num_drops)) { + if (!_gotHeader) { + if (data.size() < 16) { qCWarning(MAVLinkLogManagerLog) << "Corrupt log header. Canceling log download."; return false; } - //-- Write header - _writeData(data.data(), 16); - data.remove(0, 16); + + _writeData(data.constData(), 16); + (void) data.remove(0, 16); _gotHeader = true; // What about data start offset now that we removed 16 bytes off the start? } - if(_gotHeader && num_drops > 0) { - if(num_drops > 25) num_drops = 25; - //-- Hocus Pocus - // Write a dropout message. We don't really know the actual duration, - // so just use the number of drops * 10 ms - uint8_t bogus[] = {2, 0, 79, 0, 0}; - bogus[3] = num_drops * 10; + + if (_gotHeader && (num_drops > 0)) { + if (num_drops > 25) { + num_drops = 25; + } + + // Write a dropout message. We don't really know the actual duration, + // so just use the number of drops * 10 ms + const uint8_t duration = static_cast(num_drops) * 10; + const uint8_t bogus[] = {2, 0, 79, duration, 0}; _writeData(bogus, sizeof(bogus)); } - if(num_drops > 0) { - _writeUlogMessage(_ulogMessage); + + if (num_drops > 0) { + (void) _writeUlogMessage(_ulogMessage); _ulogMessage.clear(); - //-- If no useful information in this message. Drop it. - if(first_message == 255) { + + if (first_message == 255) { break; } - if(first_message > 0) { - data.remove(0, first_message); + + if (first_message > 0) { + (void) data.remove(0, first_message); first_message = 0; } } - if(first_message == 255 && _ulogMessage.length() > 0) { - _ulogMessage.append(data); + + if ((first_message == 255) && (!_ulogMessage.isEmpty())) { + (void) _ulogMessage.append(data); break; } - if(_ulogMessage.length()) { - _writeData(_ulogMessage.data(), _ulogMessage.length()); - if(first_message) { - _writeData(data.left(first_message).data(), first_message); + + if (_ulogMessage.length()) { + _writeData(_ulogMessage.constData(), _ulogMessage.length()); + if (first_message) { + _writeData(data.left(first_message).constData(), first_message); } _ulogMessage.clear(); } - if(first_message) { - data.remove(0, first_message); + + if (first_message) { + (void) data.remove(0, first_message); } + _ulogMessage = _writeUlogMessage(data); break; } + return !_error; } -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -MAVLinkLogManager::MAVLinkLogManager(QGCApplication* app, QGCToolbox* toolbox) - : QGCTool(app, toolbox) - , _enableAutoUpload(true) - , _enableAutoStart(false) - , _nam(nullptr) - , _currentLogfile(nullptr) - , _vehicle(nullptr) - , _logRunning(false) - , _loggingDisabled(false) - , _logProcessor(nullptr) - , _deleteAfterUpload(false) - , _windSpeed(-1) - , _publicLog(false) - , _logginDenied(false) -{ - //-- Get saved settings +/*===========================================================================*/ + +MAVLinkLogManager::MAVLinkLogManager(QObject *parent) + : QObject(parent) + , _networkManager(new QNetworkAccessManager(this)) + , _logFiles(new QmlObjectListModel(this)) + , _ulogExtension(QStringLiteral(".") + qgcApp()->toolbox()->settingsManager()->appSettings()->logFileExtension) + , _logPath(qgcApp()->toolbox()->settingsManager()->appSettings()->logSavePath()) +{ + // qCDebug(MAVLinkLogManagerLog) << Q_FUNC_INFO << this; + + (void) qmlRegisterUncreatableType("QGroundControl.MAVLinkLogManager", 1, 0, "MAVLinkLogManager", "Reference only"); + +#if !defined(Q_OS_IOS) && !defined(Q_OS_ANDROID) + QNetworkProxy tProxy = _networkManager->proxy(); + tProxy.setType(QNetworkProxy::DefaultProxy); + _networkManager->setProxy(tProxy); +#endif + QSettings settings; settings.beginGroup(kMAVLinkLogGroup); + setEmailAddress(settings.value(kEmailAddressKey, QString()).toString()); setDescription(settings.value(kDescriptionsKey, QString(kDefaultDescr)).toString()); setUploadURL(settings.value(kPx4URLKey, QString(kDefaultPx4URL)).toString()); @@ -311,393 +319,382 @@ MAVLinkLogManager::MAVLinkLogManager(QGCApplication* app, QGCToolbox* toolbox) setWindSpeed(settings.value(kWindSpeedKey, -1).toInt()); setRating(settings.value(kRateKey, "notset").toString()); setPublicLog(settings.value(kPublicLogKey, true).toBool()); -} -//----------------------------------------------------------------------------- -MAVLinkLogManager::~MAVLinkLogManager() -{ - _logFiles.clear(); -} + settings.endGroup(); -//----------------------------------------------------------------------------- -void -MAVLinkLogManager::setToolbox(QGCToolbox* toolbox) -{ - QGCTool::setToolbox(toolbox); - QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership); - qmlRegisterUncreatableType("QGroundControl.MAVLinkLogManager", 1, 0, "MAVLinkLogManager", "Reference only"); - //-- Logging location - _ulogExtension = "."; - _ulogExtension += qgcApp()->toolbox()->settingsManager()->appSettings()->logFileExtension; - _logPath = qgcApp()->toolbox()->settingsManager()->appSettings()->logSavePath(); - if(!QDir(_logPath).exists()) { - if(!QDir().mkpath(_logPath)) { + if (!QDir(_logPath).exists()) { + if (!QDir().mkpath(_logPath)) { qCWarning(MAVLinkLogManagerLog) << "Could not create MAVLink log download path:" << _logPath; _loggingDisabled = true; } } - if(!_loggingDisabled) { - //-- Load current list of logs - QString filter = "*"; - filter += _ulogExtension; + + if (!_loggingDisabled) { + const QString filter = "*" + _ulogExtension; QDirIterator it(_logPath, QStringList() << filter, QDir::Files); - while(it.hasNext()) { + while (it.hasNext()) { _insertNewLog(new MAVLinkLogFiles(this, it.next())); } + qCDebug(MAVLinkLogManagerLog) << "MAVLink logs directory:" << _logPath; - connect(toolbox->multiVehicleManager(), &MultiVehicleManager::activeVehicleChanged, this, &MAVLinkLogManager::_activeVehicleChanged); + (void) connect(qgcApp()->toolbox()->multiVehicleManager(), &MultiVehicleManager::activeVehicleChanged, this, &MAVLinkLogManager::_activeVehicleChanged); } } -//----------------------------------------------------------------------------- -void -MAVLinkLogManager::setEmailAddress(QString email) +MAVLinkLogManager::~MAVLinkLogManager() { - _emailAddress = email; - QSettings settings; - settings.beginGroup(kMAVLinkLogGroup); - settings.setValue(kEmailAddressKey, email); - emit emailAddressChanged(); + // qCDebug(MAVLinkLogManagerLog) << Q_FUNC_INFO << this; + + _logFiles->clearAndDeleteContents(); } -//----------------------------------------------------------------------------- -void -MAVLinkLogManager::setDescription(QString description) +MAVLinkLogManager *MAVLinkLogManager::instance() { - _description = description; - QSettings settings; - settings.beginGroup(kMAVLinkLogGroup); - settings.setValue(kDescriptionsKey, description); - emit descriptionChanged(); + return _mavlinkLogManagerInstance(); } -//----------------------------------------------------------------------------- -void -MAVLinkLogManager::setUploadURL(QString url) +void MAVLinkLogManager::setEmailAddress(const QString &email) { - _uploadURL = url; - if(_uploadURL.isEmpty()) { - _uploadURL = kDefaultPx4URL; + if (email != _emailAddress) { + _emailAddress = email; + QSettings settings; + settings.beginGroup(kMAVLinkLogGroup); + settings.setValue(kEmailAddressKey, email); + emit emailAddressChanged(); } - QSettings settings; - settings.beginGroup(kMAVLinkLogGroup); - settings.setValue(kPx4URLKey, _uploadURL); - emit uploadURLChanged(); } -//----------------------------------------------------------------------------- -void -MAVLinkLogManager::setFeedback(QString fb) +void MAVLinkLogManager::setDescription(const QString &description) { - _feedback = fb; - emit feedbackChanged(); + if (description != _description) { + _description = description; + QSettings settings; + settings.beginGroup(kMAVLinkLogGroup); + settings.setValue(kDescriptionsKey, description); + emit descriptionChanged(); + } } -//----------------------------------------------------------------------------- -void -MAVLinkLogManager::setVideoURL(QString url) +void MAVLinkLogManager::setUploadURL(const QString &url) { - _videoURL = url; - QSettings settings; - settings.beginGroup(kMAVLinkLogGroup); - settings.setValue(kVideoURLKey, url); - emit videoURLChanged(); + if (url != _uploadURL) { + _uploadURL = url; + if (_uploadURL.isEmpty()) { + _uploadURL = kDefaultPx4URL; + } + + QSettings settings; + settings.beginGroup(kMAVLinkLogGroup); + settings.setValue(kPx4URLKey, _uploadURL); + emit uploadURLChanged(); + } } -//----------------------------------------------------------------------------- -void -MAVLinkLogManager::setEnableAutoUpload(bool enable) +void MAVLinkLogManager::setFeedback(const QString &fb) { - _enableAutoUpload = enable; - QSettings settings; - settings.beginGroup(kMAVLinkLogGroup); - settings.setValue(kEnableAutoUploadKey, enable); - emit enableAutoUploadChanged(); + if (fb != _feedback) { + _feedback = fb; + emit feedbackChanged(); + } } -//----------------------------------------------------------------------------- -void -MAVLinkLogManager::setEnableAutoStart(bool enable) +void MAVLinkLogManager::setVideoURL(const QString &url) { - _enableAutoStart = enable; - QSettings settings; - settings.beginGroup(kMAVLinkLogGroup); - settings.setValue(kEnableAutoStartKey, enable); - emit enableAutoStartChanged(); + if (url != _videoURL) { + _videoURL = url; + QSettings settings; + settings.beginGroup(kMAVLinkLogGroup); + settings.setValue(kVideoURLKey, url); + emit videoURLChanged(); + } } -//----------------------------------------------------------------------------- -void -MAVLinkLogManager::setDeleteAfterUpload(bool enable) +void MAVLinkLogManager::setEnableAutoUpload(bool enable) { - _deleteAfterUpload = enable; - QSettings settings; - settings.beginGroup(kMAVLinkLogGroup); - settings.setValue(kEnableDeletetKey, enable); - emit deleteAfterUploadChanged(); + if (enable != _enableAutoUpload) { + _enableAutoUpload = enable; + QSettings settings; + settings.beginGroup(kMAVLinkLogGroup); + settings.setValue(kEnableAutoUploadKey, enable); + emit enableAutoUploadChanged(); + } } -//----------------------------------------------------------------------------- -void -MAVLinkLogManager::setWindSpeed(int speed) +void MAVLinkLogManager::setEnableAutoStart(bool enable) { - _windSpeed = speed; - QSettings settings; - settings.beginGroup(kMAVLinkLogGroup); - settings.setValue(kWindSpeedKey, speed); - emit windSpeedChanged(); + if (enable != _enableAutoStart) { + _enableAutoStart = enable; + QSettings settings; + settings.beginGroup(kMAVLinkLogGroup); + settings.setValue(kEnableAutoStartKey, enable); + emit enableAutoStartChanged(); + } } -//----------------------------------------------------------------------------- -void -MAVLinkLogManager::setRating(QString rate) +void MAVLinkLogManager::setDeleteAfterUpload(bool enable) { - _rating = rate; - QSettings settings; - settings.beginGroup(kMAVLinkLogGroup); - settings.setValue(kRateKey, rate); - emit ratingChanged(); + if (enable != _deleteAfterUpload) { + _deleteAfterUpload = enable; + QSettings settings; + settings.beginGroup(kMAVLinkLogGroup); + settings.setValue(kEnableDeletetKey, enable); + emit deleteAfterUploadChanged(); + } } -//----------------------------------------------------------------------------- -void -MAVLinkLogManager::setPublicLog(bool pub) +void MAVLinkLogManager::setWindSpeed(int speed) { - _publicLog = pub; - QSettings settings; - settings.beginGroup(kMAVLinkLogGroup); - settings.setValue(kPublicLogKey, pub); - emit publicLogChanged(); + if (speed != _windSpeed) { + _windSpeed = speed; + QSettings settings; + settings.beginGroup(kMAVLinkLogGroup); + settings.setValue(kWindSpeedKey, speed); + emit windSpeedChanged(); + } +} + +void MAVLinkLogManager::setRating(const QString &rate) +{ + if (rate != _rating) { + _rating = rate; + QSettings settings; + settings.beginGroup(kMAVLinkLogGroup); + settings.setValue(kRateKey, rate); + emit ratingChanged(); + } } -//----------------------------------------------------------------------------- -bool -MAVLinkLogManager::uploading() +void MAVLinkLogManager::setPublicLog(bool pub) { - return _currentLogfile != nullptr; + if (pub != _publicLog) { + _publicLog = pub; + QSettings settings; + settings.beginGroup(kMAVLinkLogGroup); + settings.setValue(kPublicLogKey, pub); + emit publicLogChanged(); + } } -//----------------------------------------------------------------------------- -void -MAVLinkLogManager::uploadLog() +void MAVLinkLogManager::uploadLog() { - if(_currentLogfile) { + if (_currentLogfile) { _currentLogfile->setUploading(false); } - for(int i = 0; i < _logFiles.count(); i++) { - _currentLogfile = qobject_cast(_logFiles.get(i)); - if (_currentLogfile) { - if(_currentLogfile->selected()) { - _currentLogfile->setSelected(false); - if(!_currentLogfile->uploaded() && !_emailAddress.isEmpty() && !_uploadURL.isEmpty()) { - _currentLogfile->setUploading(true); - _currentLogfile->setProgress(0.0); - QString filePath = _makeFilename(_currentLogfile->name()); - _sendLog(filePath); - emit uploadingChanged(); - return; - } - } - } else { - qWarning() << "Internal error"; + + for (int i = 0; i < _logFiles->count(); i++) { + _currentLogfile = qobject_cast(_logFiles->get(i)); + if (!_currentLogfile) { + qCWarning(MAVLinkLogManagerLog) << "Internal error"; + continue; + } + + if (!_currentLogfile->selected()) { + continue; + + } + + _currentLogfile->setSelected(false); + if (_currentLogfile->uploaded() || _emailAddress.isEmpty() || _uploadURL.isEmpty()) { + continue; } + + _currentLogfile->setUploading(true); + _currentLogfile->setProgress(0.0); + const QString filePath = _makeFilename(_currentLogfile->name()); + (void) _sendLog(filePath); + emit uploadingChanged(); + return; } + _currentLogfile = nullptr; emit uploadingChanged(); } -//----------------------------------------------------------------------------- -void -MAVLinkLogManager::_insertNewLog(MAVLinkLogFiles* newLog) +void MAVLinkLogManager::_insertNewLog(MAVLinkLogFiles *newLog) { - //-- Simpler than trying to sort this thing - int count = _logFiles.count(); - if(!count) { - _logFiles.append(newLog); - } else { - for(int i = 0; i < count; i++) { - MAVLinkLogFiles* f = qobject_cast(_logFiles.get(i)); - if(newLog->name() < f->name()) { - _logFiles.insert(i, newLog); - return; - } + const int count = _logFiles->count(); + if (!count) { + _logFiles->append(newLog); + return; + } + + for (int i = 0; i < count; i++) { + const MAVLinkLogFiles *const f = qobject_cast(_logFiles->get(i)); + if (newLog->name() < f->name()) { + (void) _logFiles->insert(i, newLog); + return; } - _logFiles.append(newLog); } + + _logFiles->append(newLog); } -//----------------------------------------------------------------------------- -int -MAVLinkLogManager::_getFirstSelected() +int MAVLinkLogManager::_getFirstSelected() const { - for(int i = 0; i < _logFiles.count(); i++) { - MAVLinkLogFiles* f = qobject_cast(_logFiles.get(i)); - if (f) { - if(f->selected()) { - return i; - } - } else { - qWarning() << "Internal error"; + for (int i = 0; i < _logFiles->count(); i++) { + const MAVLinkLogFiles *const f = qobject_cast(_logFiles->get(i)); + if (!f) { + qCWarning(MAVLinkLogManagerLog) << "Internal error"; + continue; + } + + if (f->selected()) { + return i; } } + return -1; } -//----------------------------------------------------------------------------- -void -MAVLinkLogManager::deleteLog() +void MAVLinkLogManager::deleteLog() { while (true) { - int idx = _getFirstSelected(); - if(idx < 0) { + const int idx = _getFirstSelected(); + if (idx < 0) { break; } - MAVLinkLogFiles* log = qobject_cast(_logFiles.get(idx)); + + MAVLinkLogFiles *const log = qobject_cast(_logFiles->get(idx)); _deleteLog(log); } } -//----------------------------------------------------------------------------- -void -MAVLinkLogManager::_deleteLog(MAVLinkLogFiles* log) +void MAVLinkLogManager::_deleteLog(MAVLinkLogFiles *log) { QString filePath = _makeFilename(log->name()); QFile gone(filePath); - if(!gone.remove()) { + if (!gone.remove()) { qCWarning(MAVLinkLogManagerLog) << "Could not delete MAVLink log file:" << _logPath; } - //-- Remove sidecar file (if any) + filePath.replace(_ulogExtension, kSidecarExtension); QFile sgone(filePath); - if(sgone.exists()) { - sgone.remove(); + if (sgone.exists()) { + (void) sgone.remove(); } - //-- Remove file from list and delete record - _logFiles.removeOne(log); + + (void) _logFiles->removeOne(log); delete log; + emit logFilesChanged(); } -//----------------------------------------------------------------------------- -void -MAVLinkLogManager::cancelUpload() +void MAVLinkLogManager::cancelUpload() { - for(int i = 0; i < _logFiles.count(); i++) { - MAVLinkLogFiles* pLogFile = qobject_cast(_logFiles.get(i)); - if (pLogFile) { - if(pLogFile->selected() && pLogFile != _currentLogfile) { - pLogFile->setSelected(false); - } - } else { - qWarning() << "Internal error"; + for (int i = 0; i < _logFiles->count(); i++) { + MAVLinkLogFiles *const pLogFile = qobject_cast(_logFiles->get(i)); + if (!pLogFile) { + qCWarning(MAVLinkLogManagerLog) << "Internal error"; + continue; + } + + if (pLogFile->selected() && (pLogFile != _currentLogfile)) { + pLogFile->setSelected(false); } } - if(_currentLogfile) { + + if (_currentLogfile) { emit abortUpload(); } } -//----------------------------------------------------------------------------- -void -MAVLinkLogManager::startLogging() +void MAVLinkLogManager::startLogging() { - //-- If we are allowed to persist data - AppSettings* appSettings = qgcApp()->toolbox()->settingsManager()->appSettings(); - if(!appSettings->disableAllPersistence()->rawValue().toBool()) { - if(_vehicle && _vehicle->px4Firmware() && !_logginDenied) { - if(_createNewLog()) { - _vehicle->startMavlinkLog(); - _logRunning = true; - emit logRunningChanged(); - } - } + AppSettings *const appSettings = qgcApp()->toolbox()->settingsManager()->appSettings(); + if (appSettings->disableAllPersistence()->rawValue().toBool()) { + return; + } + + if (!_vehicle || !_vehicle->px4Firmware() || _loggingDenied) { + return; + } + + if (!_createNewLog()) { + return; } + + _vehicle->startMavlinkLog(); + _logRunning = true; + emit logRunningChanged(); } -//----------------------------------------------------------------------------- -void -MAVLinkLogManager::stopLogging() +void MAVLinkLogManager::stopLogging() { - if(_vehicle && _vehicle->px4Firmware()) { - //-- Tell vehicle to stop sending logs + if (_vehicle && _vehicle->px4Firmware()) { _vehicle->stopMavlinkLog(); } - if(_logProcessor) { - _logProcessor->close(); - if(_logProcessor->record()) { - _logProcessor->record()->setWriting(false); - if(_enableAutoUpload) { - //-- Queue log for auto upload (set selected flag) - _logProcessor->record()->setSelected(true); - if(!uploading()) { - uploadLog(); - } + + if (!_logProcessor) { + return; + } + + _logProcessor->close(); + if (_logProcessor->record()) { + _logProcessor->record()->setWriting(false); + if (_enableAutoUpload) { + _logProcessor->record()->setSelected(true); + if (!uploading()) { + uploadLog(); } } - delete _logProcessor; - _logProcessor = nullptr; - _logRunning = false; - emit logRunningChanged(); } + + delete _logProcessor; + _logProcessor = nullptr; + _logRunning = false; + emit logRunningChanged(); } -//----------------------------------------------------------------------------- -QHttpPart -create_form_part(const QString& name, const QString& value) +QHttpPart MAVLinkLogManager::_createFormPart(QStringView name, QStringView value) { QHttpPart formPart; - formPart.setHeader(QNetworkRequest::ContentDispositionHeader, QString("form-data; name=\"%1\"").arg(name)); + formPart.setHeader(QNetworkRequest::ContentDispositionHeader, QStringLiteral("form-data; name=\"%1\"").arg(name)); formPart.setBody(value.toUtf8()); return formPart; } -//----------------------------------------------------------------------------- -bool -MAVLinkLogManager::_sendLog(const QString& logFile) +bool MAVLinkLogManager::_sendLog(const QString &logFile) { QString defaultDescription = _description; - if(_description.isEmpty()) { + if (_description.isEmpty()) { qCWarning(MAVLinkLogManagerLog) << "Log description missing. Using defaults."; defaultDescription = kDefaultDescr; } - if(_emailAddress.isEmpty()) { + + if (_emailAddress.isEmpty()) { qCWarning(MAVLinkLogManagerLog) << "User email missing."; return false; } - if(_uploadURL.isEmpty()) { + + if (_uploadURL.isEmpty()) { qCWarning(MAVLinkLogManagerLog) << "Upload URL missing."; return false; } - QFileInfo fi(logFile); - if(!fi.exists()) { + + const QFileInfo fi(logFile); + if (!fi.exists()) { qCWarning(MAVLinkLogManagerLog) << "Log file missing:" << logFile; return false; } - QFile* file = new QFile(logFile); - if(!file || !file->open(QIODevice::ReadOnly)) { + + QFile *file = new QFile(logFile, this); + if (!file || !file->open(QIODevice::ReadOnly)) { delete file; file = nullptr; qCWarning(MAVLinkLogManagerLog) << "Could not open log file:" << logFile; return false; } - if(!_nam) { - _nam = new QNetworkAccessManager(this); - } - QNetworkProxy savedProxy = _nam->proxy(); - QNetworkProxy tempProxy; - tempProxy.setType(QNetworkProxy::DefaultProxy); - _nam->setProxy(tempProxy); - //-- Build POST request - QHttpMultiPart* multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType); - QHttpPart emailPart = create_form_part("email", _emailAddress); - QHttpPart descriptionPart = create_form_part("description", _description); - QHttpPart sourcePart = create_form_part("source", "QGroundControl"); - QHttpPart versionPart = create_form_part("version", _app->applicationVersion()); - QHttpPart typePart = create_form_part("type", "flightreport"); - QHttpPart windPart = create_form_part("windSpeed", QString::number(_windSpeed)); - QHttpPart ratingPart = create_form_part("rating", _rating); - QHttpPart publicPart = create_form_part("public", _publicLog ? "true" : "false"); - //-- Assemble request and POST it + + QHttpMultiPart *const multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType); + const QHttpPart emailPart = _createFormPart(u"email", _emailAddress); + const QHttpPart descriptionPart = _createFormPart(u"description", _description); + const QHttpPart sourcePart = _createFormPart(u"source", u"QGroundControl"); + const QHttpPart versionPart = _createFormPart(u"version", QCoreApplication::applicationVersion()); + const QHttpPart typePart = _createFormPart(u"type", u"flightreport"); + const QHttpPart windPart = _createFormPart(u"windSpeed", QString::number(_windSpeed)); + const QHttpPart ratingPart = _createFormPart(u"rating", _rating); + const QHttpPart publicPart = _createFormPart(u"public", _publicLog ? u"true" : u"false"); + multiPart->append(emailPart); multiPart->append(descriptionPart); multiPart->append(sourcePart); @@ -706,117 +703,115 @@ MAVLinkLogManager::_sendLog(const QString& logFile) multiPart->append(windPart); multiPart->append(ratingPart); multiPart->append(publicPart); - //-- Optional + QHttpPart feedbackPart; - if(_feedback.isEmpty()) { - feedbackPart = create_form_part(kFeedback, "None Given"); + if (_feedback.isEmpty()) { + feedbackPart = _createFormPart(QString(kFeedback), u"None Given"); } else { - feedbackPart = create_form_part(kFeedback, _feedback); + feedbackPart = _createFormPart(QString(kFeedback), _feedback); } multiPart->append(feedbackPart); + QHttpPart videoPart; if(_videoURL.isEmpty()) { - videoPart = create_form_part(kVideoURL, "None"); + videoPart = _createFormPart(QString(kVideoURL), u"None"); } else { - videoPart = create_form_part(kVideoURL, _videoURL); + videoPart = _createFormPart(QString(kVideoURL), _videoURL); } multiPart->append(videoPart); - //-- Actual Log File + QHttpPart logPart; logPart.setHeader(QNetworkRequest::ContentTypeHeader, "application/octet-stream"); - logPart.setHeader(QNetworkRequest::ContentDispositionHeader, QString("form-data; name=\"filearg\"; filename=\"%1\"").arg(fi.fileName())); + logPart.setHeader(QNetworkRequest::ContentDispositionHeader, QStringLiteral("form-data; name=\"filearg\"; filename=\"%1\"").arg(fi.fileName())); logPart.setBodyDevice(file); multiPart->append(logPart); file->setParent(multiPart); + QNetworkRequest request(_uploadURL); request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, true); - QNetworkReply* reply = _nam->post(request, multiPart); - connect(reply, &QNetworkReply::finished, this, &MAVLinkLogManager::_uploadFinished); - connect(this, &MAVLinkLogManager::abortUpload, reply, &QNetworkReply::abort); - //connect(reply, &QNetworkReply::readyRead, this, &MAVLinkLogManager::_dataAvailable); - connect(reply, &QNetworkReply::uploadProgress, this, &MAVLinkLogManager::_uploadProgress); + QNetworkReply *const reply = _networkManager->post(request, multiPart); + (void) connect(this, &MAVLinkLogManager::abortUpload, reply, &QNetworkReply::abort); + (void) connect(reply, &QNetworkReply::finished, this, &MAVLinkLogManager::_uploadFinished); + (void) connect(reply, &QNetworkReply::uploadProgress, this, &MAVLinkLogManager::_uploadProgress); + if (MAVLinkLogManagerLog().isDebugEnabled()) { + (void) connect(reply, &QNetworkReply::readyRead, this, &MAVLinkLogManager::_dataAvailable); + } + multiPart->setParent(reply); qCDebug(MAVLinkLogManagerLog) << "Log" << fi.baseName() << "Uploading." << fi.size() << "bytes."; - _nam->setProxy(savedProxy); + return true; } -//----------------------------------------------------------------------------- -bool -MAVLinkLogManager::_processUploadResponse(int http_code, QByteArray& data) +bool MAVLinkLogManager::_processUploadResponse(int http_code, const QByteArray &data) { qCDebug(MAVLinkLogManagerLog) << "Uploaded response:" << QString::fromUtf8(data); emit readyRead(data); - return http_code == 200; + + return (http_code == 200); } -//----------------------------------------------------------------------------- -void -MAVLinkLogManager::_dataAvailable() +void MAVLinkLogManager::_dataAvailable() { - QNetworkReply* reply = qobject_cast(sender()); - if(!reply) { + QNetworkReply *const reply = qobject_cast(sender()); + if (!reply) { return; } - QByteArray data = reply->readAll(); + + const QByteArray data = reply->readAll(); qCDebug(MAVLinkLogManagerLog) << "Uploaded response data:" << QString::fromUtf8(data); } -//----------------------------------------------------------------------------- -void -MAVLinkLogManager::_uploadFinished() +void MAVLinkLogManager::_uploadFinished() { - QNetworkReply* reply = qobject_cast(sender()); - if(!reply) { + QNetworkReply *const reply = qobject_cast(sender()); + if (!reply) { return; } + const int http_code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - QByteArray data = reply->readAll(); - if(_processUploadResponse(http_code, data)) { + const QByteArray data = reply->readAll(); + + if (_processUploadResponse(http_code, data)) { qCDebug(MAVLinkLogManagerLog) << "Log uploaded."; emit succeed(); - if(_deleteAfterUpload) { - if(_currentLogfile) { + if (_deleteAfterUpload) { + if (_currentLogfile) { _deleteLog(_currentLogfile); _currentLogfile = nullptr; } - } else { - if(_currentLogfile) { - _currentLogfile->setUploaded(true); - //-- Write side-car file to flag it as uploaded - QString sideCar = _makeFilename(_currentLogfile->name()); - sideCar.replace(_ulogExtension, kSidecarExtension); - FILE* f = fopen(sideCar.toLatin1().data(), "wb"); - if(f) { - fclose(f); - } + } else if (_currentLogfile) { + _currentLogfile->setUploaded(true); + QString sideCar = _makeFilename(_currentLogfile->name()); + (void) sideCar.replace(_ulogExtension, kSidecarExtension); + + QFile file(sideCar.toLatin1().constData()); + if (file.open(QIODevice::WriteOnly)) { + file.close(); } } } else { qCWarning(MAVLinkLogManagerLog) << QString("Log Upload Error: %1 status: %2").arg(reply->errorString(), reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toString()); emit failed(); } + reply->deleteLater(); - //-- Next (if any) uploadLog(); } -//----------------------------------------------------------------------------- -void -MAVLinkLogManager::_uploadProgress(qint64 bytesSent, qint64 bytesTotal) +void MAVLinkLogManager::_uploadProgress(qint64 bytesSent, qint64 bytesTotal) { - if(bytesTotal) { - qreal progress = static_cast(bytesSent) / static_cast(bytesTotal); - if(_currentLogfile) { + if (bytesTotal) { + const qreal progress = static_cast(bytesSent) / static_cast(bytesTotal); + if (_currentLogfile) { _currentLogfile->setProgress(progress); } } + qCDebug(MAVLinkLogManagerLog) << bytesSent << "of" << bytesTotal; } -//----------------------------------------------------------------------------- -void -MAVLinkLogManager::_activeVehicleChanged(Vehicle* vehicle) +void MAVLinkLogManager::_activeVehicleChanged(Vehicle *vehicle) { //-- TODO: This is not quite right. This is being used to detect when a vehicle // connects/disconnects. In reality, if QGC is connected to multiple vehicles, @@ -825,97 +820,94 @@ MAVLinkLogManager::_activeVehicleChanged(Vehicle* vehicle) // For now, we only handle one log download at a time. The proper way is to have // each vehicle with their own instance of this "log manager". // Disconnect the previous one (if any) - if(_vehicle && _vehicle->px4Firmware()) { - disconnect(_vehicle, &Vehicle::armedChanged, this, &MAVLinkLogManager::_armedChanged); - disconnect(_vehicle, &Vehicle::mavlinkLogData, this, &MAVLinkLogManager::_mavlinkLogData); - disconnect(_vehicle, &Vehicle::mavCommandResult, this, &MAVLinkLogManager::_mavCommandResult); + if (_vehicle && _vehicle->px4Firmware()) { + (void) disconnect(_vehicle, &Vehicle::armedChanged, this, &MAVLinkLogManager::_armedChanged); + (void) disconnect(_vehicle, &Vehicle::mavlinkLogData, this, &MAVLinkLogManager::_mavlinkLogData); + (void) disconnect(_vehicle, &Vehicle::mavCommandResult, this, &MAVLinkLogManager::_mavCommandResult); _vehicle = nullptr; - //-- Stop logging (if that's the case) stopLogging(); emit canStartLogChanged(); } - // Connect new system - if(vehicle && vehicle->px4Firmware()) { + + if (vehicle && vehicle->px4Firmware()) { _vehicle = vehicle; - //-- Reset logging denied flag as well - _logginDenied = false; - connect(_vehicle, &Vehicle::armedChanged, this, &MAVLinkLogManager::_armedChanged); - connect(_vehicle, &Vehicle::mavlinkLogData, this, &MAVLinkLogManager::_mavlinkLogData); - connect(_vehicle, &Vehicle::mavCommandResult, this, &MAVLinkLogManager::_mavCommandResult); + _loggingDenied = false; + (void) connect(_vehicle, &Vehicle::armedChanged, this, &MAVLinkLogManager::_armedChanged); + (void) connect(_vehicle, &Vehicle::mavlinkLogData, this, &MAVLinkLogManager::_mavlinkLogData); + (void) connect(_vehicle, &Vehicle::mavCommandResult, this, &MAVLinkLogManager::_mavCommandResult); emit canStartLogChanged(); } } -//----------------------------------------------------------------------------- -void -MAVLinkLogManager::_mavlinkLogData(Vehicle* /*vehicle*/, uint8_t /*target_system*/, uint8_t /*target_component*/, uint16_t sequence, uint8_t first_message, QByteArray data, bool /*acked*/) +void MAVLinkLogManager::_mavlinkLogData(Vehicle* /*vehicle*/, uint8_t /*target_system*/, uint8_t /*target_component*/, uint16_t sequence, uint8_t first_message, const QByteArray &data, bool /*acked*/) { - if(_logProcessor && _logProcessor->valid()) { - if(!_logProcessor->processStreamData(sequence, first_message, data)) { - qCWarning(MAVLinkLogManagerLog) << "Error writing MAVLink log file:" << _logProcessor->fileName(); - delete _logProcessor; - _logProcessor = nullptr; - _logRunning = false; - _vehicle->stopMavlinkLog(); - emit logRunningChanged(); - } - } else { - qCWarning(MAVLinkLogManagerLog) << "MAVLink log data received when not expected."; + if (!_logProcessor || !_logProcessor->valid()) { + qCDebug(MAVLinkLogManagerLog) << "MAVLink log data received when not expected."; + return; } + + if (_logProcessor->processStreamData(sequence, first_message, data)) { + return; + } + + qCWarning(MAVLinkLogManagerLog) << "Error writing MAVLink log file:" << _logProcessor->fileName(); + delete _logProcessor; + _logProcessor = nullptr; + _logRunning = false; + _vehicle->stopMavlinkLog(); + emit logRunningChanged(); } -//----------------------------------------------------------------------------- -void -MAVLinkLogManager::_mavCommandResult(int vehicleId, int component, int command, int result, bool noReponseFromVehicle) +void MAVLinkLogManager::_mavCommandResult(int vehicleId, int component, int command, int result, bool noReponseFromVehicle) { Q_UNUSED(vehicleId); Q_UNUSED(component); Q_UNUSED(noReponseFromVehicle) - if(command == MAV_CMD_LOGGING_START || command == MAV_CMD_LOGGING_STOP) { - //-- Did it fail? - if(result != MAV_RESULT_ACCEPTED) { - if(command == MAV_CMD_LOGGING_STOP) { - //-- Not that it could happen but... - qCWarning(MAVLinkLogManagerLog) << "Stop MAVLink log command failed."; - } else { - //-- Could not start logging for some reason. - if(result == MAV_RESULT_DENIED) { - _logginDenied = true; - qCWarning(MAVLinkLogManagerLog) << "Start MAVLink log command denied."; - } else { - qCWarning(MAVLinkLogManagerLog) << "Start MAVLink log command failed."; - } - _discardLog(); - } - } + if ((command != MAV_CMD_LOGGING_START) && (command != MAV_CMD_LOGGING_STOP)) { + return; + } + + if (result == MAV_RESULT_ACCEPTED) { + return; + } + + if (command == MAV_CMD_LOGGING_STOP) { + qCWarning(MAVLinkLogManagerLog) << "Stop MAVLink log command failed."; + return; + } + + if (result == MAV_RESULT_DENIED) { + _loggingDenied = true; + qCWarning(MAVLinkLogManagerLog) << "Start MAVLink log command denied."; + } else { + qCWarning(MAVLinkLogManagerLog) << "Start MAVLink log command failed:" << result; } + + _discardLog(); } -//----------------------------------------------------------------------------- -void -MAVLinkLogManager::_discardLog() +void MAVLinkLogManager::_discardLog() { - //-- Delete (empty) log file (and record) - if(_logProcessor) { + if (_logProcessor) { _logProcessor->close(); - if(_logProcessor->record()) { + if (_logProcessor->record()) { _deleteLog(_logProcessor->record()); } delete _logProcessor; _logProcessor = nullptr; } + _logRunning = false; emit logRunningChanged(); } -//----------------------------------------------------------------------------- -bool -MAVLinkLogManager::_createNewLog() +bool MAVLinkLogManager::_createNewLog() { delete _logProcessor; - _logProcessor = new MAVLinkLogProcessor; - if(_logProcessor->create(this, _logPath, static_cast(_vehicle->id()))) { + _logProcessor = new MAVLinkLogProcessor(); + + if (_logProcessor->create(this, _logPath, static_cast(_vehicle->id()))) { _insertNewLog(_logProcessor->record()); emit logFilesChanged(); } else { @@ -923,29 +915,29 @@ MAVLinkLogManager::_createNewLog() delete _logProcessor; _logProcessor = nullptr; } - return _logProcessor != nullptr; + + return (_logProcessor != nullptr); } -//----------------------------------------------------------------------------- -void -MAVLinkLogManager::_armedChanged(bool armed) +void MAVLinkLogManager::_armedChanged(bool armed) { - if(_vehicle && _vehicle->px4Firmware()) { - if(armed) { - if(_enableAutoStart) { - startLogging(); - } - } else { - if(_logRunning && _enableAutoStart) { - stopLogging(); - } + if (!_vehicle || !_vehicle->px4Firmware()) { + return; + } + + if (armed) { + if (_enableAutoStart) { + startLogging(); } + return; + } + + if (_logRunning && _enableAutoStart) { + stopLogging(); } } -//----------------------------------------------------------------------------- -QString -MAVLinkLogManager::_makeFilename(const QString& baseName) +QString MAVLinkLogManager::_makeFilename(const QString &baseName) const { QString filePath = _logPath; filePath += "/"; diff --git a/src/Vehicle/MAVLinkLogManager.h b/src/Vehicle/MAVLinkLogManager.h index 6f499a77392..55e83179917 100644 --- a/src/Vehicle/MAVLinkLogManager.h +++ b/src/Vehicle/MAVLinkLogManager.h @@ -10,236 +10,255 @@ #pragma once -#include "QGCToolbox.h" -#include "QmlObjectListModel.h" - -#include +#include #include +#include +#include +#include Q_DECLARE_LOGGING_CATEGORY(MAVLinkLogManagerLog) +class QmlObjectListModel; class QNetworkAccessManager; class MAVLinkLogManager; class Vehicle; -//----------------------------------------------------------------------------- class MAVLinkLogFiles : public QObject { Q_OBJECT + + Q_PROPERTY(QString name READ name CONSTANT) + Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectedChanged) + Q_PROPERTY(bool uploaded READ uploaded NOTIFY uploadedChanged) + Q_PROPERTY(bool uploading READ uploading NOTIFY uploadingChanged) + Q_PROPERTY(bool writing READ writing NOTIFY writingChanged) + Q_PROPERTY(qreal progress READ progress NOTIFY progressChanged) + Q_PROPERTY(quint32 size READ size NOTIFY sizeChanged) + public: - MAVLinkLogFiles (MAVLinkLogManager* manager, const QString& filePath, bool newFile = false); - - Q_PROPERTY(QString name READ name CONSTANT) - Q_PROPERTY(quint32 size READ size NOTIFY sizeChanged) - Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectedChanged) - Q_PROPERTY(bool uploading READ uploading NOTIFY uploadingChanged) - Q_PROPERTY(qreal progress READ progress NOTIFY progressChanged) - Q_PROPERTY(bool writing READ writing NOTIFY writingChanged) - Q_PROPERTY(bool uploaded READ uploaded NOTIFY uploadedChanged) - - QString name () { return _name; } - quint32 size () const{ return _size; } - bool selected () const{ return _selected; } - bool uploading () const{ return _uploading; } - qreal progress () const{ return _progress; } - bool writing () const{ return _writing; } - bool uploaded () const{ return _uploaded; } - - void setSelected (bool selected); - void setUploading (bool uploading); - void setProgress (qreal progress); - void setWriting (bool writing); - void setSize (quint32 size); - void setUploaded (bool uploaded); + MAVLinkLogFiles(MAVLinkLogManager *manager, const QString &filePath, bool newFile = false); + ~MAVLinkLogFiles(); + + QString name() const { return _name; } + bool selected() const { return _selected; } + bool uploaded() const { return _uploaded; } + bool uploading() const { return _uploading; } + bool writing() const { return _writing; } + qreal progress() const { return _progress; } + quint32 size() const { return _size; } + + void setProgress(qreal progress); + void setSelected(bool selected); + void setSize(quint32 size); + void setUploaded(bool uploaded); + void setUploading(bool uploading); + void setWriting(bool writing); signals: - void sizeChanged (); - void selectedChanged (); - void uploadingChanged (); - void progressChanged (); - void writingChanged (); - void uploadedChanged (); + void progressChanged(); + void selectedChanged(); + void sizeChanged(); + void uploadedChanged(); + void uploadingChanged(); + void writingChanged(); private: - MAVLinkLogManager* _manager; - QString _name; - quint32 _size; - bool _selected; - bool _uploading; - qreal _progress; - bool _writing; - bool _uploaded; + bool _selected = false; + bool _uploaded = false; + bool _uploading = false; + bool _writing = false; + qreal _progress = 0; + QString _name; + quint32 _size = 0; }; -//----------------------------------------------------------------------------- +/*===========================================================================*/ + class MAVLinkLogProcessor { public: MAVLinkLogProcessor(); ~MAVLinkLogProcessor(); - void close (); - bool valid (); - bool create (MAVLinkLogManager *manager, const QString path, uint8_t id); - MAVLinkLogFiles* record () { return _record; } - QString fileName () { return _fileName; } - bool processStreamData(uint16_t _sequence, uint8_t first_message, QByteArray data); -private: - bool _checkSequence(uint16_t seq, int &num_drops); - QByteArray _writeUlogMessage(QByteArray &data); - void _writeData(void* data, int len); + + void close(); + bool valid() const { return ((_file.exists()) && (_record != nullptr)); } + bool create(MAVLinkLogManager *manager, QStringView path, uint8_t id); + MAVLinkLogFiles *record() { return _record; } + QString fileName() const { return _fileName; } + bool processStreamData(uint16_t _sequence, uint8_t first_message, const QByteArray &in); + private: - FILE* _fd; - quint32 _written; - int _sequence; - int _numDrops; - bool _gotHeader; - bool _error; - QByteArray _ulogMessage; - QString _fileName; - MAVLinkLogFiles* _record; + bool _checkSequence(uint16_t seq, int &num_drops); + QByteArray _writeUlogMessage(QByteArray &data); + void _writeData(const void* data, int len); + + bool _error = false; + bool _gotHeader = false; + int _numDrops = 0; + int _sequence = -1; + MAVLinkLogFiles *_record = nullptr; + QByteArray _ulogMessage; + QFile _file; + QString _fileName; + quint32 _written = 0; + + static constexpr int kUlogMessageHeader = 3; + static constexpr int kSequenceSize = 1 << 15; }; -//----------------------------------------------------------------------------- -class MAVLinkLogManager : public QGCTool +/*===========================================================================*/ + + +class MAVLinkLogManager : public QObject { Q_OBJECT + QML_ELEMENT + QML_UNCREATABLE("") + // QML_SINGLETON Q_MOC_INCLUDE("QmlObjectListModel.h") + Q_PROPERTY(QString emailAddress READ emailAddress WRITE setEmailAddress NOTIFY emailAddressChanged) + Q_PROPERTY(QString description READ description WRITE setDescription NOTIFY descriptionChanged) + Q_PROPERTY(QString uploadURL READ uploadURL WRITE setUploadURL NOTIFY uploadURLChanged) + Q_PROPERTY(QString feedback READ feedback WRITE setFeedback NOTIFY feedbackChanged) + Q_PROPERTY(QString videoURL READ videoURL WRITE setVideoURL NOTIFY videoURLChanged) + Q_PROPERTY(bool enableAutoUpload READ enableAutoUpload WRITE setEnableAutoUpload NOTIFY enableAutoUploadChanged) + Q_PROPERTY(bool enableAutoStart READ enableAutoStart WRITE setEnableAutoStart NOTIFY enableAutoStartChanged) + Q_PROPERTY(bool deleteAfterUpload READ deleteAfterUpload WRITE setDeleteAfterUpload NOTIFY deleteAfterUploadChanged) + Q_PROPERTY(bool publicLog READ publicLog WRITE setPublicLog NOTIFY publicLogChanged) + Q_PROPERTY(bool uploading READ uploading NOTIFY uploadingChanged) + Q_PROPERTY(bool logRunning READ logRunning NOTIFY logRunningChanged) + Q_PROPERTY(bool canStartLog READ canStartLog NOTIFY canStartLogChanged) + Q_PROPERTY(QmlObjectListModel *logFiles READ logFiles NOTIFY logFilesChanged) + Q_PROPERTY(int windSpeed READ windSpeed WRITE setWindSpeed NOTIFY windSpeedChanged) + Q_PROPERTY(QString rating READ rating WRITE setRating NOTIFY ratingChanged) + public: - MAVLinkLogManager (QGCApplication* app, QGCToolbox* toolbox); - ~MAVLinkLogManager (); - - Q_PROPERTY(QString emailAddress READ emailAddress WRITE setEmailAddress NOTIFY emailAddressChanged) - Q_PROPERTY(QString description READ description WRITE setDescription NOTIFY descriptionChanged) - Q_PROPERTY(QString uploadURL READ uploadURL WRITE setUploadURL NOTIFY uploadURLChanged) - Q_PROPERTY(QString feedback READ feedback WRITE setFeedback NOTIFY feedbackChanged) - Q_PROPERTY(QString videoURL READ videoURL WRITE setVideoURL NOTIFY videoURLChanged) - Q_PROPERTY(bool enableAutoUpload READ enableAutoUpload WRITE setEnableAutoUpload NOTIFY enableAutoUploadChanged) - Q_PROPERTY(bool enableAutoStart READ enableAutoStart WRITE setEnableAutoStart NOTIFY enableAutoStartChanged) - Q_PROPERTY(bool deleteAfterUpload READ deleteAfterUpload WRITE setDeleteAfterUpload NOTIFY deleteAfterUploadChanged) - Q_PROPERTY(bool publicLog READ publicLog WRITE setPublicLog NOTIFY publicLogChanged) - Q_PROPERTY(bool uploading READ uploading NOTIFY uploadingChanged) - Q_PROPERTY(bool logRunning READ logRunning NOTIFY logRunningChanged) - Q_PROPERTY(bool canStartLog READ canStartLog NOTIFY canStartLogChanged) - Q_PROPERTY(QmlObjectListModel* logFiles READ logFiles NOTIFY logFilesChanged) - Q_PROPERTY(int windSpeed READ windSpeed WRITE setWindSpeed NOTIFY windSpeedChanged) - Q_PROPERTY(QString rating READ rating WRITE setRating NOTIFY ratingChanged) - - Q_INVOKABLE void uploadLog (); - Q_INVOKABLE void deleteLog (); - Q_INVOKABLE void cancelUpload (); - Q_INVOKABLE void startLogging (); - Q_INVOKABLE void stopLogging (); - - QString emailAddress () { return _emailAddress; } - QString description () { return _description; } - QString uploadURL () { return _uploadURL; } - QString feedback () { return _feedback; } - QString videoURL () { return _videoURL; } - bool enableAutoUpload () const{ return _enableAutoUpload; } - bool enableAutoStart () const{ return _enableAutoStart; } - bool uploading (); - bool logRunning () const{ return _logRunning; } - bool canStartLog () { return _vehicle != nullptr && !_logginDenied; } - bool deleteAfterUpload () const{ return _deleteAfterUpload; } - bool publicLog () const{ return _publicLog; } - int windSpeed () const{ return _windSpeed; } - QString rating () { return _rating; } - QString logExtension () { return _ulogExtension; } - - QmlObjectListModel* logFiles () { return &_logFiles; } - - void setEmailAddress (QString email); - void setDescription (QString description); - void setUploadURL (QString url); - void setFeedback (QString feedback); - void setVideoURL (QString url); - void setEnableAutoUpload (bool enable); - void setEnableAutoStart (bool enable); - void setDeleteAfterUpload(bool enable); - void setWindSpeed (int speed); - void setRating (QString rate); - void setPublicLog (bool publicLog); - - // Override from QGCTool - void setToolbox (QGCToolbox *toolbox); + /// Constructs an MAVLinkLogManager object. + /// @param parent The parent QObject. + explicit MAVLinkLogManager(QObject *parent = nullptr); + + /// Destructor for the MAVLinkLogManager class. + ~MAVLinkLogManager(); + + /// Gets the singleton instance of MAVLinkLogManager. + /// @return The singleton instance. + static MAVLinkLogManager *instance(); + + Q_INVOKABLE void cancelUpload(); + Q_INVOKABLE void deleteLog(); + Q_INVOKABLE void startLogging(); + Q_INVOKABLE void stopLogging(); + Q_INVOKABLE void uploadLog(); + + QString emailAddress() const { return _emailAddress; } + QString description() const { return _description; } + QString uploadURL() const { return _uploadURL; } + QString feedback() const { return _feedback; } + QString videoURL() const { return _videoURL; } + bool enableAutoUpload() const { return _enableAutoUpload; } + bool enableAutoStart() const { return _enableAutoStart; } + bool uploading() const { return (_currentLogfile != nullptr); } + bool logRunning() const { return _logRunning; } + bool canStartLog() const { return (_vehicle != nullptr) && !_loggingDenied; } + bool deleteAfterUpload() const { return _deleteAfterUpload; } + bool publicLog() const { return _publicLog; } + int windSpeed() const { return _windSpeed; } + QString rating() const { return _rating; } + QString logExtension() const { return _ulogExtension; } + + QmlObjectListModel *logFiles() { return _logFiles; } + + void setDeleteAfterUpload(bool enable); + void setDescription(const QString &description); + void setEmailAddress(const QString &email); + void setEnableAutoStart(bool enable); + void setEnableAutoUpload(bool enable); + void setFeedback(const QString &feedback); + void setPublicLog(bool publicLog); + void setRating(const QString &rate); + void setUploadURL(const QString &url); + void setVideoURL(const QString &url); + void setWindSpeed(int speed); signals: - void emailAddressChanged (); - void descriptionChanged (); - void uploadURLChanged (); - void feedbackChanged (); - void enableAutoUploadChanged (); - void enableAutoStartChanged (); - void logFilesChanged (); - void selectedCountChanged (); - void uploadingChanged (); - void readyRead (QByteArray data); - void failed (); - void succeed (); - void abortUpload (); - void logRunningChanged (); - void canStartLogChanged (); - void deleteAfterUploadChanged (); - void windSpeedChanged (); - void ratingChanged (); - void videoURLChanged (); - void publicLogChanged (); + void abortUpload(); + void canStartLogChanged(); + void deleteAfterUploadChanged(); + void descriptionChanged(); + void emailAddressChanged(); + void enableAutoStartChanged(); + void enableAutoUploadChanged(); + void failed(); + void feedbackChanged(); + void logFilesChanged(); + void logRunningChanged(); + void publicLogChanged(); + void ratingChanged(); + void readyRead(const QByteArray &data); + void selectedCountChanged(); + void succeed(); + void uploadingChanged(); + void uploadURLChanged(); + void videoURLChanged(); + void windSpeedChanged(); private slots: - void _uploadFinished (); - void _dataAvailable (); - void _uploadProgress (qint64 bytesSent, qint64 bytesTotal); - void _activeVehicleChanged (Vehicle* vehicle); - void _mavlinkLogData (Vehicle* vehicle, uint8_t target_system, uint8_t target_component, uint16_t sequence, uint8_t first_message, QByteArray data, bool acked); - void _armedChanged (bool armed); - void _mavCommandResult (int vehicleId, int component, int command, int result, bool noReponseFromVehicle); + void _uploadFinished(); + void _dataAvailable(); + void _uploadProgress(qint64 bytesSent, qint64 bytesTotal); + void _activeVehicleChanged(Vehicle *vehicle); + void _mavlinkLogData(Vehicle *vehicle, uint8_t target_system, uint8_t target_component, uint16_t sequence, uint8_t first_message, const QByteArray &data, bool acked); + void _armedChanged(bool armed); + void _mavCommandResult(int vehicleId, int component, int command, int result, bool noReponseFromVehicle); private: - bool _sendLog (const QString& logFile); - bool _processUploadResponse (int http_code, QByteArray &data); - bool _createNewLog (); - int _getFirstSelected (); - void _insertNewLog (MAVLinkLogFiles* newLog); - void _deleteLog (MAVLinkLogFiles* log); - void _discardLog (); - QString _makeFilename (const QString& baseName); + bool _sendLog(const QString &logFile); + bool _processUploadResponse(int http_code, const QByteArray &data); + bool _createNewLog(); + int _getFirstSelected() const; + void _insertNewLog(MAVLinkLogFiles *newLog); + void _deleteLog(MAVLinkLogFiles *log); + void _discardLog(); + QString _makeFilename(const QString &baseName) const; -private: - QString _description; - QString _emailAddress; - QString _uploadURL; - QString _feedback; - QString _logPath; - QString _videoURL; - bool _enableAutoUpload; - bool _enableAutoStart; - QNetworkAccessManager* _nam; - QmlObjectListModel _logFiles; - MAVLinkLogFiles* _currentLogfile; - Vehicle* _vehicle; - bool _logRunning; - bool _loggingDisabled; - MAVLinkLogProcessor* _logProcessor; - bool _deleteAfterUpload; - int _windSpeed; - QString _rating; - bool _publicLog; - QString _ulogExtension; - bool _logginDenied; - - static constexpr const char* kMAVLinkLogGroup = "MAVLinkLogGroup"; - static constexpr const char* kEmailAddressKey = "Email"; - static constexpr const char* kDescriptionsKey = "Description"; - static constexpr const char* kDefaultDescr = "QGroundControl Session"; - static constexpr const char* kPx4URLKey = "LogURL"; - static constexpr const char* kDefaultPx4URL = "https://logs.px4.io/upload"; - static constexpr const char* kEnableAutoUploadKey = "EnableAutoUpload"; - static constexpr const char* kEnableAutoStartKey = "EnableAutoStart"; - static constexpr const char* kEnableDeletetKey = "EnableDelete"; - static constexpr const char* kVideoURLKey = "VideoURL"; - static constexpr const char* kWindSpeedKey = "WindSpeed"; - static constexpr const char* kRateKey = "RateKey"; - static constexpr const char* kPublicLogKey = "PublicLog"; - static constexpr const char* kFeedback = "feedback"; - static constexpr const char* kVideoURL = "videoUrl"; + static QHttpPart _createFormPart(QStringView name, QStringView value); + + QNetworkAccessManager *_networkManager = nullptr; + QmlObjectListModel *_logFiles = nullptr; + QString _ulogExtension; + QString _logPath; + + bool _deleteAfterUpload = false; + bool _enableAutoStart = false; + bool _enableAutoUpload = true; + bool _loggingDisabled = false; + bool _loggingDenied = false; + bool _logRunning = false; + bool _publicLog = false; + int _windSpeed = -1; + MAVLinkLogFiles *_currentLogfile = nullptr; + MAVLinkLogProcessor *_logProcessor = nullptr; + QString _description; + QString _emailAddress; + QString _feedback; + QString _rating; + QString _uploadURL; + QString _videoURL; + Vehicle *_vehicle = nullptr; + + static constexpr const char *kMAVLinkLogGroup = "MAVLinkLogGroup"; + static constexpr const char *kEmailAddressKey = "Email"; + static constexpr const char *kDescriptionsKey = "Description"; + static constexpr const char *kDefaultDescr = "QGroundControl Session"; + static constexpr const char *kPx4URLKey = "LogURL"; + static constexpr const char *kDefaultPx4URL = "https://logs.px4.io/upload"; + static constexpr const char *kEnableAutoUploadKey = "EnableAutoUpload"; + static constexpr const char *kEnableAutoStartKey = "EnableAutoStart"; + static constexpr const char *kEnableDeletetKey = "EnableDelete"; + static constexpr const char *kVideoURLKey = "VideoURL"; + static constexpr const char *kWindSpeedKey = "WindSpeed"; + static constexpr const char *kRateKey = "RateKey"; + static constexpr const char *kPublicLogKey = "PublicLog"; + static constexpr const char *kFeedback = "feedback"; + static constexpr const char *kVideoURL = "videoUrl"; }; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index e943e7bfd85..4e1bcc7af67 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -109,6 +109,7 @@ add_qgc_test(ComponentInformationCacheTest) add_qgc_test(ComponentInformationTranslationTest) add_qgc_test(FTPManagerTest) # add_qgc_test(InitialConnectTest) +add_qgc_test(MAVLinkLogManagerTest) # add_qgc_test(RequestMessageTest) # add_qgc_test(SendMavCommandWithHandlerTest) # add_qgc_test(SendMavCommandWithSignalingTest) diff --git a/test/UnitTestList.cc b/test/UnitTestList.cc index 604041f9325..a9dba5e5215 100644 --- a/test/UnitTestList.cc +++ b/test/UnitTestList.cc @@ -98,6 +98,7 @@ #include "ComponentInformationTranslationTest.h" #include "FTPManagerTest.h" // #include "InitialConnectTest.h" +#include "MAVLinkLogManagerTest.h" // #include "RequestMessageTest.h" // #include "SendMavCommandWithHandlerTest.h" // #include "SendMavCommandWithSignalingTest.h" @@ -197,6 +198,7 @@ int runTests(bool stress, QStringView unitTestOptions) UT_REGISTER_TEST(ComponentInformationTranslationTest) UT_REGISTER_TEST(FTPManagerTest) // UT_REGISTER_TEST(InitialConnectTest) + UT_REGISTER_TEST(MAVLinkLogManagerTest) // UT_REGISTER_TEST(RequestMessageTest) // UT_REGISTER_TEST(SendMavCommandWithHandlerTest) // UT_REGISTER_TEST(SendMavCommandWithSignalingTest) diff --git a/test/Vehicle/CMakeLists.txt b/test/Vehicle/CMakeLists.txt index 28a855ad4fd..d21a293a968 100644 --- a/test/Vehicle/CMakeLists.txt +++ b/test/Vehicle/CMakeLists.txt @@ -6,6 +6,10 @@ qt_add_library(VehicleTest STATIC FTPManagerTest.cc FTPManagerTest.h + InitialConnectTest.cc + InitialConnectTest.h + MAVLinkLogManagerTest.cc + MAVLinkLogManagerTest.h RequestMessageTest.cc RequestMessageTest.h SendMavCommandWithHandlerTest.cc diff --git a/test/Vehicle/MAVLinkLogManagerTest.cc b/test/Vehicle/MAVLinkLogManagerTest.cc new file mode 100644 index 00000000000..e28cec477f6 --- /dev/null +++ b/test/Vehicle/MAVLinkLogManagerTest.cc @@ -0,0 +1,18 @@ +/**************************************************************************** + * + * (c) 2009-2024 QGROUNDCONTROL PROJECT + * + * QGroundControl is licensed according to the terms in the file + * COPYING.md in the root of the source code directory. + * + ****************************************************************************/ + +#include "MAVLinkLogManagerTest.h" +#include "MAVLinkLogManager.h" + +#include + +void MAVLinkLogManagerTest::_testInitMAVLinkLogManager() +{ + QVERIFY(MAVLinkLogManager::instance()); +} diff --git a/test/Vehicle/MAVLinkLogManagerTest.h b/test/Vehicle/MAVLinkLogManagerTest.h new file mode 100644 index 00000000000..08e36649b11 --- /dev/null +++ b/test/Vehicle/MAVLinkLogManagerTest.h @@ -0,0 +1,20 @@ +/**************************************************************************** + * + * (c) 2009-2024 QGROUNDCONTROL PROJECT + * + * QGroundControl is licensed according to the terms in the file + * COPYING.md in the root of the source code directory. + * + ****************************************************************************/ + +#pragma once + +#include "UnitTest.h" + +class MAVLinkLogManagerTest : public UnitTest +{ + Q_OBJECT + +private slots: + void _testInitMAVLinkLogManager(); +};