diff --git a/bsp_hosted/ObjectFactory.cpp b/bsp_hosted/ObjectFactory.cpp index 6c85b04d..174a46ad 100644 --- a/bsp_hosted/ObjectFactory.cpp +++ b/bsp_hosted/ObjectFactory.cpp @@ -44,6 +44,8 @@ #include #include +#include "mission/utility/GlobalConfigHandler.h" + void Factory::setStaticFrameworkObjectIds() { PusServiceBase::PUS_DISTRIBUTOR = objects::PUS_PACKET_DISTRIBUTOR; PusServiceBase::PACKET_DESTINATION = objects::TM_FUNNEL; @@ -87,6 +89,5 @@ void ObjectFactory::produce(void* args) { new TemperatureSensorsDummy(); new SusDummy(); new ThermalController(objects::THERMAL_CONTROLLER, objects::NO_OBJECT); - - // new TestTask(objects::TEST_TASK); + new TestTask(objects::TEST_TASK); } diff --git a/bsp_hosted/main.cpp b/bsp_hosted/main.cpp index 24800919..e493c1c9 100644 --- a/bsp_hosted/main.cpp +++ b/bsp_hosted/main.cpp @@ -31,6 +31,9 @@ int main(void) { << "v" << common::OBSW_VERSION << " | FSFW v" << fsfw::FSFW_VERSION << " --" << std::endl; std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl; + std::cout << "-- " + << " BSP HOSTED" + << " --" << std::endl; initmission::initMission(); diff --git a/common/config/eive/eventSubsystemIds.h b/common/config/eive/eventSubsystemIds.h index 5eb379b5..8785f599 100644 --- a/common/config/eive/eventSubsystemIds.h +++ b/common/config/eive/eventSubsystemIds.h @@ -4,6 +4,7 @@ #include namespace SUBSYSTEM_ID { + enum : uint8_t { COMMON_SUBSYSTEM_ID_START = FW_SUBSYSTEM_ID_RANGE, ACS_SUBSYSTEM = 112, @@ -33,7 +34,9 @@ enum : uint8_t { PLOC_SUPV_HELPER = 136, SYRLINKS = 137, SCEX_HANDLER = 138, + CONFIGHANDLER = 139, COMMON_SUBSYSTEM_ID_END + }; } diff --git a/common/config/eive/objects.h b/common/config/eive/objects.h index 35b0de66..8663a749 100644 --- a/common/config/eive/objects.h +++ b/common/config/eive/objects.h @@ -20,6 +20,7 @@ enum commonObjects : uint32_t { THERMAL_CONTROLLER = 0x43400001, ACS_CONTROLLER = 0x43000002, CORE_CONTROLLER = 0x43000003, + GLOBAL_JSON_CFG = 0x43000006, /* 0x44 ('D') for device handlers */ MGM_0_LIS3_HANDLER = 0x44120006, diff --git a/generators/bsp_q7s_events.csv b/generators/bsp_q7s_events.csv index 707d5c63..49cdc610 100644 --- a/generators/bsp_q7s_events.csv +++ b/generators/bsp_q7s_events.csv @@ -219,3 +219,8 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path 13800;0x35e8;MISSING_PACKET;LOW;;mission/devices/devicedefinitions/ScexDefinitions.h 13801;0x35e9;EXPERIMENT_TIMEDOUT;LOW;;mission/devices/devicedefinitions/ScexDefinitions.h 13802;0x35ea;MULTI_PACKET_COMMAND_DONE;INFO;;mission/devices/devicedefinitions/ScexDefinitions.h +13901;0x364d;SET_CONFIGFILEVALUE_FAILED;MEDIUM;;mission/utility/GlobalConfigHandler.h +13902;0x364e;GET_CONFIGFILEVALUE_FAILED;MEDIUM;;mission/utility/GlobalConfigHandler.h +13903;0x364f;INSERT_CONFIGFILEVALUE_FAILED;MEDIUM;;mission/utility/GlobalConfigHandler.h +13904;0x3650;WRITE_CONFIGFILE_FAILED;MEDIUM;;mission/utility/GlobalConfigHandler.h +13905;0x3651;READ_CONFIGFILE_FAILED;MEDIUM;;mission/utility/GlobalConfigHandler.h diff --git a/generators/bsp_q7s_objects.csv b/generators/bsp_q7s_objects.csv index 4ca0ad39..94f508bc 100644 --- a/generators/bsp_q7s_objects.csv +++ b/generators/bsp_q7s_objects.csv @@ -1,6 +1,7 @@ 0x00005060;P60DOCK_TEST_TASK 0x43000002;ACS_CONTROLLER 0x43000003;CORE_CONTROLLER +0x43000006;GLOBAL_JSON_CFG 0x43400001;THERMAL_CONTROLLER 0x44120006;MGM_0_LIS3_HANDLER 0x44120010;GYRO_0_ADIS_HANDLER diff --git a/generators/bsp_q7s_returnvalues.csv b/generators/bsp_q7s_returnvalues.csv index f464a439..7fccee95 100644 --- a/generators/bsp_q7s_returnvalues.csv +++ b/generators/bsp_q7s_returnvalues.csv @@ -419,8 +419,8 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path 0x2403;MT_NoMatch;;3;MATCH_TREE_CLASS;fsfw/src/fsfw/globalfunctions/matching/MatchTree.h 0x2404;MT_Full;;4;MATCH_TREE_CLASS;fsfw/src/fsfw/globalfunctions/matching/MatchTree.h 0x2405;MT_NewNodeCreated;;5;MATCH_TREE_CLASS;fsfw/src/fsfw/globalfunctions/matching/MatchTree.h -0x3f01;DLEE_StreamTooShort;;1;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleEncoder.h -0x3f02;DLEE_DecodingError;;2;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleEncoder.h +0x3f01;DLEE_NoPacketFound;;1;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleParser.h +0x3f02;DLEE_PossiblePacketLoss;;2;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleParser.h 0x2f01;ASC_TooLongForTargetType;;1;ASCII_CONVERTER;fsfw/src/fsfw/globalfunctions/AsciiConverter.h 0x2f02;ASC_InvalidCharacters;;2;ASCII_CONVERTER;fsfw/src/fsfw/globalfunctions/AsciiConverter.h 0x2f03;ASC_BufferTooSmall;;3;ASCII_CONVERTER;fsfw/src/fsfw/globalfunctions/AsciiConverter.h diff --git a/generators/events/translateEvents.cpp b/generators/events/translateEvents.cpp index ccfa367a..95c40d66 100644 --- a/generators/events/translateEvents.cpp +++ b/generators/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 220 translations. + * @brief Auto-generated event translation file. Contains 225 translations. * @details - * Generated on: 2022-09-29 14:08:11 + * Generated on: 2022-10-10 10:17:44 */ #include "translateEvents.h" @@ -221,6 +221,11 @@ const char *REBOOT_HW_STRING = "REBOOT_HW"; const char *MISSING_PACKET_STRING = "MISSING_PACKET"; const char *EXPERIMENT_TIMEDOUT_STRING = "EXPERIMENT_TIMEDOUT"; const char *MULTI_PACKET_COMMAND_DONE_STRING = "MULTI_PACKET_COMMAND_DONE"; +const char *SET_CONFIGFILEVALUE_FAILED_STRING = "SET_CONFIGFILEVALUE_FAILED"; +const char *GET_CONFIGFILEVALUE_FAILED_STRING = "GET_CONFIGFILEVALUE_FAILED"; +const char *INSERT_CONFIGFILEVALUE_FAILED_STRING = "INSERT_CONFIGFILEVALUE_FAILED"; +const char *WRITE_CONFIGFILE_FAILED_STRING = "WRITE_CONFIGFILE_FAILED"; +const char *READ_CONFIGFILE_FAILED_STRING = "READ_CONFIGFILE_FAILED"; const char *translateEvents(Event event) { switch ((event & 0xFFFF)) { @@ -656,6 +661,16 @@ const char *translateEvents(Event event) { return EXPERIMENT_TIMEDOUT_STRING; case (13802): return MULTI_PACKET_COMMAND_DONE_STRING; + case (13901): + return SET_CONFIGFILEVALUE_FAILED_STRING; + case (13902): + return GET_CONFIGFILEVALUE_FAILED_STRING; + case (13903): + return INSERT_CONFIGFILEVALUE_FAILED_STRING; + case (13904): + return WRITE_CONFIGFILE_FAILED_STRING; + case (13905): + return READ_CONFIGFILE_FAILED_STRING; default: return "UNKNOWN_EVENT"; } diff --git a/generators/objects/translateObjects.cpp b/generators/objects/translateObjects.cpp index e88f7a44..e2079825 100644 --- a/generators/objects/translateObjects.cpp +++ b/generators/objects/translateObjects.cpp @@ -1,14 +1,15 @@ /** * @brief Auto-generated object translation file. * @details - * Contains 137 translations. - * Generated on: 2022-09-29 14:08:11 + * Contains 138 translations. + * Generated on: 2022-10-10 10:17:44 */ #include "translateObjects.h" const char *P60DOCK_TEST_TASK_STRING = "P60DOCK_TEST_TASK"; const char *ACS_CONTROLLER_STRING = "ACS_CONTROLLER"; const char *CORE_CONTROLLER_STRING = "CORE_CONTROLLER"; +const char *GLOBAL_JSON_CFG_STRING = "GLOBAL_JSON_CFG"; const char *THERMAL_CONTROLLER_STRING = "THERMAL_CONTROLLER"; const char *MGM_0_LIS3_HANDLER_STRING = "MGM_0_LIS3_HANDLER"; const char *GYRO_0_ADIS_HANDLER_STRING = "GYRO_0_ADIS_HANDLER"; @@ -152,6 +153,8 @@ const char *translateObject(object_id_t object) { return ACS_CONTROLLER_STRING; case 0x43000003: return CORE_CONTROLLER_STRING; + case 0x43000006: + return GLOBAL_JSON_CFG_STRING; case 0x43400001: return THERMAL_CONTROLLER_STRING; case 0x44120006: diff --git a/linux/fsfwconfig/events/translateEvents.cpp b/linux/fsfwconfig/events/translateEvents.cpp index ccfa367a..95c40d66 100644 --- a/linux/fsfwconfig/events/translateEvents.cpp +++ b/linux/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 220 translations. + * @brief Auto-generated event translation file. Contains 225 translations. * @details - * Generated on: 2022-09-29 14:08:11 + * Generated on: 2022-10-10 10:17:44 */ #include "translateEvents.h" @@ -221,6 +221,11 @@ const char *REBOOT_HW_STRING = "REBOOT_HW"; const char *MISSING_PACKET_STRING = "MISSING_PACKET"; const char *EXPERIMENT_TIMEDOUT_STRING = "EXPERIMENT_TIMEDOUT"; const char *MULTI_PACKET_COMMAND_DONE_STRING = "MULTI_PACKET_COMMAND_DONE"; +const char *SET_CONFIGFILEVALUE_FAILED_STRING = "SET_CONFIGFILEVALUE_FAILED"; +const char *GET_CONFIGFILEVALUE_FAILED_STRING = "GET_CONFIGFILEVALUE_FAILED"; +const char *INSERT_CONFIGFILEVALUE_FAILED_STRING = "INSERT_CONFIGFILEVALUE_FAILED"; +const char *WRITE_CONFIGFILE_FAILED_STRING = "WRITE_CONFIGFILE_FAILED"; +const char *READ_CONFIGFILE_FAILED_STRING = "READ_CONFIGFILE_FAILED"; const char *translateEvents(Event event) { switch ((event & 0xFFFF)) { @@ -656,6 +661,16 @@ const char *translateEvents(Event event) { return EXPERIMENT_TIMEDOUT_STRING; case (13802): return MULTI_PACKET_COMMAND_DONE_STRING; + case (13901): + return SET_CONFIGFILEVALUE_FAILED_STRING; + case (13902): + return GET_CONFIGFILEVALUE_FAILED_STRING; + case (13903): + return INSERT_CONFIGFILEVALUE_FAILED_STRING; + case (13904): + return WRITE_CONFIGFILE_FAILED_STRING; + case (13905): + return READ_CONFIGFILE_FAILED_STRING; default: return "UNKNOWN_EVENT"; } diff --git a/linux/fsfwconfig/objects/translateObjects.cpp b/linux/fsfwconfig/objects/translateObjects.cpp index e88f7a44..e2079825 100644 --- a/linux/fsfwconfig/objects/translateObjects.cpp +++ b/linux/fsfwconfig/objects/translateObjects.cpp @@ -1,14 +1,15 @@ /** * @brief Auto-generated object translation file. * @details - * Contains 137 translations. - * Generated on: 2022-09-29 14:08:11 + * Contains 138 translations. + * Generated on: 2022-10-10 10:17:44 */ #include "translateObjects.h" const char *P60DOCK_TEST_TASK_STRING = "P60DOCK_TEST_TASK"; const char *ACS_CONTROLLER_STRING = "ACS_CONTROLLER"; const char *CORE_CONTROLLER_STRING = "CORE_CONTROLLER"; +const char *GLOBAL_JSON_CFG_STRING = "GLOBAL_JSON_CFG"; const char *THERMAL_CONTROLLER_STRING = "THERMAL_CONTROLLER"; const char *MGM_0_LIS3_HANDLER_STRING = "MGM_0_LIS3_HANDLER"; const char *GYRO_0_ADIS_HANDLER_STRING = "GYRO_0_ADIS_HANDLER"; @@ -152,6 +153,8 @@ const char *translateObject(object_id_t object) { return ACS_CONTROLLER_STRING; case 0x43000003: return CORE_CONTROLLER_STRING; + case 0x43000006: + return GLOBAL_JSON_CFG_STRING; case 0x43400001: return THERMAL_CONTROLLER_STRING; case 0x44120006: diff --git a/mission/devices/ScexDeviceHandler.cpp b/mission/devices/ScexDeviceHandler.cpp index fa4d2cc0..c49192a7 100644 --- a/mission/devices/ScexDeviceHandler.cpp +++ b/mission/devices/ScexDeviceHandler.cpp @@ -133,8 +133,10 @@ ReturnValue_t ScexDeviceHandler::buildCommandFromCommand(DeviceCommandId_t devic void ScexDeviceHandler::fillCommandAndReplyMap() { insertInCommandAndReplyMap(scex::Cmds::PING, 5, nullptr, 0, false, false, 0, &finishCountdown); insertInCommandAndReplyMap(scex::Cmds::ION_CMD, 3, nullptr, 0, false, false, 0, &finishCountdown); - insertInCommandAndReplyMap(scex::Cmds::TEMP_CMD, 3, nullptr, 0, false, false, 0, &finishCountdown); - insertInCommandAndReplyMap(scex::Cmds::EXP_STATUS_CMD, 3, nullptr, 0, false, false, 0, &finishCountdown); + insertInCommandAndReplyMap(scex::Cmds::TEMP_CMD, 3, nullptr, 0, false, false, 0, + &finishCountdown); + insertInCommandAndReplyMap(scex::Cmds::EXP_STATUS_CMD, 3, nullptr, 0, false, false, 0, + &finishCountdown); insertInCommandAndReplyMap(scex::Cmds::ALL_CELLS_CMD, 0, nullptr, 0, true, false, scex::Cmds::ALL_CELLS_CMD, &finishCountdown); diff --git a/mission/utility/CMakeLists.txt b/mission/utility/CMakeLists.txt index 128356bf..e2459ed1 100644 --- a/mission/utility/CMakeLists.txt +++ b/mission/utility/CMakeLists.txt @@ -1,2 +1,3 @@ -target_sources(${LIB_EIVE_MISSION} PRIVATE Timestamp.cpp ProgressPrinter.cpp - Filenaming.cpp) +target_sources( + ${LIB_EIVE_MISSION} PRIVATE Timestamp.cpp ProgressPrinter.cpp Filenaming.cpp + GlobalConfigHandler.cpp) diff --git a/mission/utility/GlobalConfigFileDefinitions.h b/mission/utility/GlobalConfigFileDefinitions.h new file mode 100644 index 00000000..2e7d133a --- /dev/null +++ b/mission/utility/GlobalConfigFileDefinitions.h @@ -0,0 +1,20 @@ +/* + * GlobalConfigFileDefinitions.h + * + * Created on: July 05, 2022 + * Author: Jona Petri (IRS) + */ + +#ifndef MISSION_UTILITY_GLOBALCONFIGFILEDEFINITIONS_H_ +#define MISSION_UTILITY_GLOBALCONFIGFILEDEFINITIONS_H_ + +static constexpr double PARAM0_DEFAULT = 5.0; +static constexpr int PARAM1_DEFAULT = 905; + +enum ParamIds : uint8_t { + PARAM0 = 0, + PARAM1 = 1, + PARAM2 = 2, +}; + +#endif /* MISSION_UTILITY_GLOBALCONFIGFILEDEFINITIONS_H_ */ diff --git a/mission/utility/GlobalConfigHandler.cpp b/mission/utility/GlobalConfigHandler.cpp new file mode 100644 index 00000000..bb4b3d7d --- /dev/null +++ b/mission/utility/GlobalConfigHandler.cpp @@ -0,0 +1,269 @@ +/* + * GlobalConfigHandler.cpp + * + * Created on: May 3, 2022 + * Author: Jona Petri (IRS) + */ + +#include "GlobalConfigHandler.h" + +#include +#include +#include + +#include "fsfw/serviceinterface/ServiceInterface.h" + +MutexIF* GlobalConfigHandler::CONFIG_LOCK = nullptr; + +GlobalConfigHandler::GlobalConfigHandler(object_id_t objectId, std::string configFilePath) + : SystemObject(objectId), + NVMParameterBase(configFilePath), + commandQueue(QueueFactory::instance()->createMessageQueue(20)) { + if (CONFIG_LOCK == nullptr) { + CONFIG_LOCK = MutexFactory::instance()->createMutex(); + } +} +ReturnValue_t GlobalConfigHandler::initialize() { + ReturnValue_t result = SystemObject::initialize(); + if (result != returnvalue::OK) { +#if OBSW_VERBOSE_LEVEL >= 1 + sif::info << "GlobalConfigHandler::initialize: SystemObject::initialize() failed with " + << result << std::endl; +#endif + return result; + } + + result = ReadConfigFile(); + if (result != returnvalue::OK) { +#if OBSW_VERBOSE_LEVEL >= 1 + sif::info << "GlobalConfigHandler::initialize: Creating JSON file at " << getFullName() + << std::endl; +#endif + result = ResetConfigFile(); + if (result != returnvalue::OK) { + return result; + } + } + +#if OBSW_VERBOSE_LEVEL >= 1 + sif::info << "GlobalConfigHandler::initialize success " << std::endl; +#endif + return result; +} +GlobalConfigHandler::~GlobalConfigHandler() {} + +ReturnValue_t GlobalConfigHandler::performOperation(uint8_t operationCode) { + ReturnValue_t result = returnvalue::OK; + sif::debug << "GlobalConfigHandler::performOperation" << std::endl; + return result; +} + +ReturnValue_t GlobalConfigHandler::lockConfigFile() { + ReturnValue_t result = returnvalue::OK; + result = CONFIG_LOCK->lockMutex(MutexIF::TimeoutType::WAITING, 10); + return result; +} +ReturnValue_t GlobalConfigHandler::unlockConfigFile() { + ReturnValue_t result = returnvalue::OK; + result = CONFIG_LOCK->unlockMutex(); + return result; +} + +template +ReturnValue_t GlobalConfigHandler::setConfigFileValue(ParamIds paramID, T data) { + ReturnValue_t result = returnvalue::OK; + ReturnValue_t resultSet = returnvalue::OK; + + result = lockConfigFile(); + if (result != returnvalue::OK) { +#if OBSW_VERBOSE_LEVEL >= 1 + sif::info << "GlobalConfigHandler::setConfigFileValue lock mutex failed with " << result + << std::endl; +#endif + return result; + } + + std::string paramString; + paramString = PARAM_KEY_MAP[paramID]; + + // Check if key exists in map before setting value. No check is done in setValue! Somehow + // PARAM_KEY_MAP.count(paramID) == 0 does not work + if (paramString.empty() == true) { +#if OBSW_VERBOSE_LEVEL >= 1 + sif::info << "GlobalConfigHandler::setConfigFileValue ParamId " << PARAM_KEY_MAP[paramID] + << " not found!" << std::endl; +#endif + triggerEvent(SET_CONFIGFILEVALUE_FAILED, 1, 0); + return returnvalue::FAILED; + } + + resultSet = setValue(PARAM_KEY_MAP[paramID], data); + if (resultSet != returnvalue::OK) { + triggerEvent(SET_CONFIGFILEVALUE_FAILED, 0, 0); +#if OBSW_VERBOSE_LEVEL >= 1 + sif::info << "GlobalConfigHandler::setConfigFileValue set json failed with " << resultSet + << std::endl; +#endif + } + + result = unlockConfigFile(); + if (result != returnvalue::OK) { +#if OBSW_VERBOSE_LEVEL >= 1 + sif::info << "GlobalConfigHandler::setConfigFileValue unlock mutex failed with " << result + << std::endl; +#endif + return result; + } + + return resultSet; +} +template +ReturnValue_t GlobalConfigHandler::getConfigFileValue(ParamIds paramID, T& data) { + ReturnValue_t result = returnvalue::OK; + ReturnValue_t resultGet = returnvalue::OK; + + result = lockConfigFile(); + if (result != returnvalue::OK) { +#if OBSW_VERBOSE_LEVEL >= 1 + sif::info << "GlobalConfigHandler::getConfigFileValue lock mutex failed with " << result + << std::endl; +#endif + return result; + } + + resultGet = getValue(PARAM_KEY_MAP[paramID], data); + if (resultGet != returnvalue::OK) { + triggerEvent(GET_CONFIGFILEVALUE_FAILED, 0, 0); +#if OBSW_VERBOSE_LEVEL >= 1 + sif::info << "GlobalConfigHandler::getConfigFileValue getValue failed with " << resultGet + << std::endl; +#endif + } + result = unlockConfigFile(); + if (result != returnvalue::OK) { +#if OBSW_VERBOSE_LEVEL >= 1 + sif::info << "GlobalConfigHandler::getConfigFileValue unlock mutex failed with " << result + << std::endl; +#endif + return result; + } + + return resultGet; +} + +ReturnValue_t GlobalConfigHandler::resetConfigFileValues() { + ReturnValue_t result = returnvalue::OK; + result = lockConfigFile(); + if (result != returnvalue::OK) { +#if OBSW_VERBOSE_LEVEL >= 1 + sif::info << "GlobalConfigHandler::resetConfigFileValues lock mutex failed with " << result + << std::endl; +#endif + return result; + } + insertValue(PARAM_KEY_MAP[PARAM0], PARAM0_DEFAULT); + insertValue(PARAM_KEY_MAP[PARAM1], PARAM1_DEFAULT); + + result = unlockConfigFile(); + if (result != returnvalue::OK) { +#if OBSW_VERBOSE_LEVEL >= 1 + sif::info << "GlobalConfigHandler::resetConfigFileValues unlock mutex failed with " << result + << std::endl; +#endif + return result; + } + return result; +} +ReturnValue_t GlobalConfigHandler::WriteConfigFile() { + ReturnValue_t result = returnvalue::OK; + ReturnValue_t resultWrite = returnvalue::OK; + result = lockConfigFile(); + if (result != returnvalue::OK) { +#if OBSW_VERBOSE_LEVEL >= 1 + sif::info << "GlobalConfigHandler::WriteConfigFile lock mutex failed with " << result + << std::endl; +#endif + return result; + } + + resultWrite = writeJsonFile(); + if (resultWrite != returnvalue::OK) { + triggerEvent(WRITE_CONFIGFILE_FAILED, 0, 0); +#if OBSW_VERBOSE_LEVEL >= 1 + sif::info << "GlobalConfigHandler::WriteConfigFile write json failed with " << resultWrite + << std::endl; +#endif + } + + result = unlockConfigFile(); + if (result != returnvalue::OK) { +#if OBSW_VERBOSE_LEVEL >= 1 + sif::info << "GlobalConfigHandler::WriteConfigFile unlock mutex failed with " << result + << std::endl; +#endif + return result; + } + return resultWrite; +} +ReturnValue_t GlobalConfigHandler::ReadConfigFile() { + ReturnValue_t result = returnvalue::OK; + ReturnValue_t resultRead = returnvalue::OK; + result = lockConfigFile(); + if (result != returnvalue::OK) { +#if OBSW_VERBOSE_LEVEL >= 1 + sif::info << "GlobalConfigHandler::ReadConfigFile lock mutex failed with " << result + << std::endl; +#endif + return result; + } + + resultRead = readJsonFile(); + if (resultRead != returnvalue::OK) { + triggerEvent(READ_CONFIGFILE_FAILED, 0, 0); +#if OBSW_VERBOSE_LEVEL >= 1 + sif::info << "GlobalConfigHandler::ReadConfigFile read json failed with " << resultRead + << std::endl; +#endif + } + + result = unlockConfigFile(); + if (result != returnvalue::OK) { +#if OBSW_VERBOSE_LEVEL >= 1 + sif::info << "GlobalConfigHandler::ReadConfigFile unlock mutex failed with " << result + << std::endl; +#endif + return result; + } + + return resultRead; +} +ReturnValue_t GlobalConfigHandler::ResetConfigFile() { + ReturnValue_t result = returnvalue::OK; + result = resetConfigFileValues(); + if (result != returnvalue::OK) { +#if OBSW_VERBOSE_LEVEL >= 1 + sif::info << "GlobalConfigHandler::ResetConfigFile failed with " << result << std::endl; +#endif + return result; + } + result = writeJsonFile(); + return result; +} + +ReturnValue_t GlobalConfigHandler::setConfigFileName(std::string configFileName) { + ReturnValue_t result = returnvalue::OK; + setFullName(configFileName); + result = ResetConfigFile(); + return result; +} +std::string GlobalConfigHandler::getConfigFileName() { return getFullName(); } + +template ReturnValue_t GlobalConfigHandler::getConfigFileValue(ParamIds paramID, + double& data); +template ReturnValue_t GlobalConfigHandler::getConfigFileValue(ParamIds paramID, + int32_t& data); + +template ReturnValue_t GlobalConfigHandler::setConfigFileValue(ParamIds paramID, + double data); +template ReturnValue_t GlobalConfigHandler::setConfigFileValue(ParamIds paramID, + int32_t data); diff --git a/mission/utility/GlobalConfigHandler.h b/mission/utility/GlobalConfigHandler.h new file mode 100644 index 00000000..80e141c6 --- /dev/null +++ b/mission/utility/GlobalConfigHandler.h @@ -0,0 +1,79 @@ +/* + * GlobalConfigHandler.h + * + * Created on: May 3, 2022 + * Author: Jona Petri (IRS) + */ + +#ifndef MISSION_UTILITY_GLOBALCONFIGHANDLER_H_ +#define MISSION_UTILITY_GLOBALCONFIGHANDLER_H_ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "GlobalConfigFileDefinitions.h" +#include "OBSWConfig.h" +#include "fsfw/parameters/HasParametersIF.h" +#include "fsfw/parameters/ParameterHelper.h" +#include "mission/memory/NVMParameterBase.h" + +static std::map PARAM_KEY_MAP = { + {PARAM0, "Parameter0"}, + {PARAM1, "Parameter1"}, +}; +/* + * Idea: This class is intended to be used as a subclass for the Core Controller. + * Its tasks is managing a configuration JSON file containing config values important for various + * object. If some function to read or write a config value is called, a mutex should be used so + * only one call is done at a time. + */ +class GlobalConfigHandler : public SystemObject, + public ExecutableObjectIF, + public NVMParameterBase { + public: + GlobalConfigHandler(object_id_t objectId, std::string configFilePath); + virtual ~GlobalConfigHandler(); + + static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CONFIGHANDLER; + + static constexpr Event SET_CONFIGFILEVALUE_FAILED = MAKE_EVENT(1, severity::MEDIUM); + static constexpr Event GET_CONFIGFILEVALUE_FAILED = MAKE_EVENT(2, severity::MEDIUM); + static constexpr Event INSERT_CONFIGFILEVALUE_FAILED = MAKE_EVENT(3, severity::MEDIUM); + static constexpr Event WRITE_CONFIGFILE_FAILED = MAKE_EVENT(4, severity::MEDIUM); + static constexpr Event READ_CONFIGFILE_FAILED = MAKE_EVENT(5, severity::MEDIUM); + + ReturnValue_t performOperation(uint8_t operationCode); + + ReturnValue_t initialize(); + + template + ReturnValue_t setConfigFileValue(ParamIds paramID, T data); + template + ReturnValue_t getConfigFileValue(ParamIds paramID, T& data); + + ReturnValue_t ResetConfigFile(); + ReturnValue_t WriteConfigFile(); + std::string getConfigFileName(); + + private: + static MutexIF* CONFIG_LOCK; + + ReturnValue_t lockConfigFile(); + ReturnValue_t unlockConfigFile(); + ReturnValue_t resetConfigFileValues(); + + ReturnValue_t setConfigFileName(std::string configFileName); + + ReturnValue_t ReadConfigFile(); + + MessageQueueIF* commandQueue; +}; + +#endif /* MISSION_UTILITY_GLOBALCONFIGHANDLER_H_ */ diff --git a/tmtc b/tmtc index b2d65442..a91d40f3 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit b2d65442fe513db51128d953bc805c05d5f68e07 +Subproject commit a91d40f3337a948bc061b033e194dd629fd34be1 diff --git a/unittest/controller/CMakeLists.txt b/unittest/controller/CMakeLists.txt index bfa3d11f..7680eefa 100644 --- a/unittest/controller/CMakeLists.txt +++ b/unittest/controller/CMakeLists.txt @@ -1,4 +1,5 @@ target_sources(${UNITTEST_NAME} PRIVATE testThermalController.cpp testAcsController.cpp -) \ No newline at end of file + testConfigFileHandler.cpp +) diff --git a/unittest/controller/testConfigFileHandler.cpp b/unittest/controller/testConfigFileHandler.cpp new file mode 100644 index 00000000..b8147e29 --- /dev/null +++ b/unittest/controller/testConfigFileHandler.cpp @@ -0,0 +1,65 @@ + + +#include +#include + +#include +#include +#include +#include + +#include "../testEnvironment.h" + +TEST_CASE("Configfile Handler", "[ConfigHandler]") { + sif::debug << "Testcase config file handler" << std::endl; + // Init handler + GlobalConfigHandler confighandler = GlobalConfigHandler(objects::GLOBAL_JSON_CFG, "JSON.config"); + REQUIRE(confighandler.initialize() == returnvalue::OK); + + // Reset handler + REQUIRE(confighandler.ResetConfigFile() == returnvalue::OK); + + // Get and set double as well as int values + double doubleData = 0.0; + REQUIRE(confighandler.getConfigFileValue(PARAM0, doubleData) == returnvalue::OK); + REQUIRE(doubleData == 5.0); + + doubleData = 55.9; + double doubleDataRead = 0; + REQUIRE(confighandler.setConfigFileValue(PARAM0, doubleData) == returnvalue::OK); + + REQUIRE(confighandler.getConfigFileValue(PARAM0, doubleDataRead) == returnvalue::OK); + REQUIRE(doubleDataRead == doubleData); + + REQUIRE(confighandler.WriteConfigFile() == returnvalue::OK); + + int intData = 0; + + REQUIRE(confighandler.getConfigFileValue(PARAM1, intData) == returnvalue::OK); + REQUIRE(intData == 905); + + intData = 1337; + int intDataRead = 0; + REQUIRE(confighandler.setConfigFileValue(PARAM1, intData) == returnvalue::OK); + + REQUIRE(confighandler.getConfigFileValue(PARAM1, intDataRead) == returnvalue::OK); + REQUIRE(intDataRead == intData); + + REQUIRE(confighandler.WriteConfigFile() == returnvalue::OK); + + // Check file name + REQUIRE(confighandler.getConfigFileName() == "JSON.config"); + + // Reset and check if it worked + REQUIRE(confighandler.ResetConfigFile() == returnvalue::OK); + + doubleData = 0.0; + REQUIRE(confighandler.getConfigFileValue(PARAM0, doubleData) == returnvalue::OK); + REQUIRE(doubleData == 5.0); + + // Test invalid Parameter + REQUIRE(confighandler.getConfigFileValue(PARAM2, doubleData) != + returnvalue::OK); // NVMParameterBase::KEY_NOT_EXISTS is private, why? + REQUIRE(confighandler.setConfigFileValue(PARAM2, doubleData) != returnvalue::OK); + std::filesystem::remove("JSON.config"); +} diff --git a/unittest/controller/testThermalController.cpp b/unittest/controller/testThermalController.cpp index a65ec69b..d8cd2a1d 100644 --- a/unittest/controller/testThermalController.cpp +++ b/unittest/controller/testThermalController.cpp @@ -15,7 +15,7 @@ TEST_CASE("Thermal Controller", "[ThermalController]") { new TemperatureSensorsDummy(); new SusDummy(); - testEnvironment::initialize(); + // testEnvironment::initialize(); ThermalController controller(THERMAL_CONTROLLER_ID, objects::NO_OBJECT); ReturnValue_t result = controller.initialize(); diff --git a/unittest/main.cpp b/unittest/main.cpp index 6438577c..760ff156 100644 --- a/unittest/main.cpp +++ b/unittest/main.cpp @@ -4,7 +4,7 @@ int main(int argc, char* argv[]) { testEnvironment::setup(); - + testEnvironment::initialize(); // Catch internal function call int result = Catch::Session().run(argc, argv);