Merge pull request 'Additional Update for Local Data Pools' (#367) from mueller/fsfw-update-2 into development

Reviewed-on: fsfw/fsfw#367
This commit is contained in:
Steffen Gaisser 2021-02-09 15:20:25 +01:00
commit 8a1f043b39
19 changed files with 2558 additions and 2521 deletions

View File

@ -81,4 +81,7 @@ now
For the fsfw, this can be done by checking the processor define FSFW_CPP_OSTREAM_ENABLED from FSFWConfig.h. For the fsfw, this can be done by checking the processor define FSFW_CPP_OSTREAM_ENABLED from FSFWConfig.h.
For mission code, developers need to replace sif:: calls by the printf counterparts, but only if the CPP stream are excluded. For mission code, developers need to replace sif:: calls by the printf counterparts, but only if the CPP stream are excluded.
If this is not the case, everything should work as usual. If this is not the case, everything should work as usual.
-
### PUS Parameter Service 20
Added PUS parameter service 20 (only custom subservices available).

View File

@ -1,4 +1,4 @@
target_sources(${LIB_FSFW_NAME} target_sources(${LIB_FSFW_NAME} PRIVATE
PRIVATE
ControllerBase.cpp ControllerBase.cpp
ExtendedControllerBase.cpp
) )

View File

@ -8,6 +8,9 @@ ExtendedControllerBase::ExtendedControllerBase(object_id_t objectId,
actionHelper(this, commandQueue) { actionHelper(this, commandQueue) {
} }
ExtendedControllerBase::~ExtendedControllerBase() {
}
ReturnValue_t ExtendedControllerBase::executeAction(ActionId_t actionId, ReturnValue_t ExtendedControllerBase::executeAction(ActionId_t actionId,
MessageQueueId_t commandedBy, const uint8_t *data, size_t size) { MessageQueueId_t commandedBy, const uint8_t *data, size_t size) {
// needs to be overriden and implemented by child class. // needs to be overriden and implemented by child class.

View File

@ -22,13 +22,14 @@ class ExtendedControllerBase: public ControllerBase,
public: public:
ExtendedControllerBase(object_id_t objectId, object_id_t parentId, ExtendedControllerBase(object_id_t objectId, object_id_t parentId,
size_t commandQueueDepth = 3); size_t commandQueueDepth = 3);
virtual ~ExtendedControllerBase();
/** SystemObjectIF overrides */ /* SystemObjectIF overrides */
virtual ReturnValue_t initialize() override; virtual ReturnValue_t initialize() override;
virtual MessageQueueId_t getCommandQueue() const override; virtual MessageQueueId_t getCommandQueue() const override;
/** ExecutableObjectIF overrides */ /* ExecutableObjectIF overrides */
virtual ReturnValue_t performOperation(uint8_t opCode) override; virtual ReturnValue_t performOperation(uint8_t opCode) override;
virtual ReturnValue_t initializeAfterTaskCreation() override; virtual ReturnValue_t initializeAfterTaskCreation() override;
@ -49,15 +50,15 @@ protected:
*/ */
virtual void performControlOperation() = 0; virtual void performControlOperation() = 0;
/** Handle the four messages mentioned above */ /* Handle the four messages mentioned above */
void handleQueue() override; void handleQueue() override;
/** HasActionsIF overrides */ /* HasActionsIF overrides */
virtual ReturnValue_t executeAction(ActionId_t actionId, virtual ReturnValue_t executeAction(ActionId_t actionId,
MessageQueueId_t commandedBy, const uint8_t* data, MessageQueueId_t commandedBy, const uint8_t* data,
size_t size) override; size_t size) override;
/** HasLocalDatapoolIF overrides */ /* HasLocalDatapoolIF overrides */
virtual LocalDataPoolManager* getHkManagerHandle() override; virtual LocalDataPoolManager* getHkManagerHandle() override;
virtual object_id_t getObjectId() const override; virtual object_id_t getObjectId() const override;
virtual ReturnValue_t initializeLocalDataPool( virtual ReturnValue_t initializeLocalDataPool(

View File

@ -1,5 +1,6 @@
#include "PoolDataSetBase.h" #include "PoolDataSetBase.h"
#include "../serviceinterface/ServiceInterfaceStream.h" #include "../serviceinterface/ServiceInterfaceStream.h"
#include <cstring>
PoolDataSetBase::PoolDataSetBase(PoolVariableIF** registeredVariablesArray, PoolDataSetBase::PoolDataSetBase(PoolVariableIF** registeredVariablesArray,
const size_t maxFillCount): const size_t maxFillCount):

View File

@ -39,8 +39,12 @@ public:
* supply a pointer to this dataset to PoolVariable * supply a pointer to this dataset to PoolVariable
* initializations to register pool variables. * initializations to register pool variables.
*/ */
PoolDataSetBase(PoolVariableIF** registeredVariablesArray, PoolDataSetBase(PoolVariableIF** registeredVariablesArray, const size_t maxFillCount);
const size_t maxFillCount);
/* Forbidden for now */
PoolDataSetBase(const PoolDataSetBase& otherSet) = delete;
const PoolDataSetBase& operator=(const PoolDataSetBase& otherSet) = delete;
virtual~ PoolDataSetBase(); virtual~ PoolDataSetBase();
/** /**
@ -63,8 +67,7 @@ public:
* - @c SET_WAS_ALREADY_READ if read() is called twice without calling * - @c SET_WAS_ALREADY_READ if read() is called twice without calling
* commit() in between * commit() in between
*/ */
virtual ReturnValue_t read( virtual ReturnValue_t read(MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
uint32_t lockTimeout = 20) override; uint32_t lockTimeout = 20) override;
/** /**
* @brief The commit call initializes writing back the registered variables. * @brief The commit call initializes writing back the registered variables.
@ -84,8 +87,7 @@ public:
* - @c COMMITING_WITHOUT_READING if set was not read yet and * - @c COMMITING_WITHOUT_READING if set was not read yet and
* contains non write-only variables * contains non write-only variables
*/ */
virtual ReturnValue_t commit( virtual ReturnValue_t commit(MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
uint32_t lockTimeout = 20) override; uint32_t lockTimeout = 20) override;
/** /**

View File

@ -80,7 +80,7 @@ public:
* @param storeId If a snapshot was requested, data will be located inside * @param storeId If a snapshot was requested, data will be located inside
* the IPC store with this store ID. * the IPC store with this store ID.
*/ */
virtual void handleChangedPoolVariable(lp_id_t poolId, virtual void handleChangedPoolVariable(gp_id_t globPoolId,
store_address_t storeId = storeId::INVALID_STORE_ADDRESS) { store_address_t storeId = storeId::INVALID_STORE_ADDRESS) {
return; return;
} }

View File

@ -102,7 +102,7 @@ ReturnValue_t LocalDataPoolManager::performHkOperation() {
switch(receiver.reportingType) { switch(receiver.reportingType) {
case(ReportingType::PERIODIC): { case(ReportingType::PERIODIC): {
if(receiver.dataType == DataType::LOCAL_POOL_VARIABLE) { if(receiver.dataType == DataType::LOCAL_POOL_VARIABLE) {
// Periodic packets shall only be generated from datasets. /* Periodic packets shall only be generated from datasets */
continue; continue;
} }
performPeriodicHkGeneration(receiver); performPeriodicHkGeneration(receiver);
@ -156,19 +156,17 @@ ReturnValue_t LocalDataPoolManager::handleNotificationUpdate(HkReceiver& receive
if(receiver.dataType == DataType::LOCAL_POOL_VARIABLE) { if(receiver.dataType == DataType::LOCAL_POOL_VARIABLE) {
LocalPoolObjectBase* poolObj = HasLocalDpIFManagerAttorney::getPoolObjectHandle(owner, LocalPoolObjectBase* poolObj = HasLocalDpIFManagerAttorney::getPoolObjectHandle(owner,
receiver.dataId.localPoolId); receiver.dataId.localPoolId);
//LocalPoolObjectBase* poolObj = owner->getPoolObjectHandle(receiver.dataId.localPoolId);
if(poolObj == nullptr) { if(poolObj == nullptr) {
printWarningOrError(sif::OutputTypes::OUT_WARNING, printWarningOrError(sif::OutputTypes::OUT_WARNING,
"handleNotificationUpdate", POOLOBJECT_NOT_FOUND); "handleNotificationUpdate", POOLOBJECT_NOT_FOUND);
return POOLOBJECT_NOT_FOUND; return POOLOBJECT_NOT_FOUND;
} }
if(poolObj->hasChanged()) { if(poolObj->hasChanged()) {
// prepare and send update notification. /* Prepare and send update notification. */
CommandMessage notification; CommandMessage notification;
HousekeepingMessage::setUpdateNotificationVariableCommand(&notification, HousekeepingMessage::setUpdateNotificationVariableCommand(&notification,
receiver.dataId.localPoolId); gp_id_t(owner->getObjectId(), receiver.dataId.localPoolId));
ReturnValue_t result = hkQueue->sendMessage( ReturnValue_t result = hkQueue->sendMessage(receiver.destinationQueue, &notification);
receiver.destinationQueue, &notification);
if(result != HasReturnvaluesIF::RETURN_OK) { if(result != HasReturnvaluesIF::RETURN_OK) {
status = result; status = result;
} }
@ -185,10 +183,10 @@ ReturnValue_t LocalDataPoolManager::handleNotificationUpdate(HkReceiver& receive
return DATASET_NOT_FOUND; return DATASET_NOT_FOUND;
} }
if(dataSet->hasChanged()) { if(dataSet->hasChanged()) {
// prepare and send update notification /* Prepare and send update notification */
CommandMessage notification; CommandMessage notification;
HousekeepingMessage::setUpdateNotificationSetCommand( HousekeepingMessage::setUpdateNotificationSetCommand(&notification,
&notification, receiver.dataId.sid); receiver.dataId.sid);
ReturnValue_t result = hkQueue->sendMessage( ReturnValue_t result = hkQueue->sendMessage(
receiver.destinationQueue, &notification); receiver.destinationQueue, &notification);
if(result != HasReturnvaluesIF::RETURN_OK) { if(result != HasReturnvaluesIF::RETURN_OK) {
@ -198,8 +196,7 @@ ReturnValue_t LocalDataPoolManager::handleNotificationUpdate(HkReceiver& receive
} }
} }
if(toReset != nullptr) { if(toReset != nullptr) {
handleChangeResetLogic(receiver.dataType, handleChangeResetLogic(receiver.dataType, receiver.dataId, toReset);
receiver.dataId, toReset);
} }
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
@ -207,7 +204,7 @@ ReturnValue_t LocalDataPoolManager::handleNotificationUpdate(HkReceiver& receive
ReturnValue_t LocalDataPoolManager::handleNotificationSnapshot( ReturnValue_t LocalDataPoolManager::handleNotificationSnapshot(
HkReceiver& receiver, ReturnValue_t& status) { HkReceiver& receiver, ReturnValue_t& status) {
MarkChangedIF* toReset = nullptr; MarkChangedIF* toReset = nullptr;
// check whether data has changed and send messages in case it has. /* Check whether data has changed and send messages in case it has */
if(receiver.dataType == DataType::LOCAL_POOL_VARIABLE) { if(receiver.dataType == DataType::LOCAL_POOL_VARIABLE) {
LocalPoolObjectBase* poolObj = HasLocalDpIFManagerAttorney::getPoolObjectHandle(owner, LocalPoolObjectBase* poolObj = HasLocalDpIFManagerAttorney::getPoolObjectHandle(owner,
receiver.dataId.localPoolId); receiver.dataId.localPoolId);
@ -221,14 +218,14 @@ ReturnValue_t LocalDataPoolManager::handleNotificationSnapshot(
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
// prepare and send update snapshot. /* Prepare and send update snapshot */
timeval now; timeval now;
Clock::getClock_timeval(&now); Clock::getClock_timeval(&now);
CCSDSTime::CDS_short cds; CCSDSTime::CDS_short cds;
CCSDSTime::convertToCcsds(&cds, &now); CCSDSTime::convertToCcsds(&cds, &now);
HousekeepingSnapshot updatePacket(reinterpret_cast<uint8_t*>(&cds), HousekeepingSnapshot updatePacket(reinterpret_cast<uint8_t*>(&cds), sizeof(cds),
sizeof(cds), HasLocalDpIFManagerAttorney::getPoolObjectHandle(owner, HasLocalDpIFManagerAttorney::getPoolObjectHandle(
receiver.dataId.localPoolId)); owner,receiver.dataId.localPoolId));
store_address_t storeId; store_address_t storeId;
ReturnValue_t result = addUpdateToStore(updatePacket, storeId); ReturnValue_t result = addUpdateToStore(updatePacket, storeId);
@ -238,7 +235,7 @@ ReturnValue_t LocalDataPoolManager::handleNotificationSnapshot(
CommandMessage notification; CommandMessage notification;
HousekeepingMessage::setUpdateSnapshotVariableCommand(&notification, HousekeepingMessage::setUpdateSnapshotVariableCommand(&notification,
receiver.dataId.localPoolId, storeId); gp_id_t(owner->getObjectId(), receiver.dataId.localPoolId), storeId);
result = hkQueue->sendMessage(receiver.destinationQueue, result = hkQueue->sendMessage(receiver.destinationQueue,
&notification); &notification);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
@ -259,7 +256,7 @@ ReturnValue_t LocalDataPoolManager::handleNotificationSnapshot(
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
// prepare and send update snapshot. /* Prepare and send update snapshot */
timeval now; timeval now;
Clock::getClock_timeval(&now); Clock::getClock_timeval(&now);
CCSDSTime::CDS_short cds; CCSDSTime::CDS_short cds;
@ -309,7 +306,7 @@ ReturnValue_t LocalDataPoolManager::addUpdateToStore(
void LocalDataPoolManager::handleChangeResetLogic( void LocalDataPoolManager::handleChangeResetLogic(
DataType type, DataId dataId, MarkChangedIF* toReset) { DataType type, DataId dataId, MarkChangedIF* toReset) {
if(hkUpdateResetList == nullptr) { if(hkUpdateResetList == nullptr) {
// config error! /* Config error */
return; return;
} }
HkUpdateResetList& listRef = *hkUpdateResetList; HkUpdateResetList& listRef = *hkUpdateResetList;
@ -326,16 +323,16 @@ void LocalDataPoolManager::handleChangeResetLogic(
continue; continue;
} }
// only one update recipient, we can reset changes status immediately. /* Only one update recipient, we can reset changes status immediately */
if(changeInfo.updateCounter <= 1) { if(changeInfo.updateCounter <= 1) {
toReset->setChanged(false); toReset->setChanged(false);
} }
// All recipients have been notified, reset the changed flag. /* All recipients have been notified, reset the changed flag */
if(changeInfo.currentUpdateCounter <= 1) { if(changeInfo.currentUpdateCounter <= 1) {
toReset->setChanged(false); toReset->setChanged(false);
changeInfo.currentUpdateCounter = 0; changeInfo.currentUpdateCounter = 0;
} }
// Not all recipiens have been notified yet, decrement. /* Not all recipiens have been notified yet, decrement */
else { else {
changeInfo.currentUpdateCounter--; changeInfo.currentUpdateCounter--;
} }
@ -371,7 +368,6 @@ ReturnValue_t LocalDataPoolManager::subscribeForPeriodicPacket(sid_t sid,
hkReceiver.destinationQueue = hkReceiverObject->getHkQueue(); hkReceiver.destinationQueue = hkReceiverObject->getHkQueue();
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid); LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
//LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid);
if(dataSet != nullptr) { if(dataSet != nullptr) {
LocalPoolDataSetAttorney::setReportingEnabled(*dataSet, enableReporting); LocalPoolDataSetAttorney::setReportingEnabled(*dataSet, enableReporting);
LocalPoolDataSetAttorney::setDiagnostic(*dataSet, isDiagnostics); LocalPoolDataSetAttorney::setDiagnostic(*dataSet, isDiagnostics);
@ -557,15 +553,14 @@ ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage(
dataSet, true); dataSet, true);
} }
// Notification handling. /* Notification handling */
case(HousekeepingMessage::UPDATE_NOTIFICATION_SET): { case(HousekeepingMessage::UPDATE_NOTIFICATION_SET): {
owner->handleChangedDataset(sid); owner->handleChangedDataset(sid);
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
case(HousekeepingMessage::UPDATE_NOTIFICATION_VARIABLE): { case(HousekeepingMessage::UPDATE_NOTIFICATION_VARIABLE): {
lp_id_t locPoolId = HousekeepingMessage:: gp_id_t globPoolId = HousekeepingMessage::getUpdateNotificationVariableCommand(message);
getUpdateNotificationVariableCommand(message); owner->handleChangedPoolVariable(globPoolId);
owner->handleChangedPoolVariable(locPoolId);
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
case(HousekeepingMessage::UPDATE_SNAPSHOT_SET): { case(HousekeepingMessage::UPDATE_SNAPSHOT_SET): {
@ -576,9 +571,9 @@ ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage(
} }
case(HousekeepingMessage::UPDATE_SNAPSHOT_VARIABLE): { case(HousekeepingMessage::UPDATE_SNAPSHOT_VARIABLE): {
store_address_t storeId; store_address_t storeId;
lp_id_t localPoolId = HousekeepingMessage:: gp_id_t globPoolId = HousekeepingMessage::getUpdateSnapshotVariableCommand(message,
getUpdateSnapshotVariableCommand(message, &storeId); &storeId);
owner->handleChangedPoolVariable(localPoolId, storeId); owner->handleChangedPoolVariable(globPoolId, storeId);
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
@ -693,7 +688,6 @@ void LocalDataPoolManager::setNonDiagnosticIntervalFactor(
void LocalDataPoolManager::performPeriodicHkGeneration(HkReceiver& receiver) { void LocalDataPoolManager::performPeriodicHkGeneration(HkReceiver& receiver) {
sid_t sid = receiver.dataId.sid; sid_t sid = receiver.dataId.sid;
//LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid);
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid); LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
if(dataSet == nullptr) { if(dataSet == nullptr) {
printWarningOrError(sif::OutputTypes::OUT_WARNING, printWarningOrError(sif::OutputTypes::OUT_WARNING,
@ -710,24 +704,23 @@ void LocalDataPoolManager::performPeriodicHkGeneration(HkReceiver& receiver) {
LocalPoolDataSetAttorney::getPeriodicHelper(*dataSet); LocalPoolDataSetAttorney::getPeriodicHelper(*dataSet);
if(periodicHelper == nullptr) { if(periodicHelper == nullptr) {
// Configuration error. /* Configuration error */
return; return;
} }
if(periodicHelper->checkOpNecessary()) { if(not periodicHelper->checkOpNecessary()) {
return; return;
} }
ReturnValue_t result = generateHousekeepingPacket( ReturnValue_t result = generateHousekeepingPacket(
sid, dataSet, true); sid, dataSet, true);
if(result != HasReturnvaluesIF::RETURN_OK) { if(result != HasReturnvaluesIF::RETURN_OK) {
// configuration error /* Configuration error */
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "LocalDataPoolManager::performHkOperation: " sif::warning << "LocalDataPoolManager::performHkOperation: HK generation failed." <<
<< "HK generation failed." << std::endl; std::endl;
#else #else
sif::printWarning("LocalDataPoolManager::performHkOperation: " sif::printWarning("LocalDataPoolManager::performHkOperation: HK generation failed.\n");
"HK generation failed.\n");
#endif #endif
} }
} }
@ -735,7 +728,6 @@ void LocalDataPoolManager::performPeriodicHkGeneration(HkReceiver& receiver) {
ReturnValue_t LocalDataPoolManager::togglePeriodicGeneration(sid_t sid, ReturnValue_t LocalDataPoolManager::togglePeriodicGeneration(sid_t sid,
bool enable, bool isDiagnostics) { bool enable, bool isDiagnostics) {
//LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid);
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid); LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
if((LocalPoolDataSetAttorney::isDiagnostics(*dataSet) and not isDiagnostics) or if((LocalPoolDataSetAttorney::isDiagnostics(*dataSet) and not isDiagnostics) or
(not LocalPoolDataSetAttorney::isDiagnostics(*dataSet) and isDiagnostics)) { (not LocalPoolDataSetAttorney::isDiagnostics(*dataSet) and isDiagnostics)) {
@ -753,7 +745,6 @@ ReturnValue_t LocalDataPoolManager::togglePeriodicGeneration(sid_t sid,
ReturnValue_t LocalDataPoolManager::changeCollectionInterval(sid_t sid, ReturnValue_t LocalDataPoolManager::changeCollectionInterval(sid_t sid,
float newCollectionInterval, bool isDiagnostics) { float newCollectionInterval, bool isDiagnostics) {
//LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid);
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid); LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
bool targetIsDiagnostics = LocalPoolDataSetAttorney::isDiagnostics(*dataSet); bool targetIsDiagnostics = LocalPoolDataSetAttorney::isDiagnostics(*dataSet);
if((targetIsDiagnostics and not isDiagnostics) or if((targetIsDiagnostics and not isDiagnostics) or
@ -848,7 +839,6 @@ MutexIF* LocalDataPoolManager::getLocalPoolMutex() {
object_id_t LocalDataPoolManager::getCreatorObjectId() const { object_id_t LocalDataPoolManager::getCreatorObjectId() const {
return owner->getObjectId(); return owner->getObjectId();
//return owner->getObjectId();
} }
void LocalDataPoolManager::printWarningOrError(sif::OutputTypes outputType, void LocalDataPoolManager::printWarningOrError(sif::OutputTypes outputType,
@ -883,26 +873,30 @@ void LocalDataPoolManager::printWarningOrError(sif::OutputTypes outputType,
} }
if(outputType == sif::OutputTypes::OUT_WARNING) { if(outputType == sif::OutputTypes::OUT_WARNING) {
#if FSFW_VERBOSE_LEVEL >= 1
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "LocalDataPoolManager::" << functionName sif::warning << "LocalDataPoolManager::" << functionName
<< ": Object ID " << std::setw(8) << std::setfill('0') << ": Object ID 0x" << std::setw(8) << std::setfill('0')
<< std::hex << owner->getObjectId() << " | " << errorPrint << std::hex << owner->getObjectId() << " | " << errorPrint
<< std::dec << std::setfill(' ') << std::endl; << std::dec << std::setfill(' ') << std::endl;
#else #else
sif::printWarning("LocalDataPoolManager::%s: Object ID 0x%08x | %s\n", sif::printWarning("LocalDataPoolManager::%s: Object ID 0x%08x | %s\n",
functionName, owner->getObjectId(), errorPrint); functionName, owner->getObjectId(), errorPrint);
#endif #endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
} }
else if(outputType == sif::OutputTypes::OUT_ERROR) { else if(outputType == sif::OutputTypes::OUT_ERROR) {
#if FSFW_VERBOSE_LEVEL >= 1
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "LocalDataPoolManager::" << functionName sif::error << "LocalDataPoolManager::" << functionName
<< ": Object ID " << std::setw(8) << std::setfill('0') << ": Object ID 0x" << std::setw(8) << std::setfill('0')
<< std::hex << owner->getObjectId() << " | " << errorPrint << std::hex << owner->getObjectId() << " | " << errorPrint
<< std::dec << std::setfill(' ') << std::endl; << std::dec << std::setfill(' ') << std::endl;
#else #else
sif::printError("LocalDataPoolManager::%s: Object ID 0x%08x | %s\n", sif::printError("LocalDataPoolManager::%s: Object ID 0x%08x | %s\n",
functionName, owner->getObjectId(), errorPrint); functionName, owner->getObjectId(), errorPrint);
#endif #endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
} }
} }

View File

@ -51,6 +51,7 @@ LocalPoolDataSetBase::LocalPoolDataSetBase(sid_t sid,
AccessPoolManagerIF* accessor = HasLocalDpIFUserAttorney::getAccessorHandle(hkOwner); AccessPoolManagerIF* accessor = HasLocalDpIFUserAttorney::getAccessorHandle(hkOwner);
if(accessor != nullptr) { if(accessor != nullptr) {
mutexIfSingleDataCreator = accessor->getLocalPoolMutex(); mutexIfSingleDataCreator = accessor->getLocalPoolMutex();
poolManager = accessor->getPoolManagerHandle();
} }
} }
@ -66,9 +67,19 @@ LocalPoolDataSetBase::LocalPoolDataSetBase(
LocalPoolDataSetBase::~LocalPoolDataSetBase() { LocalPoolDataSetBase::~LocalPoolDataSetBase() {
/* We only delete objects which were created in the class constructor */
if(periodicHelper != nullptr) { if(periodicHelper != nullptr) {
delete periodicHelper; delete periodicHelper;
} }
/* In case set was read but not comitted, we commit all variables with an invalid state */
if(state == States::STATE_SET_WAS_READ) {
for (uint16_t count = 0; count < fillCount; count++) {
if(registeredVariables[count] != nullptr) {
registeredVariables[count]->setValid(false);
registeredVariables[count]->commit(MutexIF::TimeoutType::WAITING, 20);
}
}
}
} }
ReturnValue_t LocalPoolDataSetBase::lockDataPool( ReturnValue_t LocalPoolDataSetBase::lockDataPool(
@ -83,7 +94,7 @@ ReturnValue_t LocalPoolDataSetBase::lockDataPool(
ReturnValue_t LocalPoolDataSetBase::serializeWithValidityBuffer(uint8_t **buffer, ReturnValue_t LocalPoolDataSetBase::serializeWithValidityBuffer(uint8_t **buffer,
size_t *size, size_t maxSize, size_t *size, size_t maxSize,
SerializeIF::Endianness streamEndianness) const { SerializeIF::Endianness streamEndianness) const {
ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED; ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
uint8_t validityMaskSize = std::ceil(static_cast<float>(fillCount)/8.0); uint8_t validityMaskSize = std::ceil(static_cast<float>(fillCount)/8.0);
uint8_t validityMask[validityMaskSize]; uint8_t validityMask[validityMaskSize];
uint8_t validBufferIndex = 0; uint8_t validBufferIndex = 0;

View File

@ -97,12 +97,18 @@ public:
* @brief The destructor automatically manages writing the valid * @brief The destructor automatically manages writing the valid
* information of variables. * information of variables.
* @details * @details
* In case the data set was read out, but not committed(indicated by state), * In case the data set was read out, but not committed (indicated by state),
* the destructor parses all variables that are still registered to the set. * the destructor parses all variables that are still registered to the set.
* For each, the valid flag in the data pool is set to "invalid". * For each, the valid flag in the data pool is set to "invalid".
*/ */
~LocalPoolDataSetBase(); ~LocalPoolDataSetBase();
/* The copy constructor and assingment constructor are forbidden for now.
The use-cases are limited and the first step would be to implement them properly for the
base class */
LocalPoolDataSetBase(const LocalPoolDataSetBase& otherSet) = delete;
const LocalPoolDataSetBase& operator=(const LocalPoolDataSetBase& otherSet) = delete;
void setValidityBufferGeneration(bool withValidityBuffer); void setValidityBufferGeneration(bool withValidityBuffer);
sid_t getSid() const; sid_t getSid() const;
@ -153,6 +159,7 @@ public:
bool hasChanged() const override; bool hasChanged() const override;
object_id_t getCreatorObjectId(); object_id_t getCreatorObjectId();
protected: protected:
sid_t sid; sid_t sid;
//! This mutex is used if the data is created by one object only. //! This mutex is used if the data is created by one object only.

View File

@ -20,12 +20,10 @@ class LocalPoolObjectBase: public PoolVariableIF,
public HasReturnvaluesIF, public HasReturnvaluesIF,
public MarkChangedIF { public MarkChangedIF {
public: public:
LocalPoolObjectBase(lp_id_t poolId, LocalPoolObjectBase(lp_id_t poolId, HasLocalDataPoolIF* hkOwner, DataSetIF* dataSet,
HasLocalDataPoolIF* hkOwner, DataSetIF* dataSet,
pool_rwm_t setReadWriteMode); pool_rwm_t setReadWriteMode);
LocalPoolObjectBase(object_id_t poolOwner, lp_id_t poolId, LocalPoolObjectBase(object_id_t poolOwner, lp_id_t poolId, DataSetIF* dataSet = nullptr,
DataSetIF* dataSet = nullptr,
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE); pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE);
void setReadWriteMode(pool_rwm_t newReadWriteMode); void setReadWriteMode(pool_rwm_t newReadWriteMode);

View File

@ -38,7 +38,6 @@ public:
bool isDiagnostics, bool isDiagnostics,
object_id_t packetDestination) = 0; object_id_t packetDestination) = 0;
/** /**
* @brief Subscribe for a notification message which will be sent * @brief Subscribe for a notification message which will be sent
* if a dataset has changed. * if a dataset has changed.
@ -46,16 +45,15 @@ public:
* This subscription mechanism will generally be used internally by * This subscription mechanism will generally be used internally by
* other software components. * other software components.
* @param setId Set ID of the set to receive update messages from. * @param setId Set ID of the set to receive update messages from.
* @param destinationObject * @param destinationObject Object ID of the receiver.
* @param targetQueueId * @param targetQueueId Receiver queue ID
* @param generateSnapshot If this is set to true, a copy of the current * @param generateSnapshot If this is set to true, a copy of the current data with a
* data with a timestamp will be generated and sent via message. * timestamp will be generated and sent via message.
* Otherwise, only an notification message is sent. * Otherwise, only an notification message is sent.
* @return * @return
*/ */
virtual ReturnValue_t subscribeForSetUpdateMessages(const uint32_t setId, virtual ReturnValue_t subscribeForSetUpdateMessages(const uint32_t setId,
object_id_t destinationObject, object_id_t destinationObject, MessageQueueId_t targetQueueId,
MessageQueueId_t targetQueueId,
bool generateSnapshot) = 0; bool generateSnapshot) = 0;
/** /**
@ -65,11 +63,11 @@ public:
* This subscription mechanism will generally be used internally by * This subscription mechanism will generally be used internally by
* other software components. * other software components.
* @param localPoolId Pool ID of the pool variable * @param localPoolId Pool ID of the pool variable
* @param destinationObject * @param destinationObject Object ID of the receiver
* @param targetQueueId * @param targetQueueId Receiver queue ID
* @param generateSnapshot If this is set to true, a copy of the current * @param generateSnapshot If this is set to true, a copy of the current data with a
* data with a timestamp will be generated and sent via message. * timestamp will be generated and sent via message. Otherwise,
* Otherwise, only an notification message is sent. * only an notification message is sent.
* @return * @return
*/ */
virtual ReturnValue_t subscribeForVariableUpdateMessages( virtual ReturnValue_t subscribeForVariableUpdateMessages(

View File

@ -17,16 +17,15 @@ object_id_t DeviceHandlerBase::powerSwitcherId = objects::NO_OBJECT;
object_id_t DeviceHandlerBase::rawDataReceiverId = objects::NO_OBJECT; object_id_t DeviceHandlerBase::rawDataReceiverId = objects::NO_OBJECT;
object_id_t DeviceHandlerBase::defaultFdirParentId = objects::NO_OBJECT; object_id_t DeviceHandlerBase::defaultFdirParentId = objects::NO_OBJECT;
DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication,
object_id_t deviceCommunication, CookieIF * comCookie, CookieIF* comCookie, FailureIsolationBase* fdirInstance, size_t cmdQueueSize):
FailureIsolationBase* fdirInstance, size_t cmdQueueSize) :
SystemObject(setObjectId), mode(MODE_OFF), submode(SUBMODE_NONE), SystemObject(setObjectId), mode(MODE_OFF), submode(SUBMODE_NONE),
wiretappingMode(OFF), storedRawData(StorageManagerIF::INVALID_ADDRESS), wiretappingMode(OFF), storedRawData(StorageManagerIF::INVALID_ADDRESS),
deviceCommunicationId(deviceCommunication), comCookie(comCookie), deviceCommunicationId(deviceCommunication), comCookie(comCookie),
healthHelper(this,setObjectId), modeHelper(this), parameterHelper(this), healthHelper(this,setObjectId), modeHelper(this), parameterHelper(this),
actionHelper(this, nullptr), poolManager(this, nullptr), actionHelper(this, nullptr), poolManager(this, nullptr),
childTransitionFailure(RETURN_OK), fdirInstance(fdirInstance), childTransitionFailure(RETURN_OK), fdirInstance(fdirInstance),
hkSwitcher(this), defaultFDIRUsed(fdirInstance == nullptr), defaultFDIRUsed(fdirInstance == nullptr),
switchOffWasReported(false), childTransitionDelay(5000), switchOffWasReported(false), childTransitionDelay(5000),
transitionSourceMode(_MODE_POWER_DOWN), transitionSourceMode(_MODE_POWER_DOWN),
transitionSourceSubMode(SUBMODE_NONE) { transitionSourceSubMode(SUBMODE_NONE) {
@ -80,7 +79,6 @@ ReturnValue_t DeviceHandlerBase::performOperation(uint8_t counter) {
checkSwitchState(); checkSwitchState();
decrementDeviceReplyMap(); decrementDeviceReplyMap();
fdirInstance->checkForFailures(); fdirInstance->checkForFailures();
hkSwitcher.performOperation();
performOperationHook(); performOperationHook();
return RETURN_OK; return RETURN_OK;
} }
@ -92,7 +90,7 @@ ReturnValue_t DeviceHandlerBase::performOperation(uint8_t counter) {
switch (getComAction()) { switch (getComAction()) {
case CommunicationAction::SEND_WRITE: case CommunicationAction::SEND_WRITE:
if (cookieInfo.state == COOKIE_UNUSED) { if (cookieInfo.state == COOKIE_UNUSED) {
// if no external command was specified, build internal command. /* If no external command was specified, build internal command. */
buildInternalCommand(); buildInternalCommand();
} }
doSendWrite(); doSendWrite();
@ -105,8 +103,8 @@ ReturnValue_t DeviceHandlerBase::performOperation(uint8_t counter) {
break; break;
case CommunicationAction::GET_READ: case CommunicationAction::GET_READ:
doGetRead(); doGetRead();
// This will be performed after datasets have been updated by the /* This will be performed after datasets have been updated by the
// custom device implementation. custom device implementation. */
poolManager.performHkOperation(); poolManager.performHkOperation();
break; break;
default: default:
@ -205,11 +203,6 @@ ReturnValue_t DeviceHandlerBase::initialize() {
return result; return result;
} }
result = hkSwitcher.initialize();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = poolManager.initialize(commandQueue); result = poolManager.initialize(commandQueue);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
@ -442,8 +435,7 @@ ReturnValue_t DeviceHandlerBase::insertInReplyMap(DeviceCommandId_t replyId,
} }
} }
ReturnValue_t DeviceHandlerBase::insertInCommandMap( ReturnValue_t DeviceHandlerBase::insertInCommandMap(DeviceCommandId_t deviceCommand) {
DeviceCommandId_t deviceCommand) {
DeviceCommandInfo info; DeviceCommandInfo info;
info.expectedReplies = 0; info.expectedReplies = 0;
info.isExecuting = false; info.isExecuting = false;
@ -506,7 +498,8 @@ void DeviceHandlerBase::setTransition(Mode_t modeTo, Submode_t submodeTo) {
} }
void DeviceHandlerBase::setMode(Mode_t newMode, uint8_t newSubmode) { void DeviceHandlerBase::setMode(Mode_t newMode, uint8_t newSubmode) {
changeHK(mode, submode, false); /* TODO: This will probably be done by the LocalDataPoolManager now */
//changeHK(mode, submode, false);
submode = newSubmode; submode = newSubmode;
mode = newMode; mode = newMode;
modeChanged(); modeChanged();
@ -529,7 +522,8 @@ void DeviceHandlerBase::setMode(Mode_t newMode, uint8_t newSubmode) {
} }
} }
changeHK(mode, submode, true); /* TODO: This will probably be done by the LocalDataPoolManager now */
//changeHK(mode, submode, true);
} }
void DeviceHandlerBase::setMode(Mode_t newMode) { void DeviceHandlerBase::setMode(Mode_t newMode) {
@ -706,13 +700,11 @@ void DeviceHandlerBase::parseReply(const uint8_t* receivedData,
ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED; ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED;
DeviceCommandId_t foundId = DeviceHandlerIF::NO_COMMAND_ID; DeviceCommandId_t foundId = DeviceHandlerIF::NO_COMMAND_ID;
size_t foundLen = 0; size_t foundLen = 0;
// The loop may not execute more often than the number of received bytes /* The loop may not execute more often than the number of received bytes
// (worst case). This approach avoids infinite loops due to buggy (worst case). This approach avoids infinite loops due to buggy scanForReply routines. */
// scanForReply routines.
uint32_t remainingLength = receivedDataLen; uint32_t remainingLength = receivedDataLen;
for (uint32_t count = 0; count < receivedDataLen; count++) { for (uint32_t count = 0; count < receivedDataLen; count++) {
result = scanForReply(receivedData, remainingLength, &foundId, result = scanForReply(receivedData, remainingLength, &foundId, &foundLen);
&foundLen);
switch (result) { switch (result) {
case RETURN_OK: case RETURN_OK:
handleReply(receivedData, foundId, foundLen); handleReply(receivedData, foundId, foundLen);
@ -795,9 +787,9 @@ void DeviceHandlerBase::handleReply(const uint8_t* receivedData,
replyToReply(iter, result); replyToReply(iter, result);
} }
else { else {
// Other completion failure messages are created by timeout. /* Other completion failure messages are created by timeout.
// Powering down the device might take some time during which periodic Powering down the device might take some time during which periodic
// replies may still come in. replies may still come in. */
if (mode != _MODE_WAIT_OFF) { if (mode != _MODE_WAIT_OFF) {
triggerEvent(DEVICE_UNREQUESTED_REPLY, foundId); triggerEvent(DEVICE_UNREQUESTED_REPLY, foundId);
} }
@ -1248,11 +1240,11 @@ void DeviceHandlerBase::handleDeviceTM(SerializeIF *dataSet, DeviceCommandId_t r
} }
if (forceDirectTm and defaultRawReceiver != MessageQueueIF::NO_QUEUE) if (forceDirectTm and defaultRawReceiver != MessageQueueIF::NO_QUEUE)
{ {
// sid_t setSid = sid_t(this->getObjectId(), replyId); // sid_t setSid = sid_t(this->getObjectId(), replyId);
// LocalPoolDataSetBase* dataset = getDataSetHandle(setSid); // LocalPoolDataSetBase* dataset = getDataSetHandle(setSid);
// if(dataset != nullptr) { // if(dataset != nullptr) {
// poolManager.generateHousekeepingPacket(setSid, dataset, true); // poolManager.generateHousekeepingPacket(setSid, dataset, true);
// } // }
// hiding of sender needed so the service will handle it as // hiding of sender needed so the service will handle it as
// unexpected Data, no matter what state (progress or completed) // unexpected Data, no matter what state (progress or completed)
@ -1379,9 +1371,9 @@ void DeviceHandlerBase::forwardEvent(Event event, uint32_t parameter1,
void DeviceHandlerBase::doOffActivity() { void DeviceHandlerBase::doOffActivity() {
} }
ReturnValue_t DeviceHandlerBase::getParameter(uint8_t domainId, ReturnValue_t DeviceHandlerBase::getParameter(uint8_t domainId, uint8_t uniqueId,
uint8_t uniqueId, ParameterWrapper* parameterWrapper, ParameterWrapper* parameterWrapper, const ParameterWrapper* newValues,
const ParameterWrapper* newValues, uint16_t startAtIndex) { uint16_t startAtIndex) {
ReturnValue_t result = fdirInstance->getParameter(domainId, uniqueId, parameterWrapper, ReturnValue_t result = fdirInstance->getParameter(domainId, uniqueId, parameterWrapper,
newValues, startAtIndex); newValues, startAtIndex);
if (result != INVALID_DOMAIN_ID) { if (result != INVALID_DOMAIN_ID) {
@ -1407,14 +1399,10 @@ bool DeviceHandlerBase::commandIsExecuting(DeviceCommandId_t commandId) {
} }
void DeviceHandlerBase::changeHK(Mode_t mode, Submode_t submode, bool enable) {
}
void DeviceHandlerBase::setTaskIF(PeriodicTaskIF* task){ void DeviceHandlerBase::setTaskIF(PeriodicTaskIF* task){
executingTask = task; executingTask = task;
} }
// Default implementations empty.
void DeviceHandlerBase::debugInterface(uint8_t positionTracker, void DeviceHandlerBase::debugInterface(uint8_t positionTracker,
object_id_t objectId, uint32_t parameter) {} object_id_t objectId, uint32_t parameter) {}

View File

@ -20,7 +20,6 @@
#include "../action/ActionHelper.h" #include "../action/ActionHelper.h"
#include "../health/HealthHelper.h" #include "../health/HealthHelper.h"
#include "../parameters/ParameterHelper.h" #include "../parameters/ParameterHelper.h"
#include "../datapool/HkSwitchHelper.h"
#include "../datapoollocal/HasLocalDataPoolIF.h" #include "../datapoollocal/HasLocalDataPoolIF.h"
#include "../datapoollocal/LocalDataPoolManager.h" #include "../datapoollocal/LocalDataPoolManager.h"
@ -80,14 +79,14 @@ class StorageManagerIF;
* @ingroup devices * @ingroup devices
*/ */
class DeviceHandlerBase: public DeviceHandlerIF, class DeviceHandlerBase: public DeviceHandlerIF,
public HasReturnvaluesIF, public HasReturnvaluesIF,
public ExecutableObjectIF, public ExecutableObjectIF,
public SystemObject, public SystemObject,
public HasModesIF, public HasModesIF,
public HasHealthIF, public HasHealthIF,
public HasActionsIF, public HasActionsIF,
public ReceivesParameterMessagesIF, public ReceivesParameterMessagesIF,
public HasLocalDataPoolIF { public HasLocalDataPoolIF {
friend void (Factory::setStaticFrameworkObjectIds)(); friend void (Factory::setStaticFrameworkObjectIds)();
public: public:
/** /**
@ -148,8 +147,7 @@ public:
* 4. Decrements counter for timeout of replies by calling * 4. Decrements counter for timeout of replies by calling
* decrementDeviceReplyMap() * decrementDeviceReplyMap()
* 5. Performs FDIR check for failures * 5. Performs FDIR check for failures
* 6. Calls hkSwitcher.performOperation() * 6. If the device mode is MODE_OFF, return RETURN_OK.
* 7. If the device mode is MODE_OFF, return RETURN_OK.
* Otherwise, perform the Action property and performs depending * Otherwise, perform the Action property and performs depending
* on value specified by input value counter (incremented in PST). * on value specified by input value counter (incremented in PST).
* The child class tells base class what to do by setting this value. * The child class tells base class what to do by setting this value.
@ -217,9 +215,8 @@ public:
HealthState getHealth(); HealthState getHealth();
ReturnValue_t setHealth(HealthState health); ReturnValue_t setHealth(HealthState health);
virtual ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId, virtual ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId,
ParameterWrapper *parameterWrapper, ParameterWrapper *parameterWrapper, const ParameterWrapper *newValues,
const ParameterWrapper *newValues, uint16_t startAtIndex) override; uint16_t startAtIndex) override;
protected: protected:
/** /**
@ -248,7 +245,6 @@ protected:
* for a failed transition * for a failed transition
*/ */
virtual void doStartUp() = 0; virtual void doStartUp() = 0;
/** /**
* @brief This is used to let the child class handle the transition * @brief This is used to let the child class handle the transition
* from mode @c _MODE_SHUT_DOWN to @c _MODE_POWER_DOWN * from mode @c _MODE_SHUT_DOWN to @c _MODE_POWER_DOWN
@ -274,6 +270,7 @@ protected:
*/ */
virtual void doShutDown() = 0; virtual void doShutDown() = 0;
/* Command handling */
/** /**
* Build the device command to send for normal mode. * Build the device command to send for normal mode.
* *
@ -294,7 +291,6 @@ protected:
* - Anything else triggers an even with the returnvalue as a parameter. * - Anything else triggers an even with the returnvalue as a parameter.
*/ */
virtual ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t * id) = 0; virtual ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t * id) = 0;
/** /**
* Build the device command to send for a transitional mode. * Build the device command to send for a transitional mode.
* *
@ -318,7 +314,6 @@ protected:
* - Anything else triggers an even with the returnvalue as a parameter * - Anything else triggers an even with the returnvalue as a parameter
*/ */
virtual ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t * id) = 0; virtual ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t * id) = 0;
/** /**
* @brief Build a device command packet from data supplied by a direct * @brief Build a device command packet from data supplied by a direct
* command (PUS Service 8) * command (PUS Service 8)
@ -347,6 +342,7 @@ protected:
virtual ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand, virtual ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand,
const uint8_t * commandData, size_t commandDataLen) = 0; const uint8_t * commandData, size_t commandDataLen) = 0;
/* Reply handling */
/** /**
* @brief Scans a buffer for a valid reply. * @brief Scans a buffer for a valid reply.
* @details * @details
@ -382,7 +378,6 @@ protected:
*/ */
virtual ReturnValue_t scanForReply(const uint8_t *start, size_t len, virtual ReturnValue_t scanForReply(const uint8_t *start, size_t len,
DeviceCommandId_t *foundId, size_t *foundLen) = 0; DeviceCommandId_t *foundId, size_t *foundLen) = 0;
/** /**
* @brief Interpret a reply from the device. * @brief Interpret a reply from the device.
* @details * @details
@ -404,10 +399,19 @@ protected:
*/ */
virtual ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, virtual ReturnValue_t interpretDeviceReply(DeviceCommandId_t id,
const uint8_t *packet) = 0; const uint8_t *packet) = 0;
MessageQueueId_t getCommanderId(DeviceCommandId_t replyId) const;
/** /**
* @brief fill the #DeviceCommandMap and #DeviceReplyMap * Helper function to get pending command. This is useful for devices
* called by the initialize() of the base class * like SPI sensors to identify the last sent command.
* This only returns the command sent in the last SEND_WRITE cycle.
* @return
*/
DeviceCommandId_t getPendingCommand() const;
/* Specifying commands and replies */
/**
* @brief Fill the #DeviceCommandMap and #DeviceReplyMap called by the #initialize
* of the base class
* @details * @details
* This is used to let the base class know which replies are expected. * This is used to let the base class know which replies are expected.
* There are different scenarios regarding this: * There are different scenarios regarding this:
@ -437,7 +441,6 @@ protected:
* handled by returning @c APERIODIC_REPLY in scanForReply(). * handled by returning @c APERIODIC_REPLY in scanForReply().
*/ */
virtual void fillCommandAndReplyMap() = 0; virtual void fillCommandAndReplyMap() = 0;
/** /**
* This is a helper method to facilitate inserting entries in the command map. * This is a helper method to facilitate inserting entries in the command map.
* @param deviceCommand Identifier of the command to add. * @param deviceCommand Identifier of the command to add.
@ -455,7 +458,6 @@ protected:
LocalPoolDataSetBase* replyDataSet = nullptr, LocalPoolDataSetBase* replyDataSet = nullptr,
size_t replyLen = 0, bool periodic = false, size_t replyLen = 0, bool periodic = false,
bool hasDifferentReplyId = false, DeviceCommandId_t replyId = 0); bool hasDifferentReplyId = false, DeviceCommandId_t replyId = 0);
/** /**
* @brief This is a helper method to insert replies in the reply map. * @brief This is a helper method to insert replies in the reply map.
* @param deviceCommand Identifier of the reply to add. * @param deviceCommand Identifier of the reply to add.
@ -469,7 +471,6 @@ protected:
ReturnValue_t insertInReplyMap(DeviceCommandId_t deviceCommand, ReturnValue_t insertInReplyMap(DeviceCommandId_t deviceCommand,
uint16_t maxDelayCycles, LocalPoolDataSetBase* dataSet = nullptr, uint16_t maxDelayCycles, LocalPoolDataSetBase* dataSet = nullptr,
size_t replyLen = 0, bool periodic = false); size_t replyLen = 0, bool periodic = false);
/** /**
* @brief A simple command to add a command to the commandList. * @brief A simple command to add a command to the commandList.
* @param deviceCommand The command to add * @param deviceCommand The command to add
@ -495,25 +496,14 @@ protected:
ReturnValue_t updateReplyMapEntry(DeviceCommandId_t deviceReply, ReturnValue_t updateReplyMapEntry(DeviceCommandId_t deviceReply,
uint16_t delayCycles, uint16_t maxDelayCycles, uint16_t delayCycles, uint16_t maxDelayCycles,
bool periodic = false); bool periodic = false);
/**
* @brief Can be used to set the dataset corresponding to a reply ID manually.
* @details
* Used by the local data pool manager.
*/
ReturnValue_t setReplyDataset(DeviceCommandId_t replyId, ReturnValue_t setReplyDataset(DeviceCommandId_t replyId,
LocalPoolDataSetBase* dataset); LocalPoolDataSetBase* dataset);
/**
* @brief Can be implemented by child handler to
* perform debugging
* @details Example: Calling this in performOperation
* to track values like mode.
* @param positionTracker Provide the child handler a way to know
* where the debugInterface was called
* @param objectId Provide the child handler object Id to
* specify actions for spefic devices
* @param parameter Supply a parameter of interest
* Please delete all debugInterface calls in DHB after debugging is finished !
*/
virtual void debugInterface(uint8_t positionTracker = 0,
object_id_t objectId = 0, uint32_t parameter = 0);
/** /**
* Get the time needed to transit from modeFrom to modeTo. * Get the time needed to transit from modeFrom to modeTo.
* *
@ -532,6 +522,73 @@ protected:
*/ */
virtual uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) = 0; virtual uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) = 0;
/* Functions used by the local data pool manager */
/**
* This function is used to initialize the local housekeeping pool
* entries. The default implementation leaves the pool empty.
* @param localDataPoolMap
* @return
*/
virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) override;
/**
* @brief Set all datapool variables that are update periodically in
* normal mode invalid
* @details
* The default implementation will set all datasets which have been added
* in #fillCommandAndReplyMap to invalid. It will also set all pool
* variables inside the dataset to invalid. The user can override this
* method optionally.
*/
virtual void setNormalDatapoolEntriesInvalid();
/**
* @brief Get the dataset handle for a given SID.
* @details
* The default implementation will use the deviceCommandMap to look for the corresponding
* dataset handle. The user can override this function if this is not desired.
* @param sid
* @return
*/
virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
/* HasModesIF overrides */
virtual void startTransition(Mode_t mode, Submode_t submode) override;
virtual void setToExternalControl() override;
virtual void announceMode(bool recursive) override;
/**
* @brief Set the device handler mode
* @details
* Sets #timeoutStart with every call Also sets #transitionTargetMode if necessary so
* transitional states can be entered from everywhere without breaking the state machine
* (which relies on a correct #transitionTargetMode).
* The submode is left unchanged.
*
* @param newMode
*/
void setMode(Mode_t newMode);
/**
* @overload
* @param submode
*/
void setMode(Mode_t newMode, Submode_t submode);
/**
* @brief Should be implemented properly by child class.
* @param mode
* @param submode
* @return
* - @c RETURN_OK if valid
* - @c RETURN_FAILED if invalid
*/
virtual ReturnValue_t isModeCombinationValid(Mode_t mode,
Submode_t submode);
/**
* @brief Notify child about mode change.
* @details
* Can be overriden to be used like a callback.
*/
virtual void modeChanged();
/* Power handling functions */
/** /**
* Return the switches connected to the device. * Return the switches connected to the device.
* *
@ -547,39 +604,48 @@ protected:
uint8_t *numberOfSwitches); uint8_t *numberOfSwitches);
/** /**
* This function is used to initialize the local housekeeping pool * @brief Helper function to report a missed reply
* entries. The default implementation leaves the pool empty. * @details Can be overwritten by children to act on missed replies or to fake reporting Id.
* @param localDataPoolMap * @param id of the missed reply
* @return
*/ */
virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap, virtual void missedReply(DeviceCommandId_t id);
LocalDataPoolManager& poolManager) override;
/**
* Required for HasLocalDataPoolIF, return a handle to the local pool manager.
* @return
*/
LocalDataPoolManager* getHkManagerHandle() override;
/* Miscellaneous functions */
/** /**
* @brief Hook function for child handlers which is called once per * @brief Hook function for child handlers which is called once per
* performOperation(). Default implementation is empty. * performOperation(). Default implementation is empty.
*/ */
virtual void performOperationHook(); virtual void performOperationHook();
/**
* @brief Can be implemented by child handler to
* perform debugging
* @details Example: Calling this in performOperation
* to track values like mode.
* @param positionTracker Provide the child handler a way to know
* where the debugInterface was called
* @param objectId Provide the child handler object Id to
* specify actions for spefic devices
* @param parameter Supply a parameter of interest
* Please delete all debugInterface calls in DHB after debugging is finished !
*/
virtual void debugInterface(uint8_t positionTracker = 0,
object_id_t objectId = 0, uint32_t parameter = 0);
protected: protected:
/**
* The Returnvalues id of this class, required by HasReturnvaluesIF
*/
static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_BASE; static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_BASE;
static const ReturnValue_t INVALID_CHANNEL = MAKE_RETURN_CODE(0xA0); static const ReturnValue_t INVALID_CHANNEL = MAKE_RETURN_CODE(0xA0);
/* Return codes for scanForReply */ /* Return codes for scanForReply */
static const ReturnValue_t APERIODIC_REPLY = MAKE_RETURN_CODE(0xB0); //!< This is used to specify for replies from a device which are not replies to requests //! This is used to specify for replies from a device which are not replies to requests
static const ReturnValue_t IGNORE_REPLY_DATA = MAKE_RETURN_CODE(0xB1); //!< Ignore parts of the received packet static const ReturnValue_t APERIODIC_REPLY = MAKE_RETURN_CODE(0xB0);
static const ReturnValue_t IGNORE_FULL_PACKET = MAKE_RETURN_CODE(0xB2); //!< Ignore full received packet //! Ignore parts of the received packet
static const ReturnValue_t IGNORE_REPLY_DATA = MAKE_RETURN_CODE(0xB1);
//! Ignore full received packet
static const ReturnValue_t IGNORE_FULL_PACKET = MAKE_RETURN_CODE(0xB2);
/* Return codes for command building */ /* Return codes for command building */
static const ReturnValue_t NOTHING_TO_SEND = MAKE_RETURN_CODE(0xC0); //!< Return this if no command sending in required //! Return this if no command sending in required
static const ReturnValue_t NOTHING_TO_SEND = MAKE_RETURN_CODE(0xC0);
static const ReturnValue_t COMMAND_MAP_ERROR = MAKE_RETURN_CODE(0xC2); static const ReturnValue_t COMMAND_MAP_ERROR = MAKE_RETURN_CODE(0xC2);
// Return codes for getSwitches */ // Return codes for getSwitches */
static const ReturnValue_t NO_SWITCH = MAKE_RETURN_CODE(0xD0); static const ReturnValue_t NO_SWITCH = MAKE_RETURN_CODE(0xD0);
@ -589,9 +655,9 @@ protected:
static const MessageQueueId_t NO_COMMANDER = 0; static const MessageQueueId_t NO_COMMANDER = 0;
/** Pointer to the raw packet that will be sent.*/ //! Pointer to the raw packet that will be sent.
uint8_t *rawPacket = nullptr; uint8_t *rawPacket = nullptr;
/** Size of the #rawPacket. */ //! Size of the #rawPacket.
uint32_t rawPacketLen = 0; uint32_t rawPacketLen = 0;
/** /**
@ -649,15 +715,15 @@ protected:
/** Cookie used for communication */ /** Cookie used for communication */
CookieIF * comCookie; CookieIF * comCookie;
/** Health helper for HasHealthIF */ /* Health helper for HasHealthIF */
HealthHelper healthHelper; HealthHelper healthHelper;
/** Mode helper for HasModesIF */ /* Mode helper for HasModesIF */
ModeHelper modeHelper; ModeHelper modeHelper;
/** Parameter helper for ReceivesParameterMessagesIF */ /* Parameter helper for ReceivesParameterMessagesIF */
ParameterHelper parameterHelper; ParameterHelper parameterHelper;
/** Action helper for HasActionsIF */ /* Action helper for HasActionsIF */
ActionHelper actionHelper; ActionHelper actionHelper;
/** Housekeeping Manager */ /* Housekeeping Manager */
LocalDataPoolManager poolManager; LocalDataPoolManager poolManager;
/** /**
@ -740,90 +806,41 @@ protected:
* default class is instantiated. */ * default class is instantiated. */
FailureIsolationBase* fdirInstance; FailureIsolationBase* fdirInstance;
HkSwitchHelper hkSwitcher; //! To correctly delete the default instance.
bool defaultFDIRUsed;
bool defaultFDIRUsed; //!< To correctly delete the default instance. //! Indicates if SWITCH_WENT_OFF was already thrown.
bool switchOffWasReported;
bool switchOffWasReported; //!< Indicates if SWITCH_WENT_OFF was already thrown. /** Pointer to the task which executes this component,
is invalid before setTaskIF was called. */
//! Pointer to the task which executes this component, is invalid
//! before setTaskIF was called.
PeriodicTaskIF* executingTask = nullptr; PeriodicTaskIF* executingTask = nullptr;
//!< Object which switches power on and off. //! Object which switches power on and off.
static object_id_t powerSwitcherId; static object_id_t powerSwitcherId;
//!< Object which receives RAW data by default. //! Object which receives RAW data by default.
static object_id_t rawDataReceiverId; static object_id_t rawDataReceiverId;
//!< Object which may be the root cause of an identified fault. //! Object which may be the root cause of an identified fault.
static object_id_t defaultFdirParentId; static object_id_t defaultFdirParentId;
/** /**
* @brief Set all datapool variables that are update periodically in * @brief Send a reply to a received device handler command.
* normal mode invalid
* @details
* The default implementation will set all datasets which have been added
* in #fillCommandAndReplyMap to invalid. It will also set all pool
* variables inside the dataset to invalid. The user can override this
* method optionally.
*/
virtual void setNormalDatapoolEntriesInvalid();
MessageQueueId_t getCommanderId(DeviceCommandId_t replyId) const;
/**
* Helper function to get pending command. This is useful for devices
* like SPI sensors to identify the last sent command.
* This only returns the command sent in the last SEND_WRITE cycle.
* @return
*/
DeviceCommandId_t getPendingCommand() const;
/**
* Helper function to report a missed reply
*
* Can be overwritten by children to act on missed replies or to fake
* reporting Id.
*
* @param id of the missed reply
*/
virtual void missedReply(DeviceCommandId_t id);
/**
* Send a reply to a received device handler command.
* *
* This also resets #DeviceHandlerCommand to 0. * This also resets #DeviceHandlerCommand to 0.
* *
* @param reply the reply type * @param reply the reply type
* @param parameter parameter for the reply * @param parameter parameter for the reply
*/ */
void replyReturnvalueToCommand(ReturnValue_t status, void replyReturnvalueToCommand(ReturnValue_t status, uint32_t parameter = 0);
uint32_t parameter = 0); /**
* TODO: Whats the difference between this and the upper command?
* @param status
* @param parameter
*/
void replyToCommand(ReturnValue_t status, uint32_t parameter = 0); void replyToCommand(ReturnValue_t status, uint32_t parameter = 0);
/**
* Set the device handler mode
*
* Sets #timeoutStart with every call.
*
* Sets #transitionTargetMode if necessary so transitional states can be
* entered from everywhere without breaking the state machine
* (which relies on a correct #transitionTargetMode).
*
* The submode is left unchanged.
*
* @param newMode
*/
void setMode(Mode_t newMode);
/**
* @overload
* @param submode
*/
void setMode(Mode_t newMode, Submode_t submode);
/** /**
* Do the transition to the main modes (MODE_ON, MODE_NORMAL and MODE_RAW). * Do the transition to the main modes (MODE_ON, MODE_NORMAL and MODE_RAW).
* *
@ -865,16 +882,6 @@ protected:
*/ */
virtual void doTransition(Mode_t modeFrom, Submode_t subModeFrom); virtual void doTransition(Mode_t modeFrom, Submode_t subModeFrom);
/**
* @param mode
* @param submode
* @return
* - @c RETURN_OK if valid
* - @c RETURN_FAILED if invalid
*/
virtual ReturnValue_t isModeCombinationValid(Mode_t mode,
Submode_t submode);
/** /**
* Get the communication action for the current step. * Get the communication action for the current step.
* The step number can be read from #pstStep. * The step number can be read from #pstStep.
@ -883,27 +890,28 @@ protected:
virtual CommunicationAction getComAction(); virtual CommunicationAction getComAction();
/** /**
* Build the device command to send for raw mode. * Checks state of switches in conjunction with mode and triggers an event
* * if they don't fit.
* This is only called in @c MODE_RAW. It is for the rare case that in
* raw mode packets are to be sent by the handler itself. It is NOT needed
* for the raw commanding service. Its only current use is in the STR
* handler which gets its raw packets from a different source.
* Also it can be used for transitional commands, to get the device ready
* for @c MODE_RAW
*
* As it is almost never used, there is a default implementation
* returning @c NOTHING_TO_SEND.
*
* #rawPacket and #rawPacketLen must be set by this method to the packet
* to be sent.
*
* @param[out] id the device command id built
* @return
* - @c RETURN_OK when a command is to be sent
* - not @c NOTHING_TO_SEND when no command is to be sent
*/ */
virtual ReturnValue_t buildChildRawCommand(); virtual void checkSwitchState();
/**
* Reserved for the rare case where a device needs to perform additional
* operation cyclically in OFF mode.
*/
virtual void doOffActivity();
/**
* Reserved for the rare case where a device needs to perform additional
* operation cyclically in ON mode.
*/
virtual void doOnActivity();
/**
* Required for HasLocalDataPoolIF, return a handle to the local pool manager.
* @return
*/
LocalDataPoolManager* getHkManagerHandle() override;
/** /**
* Returns the delay cycle count of a reply. * Returns the delay cycle count of a reply.
@ -915,24 +923,6 @@ protected:
*/ */
uint8_t getReplyDelayCycles(DeviceCommandId_t deviceCommand); uint8_t getReplyDelayCycles(DeviceCommandId_t deviceCommand);
/**
* Construct a command reply containing a raw reply.
*
* It gets space in the #IPCStore, copies data there, then sends a raw reply
* containing the store address.
*
* This method is virtual, as devices can have different channels to send
* raw replies
*
* @param data data to send
* @param len length of @c data
* @param sendTo the messageQueueId of the one to send to
* @param isCommand marks the raw data as a command, the message then
* will be of type raw_command
*/
virtual void replyRawData(const uint8_t *data, size_t len,
MessageQueueId_t sendTo, bool isCommand = false);
/** /**
* Calls replyRawData() with #defaultRawReceiver, but checks if wiretapping * Calls replyRawData() with #defaultRawReceiver, but checks if wiretapping
* is active and if so, does not send the data as the wiretapping will have * is active and if so, does not send the data as the wiretapping will have
@ -940,11 +930,6 @@ protected:
*/ */
void replyRawReplyIfnotWiretapped(const uint8_t *data, size_t len); void replyRawReplyIfnotWiretapped(const uint8_t *data, size_t len);
/**
* @brief Notify child about mode change.
*/
virtual void modeChanged(void);
/** /**
* Enable the reply checking for a command * Enable the reply checking for a command
* *
@ -972,6 +957,45 @@ protected:
uint8_t expectedReplies = 1, bool useAlternateId = false, uint8_t expectedReplies = 1, bool useAlternateId = false,
DeviceCommandId_t alternateReplyID = 0); DeviceCommandId_t alternateReplyID = 0);
/**
* @brief Build the device command to send for raw mode.
* @details
* This is only called in @c MODE_RAW. It is for the rare case that in
* raw mode packets are to be sent by the handler itself. It is NOT needed
* for the raw commanding service. Its only current use is in the STR
* handler which gets its raw packets from a different source.
* Also it can be used for transitional commands, to get the device ready
* for @c MODE_RAW
*
* As it is almost never used, there is a default implementation
* returning @c NOTHING_TO_SEND.
*
* #rawPacket and #rawPacketLen must be set by this method to the packet
* to be sent.
*
* @param[out] id the device command id built
* @return
* - @c RETURN_OK when a command is to be sent
* - not @c NOTHING_TO_SEND when no command is to be sent
*/
virtual ReturnValue_t buildChildRawCommand();
/**
* @brief Construct a command reply containing a raw reply.
* @details
* It gets space in the #IPCStore, copies data there, then sends a raw reply
* containing the store address. This method is virtual, as devices can have different channels
* to send raw replies
*
* @param data data to send
* @param len length of @c data
* @param sendTo the messageQueueId of the one to send to
* @param isCommand marks the raw data as a command, the message then
* will be of type raw_command
*/
virtual void replyRawData(const uint8_t *data, size_t len,
MessageQueueId_t sendTo, bool isCommand = false);
/** /**
* Get the state of the PCDU switches in the local datapool * Get the state of the PCDU switches in the local datapool
* @return * @return
@ -981,12 +1005,7 @@ protected:
* #switches are off * #switches are off
* - @c PowerSwitchIF::RETURN_FAILED if an error occured * - @c PowerSwitchIF::RETURN_FAILED if an error occured
*/ */
ReturnValue_t getStateOfSwitches(void); ReturnValue_t getStateOfSwitches();
/**
* build a list of sids and pass it to the #hkSwitcher
*/
virtual void changeHK(Mode_t mode, Submode_t submode, bool enable);
/** /**
* Children can overwrite this function to suppress checking of the * Children can overwrite this function to suppress checking of the
@ -1006,17 +1025,12 @@ protected:
void handleDeviceTM(SerializeIF *dataSet, DeviceCommandId_t replyId, void handleDeviceTM(SerializeIF *dataSet, DeviceCommandId_t replyId,
bool forceDirectTm = false); bool forceDirectTm = false);
// void handleDeviceTM(uint8_t* data, size_t dataSize, DeviceCommandId_t replyId, // void handleDeviceTM(uint8_t* data, size_t dataSize, DeviceCommandId_t replyId,
// bool forceDirectTm); // bool forceDirectTm);
virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t *msToReachTheMode); uint32_t *msToReachTheMode);
/* HasModesIF overrides */
virtual void startTransition(Mode_t mode, Submode_t submode) override;
virtual void setToExternalControl() override;
virtual void announceMode(bool recursive) override;
virtual ReturnValue_t letChildHandleMessage(CommandMessage *message); virtual ReturnValue_t letChildHandleMessage(CommandMessage *message);
/** /**
@ -1034,23 +1048,6 @@ protected:
*/ */
virtual void forwardEvent(Event event, uint32_t parameter1 = 0, virtual void forwardEvent(Event event, uint32_t parameter1 = 0,
uint32_t parameter2 = 0) const; uint32_t parameter2 = 0) const;
/**
* Checks state of switches in conjunction with mode and triggers an event
* if they don't fit.
*/
virtual void checkSwitchState();
/**
* Reserved for the rare case where a device needs to perform additional
* operation cyclically in OFF mode.
*/
virtual void doOffActivity();
/**
* Reserved for the rare case where a device needs to perform additional
* operation cyclically in ON mode.
*/
virtual void doOnActivity();
/** /**
* Checks if current mode is transitional mode. * Checks if current mode is transitional mode.
@ -1163,7 +1160,6 @@ private:
void buildRawDeviceCommand(CommandMessage* message); void buildRawDeviceCommand(CommandMessage* message);
void buildInternalCommand(void); void buildInternalCommand(void);
/** /**
* Decrement the counter for the timout of replies. * Decrement the counter for the timout of replies.
* *
@ -1171,7 +1167,6 @@ private:
* reply has timed out (that means a reply was expected but not received). * reply has timed out (that means a reply was expected but not received).
*/ */
void decrementDeviceReplyMap(void); void decrementDeviceReplyMap(void);
/** /**
* Convenience function to handle a reply. * Convenience function to handle a reply.
* *
@ -1186,8 +1181,8 @@ private:
* @foundLen the length of the packet * @foundLen the length of the packet
*/ */
void handleReply(const uint8_t *data, DeviceCommandId_t id, uint32_t foundLen); void handleReply(const uint8_t *data, DeviceCommandId_t id, uint32_t foundLen);
void replyToReply(DeviceReplyMap::iterator iter, ReturnValue_t status); void replyToReply(DeviceReplyMap::iterator iter, ReturnValue_t status);
/** /**
* Build and send a command to the device. * Build and send a command to the device.
* *
@ -1202,7 +1197,6 @@ private:
* sends the command via RMAP. * sends the command via RMAP.
*/ */
void doSendWrite(void); void doSendWrite(void);
/** /**
* Check if the RMAP sendWrite action was successful. * Check if the RMAP sendWrite action was successful.
* *
@ -1212,7 +1206,6 @@ private:
* - if the action was successful, the reply timout counter is initialized * - if the action was successful, the reply timout counter is initialized
*/ */
void doGetWrite(void); void doGetWrite(void);
/** /**
* Send a RMAP getRead command. * Send a RMAP getRead command.
* *
@ -1220,7 +1213,6 @@ private:
* This is always executed, independently from the current mode. * This is always executed, independently from the current mode.
*/ */
void doSendRead(void); void doSendRead(void);
/** /**
* Check the getRead reply and the contained data. * Check the getRead reply and the contained data.
* *
@ -1250,14 +1242,12 @@ private:
void setTransition(Mode_t modeTo, Submode_t submodeTo); void setTransition(Mode_t modeTo, Submode_t submodeTo);
/** /**
* calls the right child function for the transitional submodes * Calls the right child function for the transitional submodes
*/ */
void callChildStatemachine(); void callChildStatemachine();
ReturnValue_t handleDeviceHandlerMessage(CommandMessage *message); ReturnValue_t handleDeviceHandlerMessage(CommandMessage *message);
virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
virtual dur_millis_t getPeriodicOperationFrequency() const override; virtual dur_millis_t getPeriodicOperationFrequency() const override;
void parseReply(const uint8_t* receivedData, void parseReply(const uint8_t* receivedData,
@ -1266,6 +1256,13 @@ private:
void handleTransitionToOnMode(Mode_t commandedMode, void handleTransitionToOnMode(Mode_t commandedMode,
Submode_t commandedSubmode); Submode_t commandedSubmode);
/**
* Generic internal printer function which also handles printing the object ID.
* @param errorType
* @param functionName
* @param errorCode
* @param errorPrint
*/
void printWarningOrError(sif::OutputTypes errorType, void printWarningOrError(sif::OutputTypes errorType,
const char* functionName, const char* functionName,
ReturnValue_t errorCode = HasReturnvaluesIF::RETURN_FAILED, ReturnValue_t errorCode = HasReturnvaluesIF::RETURN_FAILED,

View File

@ -125,8 +125,10 @@ sid_t HousekeepingMessage::getSid(const CommandMessage* message) {
return sid; return sid;
} }
void HousekeepingMessage::setSid(CommandMessage *message, sid_t sid) { gp_id_t HousekeepingMessage::getGpid(const CommandMessage* message) {
std::memcpy(message->getData(), &sid.raw, sizeof(sid.raw)); gp_id_t globalPoolId;
std::memcpy(&globalPoolId.raw, message->getData(), sizeof(globalPoolId.raw));
return globalPoolId;
} }
void HousekeepingMessage::setHkStuctureReportReply(CommandMessage *reply, void HousekeepingMessage::setHkStuctureReportReply(CommandMessage *reply,
@ -169,9 +171,9 @@ void HousekeepingMessage::setUpdateNotificationSetCommand(
} }
void HousekeepingMessage::setUpdateNotificationVariableCommand( void HousekeepingMessage::setUpdateNotificationVariableCommand(
CommandMessage *command, lp_id_t localPoolId) { CommandMessage *command, gp_id_t globalPoolId) {
command->setCommand(UPDATE_NOTIFICATION_VARIABLE); command->setCommand(UPDATE_NOTIFICATION_VARIABLE);
command->setParameter(localPoolId); setGpid(command, globalPoolId);
} }
void HousekeepingMessage::setUpdateSnapshotSetCommand(CommandMessage *command, void HousekeepingMessage::setUpdateSnapshotSetCommand(CommandMessage *command,
@ -182,9 +184,9 @@ void HousekeepingMessage::setUpdateSnapshotSetCommand(CommandMessage *command,
} }
void HousekeepingMessage::setUpdateSnapshotVariableCommand( void HousekeepingMessage::setUpdateSnapshotVariableCommand(
CommandMessage *command, lp_id_t localPoolId, store_address_t storeId) { CommandMessage *command, gp_id_t globalPoolId, store_address_t storeId) {
command->setCommand(UPDATE_SNAPSHOT_VARIABLE); command->setCommand(UPDATE_SNAPSHOT_VARIABLE);
command->setParameter(localPoolId); setGpid(command, globalPoolId);
command->setParameter3(storeId.raw); command->setParameter3(storeId.raw);
} }
@ -193,9 +195,9 @@ sid_t HousekeepingMessage::getUpdateNotificationSetCommand(
return getSid(command); return getSid(command);
} }
lp_id_t HousekeepingMessage::getUpdateNotificationVariableCommand( gp_id_t HousekeepingMessage::getUpdateNotificationVariableCommand(
const CommandMessage *command) { const CommandMessage *command) {
return command->getParameter(); return getGpid(command);
} }
sid_t HousekeepingMessage::getUpdateSnapshotSetCommand( sid_t HousekeepingMessage::getUpdateSnapshotSetCommand(
@ -206,10 +208,18 @@ sid_t HousekeepingMessage::getUpdateSnapshotSetCommand(
return getSid(command); return getSid(command);
} }
lp_id_t HousekeepingMessage::getUpdateSnapshotVariableCommand( gp_id_t HousekeepingMessage::getUpdateSnapshotVariableCommand(
const CommandMessage *command, store_address_t *storeId) { const CommandMessage *command, store_address_t *storeId) {
if(storeId != nullptr) { if(storeId != nullptr) {
*storeId = command->getParameter3(); *storeId = command->getParameter3();
} }
return command->getParameter(); return getGpid(command);
}
void HousekeepingMessage::setSid(CommandMessage *message, sid_t sid) {
std::memcpy(message->getData(), &sid.raw, sizeof(sid.raw));
}
void HousekeepingMessage::setGpid(CommandMessage *message, gp_id_t globalPoolId) {
std::memcpy(message->getData(), &globalPoolId.raw, sizeof(globalPoolId.raw));
} }

View File

@ -75,6 +75,7 @@ public:
//static constexpr Command_t UPDATE_HK_REPORT = MAKE_COMMAND_ID(134); //static constexpr Command_t UPDATE_HK_REPORT = MAKE_COMMAND_ID(134);
static sid_t getSid(const CommandMessage* message); static sid_t getSid(const CommandMessage* message);
static gp_id_t getGpid(const CommandMessage* message);
/* Housekeeping Interface Messages */ /* Housekeeping Interface Messages */
@ -123,26 +124,27 @@ public:
static void setUpdateNotificationSetCommand(CommandMessage* command, static void setUpdateNotificationSetCommand(CommandMessage* command,
sid_t sid); sid_t sid);
static void setUpdateNotificationVariableCommand(CommandMessage* command, static void setUpdateNotificationVariableCommand(CommandMessage* command,
lp_id_t localPoolId); gp_id_t globalPoolId);
static void setUpdateSnapshotSetCommand(CommandMessage* command, sid_t sid, static void setUpdateSnapshotSetCommand(CommandMessage* command, sid_t sid,
store_address_t storeId); store_address_t storeId);
static void setUpdateSnapshotVariableCommand(CommandMessage* command, static void setUpdateSnapshotVariableCommand(CommandMessage* command,
lp_id_t localPoolId, store_address_t storeId); gp_id_t globalPoolId, store_address_t storeId);
static sid_t getUpdateNotificationSetCommand(const CommandMessage* command); static sid_t getUpdateNotificationSetCommand(const CommandMessage* command);
static lp_id_t getUpdateNotificationVariableCommand( static gp_id_t getUpdateNotificationVariableCommand(
const CommandMessage* command); const CommandMessage* command);
static sid_t getUpdateSnapshotSetCommand(const CommandMessage* command, static sid_t getUpdateSnapshotSetCommand(const CommandMessage* command,
store_address_t* storeId); store_address_t* storeId);
static lp_id_t getUpdateSnapshotVariableCommand(const CommandMessage* command, static gp_id_t getUpdateSnapshotVariableCommand(const CommandMessage* command,
store_address_t* storeId); store_address_t* storeId);
/** Utility */ /** Utility */
static void clear(CommandMessage* message); static void clear(CommandMessage* message);
private: private:
static void setSid(CommandMessage* message, sid_t sid); static void setSid(CommandMessage* message, sid_t sid);
static void setGpid(CommandMessage* message, gp_id_t globalPoolId);
}; };

View File

@ -18,17 +18,19 @@ QueueMapManager* QueueMapManager::instance() {
ReturnValue_t QueueMapManager::addMessageQueue( ReturnValue_t QueueMapManager::addMessageQueue(
MessageQueueIF* queueToInsert, MessageQueueId_t* id) { MessageQueueIF* queueToInsert, MessageQueueId_t* id) {
// Not thread-safe, but it is assumed all message queues are created /* Not thread-safe, but it is assumed all message queues are created at software initialization
// at software initialization now. If this is to be made thread-safe in now. If this is to be made thread-safe in the future, it propably would be sufficient to lock
// the future, it propably would be sufficient to lock the increment the increment operation here. */
// operation here
uint32_t currentId = queueCounter++; uint32_t currentId = queueCounter++;
auto returnPair = queueMap.emplace(currentId, queueToInsert); auto returnPair = queueMap.emplace(currentId, queueToInsert);
if(not returnPair.second) { if(not returnPair.second) {
// this should never happen for the atomic variable. /* This should never happen for the atomic variable. */
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "QueueMapManager: This ID is already inside the map!" sif::error << "QueueMapManager::addMessageQueue This ID is already "
<< std::endl; "inside the map!" << std::endl;
#else
sif::printError("QueueMapManager::addMessageQueue This ID is already "
"inside the map!\n");
#endif #endif
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
@ -47,8 +49,11 @@ MessageQueueIF* QueueMapManager::getMessageQueue(
} }
else { else {
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "QueueMapManager::getQueueHandle: The ID " << sif::warning << "QueueMapManager::getQueueHandle: The ID " << messageQueueId <<
messageQueueId << " does not exists in the map" << std::endl; " does not exists in the map!" << std::endl;
#else
sif::printWarning("QueueMapManager::getQueueHandle: The ID %d does not exist in the map!\n",
messageQueueId);
#endif #endif
return nullptr; return nullptr;
} }

View File

@ -36,7 +36,7 @@ public:
private: private:
//! External instantiation is forbidden. //! External instantiation is forbidden.
QueueMapManager(); QueueMapManager();
uint32_t queueCounter = 1; uint32_t queueCounter = 0;
MutexIF* mapLock; MutexIF* mapLock;
QueueMap queueMap; QueueMap queueMap;
static QueueMapManager* mqManagerInstance; static QueueMapManager* mqManagerInstance;

View File

@ -223,8 +223,11 @@ ReturnValue_t Service3Housekeeping::handleReply(const CommandMessage* reply,
default: default:
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "Service3Housekeeping::handleReply: Invalid reply with " sif::warning << "Service3Housekeeping::handleReply: Invalid reply with "
<< "reply command " << command << "!" << std::endl; << "reply command " << command << "!" << std::endl;
#else
sif::printWarning("Service3Housekeeping::handleReply: Invalid reply with "
"reply command %hu!\n", command);
#endif #endif
return CommandingServiceBase::INVALID_REPLY; return CommandingServiceBase::INVALID_REPLY;
} }
@ -250,20 +253,34 @@ void Service3Housekeeping::handleUnrequestedReply(
break; break;
} }
default: case(HousekeepingMessage::HK_REQUEST_SUCCESS): {
break;
}
case(HousekeepingMessage::HK_REQUEST_FAILURE): {
break;
}
default: {
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "Service3Housekeeping::handleUnrequestedReply: Invalid " sif::warning << "Service3Housekeeping::handleUnrequestedReply: Invalid reply with reply "
<< "reply with " << "reply command " << command << "!" "command " << command << "!" << std::endl;
<< std::endl; #else
sif::printWarning("Service3Housekeeping::handleUnrequestedReply: Invalid reply with "
"reply command %hu!\n", command);
#endif #endif
return; return;
} }
}
if(result != HasReturnvaluesIF::RETURN_OK) { if(result != HasReturnvaluesIF::RETURN_OK) {
// Configuration error /* Configuration error */
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::debug << "Service3Housekeeping::handleUnrequestedReply:" sif::warning << "Service3Housekeeping::handleUnrequestedReply: Could not generate reply!" <<
<< "Could not generate reply!" << std::endl; std::endl;
#else
sif::printWarning("Service3Housekeeping::handleUnrequestedReply: "
"Could not generate reply!\n");
#endif #endif
} }
} }