diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3b0917fd..8ba6a187 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,5 +1,13 @@
cmake_minimum_required(VERSION 3.13)
+option(FSFW_GENERATE_SECTIONS
+ "Generate function and data sections. Required to remove unused code" ON
+)
+
+if(FSFW_GENERATE_SECTIONS)
+ option(FSFW_REMOVE_UNUSED_CODE "Remove unused code" ON)
+endif()
+
option(FSFW_WARNING_SHADOW_LOCAL_GCC "Enable -Wshadow=local warning in GCC" ON)
# Options to exclude parts of the FSFW from compilation.
option(FSFW_USE_RMAP "Compile with RMAP" ON)
@@ -26,15 +34,22 @@ if(NOT OS_FSFW)
endif()
+set(FSFW_OSAL_DEFINITION FSFW_HOST)
+
if(${OS_FSFW} STREQUAL host)
set(OS_FSFW_NAME "Host")
elseif(${OS_FSFW} STREQUAL linux)
set(OS_FSFW_NAME "Linux")
+ set(FSFW_OSAL_DEFINITION FSFW_LINUX)
elseif(${OS_FSFW} STREQUAL freertos)
set(OS_FSFW_NAME "FreeRTOS")
- target_link_libraries(${LIB_FSFW_NAME} ${LIB_OS_NAME})
+ set(FSFW_OSAL_DEFINITION FSFW_FREERTOS)
+ target_link_libraries(${LIB_FSFW_NAME} PRIVATE
+ ${LIB_OS_NAME}
+ )
elseif(${OS_FSFW} STREQUAL rtems)
set(OS_FSFW_NAME "RTEMS")
+ set(FSFW_OSAL_DEFINITION FSFW_RTEMS)
else()
message(WARNING
"Invalid operating system for FSFW specified! Setting to host.."
@@ -43,6 +58,14 @@ else()
set(OS_FSFW "host")
endif()
+target_compile_definitions(${LIB_FSFW_NAME} PRIVATE
+ ${FSFW_OSAL_DEFINITION}
+)
+
+target_compile_definitions(${LIB_FSFW_NAME} INTERFACE
+ ${FSFW_OSAL_DEFINITION}
+)
+
message(STATUS "Compiling FSFW for the ${OS_FSFW_NAME} operating system.")
add_subdirectory(action)
@@ -88,6 +111,7 @@ add_subdirectory(timemanager)
add_subdirectory(tmstorage)
add_subdirectory(tmtcpacket)
add_subdirectory(tmtcservices)
+add_subdirectory(unittest)
# The project CMakeLists file has to set the FSFW_CONFIG_PATH and add it.
# If this is not given, we include the default configuration and emit a warning.
@@ -107,6 +131,21 @@ else()
)
endif()
+foreach(INCLUDE_PATH ${FSFW_ADDITIONAL_INC_PATH})
+ if(IS_ABSOLUTE ${INCLUDE_PATH})
+ set(CURR_ABS_INC_PATH "${FREERTOS_PATH}")
+ else()
+ get_filename_component(CURR_ABS_INC_PATH
+ ${INCLUDE_PATH} REALPATH BASE_DIR ${CMAKE_SOURCE_DIR})
+ endif()
+
+ if(CMAKE_VERBOSE)
+ message(STATUS "FSFW include path: ${CURR_ABS_INC_PATH}")
+ endif()
+
+ list(APPEND FSFW_ADD_INC_PATHS_ABS ${CURR_ABS_INC_PATH})
+endforeach()
+
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if(NOT DEFINED FSFW_WARNING_FLAGS)
set(FSFW_WARNING_FLAGS
@@ -117,7 +156,20 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
-Wno-psabi
)
endif()
-
+
+ if(FSFW_GENERATE_SECTIONS)
+ target_compile_options(${LIB_FSFW_NAME} PRIVATE
+ "-ffunction-sections"
+ "-fdata-sections"
+ )
+ endif()
+
+ if(FSFW_REMOVE_UNUSED_CODE)
+ target_link_options(${LIB_FSFW_NAME} PRIVATE
+ "Wl,--gc-sections"
+ )
+ endif()
+
if(FSFW_WARNING_SHADOW_LOCAL_GCC)
list(APPEND WARNING_FLAGS "-Wshadow=local")
endif()
@@ -132,6 +184,7 @@ endif()
target_include_directories(${LIB_FSFW_NAME} INTERFACE
${CMAKE_SOURCE_DIR}
${FSFW_CONFIG_PATH_ABSOLUTE}
+ ${FSFW_ADD_INC_PATHS_ABS}
)
# Includes path required to compile FSFW itself as well
@@ -140,9 +193,14 @@ target_include_directories(${LIB_FSFW_NAME} INTERFACE
target_include_directories(${LIB_FSFW_NAME} PRIVATE
${CMAKE_SOURCE_DIR}
${FSFW_CONFIG_PATH_ABSOLUTE}
+ ${FSFW_ADD_INC_PATHS_ABS}
)
target_compile_options(${LIB_FSFW_NAME} PRIVATE
${FSFW_WARNING_FLAGS}
${COMPILER_FLAGS}
)
+
+target_link_libraries(${LIB_FSFW_NAME} PRIVATE
+ ${FSFW_ADDITIONAL_LINK_LIBS}
+)
\ No newline at end of file
diff --git a/FSFWVersion.h b/FSFWVersion.h
index 11a60891..df2d49a5 100644
--- a/FSFWVersion.h
+++ b/FSFWVersion.h
@@ -3,9 +3,9 @@
const char* const FSFW_VERSION_NAME = "ASTP";
-#define FSFW_VERSION 0
-#define FSFW_SUBVERSION 0
-#define FSFW_REVISION 1
+#define FSFW_VERSION 1
+#define FSFW_SUBVERSION 0
+#define FSFW_REVISION 0
diff --git a/README.md b/README.md
index fb3be429..484d65c0 100644
--- a/README.md
+++ b/README.md
@@ -38,11 +38,12 @@ a starting point. The [configuration section](doc/README-config.md#top) provides
[1. High-level overview](doc/README-highlevel.md#top)
[2. Core components](doc/README-core.md#top)
-[3. OSAL overview](doc/README-osal.md#top)
-[4. PUS services](doc/README-pus.md#top)
-[5. Device Handler overview](doc/README-devicehandlers.md#top)
-[6. Controller overview](doc/README-controllers.md#top)
-[7. Local Data Pools](doc/README-localpools.md#top)
+[3. Configuration](doc/README-config.md#top)
+[4. OSAL overview](doc/README-osal.md#top)
+[5. PUS services](doc/README-pus.md#top)
+[6. Device Handler overview](doc/README-devicehandlers.md#top)
+[7. Controller overview](doc/README-controllers.md#top)
+[8. Local Data Pools](doc/README-localpools.md#top)
diff --git a/action/ActionHelper.cpp b/action/ActionHelper.cpp
index 4b64a40c..b2374ed6 100644
--- a/action/ActionHelper.cpp
+++ b/action/ActionHelper.cpp
@@ -147,11 +147,6 @@ ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo,
return result;
}
- if (result != HasReturnvaluesIF::RETURN_OK) {
- ipcStore->deleteData(storeAddress);
- return result;
- }
-
/* We don't need to report the objectId, as we receive REQUESTED data before the completion
success message. True aperiodic replies need to be reported with another dedicated message. */
ActionMessage::setDataReply(&reply, replyId, storeAddress);
diff --git a/container/FixedArrayList.h b/container/FixedArrayList.h
index 89b76388..7af636b6 100644
--- a/container/FixedArrayList.h
+++ b/container/FixedArrayList.h
@@ -8,7 +8,9 @@
*/
template
class FixedArrayList: public ArrayList {
- static_assert(MAX_SIZE <= (pow(2,sizeof(count_t)*8)-1), "count_t is not large enough to hold MAX_SIZE");
+#if !defined(_MSC_VER)
+ static_assert(MAX_SIZE <= (std::pow(2,sizeof(count_t)*8)-1), "count_t is not large enough to hold MAX_SIZE");
+#endif
private:
T data[MAX_SIZE];
public:
diff --git a/container/SharedRingBuffer.cpp b/container/SharedRingBuffer.cpp
index 1681325d..fe36341d 100644
--- a/container/SharedRingBuffer.cpp
+++ b/container/SharedRingBuffer.cpp
@@ -1,6 +1,6 @@
#include "SharedRingBuffer.h"
#include "../ipc/MutexFactory.h"
-#include "../ipc/MutexHelper.h"
+#include "../ipc/MutexGuard.h"
SharedRingBuffer::SharedRingBuffer(object_id_t objectId, const size_t size,
bool overwriteOld, size_t maxExcessBytes):
@@ -17,6 +17,9 @@ SharedRingBuffer::SharedRingBuffer(object_id_t objectId, uint8_t *buffer,
mutex = MutexFactory::instance()->createMutex();
}
+SharedRingBuffer::~SharedRingBuffer() {
+ MutexFactory::instance()->deleteMutex(mutex);
+}
void SharedRingBuffer::setToUseReceiveSizeFIFO(size_t fifoDepth) {
this->fifoDepth = fifoDepth;
diff --git a/container/SharedRingBuffer.h b/container/SharedRingBuffer.h
index 43ab6e8f..9d6ea56c 100644
--- a/container/SharedRingBuffer.h
+++ b/container/SharedRingBuffer.h
@@ -26,6 +26,18 @@ public:
*/
SharedRingBuffer(object_id_t objectId, const size_t size,
bool overwriteOld, size_t maxExcessBytes);
+ /**
+ * This constructor takes an external buffer with the specified size.
+ * @param buffer
+ * @param size
+ * @param overwriteOld
+ * If the ring buffer is overflowing at a write operartion, the oldest data
+ * will be overwritten.
+ */
+ SharedRingBuffer(object_id_t objectId, uint8_t* buffer, const size_t size,
+ bool overwriteOld, size_t maxExcessBytes);
+
+ virtual~ SharedRingBuffer();
/**
* @brief This function can be used to add an optional FIFO to the class
@@ -37,16 +49,7 @@ public:
*/
void setToUseReceiveSizeFIFO(size_t fifoDepth);
- /**
- * This constructor takes an external buffer with the specified size.
- * @param buffer
- * @param size
- * @param overwriteOld
- * If the ring buffer is overflowing at a write operartion, the oldest data
- * will be overwritten.
- */
- SharedRingBuffer(object_id_t objectId, uint8_t* buffer, const size_t size,
- bool overwriteOld, size_t maxExcessBytes);
+
/**
* Unless a read-only constant value is read, all operations on the
@@ -66,7 +69,7 @@ public:
/**
* The mutex handle can be accessed directly, for example to perform
- * the lock with the #MutexHelper for a RAII compliant lock operation.
+ * the lock with the #MutexGuard for a RAII compliant lock operation.
* @return
*/
MutexIF* getMutexHandle() const;
diff --git a/controller/ExtendedControllerBase.cpp b/controller/ExtendedControllerBase.cpp
index 95ba012e..b5b8c660 100644
--- a/controller/ExtendedControllerBase.cpp
+++ b/controller/ExtendedControllerBase.cpp
@@ -17,14 +17,6 @@ ReturnValue_t ExtendedControllerBase::executeAction(ActionId_t actionId,
return HasReturnvaluesIF::RETURN_OK;
}
-
-
-ReturnValue_t ExtendedControllerBase::initializeLocalDataPool(
- localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) {
- /* Needs to be overriden and implemented by child class. */
- return HasReturnvaluesIF::RETURN_OK;
-}
-
object_id_t ExtendedControllerBase::getObjectId() const {
return SystemObject::getObjectId();
}
@@ -107,14 +99,6 @@ MessageQueueId_t ExtendedControllerBase::getCommandQueue() const {
return commandQueue->getId();
}
-LocalPoolDataSetBase* ExtendedControllerBase::getDataSetHandle(sid_t sid) {
-#if FSFW_CPP_OSTREAM_ENABLED == 1
- sif::warning << "ExtendedControllerBase::getDataSetHandle: No child "
- << " implementation provided, returning nullptr!" << std::endl;
-#endif
- return nullptr;
-}
-
LocalDataPoolManager* ExtendedControllerBase::getHkManagerHandle() {
return &poolManager;
}
diff --git a/controller/ExtendedControllerBase.h b/controller/ExtendedControllerBase.h
index f069819b..d5d43933 100644
--- a/controller/ExtendedControllerBase.h
+++ b/controller/ExtendedControllerBase.h
@@ -61,11 +61,11 @@ protected:
/* HasLocalDatapoolIF overrides */
virtual LocalDataPoolManager* getHkManagerHandle() override;
virtual object_id_t getObjectId() const override;
- virtual ReturnValue_t initializeLocalDataPool(
- localpool::DataPool& localDataPoolMap,
- LocalDataPoolManager& poolManager) override;
virtual uint32_t getPeriodicOperationFrequency() const override;
- virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
+
+ virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
+ LocalDataPoolManager& poolManager) override = 0;
+ virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override = 0;
};
diff --git a/datalinklayer/DataLinkLayer.h b/datalinklayer/DataLinkLayer.h
index 17a57d61..27e69006 100644
--- a/datalinklayer/DataLinkLayer.h
+++ b/datalinklayer/DataLinkLayer.h
@@ -19,7 +19,8 @@ class VirtualChannelReception;
class DataLinkLayer : public CCSDSReturnValuesIF {
public:
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SYSTEM_1;
- static const Event RF_AVAILABLE = MAKE_EVENT(0, severity::INFO); //!< A RF available signal was detected. P1: raw RFA state, P2: 0
+ //! [EXPORT] : [COMMENT] A RF available signal was detected. P1: raw RFA state, P2: 0
+ static const Event RF_AVAILABLE = MAKE_EVENT(0, severity::INFO);
static const Event RF_LOST = MAKE_EVENT(1, severity::INFO); //!< A previously found RF available signal was lost. P1: raw RFA state, P2: 0
static const Event BIT_LOCK = MAKE_EVENT(2, severity::INFO); //!< A Bit Lock signal. Was detected. P1: raw BLO state, P2: 0
static const Event BIT_LOCK_LOST = MAKE_EVENT(3, severity::INFO); //!< A previously found Bit Lock signal was lost. P1: raw BLO state, P2: 0
diff --git a/datapool/HkSwitchHelper.cpp b/datapool/HkSwitchHelper.cpp
index 1a2a25eb..21e37f59 100644
--- a/datapool/HkSwitchHelper.cpp
+++ b/datapool/HkSwitchHelper.cpp
@@ -7,7 +7,7 @@ HkSwitchHelper::HkSwitchHelper(EventReportingProxyIF* eventProxy) :
}
HkSwitchHelper::~HkSwitchHelper() {
- // TODO Auto-generated destructor stub
+ QueueFactory::instance()->deleteMessageQueue(actionQueue);
}
ReturnValue_t HkSwitchHelper::initialize() {
diff --git a/datapool/PoolDataSetBase.cpp b/datapool/PoolDataSetBase.cpp
index bdca22c3..1bd58698 100644
--- a/datapool/PoolDataSetBase.cpp
+++ b/datapool/PoolDataSetBase.cpp
@@ -8,13 +8,16 @@
PoolDataSetBase::PoolDataSetBase(PoolVariableIF** registeredVariablesArray,
const size_t maxFillCount):
registeredVariables(registeredVariablesArray),
- maxFillCount(maxFillCount) {
-}
+ maxFillCount(maxFillCount) {}
PoolDataSetBase::~PoolDataSetBase() {}
ReturnValue_t PoolDataSetBase::registerVariable(PoolVariableIF *variable) {
+ if(registeredVariables == nullptr) {
+ /* Underlying container invalid */
+ return HasReturnvaluesIF::RETURN_FAILED;
+ }
if (state != States::STATE_SET_UNINITIALISED) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "DataSet::registerVariable: Call made in wrong position." << std::endl;
@@ -61,11 +64,11 @@ ReturnValue_t PoolDataSetBase::read(MutexIF::TimeoutType timeoutType,
}
else {
#if FSFW_CPP_OSTREAM_ENABLED == 1
- sif::error << "DataSet::read(): Call made in wrong position. Don't forget to commit"
- " member datasets!" << std::endl;
+ sif::warning << "PoolDataSetBase::read: Call made in wrong position. Don't forget to "
+ "commit member datasets!" << std::endl;
#else
- sif::printError("DataSet::read(): Call made in wrong position. Don't forget to commit"
- " member datasets!\n");
+ sif::printWarning("PoolDataSetBase::read: Call made in wrong position. Don't forget to "
+ "commit member datasets!\n");
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
result = SET_WAS_ALREADY_READ;
}
diff --git a/datapool/PoolDataSetIF.h b/datapool/PoolDataSetIF.h
index 9151f2f8..f905cc4d 100644
--- a/datapool/PoolDataSetIF.h
+++ b/datapool/PoolDataSetIF.h
@@ -9,8 +9,8 @@
* and unlock a data pool and read/commit semantics.
*/
class PoolDataSetIF:
- public DataSetIF,
- public ReadCommitIF {
+ virtual public DataSetIF,
+ virtual public ReadCommitIF {
public:
virtual~ PoolDataSetIF() {};
diff --git a/datapool/PoolEntry.cpp b/datapool/PoolEntry.cpp
index a5867222..6504e20c 100644
--- a/datapool/PoolEntry.cpp
+++ b/datapool/PoolEntry.cpp
@@ -7,7 +7,7 @@
template
PoolEntry::PoolEntry(std::initializer_list initValue, bool setValid ):
- length(initValue.size()), valid(setValid) {
+ length(static_cast(initValue.size())), valid(setValid) {
this->address = new T[this->length];
if(initValue.size() == 0) {
std::memset(this->address, 0, this->getByteSize());
diff --git a/datapool/SharedDataSetIF.h b/datapool/SharedDataSetIF.h
index b8d98794..4d23f87f 100644
--- a/datapool/SharedDataSetIF.h
+++ b/datapool/SharedDataSetIF.h
@@ -1,13 +1,15 @@
#ifndef FRAMEWORK_DATAPOOL_SHAREDDATASETIF_H_
#define FRAMEWORK_DATAPOOL_SHAREDDATASETIF_H_
+
#include "PoolDataSetIF.h"
-class SharedDataSetIF: public PoolDataSetIF {
+class SharedDataSetIF {
public:
virtual ~SharedDataSetIF() {};
private:
- virtual ReturnValue_t lockDataset(dur_millis_t mutexTimeout) = 0;
+ virtual ReturnValue_t lockDataset(MutexIF::TimeoutType timeoutType,
+ dur_millis_t mutexTimeout) = 0;
virtual ReturnValue_t unlockDataset() = 0;
};
diff --git a/datapoollocal/HasLocalDataPoolIF.h b/datapoollocal/HasLocalDataPoolIF.h
index d52c72b6..74e372c9 100644
--- a/datapoollocal/HasLocalDataPoolIF.h
+++ b/datapoollocal/HasLocalDataPoolIF.h
@@ -65,34 +65,45 @@ public:
* usually be the period the pool owner performs its periodic operation.
* @return
*/
- virtual uint32_t getPeriodicOperationFrequency() const = 0;
+ virtual dur_millis_t getPeriodicOperationFrequency() const = 0;
/**
* @brief This function will be called by the manager if an update
* notification is received.
* @details HasLocalDataPoolIF
* Can be overriden by the child class to handle changed datasets.
- * @param sid
- * @param storeId If a snapshot was requested, data will be located inside
+ * @param sid SID of the updated set
+ * @param storeId If a snapshot was requested, data will be located inside
* the IPC store with this store ID.
+ * @param clearMessage If this is set to true, the pool manager will take care of
+ * clearing the store automatically
*/
virtual void handleChangedDataset(sid_t sid,
- store_address_t storeId = storeId::INVALID_STORE_ADDRESS) {
- return;
+ store_address_t storeId = storeId::INVALID_STORE_ADDRESS,
+ bool* clearMessage = nullptr) {
+ if(clearMessage != nullptr) {
+ *clearMessage = true;
+ }
}
/**
* @brief This function will be called by the manager if an update
* notification is received.
* @details
- * Can be overriden by the child class to handle changed pool IDs.
- * @param sid
- * @param storeId If a snapshot was requested, data will be located inside
+ * Can be overriden by the child class to handle changed pool variables.
+ * @param gpid GPID of the updated variable.
+ * @param storeId If a snapshot was requested, data will be located inside
* the IPC store with this store ID.
+ * @param clearMessage Relevant for snapshots. If the boolean this points to is set to true,
+ * the pool manager will take care of clearing the store automatically
+ * after the callback.
*/
- virtual void handleChangedPoolVariable(gp_id_t globPoolId,
- store_address_t storeId = storeId::INVALID_STORE_ADDRESS) {
- return;
+ virtual void handleChangedPoolVariable(gp_id_t gpid,
+ store_address_t storeId = storeId::INVALID_STORE_ADDRESS,
+ bool* clearMessage = nullptr) {
+ if(clearMessage != nullptr) {
+ *clearMessage = true;
+ }
}
/**
diff --git a/datapoollocal/LocalDataPoolManager.cpp b/datapoollocal/LocalDataPoolManager.cpp
index 72873d99..dbe68ff1 100644
--- a/datapoollocal/LocalDataPoolManager.cpp
+++ b/datapoollocal/LocalDataPoolManager.cpp
@@ -10,7 +10,7 @@
#include "../housekeeping/AcceptsHkPacketsIF.h"
#include "../timemanager/CCSDSTime.h"
#include "../ipc/MutexFactory.h"
-#include "../ipc/MutexHelper.h"
+#include "../ipc/MutexGuard.h"
#include "../ipc/QueueFactory.h"
#include
@@ -38,7 +38,11 @@ LocalDataPoolManager::LocalDataPoolManager(HasLocalDataPoolIF* owner, MessageQue
hkQueue = queueToUse;
}
-LocalDataPoolManager::~LocalDataPoolManager() {}
+LocalDataPoolManager::~LocalDataPoolManager() {
+ if(mutex != nullptr) {
+ MutexFactory::instance()->deleteMutex(mutex);
+ }
+}
ReturnValue_t LocalDataPoolManager::initialize(MessageQueueIF* queueToUse) {
if(queueToUse == nullptr) {
@@ -132,13 +136,16 @@ ReturnValue_t LocalDataPoolManager::performHkOperation() {
ReturnValue_t LocalDataPoolManager::handleHkUpdate(HkReceiver& receiver,
ReturnValue_t& status) {
if(receiver.dataType == DataType::LOCAL_POOL_VARIABLE) {
- // Update packets shall only be generated from datasets.
+ /* Update packets shall only be generated from datasets. */
return HasReturnvaluesIF::RETURN_FAILED;
}
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner,
receiver.dataId.sid);
+ if(dataSet == nullptr) {
+ return DATASET_NOT_FOUND;
+ }
if(dataSet->hasChanged()) {
- // prepare and send update notification
+ /* Prepare and send update notification */
ReturnValue_t result = generateHousekeepingPacket(
receiver.dataId.sid, dataSet, true);
if(result != HasReturnvaluesIF::RETURN_OK) {
@@ -328,7 +335,7 @@ void LocalDataPoolManager::handleChangeResetLogic(
toReset->setChanged(false);
}
/* All recipients have been notified, reset the changed flag */
- if(changeInfo.currentUpdateCounter <= 1) {
+ else if(changeInfo.currentUpdateCounter <= 1) {
toReset->setChanged(false);
changeInfo.currentUpdateCounter = 0;
}
@@ -372,7 +379,7 @@ ReturnValue_t LocalDataPoolManager::subscribeForPeriodicPacket(sid_t sid,
LocalPoolDataSetAttorney::setReportingEnabled(*dataSet, enableReporting);
LocalPoolDataSetAttorney::setDiagnostic(*dataSet, isDiagnostics);
LocalPoolDataSetAttorney::initializePeriodicHelper(*dataSet, collectionInterval,
- owner->getPeriodicOperationFrequency(), isDiagnostics);
+ owner->getPeriodicOperationFrequency());
}
hkReceivers.push_back(hkReceiver);
@@ -398,7 +405,6 @@ ReturnValue_t LocalDataPoolManager::subscribeForUpdatePacket(sid_t sid,
hkReceiver.destinationQueue = hkReceiverObject->getHkQueue();
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
- //LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid);
if(dataSet != nullptr) {
LocalPoolDataSetAttorney::setReportingEnabled(*dataSet, true);
LocalPoolDataSetAttorney::setDiagnostic(*dataSet, isDiagnostics);
@@ -516,11 +522,19 @@ ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage(
}
case(HousekeepingMessage::REPORT_DIAGNOSTICS_REPORT_STRUCTURES): {
- return generateSetStructurePacket(sid, true);
+ result = generateSetStructurePacket(sid, true);
+ if(result == HasReturnvaluesIF::RETURN_OK) {
+ return result;
+ }
+ break;
}
case(HousekeepingMessage::REPORT_HK_REPORT_STRUCTURES): {
- return generateSetStructurePacket(sid, false);
+ result = generateSetStructurePacket(sid, false);
+ if(result == HasReturnvaluesIF::RETURN_OK) {
+ return result;
+ }
+ break;
}
case(HousekeepingMessage::MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL):
case(HousekeepingMessage::MODIFY_PARAMETER_REPORT_COLLECTION_INTERVAL): {
@@ -540,14 +554,15 @@ ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage(
case(HousekeepingMessage::GENERATE_ONE_PARAMETER_REPORT):
case(HousekeepingMessage::GENERATE_ONE_DIAGNOSTICS_REPORT): {
LocalPoolDataSetBase* dataSet =HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
- //LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid);
if(command == HousekeepingMessage::GENERATE_ONE_PARAMETER_REPORT
and LocalPoolDataSetAttorney::isDiagnostics(*dataSet)) {
- return WRONG_HK_PACKET_TYPE;
+ result = WRONG_HK_PACKET_TYPE;
+ break;
}
else if(command == HousekeepingMessage::GENERATE_ONE_DIAGNOSTICS_REPORT
and not LocalPoolDataSetAttorney::isDiagnostics(*dataSet)) {
- return WRONG_HK_PACKET_TYPE;
+ result = WRONG_HK_PACKET_TYPE;
+ break;
}
return generateHousekeepingPacket(HousekeepingMessage::getSid(message),
dataSet, true);
@@ -566,14 +581,22 @@ ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage(
case(HousekeepingMessage::UPDATE_SNAPSHOT_SET): {
store_address_t storeId;
HousekeepingMessage::getUpdateSnapshotSetCommand(message, &storeId);
- owner->handleChangedDataset(sid, storeId);
+ bool clearMessage = true;
+ owner->handleChangedDataset(sid, storeId, &clearMessage);
+ if(clearMessage) {
+ message->clear();
+ }
return HasReturnvaluesIF::RETURN_OK;
}
case(HousekeepingMessage::UPDATE_SNAPSHOT_VARIABLE): {
store_address_t storeId;
gp_id_t globPoolId = HousekeepingMessage::getUpdateSnapshotVariableCommand(message,
&storeId);
- owner->handleChangedPoolVariable(globPoolId, storeId);
+ bool clearMessage = true;
+ owner->handleChangedPoolVariable(globPoolId, storeId, &clearMessage);
+ if(clearMessage) {
+ message->clear();
+ }
return HasReturnvaluesIF::RETURN_OK;
}
@@ -616,7 +639,7 @@ ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid,
LocalPoolDataSetBase* dataSet, bool forDownlink,
MessageQueueId_t destination) {
if(dataSet == nullptr) {
- // Configuration error.
+ /* Configuration error. */
printWarningOrError(sif::OutputTypes::OUT_WARNING,
"generateHousekeepingPacket",
DATASET_NOT_FOUND);
@@ -632,7 +655,7 @@ ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid,
return result;
}
- // and now we set a HK message and send it the HK packet destination.
+ /* Now we set a HK message and send it the HK packet destination. */
CommandMessage hkMessage;
if(LocalPoolDataSetAttorney::isDiagnostics(*dataSet)) {
HousekeepingMessage::setHkDiagnosticsReply(&hkMessage, sid, storeId);
@@ -642,7 +665,7 @@ ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid,
}
if(hkQueue == nullptr) {
- // error, no queue available to send packet with.
+ /* Error, no queue available to send packet with. */
printWarningOrError(sif::OutputTypes::OUT_WARNING,
"generateHousekeepingPacket",
QUEUE_OR_DESTINATION_INVALID);
@@ -650,7 +673,7 @@ ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid,
}
if(destination == MessageQueueIF::NO_QUEUE) {
if(hkDestinationId == MessageQueueIF::NO_QUEUE) {
- // error, all destinations invalid
+ /* Error, all destinations invalid */
printWarningOrError(sif::OutputTypes::OUT_WARNING,
"generateHousekeepingPacket",
QUEUE_OR_DESTINATION_INVALID);
@@ -729,6 +752,12 @@ void LocalDataPoolManager::performPeriodicHkGeneration(HkReceiver& receiver) {
ReturnValue_t LocalDataPoolManager::togglePeriodicGeneration(sid_t sid,
bool enable, bool isDiagnostics) {
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
+ if(dataSet == nullptr) {
+ printWarningOrError(sif::OutputTypes::OUT_WARNING, "togglePeriodicGeneration",
+ DATASET_NOT_FOUND);
+ return DATASET_NOT_FOUND;
+ }
+
if((LocalPoolDataSetAttorney::isDiagnostics(*dataSet) and not isDiagnostics) or
(not LocalPoolDataSetAttorney::isDiagnostics(*dataSet) and isDiagnostics)) {
return WRONG_HK_PACKET_TYPE;
@@ -746,6 +775,12 @@ ReturnValue_t LocalDataPoolManager::togglePeriodicGeneration(sid_t sid,
ReturnValue_t LocalDataPoolManager::changeCollectionInterval(sid_t sid,
float newCollectionInterval, bool isDiagnostics) {
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
+ if(dataSet == nullptr) {
+ printWarningOrError(sif::OutputTypes::OUT_WARNING, "changeCollectionInterval",
+ DATASET_NOT_FOUND);
+ return DATASET_NOT_FOUND;
+ }
+
bool targetIsDiagnostics = LocalPoolDataSetAttorney::isDiagnostics(*dataSet);
if((targetIsDiagnostics and not isDiagnostics) or
(not targetIsDiagnostics and isDiagnostics)) {
@@ -756,7 +791,7 @@ ReturnValue_t LocalDataPoolManager::changeCollectionInterval(sid_t sid,
LocalPoolDataSetAttorney::getPeriodicHelper(*dataSet);
if(periodicHelper == nullptr) {
- // config error
+ /* Configuration error, set might not have a corresponding pool manager */
return PERIODIC_HELPER_INVALID;
}
@@ -766,13 +801,11 @@ ReturnValue_t LocalDataPoolManager::changeCollectionInterval(sid_t sid,
ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid,
bool isDiagnostics) {
- // Get and check dataset first.
- //LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid);
+ /* Get and check dataset first. */
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
if(dataSet == nullptr) {
printWarningOrError(sif::OutputTypes::OUT_WARNING,
- "performPeriodicHkGeneration",
- DATASET_NOT_FOUND);
+ "performPeriodicHkGeneration", DATASET_NOT_FOUND);
return DATASET_NOT_FOUND;
}
@@ -831,6 +864,10 @@ ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid,
void LocalDataPoolManager::clearReceiversList() {
/* Clear the vector completely and releases allocated memory. */
HkReceivers().swap(hkReceivers);
+ /* Also clear the reset helper if it exists */
+ if(hkUpdateResetList != nullptr) {
+ HkUpdateResetList().swap(*hkUpdateResetList);
+ }
}
MutexIF* LocalDataPoolManager::getLocalPoolMutex() {
@@ -843,6 +880,7 @@ object_id_t LocalDataPoolManager::getCreatorObjectId() const {
void LocalDataPoolManager::printWarningOrError(sif::OutputTypes outputType,
const char* functionName, ReturnValue_t error, const char* errorPrint) {
+#if FSFW_VERBOSE_LEVEL >= 1
if(errorPrint == nullptr) {
if(error == DATASET_NOT_FOUND) {
errorPrint = "Dataset not found";
@@ -871,33 +909,32 @@ void LocalDataPoolManager::printWarningOrError(sif::OutputTypes outputType,
errorPrint = "Unknown error";
}
}
+ object_id_t objectId = 0xffffffff;
+ if(owner != nullptr) {
+ objectId = owner->getObjectId();
+ }
if(outputType == sif::OutputTypes::OUT_WARNING) {
-#if FSFW_VERBOSE_LEVEL >= 1
#if FSFW_CPP_OSTREAM_ENABLED == 1
- sif::warning << "LocalDataPoolManager::" << functionName
- << ": Object ID 0x" << std::setw(8) << std::setfill('0')
- << std::hex << owner->getObjectId() << " | " << errorPrint
- << std::dec << std::setfill(' ') << std::endl;
+ sif::warning << "LocalDataPoolManager::" << functionName << ": Object ID 0x" <<
+ std::setw(8) << std::setfill('0') << std::hex << objectId << " | " << errorPrint <<
+ std::dec << std::setfill(' ') << std::endl;
#else
sif::printWarning("LocalDataPoolManager::%s: Object ID 0x%08x | %s\n",
- functionName, owner->getObjectId(), errorPrint);
+ functionName, objectId, errorPrint);
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
-#endif /* FSFW_VERBOSE_LEVEL >= 1 */
}
else if(outputType == sif::OutputTypes::OUT_ERROR) {
-#if FSFW_VERBOSE_LEVEL >= 1
#if FSFW_CPP_OSTREAM_ENABLED == 1
- sif::error << "LocalDataPoolManager::" << functionName
- << ": Object ID 0x" << std::setw(8) << std::setfill('0')
- << std::hex << owner->getObjectId() << " | " << errorPrint
- << std::dec << std::setfill(' ') << std::endl;
+ sif::error << "LocalDataPoolManager::" << functionName << ": Object ID 0x" <<
+ std::setw(8) << std::setfill('0') << std::hex << objectId << " | " << errorPrint <<
+ std::dec << std::setfill(' ') << std::endl;
#else
sif::printError("LocalDataPoolManager::%s: Object ID 0x%08x | %s\n",
- functionName, owner->getObjectId(), errorPrint);
+ functionName, objectId, errorPrint);
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
-#endif /* FSFW_VERBOSE_LEVEL >= 1 */
}
+#endif /* #if FSFW_VERBOSE_LEVEL >= 1 */
}
LocalDataPoolManager* LocalDataPoolManager::getPoolManagerHandle() {
diff --git a/datapoollocal/LocalDataPoolManager.h b/datapoollocal/LocalDataPoolManager.h
index ff6edb95..2ec81f1c 100644
--- a/datapoollocal/LocalDataPoolManager.h
+++ b/datapoollocal/LocalDataPoolManager.h
@@ -14,7 +14,7 @@
#include "../ipc/MutexIF.h"
#include "../ipc/CommandMessage.h"
#include "../ipc/MessageQueueIF.h"
-#include "../ipc/MutexHelper.h"
+#include "../ipc/MutexGuard.h"
#include