diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc
index d5a550e..9373f9d 100644
--- a/qgroundcontrol.qrc
+++ b/qgroundcontrol.qrc
@@ -337,5 +337,7 @@
src/comm/APMArduSubMockLink.params
src/comm/PX4MockLink.params
src/comm/MockLink.Version.MetaData.json
+ src/comm/MockLink.Version.MetaData.json.gz
+ src/comm/MockLink.Parameter.MetaData.json
diff --git a/src/Vehicle/ComponentInformationManager.cc b/src/Vehicle/ComponentInformationManager.cc
index d3d3c52..f811313 100644
--- a/src/Vehicle/ComponentInformationManager.cc
+++ b/src/Vehicle/ComponentInformationManager.cc
@@ -10,14 +10,21 @@
#include "ComponentInformationManager.h"
#include "Vehicle.h"
#include "FTPManager.h"
+#include "QGCZlib.h"
+#include "JsonHelper.h"
#include
+#include
+#include
QGC_LOGGING_CATEGORY(ComponentInformationManagerLog, "ComponentInformationManagerLog")
+const char* ComponentInformationManager::_jsonVersionKey = "version";
+const char* ComponentInformationManager::_jsonSupportedCompMetadataTypesKey = "supportedCompMetadataTypes";
+
ComponentInformationManager::StateFn ComponentInformationManager::_rgStates[]= {
ComponentInformationManager::_stateRequestCompInfoVersion,
- //ComponentInformationManager::_stateRequestCompInfoParam,
+ ComponentInformationManager::_stateRequestCompInfoParam,
ComponentInformationManager::_stateRequestAllCompInfoComplete
};
@@ -27,6 +34,7 @@ RequestMetaDataTypeStateMachine::StateFn RequestMetaDataTypeStateMachine::_rgSta
RequestMetaDataTypeStateMachine::_stateRequestCompInfo,
RequestMetaDataTypeStateMachine::_stateRequestMetaDataJson,
RequestMetaDataTypeStateMachine::_stateRequestTranslationJson,
+ RequestMetaDataTypeStateMachine::_stateRequestComplete,
};
int RequestMetaDataTypeStateMachine::_cStates = sizeof(RequestMetaDataTypeStateMachine::_rgStates) / sizeof(RequestMetaDataTypeStateMachine::_rgStates[0]);
@@ -69,7 +77,12 @@ void ComponentInformationManager::_stateRequestCompInfoComplete(void)
void ComponentInformationManager::_stateRequestCompInfoParam(StateMachine* stateMachine)
{
ComponentInformationManager* compMgr = static_cast(stateMachine);
- compMgr->_requestTypeStateMachine.request(COMP_METADATA_TYPE_PARAMETER);
+
+ if (compMgr->_isCompTypeSupported(COMP_METADATA_TYPE_PARAMETER)) {
+ compMgr->_requestTypeStateMachine.request(COMP_METADATA_TYPE_PARAMETER);
+ } else {
+
+ }
}
void ComponentInformationManager::_stateRequestAllCompInfoComplete(StateMachine* stateMachine)
@@ -80,6 +93,41 @@ void ComponentInformationManager::_stateRequestAllCompInfoComplete(StateMachine*
compMgr->_requestAllCompleteFnData = nullptr;
}
+void ComponentInformationManager::_compInfoJsonAvailable(const QString& metadataJsonFileName, const QString& translationsJsonFileName)
+{
+ qCDebug(ComponentInformationManagerLog) << "_compInfoJsonAvailable metadata:translation" << metadataJsonFileName << translationsJsonFileName;
+
+ if (!metadataJsonFileName.isEmpty()) {
+ QString errorString;
+ QJsonDocument jsonDoc;
+ if (!JsonHelper::isJsonFile(metadataJsonFileName, jsonDoc, errorString)) {
+ qCWarning(ComponentInformationManagerLog) << "Version json file read failed" << errorString;
+ return;
+ }
+ QJsonObject jsonObj = jsonDoc.object();
+
+ if (currentState() == _stateRequestCompInfoVersion) {
+ QList keyInfoList = {
+ { _jsonVersionKey, QJsonValue::Double, true },
+ { _jsonSupportedCompMetadataTypesKey, QJsonValue::Array, true },
+ };
+ if (!JsonHelper::validateKeys(jsonObj, keyInfoList, errorString)) {
+ qCWarning(ComponentInformationManagerLog) << "Version json validation failed:" << errorString;
+ return;
+ }
+
+ for (const QJsonValue& idValue: jsonObj[_jsonSupportedCompMetadataTypesKey].toArray()) {
+ _supportedMetaDataTypes.append(static_cast(idValue.toInt()));
+ }
+ }
+ }
+}
+
+bool ComponentInformationManager::_isCompTypeSupported(COMP_METADATA_TYPE type)
+{
+ return _supportedMetaDataTypes.contains(type);
+}
+
RequestMetaDataTypeStateMachine::RequestMetaDataTypeStateMachine(ComponentInformationManager* compMgr)
: _compMgr(compMgr)
{
@@ -91,6 +139,8 @@ void RequestMetaDataTypeStateMachine::request(COMP_METADATA_TYPE type)
_compInfoAvailable = false;
_type = type;
_stateIndex = -1;
+ _jsonMetadataFileName.clear();
+ _jsonTranslationFileName.clear();
start();
}
@@ -171,9 +221,47 @@ void RequestMetaDataTypeStateMachine::_stateRequestCompInfo(StateMachine* stateM
}
}
-void RequestMetaDataTypeStateMachine::_downloadComplete(const QString& file, const QString& errorMsg)
+QString RequestMetaDataTypeStateMachine::_downloadCompleteJsonWorker(const QString& fileName, const QString& inflatedFileName)
{
- qCDebug(ComponentInformationManagerLog) << "RequestMetaDataTypeStateMachine::_downloadComplete" << file << errorMsg;
+ QString outputFileName = fileName;
+
+ if (fileName.endsWith(".gz", Qt::CaseInsensitive)) {
+ outputFileName = (QDir(QStandardPaths::writableLocation(QStandardPaths::TempLocation)).absoluteFilePath(inflatedFileName));
+ if (QGCZlib::inflateGzipFile(fileName, outputFileName)) {
+ QFile(fileName).remove();
+ } else {
+ qCWarning(ComponentInformationManagerLog) << "Inflate of compressed json failed" << inflatedFileName;
+ outputFileName.clear();
+ }
+ } else {
+ outputFileName = fileName;
+ }
+
+ return outputFileName;
+}
+
+void RequestMetaDataTypeStateMachine::_downloadCompleteMetaDataJson(const QString& fileName, const QString& errorMsg)
+{
+ qCDebug(ComponentInformationManagerLog) << "RequestMetaDataTypeStateMachine::_downloadCompleteMetaDataJson fileName:errorMsg" << fileName << errorMsg;
+
+ if (errorMsg.isEmpty()) {
+ _jsonMetadataFileName = _downloadCompleteJsonWorker(fileName, "metadata.json");
+ }
+
+ advance();
+}
+
+void RequestMetaDataTypeStateMachine::_downloadCompleteTranslationJson(const QString& fileName, const QString& errorMsg)
+{
+ qCDebug(ComponentInformationManagerLog) << "RequestMetaDataTypeStateMachine::_downloadCompleteTranslationJson fileName:errorMsg" << fileName << errorMsg;
+
+ QString jsonTranslationFileName;
+ if (errorMsg.isEmpty()) {
+ jsonTranslationFileName = _downloadCompleteJsonWorker(fileName, "translation.json");
+ }
+
+ _compMgr->_compInfoJsonAvailable(_jsonMetadataFileName, jsonTranslationFileName);
+
advance();
}
@@ -186,9 +274,9 @@ void RequestMetaDataTypeStateMachine::_stateRequestMetaDataJson(StateMachine* st
if (requestMachine->_compInfoAvailable) {
ComponentInformation_t& compInfo = requestMachine->_compInfo;
- qCDebug(ComponentInformationManagerLog) << "Downloading metadata json" << compInfo.translationURI;
+ qCDebug(ComponentInformationManagerLog) << "Downloading metadata json" << compInfo.metadataURI;
if (_uriIsFTP(compInfo.metadataURI)) {
- connect(ftpManager, &FTPManager::downloadComplete, requestMachine, &RequestMetaDataTypeStateMachine::_downloadComplete);
+ connect(ftpManager, &FTPManager::downloadComplete, requestMachine, &RequestMetaDataTypeStateMachine::_downloadCompleteMetaDataJson);
ftpManager->download(compInfo.metadataURI, QStandardPaths::writableLocation(QStandardPaths::TempLocation));
} else {
// FIXME: NYI
@@ -214,7 +302,7 @@ void RequestMetaDataTypeStateMachine::_stateRequestTranslationJson(StateMachine*
} else {
qCDebug(ComponentInformationManagerLog) << "Downloading translation json" << compInfo.translationURI;
if (_uriIsFTP(compInfo.translationURI)) {
- connect(ftpManager, &FTPManager::downloadComplete, requestMachine, &RequestMetaDataTypeStateMachine::_downloadComplete);
+ connect(ftpManager, &FTPManager::downloadComplete, requestMachine, &RequestMetaDataTypeStateMachine::_downloadCompleteTranslationJson);
ftpManager->download(compInfo.metadataURI, QStandardPaths::writableLocation(QStandardPaths::TempLocation));
} else {
// FIXME: NYI
@@ -227,6 +315,14 @@ void RequestMetaDataTypeStateMachine::_stateRequestTranslationJson(StateMachine*
}
}
+void RequestMetaDataTypeStateMachine::_stateRequestComplete(StateMachine* stateMachine)
+{
+ RequestMetaDataTypeStateMachine* requestMachine = static_cast(stateMachine);
+
+ requestMachine->compMgr()->_compInfoJsonAvailable(requestMachine->_jsonMetadataFileName, requestMachine->_jsonTranslationFileName);
+ requestMachine->advance();
+}
+
bool RequestMetaDataTypeStateMachine::_uriIsFTP(const QString& uri)
{
return uri.startsWith("mavlinkftp", Qt::CaseInsensitive);
diff --git a/src/Vehicle/ComponentInformationManager.h b/src/Vehicle/ComponentInformationManager.h
index 356c1bb..5112ddb 100644
--- a/src/Vehicle/ComponentInformationManager.h
+++ b/src/Vehicle/ComponentInformationManager.h
@@ -43,12 +43,15 @@ public:
void statesCompleted (void) const final;
private slots:
- void _downloadComplete(const QString& file, const QString& errorMsg);
+ void _downloadCompleteMetaDataJson (const QString& file, const QString& errorMsg);
+ void _downloadCompleteTranslationJson(const QString& file, const QString& errorMsg);
+ QString _downloadCompleteJsonWorker (const QString& jsonFileName, const QString& inflatedFileName);
private:
static void _stateRequestCompInfo (StateMachine* stateMachine);
static void _stateRequestMetaDataJson (StateMachine* stateMachine);
static void _stateRequestTranslationJson (StateMachine* stateMachine);
+ static void _stateRequestComplete (StateMachine* stateMachine);
static bool _uriIsFTP (const QString& uri);
@@ -56,6 +59,8 @@ private:
COMP_METADATA_TYPE _type = COMP_METADATA_TYPE_VERSION;
bool _compInfoAvailable = false;
ComponentInformation_t _compInfo;
+ QString _jsonMetadataFileName;
+ QString _jsonTranslationFileName;
static StateFn _rgStates[];
static int _cStates;
@@ -78,7 +83,9 @@ public:
const StateFn* rgStates (void) const final;
private:
- void _stateRequestCompInfoComplete(void);
+ void _stateRequestCompInfoComplete (void);
+ void _compInfoJsonAvailable (const QString& metadataJsonFileName, const QString& translationsJsonFileName);
+ bool _isCompTypeSupported (COMP_METADATA_TYPE type);
static void _stateRequestCompInfoVersion (StateMachine* stateMachine);
static void _stateRequestCompInfoParam (StateMachine* stateMachine);
@@ -97,5 +104,8 @@ private:
static StateFn _rgStates[];
static int _cStates;
+ static const char* _jsonVersionKey;
+ static const char* _jsonSupportedCompMetadataTypesKey;
+
friend class RequestMetaDataTypeStateMachine;
};
diff --git a/src/Vehicle/StateMachine.cc b/src/Vehicle/StateMachine.cc
index a9df899..2cbc7df 100644
--- a/src/Vehicle/StateMachine.cc
+++ b/src/Vehicle/StateMachine.cc
@@ -50,3 +50,12 @@ void StateMachine::statesCompleted(void) const
{
}
+
+StateMachine::StateFn StateMachine::currentState(void)
+{
+ if (_active) {
+ return rgStates()[_stateIndex];
+ } else {
+ return nullptr;
+ }
+}
diff --git a/src/Vehicle/StateMachine.h b/src/Vehicle/StateMachine.h
index 738c195..7710574 100644
--- a/src/Vehicle/StateMachine.h
+++ b/src/Vehicle/StateMachine.h
@@ -29,6 +29,8 @@ public:
/// Move the state machine to the specified state and call the state function
void move(StateFn stateFn);
+ StateFn currentState(void);
+
/// @return The number of states in the rgStates array
virtual int stateCount(void) const = 0;