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 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.
-
### PUS Parameter Service 20
Added PUS parameter service 20 (only custom subservices available).

View File

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

View File

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

View File

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

View File

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

View File

@ -39,8 +39,12 @@ public:
* supply a pointer to this dataset to PoolVariable
* initializations to register pool variables.
*/
PoolDataSetBase(PoolVariableIF** registeredVariablesArray,
const size_t maxFillCount);
PoolDataSetBase(PoolVariableIF** registeredVariablesArray, const size_t maxFillCount);
/* Forbidden for now */
PoolDataSetBase(const PoolDataSetBase& otherSet) = delete;
const PoolDataSetBase& operator=(const PoolDataSetBase& otherSet) = delete;
virtual~ PoolDataSetBase();
/**
@ -63,8 +67,7 @@ public:
* - @c SET_WAS_ALREADY_READ if read() is called twice without calling
* commit() in between
*/
virtual ReturnValue_t read(
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
virtual ReturnValue_t read(MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
uint32_t lockTimeout = 20) override;
/**
* @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
* contains non write-only variables
*/
virtual ReturnValue_t commit(
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
virtual ReturnValue_t commit(MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
uint32_t lockTimeout = 20) override;
/**

View File

@ -80,7 +80,7 @@ public:
* @param storeId If a snapshot was requested, data will be located inside
* 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) {
return;
}

View File

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

View File

@ -103,6 +103,12 @@ public:
*/
~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);
sid_t getSid() const;
@ -153,6 +159,7 @@ public:
bool hasChanged() const override;
object_id_t getCreatorObjectId();
protected:
sid_t sid;
//! 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 MarkChangedIF {
public:
LocalPoolObjectBase(lp_id_t poolId,
HasLocalDataPoolIF* hkOwner, DataSetIF* dataSet,
LocalPoolObjectBase(lp_id_t poolId, HasLocalDataPoolIF* hkOwner, DataSetIF* dataSet,
pool_rwm_t setReadWriteMode);
LocalPoolObjectBase(object_id_t poolOwner, lp_id_t poolId,
DataSetIF* dataSet = nullptr,
LocalPoolObjectBase(object_id_t poolOwner, lp_id_t poolId, DataSetIF* dataSet = nullptr,
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE);
void setReadWriteMode(pool_rwm_t newReadWriteMode);

View File

@ -38,7 +38,6 @@ public:
bool isDiagnostics,
object_id_t packetDestination) = 0;
/**
* @brief Subscribe for a notification message which will be sent
* if a dataset has changed.
@ -46,16 +45,15 @@ public:
* This subscription mechanism will generally be used internally by
* other software components.
* @param setId Set ID of the set to receive update messages from.
* @param destinationObject
* @param targetQueueId
* @param generateSnapshot If this is set to true, a copy of the current
* data with a timestamp will be generated and sent via message.
* @param destinationObject Object ID of the receiver.
* @param targetQueueId Receiver queue ID
* @param generateSnapshot If this is set to true, a copy of the current data with a
* timestamp will be generated and sent via message.
* Otherwise, only an notification message is sent.
* @return
*/
virtual ReturnValue_t subscribeForSetUpdateMessages(const uint32_t setId,
object_id_t destinationObject,
MessageQueueId_t targetQueueId,
object_id_t destinationObject, MessageQueueId_t targetQueueId,
bool generateSnapshot) = 0;
/**
@ -65,11 +63,11 @@ public:
* This subscription mechanism will generally be used internally by
* other software components.
* @param localPoolId Pool ID of the pool variable
* @param destinationObject
* @param targetQueueId
* @param generateSnapshot If this is set to true, a copy of the current
* data with a timestamp will be generated and sent via message.
* Otherwise, only an notification message is sent.
* @param destinationObject Object ID of the receiver
* @param targetQueueId Receiver queue ID
* @param generateSnapshot If this is set to true, a copy of the current data with a
* timestamp will be generated and sent via message. Otherwise,
* only an notification message is sent.
* @return
*/
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::defaultFdirParentId = objects::NO_OBJECT;
DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId,
object_id_t deviceCommunication, CookieIF * comCookie,
FailureIsolationBase* fdirInstance, size_t cmdQueueSize) :
DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication,
CookieIF* comCookie, FailureIsolationBase* fdirInstance, size_t cmdQueueSize):
SystemObject(setObjectId), mode(MODE_OFF), submode(SUBMODE_NONE),
wiretappingMode(OFF), storedRawData(StorageManagerIF::INVALID_ADDRESS),
deviceCommunicationId(deviceCommunication), comCookie(comCookie),
healthHelper(this,setObjectId), modeHelper(this), parameterHelper(this),
actionHelper(this, nullptr), poolManager(this, nullptr),
childTransitionFailure(RETURN_OK), fdirInstance(fdirInstance),
hkSwitcher(this), defaultFDIRUsed(fdirInstance == nullptr),
defaultFDIRUsed(fdirInstance == nullptr),
switchOffWasReported(false), childTransitionDelay(5000),
transitionSourceMode(_MODE_POWER_DOWN),
transitionSourceSubMode(SUBMODE_NONE) {
@ -80,7 +79,6 @@ ReturnValue_t DeviceHandlerBase::performOperation(uint8_t counter) {
checkSwitchState();
decrementDeviceReplyMap();
fdirInstance->checkForFailures();
hkSwitcher.performOperation();
performOperationHook();
return RETURN_OK;
}
@ -92,7 +90,7 @@ ReturnValue_t DeviceHandlerBase::performOperation(uint8_t counter) {
switch (getComAction()) {
case CommunicationAction::SEND_WRITE:
if (cookieInfo.state == COOKIE_UNUSED) {
// if no external command was specified, build internal command.
/* If no external command was specified, build internal command. */
buildInternalCommand();
}
doSendWrite();
@ -105,8 +103,8 @@ ReturnValue_t DeviceHandlerBase::performOperation(uint8_t counter) {
break;
case CommunicationAction::GET_READ:
doGetRead();
// This will be performed after datasets have been updated by the
// custom device implementation.
/* This will be performed after datasets have been updated by the
custom device implementation. */
poolManager.performHkOperation();
break;
default:
@ -205,11 +203,6 @@ ReturnValue_t DeviceHandlerBase::initialize() {
return result;
}
result = hkSwitcher.initialize();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = poolManager.initialize(commandQueue);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
@ -442,8 +435,7 @@ ReturnValue_t DeviceHandlerBase::insertInReplyMap(DeviceCommandId_t replyId,
}
}
ReturnValue_t DeviceHandlerBase::insertInCommandMap(
DeviceCommandId_t deviceCommand) {
ReturnValue_t DeviceHandlerBase::insertInCommandMap(DeviceCommandId_t deviceCommand) {
DeviceCommandInfo info;
info.expectedReplies = 0;
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) {
changeHK(mode, submode, false);
/* TODO: This will probably be done by the LocalDataPoolManager now */
//changeHK(mode, submode, false);
submode = newSubmode;
mode = newMode;
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) {
@ -706,13 +700,11 @@ void DeviceHandlerBase::parseReply(const uint8_t* receivedData,
ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED;
DeviceCommandId_t foundId = DeviceHandlerIF::NO_COMMAND_ID;
size_t foundLen = 0;
// The loop may not execute more often than the number of received bytes
// (worst case). This approach avoids infinite loops due to buggy
// scanForReply routines.
/* The loop may not execute more often than the number of received bytes
(worst case). This approach avoids infinite loops due to buggy scanForReply routines. */
uint32_t remainingLength = receivedDataLen;
for (uint32_t count = 0; count < receivedDataLen; count++) {
result = scanForReply(receivedData, remainingLength, &foundId,
&foundLen);
result = scanForReply(receivedData, remainingLength, &foundId, &foundLen);
switch (result) {
case RETURN_OK:
handleReply(receivedData, foundId, foundLen);
@ -795,9 +787,9 @@ void DeviceHandlerBase::handleReply(const uint8_t* receivedData,
replyToReply(iter, result);
}
else {
// Other completion failure messages are created by timeout.
// Powering down the device might take some time during which periodic
// replies may still come in.
/* Other completion failure messages are created by timeout.
Powering down the device might take some time during which periodic
replies may still come in. */
if (mode != _MODE_WAIT_OFF) {
triggerEvent(DEVICE_UNREQUESTED_REPLY, foundId);
}
@ -1379,9 +1371,9 @@ void DeviceHandlerBase::forwardEvent(Event event, uint32_t parameter1,
void DeviceHandlerBase::doOffActivity() {
}
ReturnValue_t DeviceHandlerBase::getParameter(uint8_t domainId,
uint8_t uniqueId, ParameterWrapper* parameterWrapper,
const ParameterWrapper* newValues, uint16_t startAtIndex) {
ReturnValue_t DeviceHandlerBase::getParameter(uint8_t domainId, uint8_t uniqueId,
ParameterWrapper* parameterWrapper, const ParameterWrapper* newValues,
uint16_t startAtIndex) {
ReturnValue_t result = fdirInstance->getParameter(domainId, uniqueId, parameterWrapper,
newValues, startAtIndex);
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){
executingTask = task;
}
// Default implementations empty.
void DeviceHandlerBase::debugInterface(uint8_t positionTracker,
object_id_t objectId, uint32_t parameter) {}

View File

@ -20,7 +20,6 @@
#include "../action/ActionHelper.h"
#include "../health/HealthHelper.h"
#include "../parameters/ParameterHelper.h"
#include "../datapool/HkSwitchHelper.h"
#include "../datapoollocal/HasLocalDataPoolIF.h"
#include "../datapoollocal/LocalDataPoolManager.h"
@ -148,8 +147,7 @@ public:
* 4. Decrements counter for timeout of replies by calling
* decrementDeviceReplyMap()
* 5. Performs FDIR check for failures
* 6. Calls hkSwitcher.performOperation()
* 7. If the device mode is MODE_OFF, return RETURN_OK.
* 6. If the device mode is MODE_OFF, return RETURN_OK.
* Otherwise, perform the Action property and performs depending
* on value specified by input value counter (incremented in PST).
* The child class tells base class what to do by setting this value.
@ -217,9 +215,8 @@ public:
HealthState getHealth();
ReturnValue_t setHealth(HealthState health);
virtual ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId,
ParameterWrapper *parameterWrapper,
const ParameterWrapper *newValues, uint16_t startAtIndex) override;
ParameterWrapper *parameterWrapper, const ParameterWrapper *newValues,
uint16_t startAtIndex) override;
protected:
/**
@ -248,7 +245,6 @@ protected:
* for a failed transition
*/
virtual void doStartUp() = 0;
/**
* @brief This is used to let the child class handle the transition
* from mode @c _MODE_SHUT_DOWN to @c _MODE_POWER_DOWN
@ -274,6 +270,7 @@ protected:
*/
virtual void doShutDown() = 0;
/* Command handling */
/**
* 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.
*/
virtual ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t * id) = 0;
/**
* 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
*/
virtual ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t * id) = 0;
/**
* @brief Build a device command packet from data supplied by a direct
* command (PUS Service 8)
@ -347,6 +342,7 @@ protected:
virtual ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand,
const uint8_t * commandData, size_t commandDataLen) = 0;
/* Reply handling */
/**
* @brief Scans a buffer for a valid reply.
* @details
@ -382,7 +378,6 @@ protected:
*/
virtual ReturnValue_t scanForReply(const uint8_t *start, size_t len,
DeviceCommandId_t *foundId, size_t *foundLen) = 0;
/**
* @brief Interpret a reply from the device.
* @details
@ -404,10 +399,19 @@ protected:
*/
virtual ReturnValue_t interpretDeviceReply(DeviceCommandId_t id,
const uint8_t *packet) = 0;
MessageQueueId_t getCommanderId(DeviceCommandId_t replyId) const;
/**
* @brief fill the #DeviceCommandMap and #DeviceReplyMap
* called by the initialize() of the base class
* 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;
/* Specifying commands and replies */
/**
* @brief Fill the #DeviceCommandMap and #DeviceReplyMap called by the #initialize
* of the base class
* @details
* This is used to let the base class know which replies are expected.
* There are different scenarios regarding this:
@ -437,7 +441,6 @@ protected:
* handled by returning @c APERIODIC_REPLY in scanForReply().
*/
virtual void fillCommandAndReplyMap() = 0;
/**
* This is a helper method to facilitate inserting entries in the command map.
* @param deviceCommand Identifier of the command to add.
@ -455,7 +458,6 @@ protected:
LocalPoolDataSetBase* replyDataSet = nullptr,
size_t replyLen = 0, bool periodic = false,
bool hasDifferentReplyId = false, DeviceCommandId_t replyId = 0);
/**
* @brief This is a helper method to insert replies in the reply map.
* @param deviceCommand Identifier of the reply to add.
@ -469,7 +471,6 @@ protected:
ReturnValue_t insertInReplyMap(DeviceCommandId_t deviceCommand,
uint16_t maxDelayCycles, LocalPoolDataSetBase* dataSet = nullptr,
size_t replyLen = 0, bool periodic = false);
/**
* @brief A simple command to add a command to the commandList.
* @param deviceCommand The command to add
@ -495,25 +496,14 @@ protected:
ReturnValue_t updateReplyMapEntry(DeviceCommandId_t deviceReply,
uint16_t delayCycles, uint16_t maxDelayCycles,
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,
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.
*
@ -532,6 +522,73 @@ protected:
*/
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.
*
@ -547,39 +604,48 @@ protected:
uint8_t *numberOfSwitches);
/**
* This function is used to initialize the local housekeeping pool
* entries. The default implementation leaves the pool empty.
* @param localDataPoolMap
* @return
* @brief Helper function to report a missed reply
* @details Can be overwritten by children to act on missed replies or to fake reporting Id.
* @param id of the missed reply
*/
virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) override;
/**
* Required for HasLocalDataPoolIF, return a handle to the local pool manager.
* @return
*/
LocalDataPoolManager* getHkManagerHandle() override;
virtual void missedReply(DeviceCommandId_t id);
/* Miscellaneous functions */
/**
* @brief Hook function for child handlers which is called once per
* performOperation(). Default implementation is empty.
*/
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:
/**
* The Returnvalues id of this class, required by HasReturnvaluesIF
*/
static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_BASE;
static const ReturnValue_t INVALID_CHANNEL = MAKE_RETURN_CODE(0xA0);
/* 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
static const ReturnValue_t IGNORE_REPLY_DATA = MAKE_RETURN_CODE(0xB1); //!< Ignore parts of the received packet
static const ReturnValue_t IGNORE_FULL_PACKET = MAKE_RETURN_CODE(0xB2); //!< Ignore full received packet
//! This is used to specify for replies from a device which are not replies to requests
static const ReturnValue_t APERIODIC_REPLY = MAKE_RETURN_CODE(0xB0);
//! 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 */
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);
// Return codes for getSwitches */
static const ReturnValue_t NO_SWITCH = MAKE_RETURN_CODE(0xD0);
@ -589,9 +655,9 @@ protected:
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;
/** Size of the #rawPacket. */
//! Size of the #rawPacket.
uint32_t rawPacketLen = 0;
/**
@ -649,15 +715,15 @@ protected:
/** Cookie used for communication */
CookieIF * comCookie;
/** Health helper for HasHealthIF */
/* Health helper for HasHealthIF */
HealthHelper healthHelper;
/** Mode helper for HasModesIF */
/* Mode helper for HasModesIF */
ModeHelper modeHelper;
/** Parameter helper for ReceivesParameterMessagesIF */
/* Parameter helper for ReceivesParameterMessagesIF */
ParameterHelper parameterHelper;
/** Action helper for HasActionsIF */
/* Action helper for HasActionsIF */
ActionHelper actionHelper;
/** Housekeeping Manager */
/* Housekeeping Manager */
LocalDataPoolManager poolManager;
/**
@ -740,90 +806,41 @@ protected:
* default class is instantiated. */
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;
//!< Object which switches power on and off.
//! Object which switches power on and off.
static object_id_t powerSwitcherId;
//!< Object which receives RAW data by default.
//! Object which receives RAW data by default.
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;
/**
* @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();
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.
* @brief Send a reply to a received device handler command.
*
* This also resets #DeviceHandlerCommand to 0.
*
* @param reply the reply type
* @param parameter parameter for the reply
*/
void replyReturnvalueToCommand(ReturnValue_t status,
uint32_t parameter = 0);
void replyReturnvalueToCommand(ReturnValue_t status, 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);
/**
* 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).
*
@ -865,16 +882,6 @@ protected:
*/
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.
* The step number can be read from #pstStep.
@ -883,27 +890,28 @@ protected:
virtual CommunicationAction getComAction();
/**
* Build the device command to send for raw mode.
*
* 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
* Checks state of switches in conjunction with mode and triggers an event
* if they don't fit.
*/
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.
@ -915,24 +923,6 @@ protected:
*/
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
* 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);
/**
* @brief Notify child about mode change.
*/
virtual void modeChanged(void);
/**
* Enable the reply checking for a command
*
@ -972,6 +957,45 @@ protected:
uint8_t expectedReplies = 1, bool useAlternateId = false,
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
* @return
@ -981,12 +1005,7 @@ protected:
* #switches are off
* - @c PowerSwitchIF::RETURN_FAILED if an error occured
*/
ReturnValue_t getStateOfSwitches(void);
/**
* build a list of sids and pass it to the #hkSwitcher
*/
virtual void changeHK(Mode_t mode, Submode_t submode, bool enable);
ReturnValue_t getStateOfSwitches();
/**
* Children can overwrite this function to suppress checking of the
@ -1012,11 +1031,6 @@ protected:
virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
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);
/**
@ -1034,23 +1048,6 @@ protected:
*/
virtual void forwardEvent(Event event, uint32_t parameter1 = 0,
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.
@ -1163,7 +1160,6 @@ private:
void buildRawDeviceCommand(CommandMessage* message);
void buildInternalCommand(void);
/**
* 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).
*/
void decrementDeviceReplyMap(void);
/**
* Convenience function to handle a reply.
*
@ -1186,8 +1181,8 @@ private:
* @foundLen the length of the packet
*/
void handleReply(const uint8_t *data, DeviceCommandId_t id, uint32_t foundLen);
void replyToReply(DeviceReplyMap::iterator iter, ReturnValue_t status);
/**
* Build and send a command to the device.
*
@ -1202,7 +1197,6 @@ private:
* sends the command via RMAP.
*/
void doSendWrite(void);
/**
* Check if the RMAP sendWrite action was successful.
*
@ -1212,7 +1206,6 @@ private:
* - if the action was successful, the reply timout counter is initialized
*/
void doGetWrite(void);
/**
* Send a RMAP getRead command.
*
@ -1220,7 +1213,6 @@ private:
* This is always executed, independently from the current mode.
*/
void doSendRead(void);
/**
* Check the getRead reply and the contained data.
*
@ -1250,14 +1242,12 @@ private:
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();
ReturnValue_t handleDeviceHandlerMessage(CommandMessage *message);
virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
virtual dur_millis_t getPeriodicOperationFrequency() const override;
void parseReply(const uint8_t* receivedData,
@ -1266,6 +1256,13 @@ private:
void handleTransitionToOnMode(Mode_t commandedMode,
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,
const char* functionName,
ReturnValue_t errorCode = HasReturnvaluesIF::RETURN_FAILED,

View File

@ -125,8 +125,10 @@ sid_t HousekeepingMessage::getSid(const CommandMessage* message) {
return sid;
}
void HousekeepingMessage::setSid(CommandMessage *message, sid_t sid) {
std::memcpy(message->getData(), &sid.raw, sizeof(sid.raw));
gp_id_t HousekeepingMessage::getGpid(const CommandMessage* message) {
gp_id_t globalPoolId;
std::memcpy(&globalPoolId.raw, message->getData(), sizeof(globalPoolId.raw));
return globalPoolId;
}
void HousekeepingMessage::setHkStuctureReportReply(CommandMessage *reply,
@ -169,9 +171,9 @@ void HousekeepingMessage::setUpdateNotificationSetCommand(
}
void HousekeepingMessage::setUpdateNotificationVariableCommand(
CommandMessage *command, lp_id_t localPoolId) {
CommandMessage *command, gp_id_t globalPoolId) {
command->setCommand(UPDATE_NOTIFICATION_VARIABLE);
command->setParameter(localPoolId);
setGpid(command, globalPoolId);
}
void HousekeepingMessage::setUpdateSnapshotSetCommand(CommandMessage *command,
@ -182,9 +184,9 @@ void HousekeepingMessage::setUpdateSnapshotSetCommand(CommandMessage *command,
}
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->setParameter(localPoolId);
setGpid(command, globalPoolId);
command->setParameter3(storeId.raw);
}
@ -193,9 +195,9 @@ sid_t HousekeepingMessage::getUpdateNotificationSetCommand(
return getSid(command);
}
lp_id_t HousekeepingMessage::getUpdateNotificationVariableCommand(
gp_id_t HousekeepingMessage::getUpdateNotificationVariableCommand(
const CommandMessage *command) {
return command->getParameter();
return getGpid(command);
}
sid_t HousekeepingMessage::getUpdateSnapshotSetCommand(
@ -206,10 +208,18 @@ sid_t HousekeepingMessage::getUpdateSnapshotSetCommand(
return getSid(command);
}
lp_id_t HousekeepingMessage::getUpdateSnapshotVariableCommand(
gp_id_t HousekeepingMessage::getUpdateSnapshotVariableCommand(
const CommandMessage *command, store_address_t *storeId) {
if(storeId != nullptr) {
*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 sid_t getSid(const CommandMessage* message);
static gp_id_t getGpid(const CommandMessage* message);
/* Housekeeping Interface Messages */
@ -123,26 +124,27 @@ public:
static void setUpdateNotificationSetCommand(CommandMessage* command,
sid_t sid);
static void setUpdateNotificationVariableCommand(CommandMessage* command,
lp_id_t localPoolId);
gp_id_t globalPoolId);
static void setUpdateSnapshotSetCommand(CommandMessage* command, sid_t sid,
store_address_t storeId);
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 lp_id_t getUpdateNotificationVariableCommand(
static gp_id_t getUpdateNotificationVariableCommand(
const CommandMessage* command);
static sid_t getUpdateSnapshotSetCommand(const CommandMessage* command,
store_address_t* storeId);
static lp_id_t getUpdateSnapshotVariableCommand(const CommandMessage* command,
static gp_id_t getUpdateSnapshotVariableCommand(const CommandMessage* command,
store_address_t* storeId);
/** Utility */
static void clear(CommandMessage* message);
private:
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(
MessageQueueIF* queueToInsert, MessageQueueId_t* id) {
// Not thread-safe, but it is assumed all message queues are created
// at software initialization now. If this is to be made thread-safe in
// the future, it propably would be sufficient to lock the increment
// operation here
/* Not thread-safe, but it is assumed all message queues are created at software initialization
now. If this is to be made thread-safe in the future, it propably would be sufficient to lock
the increment operation here. */
uint32_t currentId = queueCounter++;
auto returnPair = queueMap.emplace(currentId, queueToInsert);
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
sif::error << "QueueMapManager: This ID is already inside the map!"
<< std::endl;
sif::error << "QueueMapManager::addMessageQueue This ID is already "
"inside the map!" << std::endl;
#else
sif::printError("QueueMapManager::addMessageQueue This ID is already "
"inside the map!\n");
#endif
return HasReturnvaluesIF::RETURN_FAILED;
}
@ -47,8 +49,11 @@ MessageQueueIF* QueueMapManager::getMessageQueue(
}
else {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "QueueMapManager::getQueueHandle: The ID " <<
messageQueueId << " does not exists in the map" << std::endl;
sif::warning << "QueueMapManager::getQueueHandle: The ID " << messageQueueId <<
" 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
return nullptr;
}

View File

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

View File

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