Merge remote-tracking branch 'upstream/mueller/master' into mueller/master

This commit is contained in:
Robin Müller 2021-02-05 11:17:26 +01:00
commit 257e79f8fc
13 changed files with 348 additions and 320 deletions

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

@ -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();
} }
} }
@ -83,7 +84,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

@ -38,24 +38,22 @@ 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.
* @details * @details
* 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;
/** /**
@ -64,12 +62,12 @@ public:
* @details * @details
* 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

@ -435,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;
@ -701,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);
@ -790,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);
} }

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

@ -4,199 +4,199 @@
Service3Housekeeping::Service3Housekeeping(object_id_t objectId, uint16_t apid, Service3Housekeeping::Service3Housekeeping(object_id_t objectId, uint16_t apid,
uint8_t serviceId): uint8_t serviceId):
CommandingServiceBase(objectId, apid, serviceId, CommandingServiceBase(objectId, apid, serviceId,
NUM_OF_PARALLEL_COMMANDS, COMMAND_TIMEOUT_SECONDS) {} NUM_OF_PARALLEL_COMMANDS, COMMAND_TIMEOUT_SECONDS) {}
Service3Housekeeping::~Service3Housekeeping() {} Service3Housekeeping::~Service3Housekeeping() {}
ReturnValue_t Service3Housekeeping::isValidSubservice(uint8_t subservice) { ReturnValue_t Service3Housekeeping::isValidSubservice(uint8_t subservice) {
switch(static_cast<Subservice>(subservice)) { switch(static_cast<Subservice>(subservice)) {
case Subservice::ENABLE_PERIODIC_HK_REPORT_GENERATION: case Subservice::ENABLE_PERIODIC_HK_REPORT_GENERATION:
case Subservice::DISABLE_PERIODIC_HK_REPORT_GENERATION: case Subservice::DISABLE_PERIODIC_HK_REPORT_GENERATION:
case Subservice::ENABLE_PERIODIC_DIAGNOSTICS_REPORT_GENERATION: case Subservice::ENABLE_PERIODIC_DIAGNOSTICS_REPORT_GENERATION:
case Subservice::DISABLE_PERIODIC_DIAGNOSTICS_REPORT_GENERATION: case Subservice::DISABLE_PERIODIC_DIAGNOSTICS_REPORT_GENERATION:
case Subservice::REPORT_HK_REPORT_STRUCTURES: case Subservice::REPORT_HK_REPORT_STRUCTURES:
case Subservice::REPORT_DIAGNOSTICS_REPORT_STRUCTURES : case Subservice::REPORT_DIAGNOSTICS_REPORT_STRUCTURES :
case Subservice::GENERATE_ONE_PARAMETER_REPORT: case Subservice::GENERATE_ONE_PARAMETER_REPORT:
case Subservice::GENERATE_ONE_DIAGNOSTICS_REPORT: case Subservice::GENERATE_ONE_DIAGNOSTICS_REPORT:
case Subservice::MODIFY_PARAMETER_REPORT_COLLECTION_INTERVAL: case Subservice::MODIFY_PARAMETER_REPORT_COLLECTION_INTERVAL:
case Subservice::MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL: case Subservice::MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL:
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
// Telemetry or invalid subservice. // Telemetry or invalid subservice.
case Subservice::HK_DEFINITIONS_REPORT: case Subservice::HK_DEFINITIONS_REPORT:
case Subservice::DIAGNOSTICS_DEFINITION_REPORT: case Subservice::DIAGNOSTICS_DEFINITION_REPORT:
case Subservice::HK_REPORT: case Subservice::HK_REPORT:
case Subservice::DIAGNOSTICS_REPORT: case Subservice::DIAGNOSTICS_REPORT:
default: default:
return AcceptsTelecommandsIF::INVALID_SUBSERVICE; return AcceptsTelecommandsIF::INVALID_SUBSERVICE;
} }
} }
ReturnValue_t Service3Housekeeping::getMessageQueueAndObject(uint8_t subservice, ReturnValue_t Service3Housekeeping::getMessageQueueAndObject(uint8_t subservice,
const uint8_t *tcData, size_t tcDataLen, const uint8_t *tcData, size_t tcDataLen,
MessageQueueId_t *id, object_id_t *objectId) { MessageQueueId_t *id, object_id_t *objectId) {
ReturnValue_t result = checkAndAcquireTargetID(objectId,tcData,tcDataLen); ReturnValue_t result = checkAndAcquireTargetID(objectId,tcData,tcDataLen);
if(result != RETURN_OK) { if(result != RETURN_OK) {
return result; return result;
} }
return checkInterfaceAndAcquireMessageQueue(id,objectId); return checkInterfaceAndAcquireMessageQueue(id,objectId);
} }
ReturnValue_t Service3Housekeeping::checkAndAcquireTargetID( ReturnValue_t Service3Housekeeping::checkAndAcquireTargetID(
object_id_t* objectIdToSet, const uint8_t* tcData, size_t tcDataLen) { object_id_t* objectIdToSet, const uint8_t* tcData, size_t tcDataLen) {
if(SerializeAdapter::deSerialize(objectIdToSet, &tcData, &tcDataLen, if(SerializeAdapter::deSerialize(objectIdToSet, &tcData, &tcDataLen,
SerializeIF::Endianness::BIG) != HasReturnvaluesIF::RETURN_OK) { SerializeIF::Endianness::BIG) != HasReturnvaluesIF::RETURN_OK) {
return CommandingServiceBase::INVALID_TC; return CommandingServiceBase::INVALID_TC;
} }
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
ReturnValue_t Service3Housekeeping::checkInterfaceAndAcquireMessageQueue( ReturnValue_t Service3Housekeeping::checkInterfaceAndAcquireMessageQueue(
MessageQueueId_t* messageQueueToSet, object_id_t* objectId) { MessageQueueId_t* messageQueueToSet, object_id_t* objectId) {
// check HasLocalDataPoolIF property of target // check HasLocalDataPoolIF property of target
HasLocalDataPoolIF* possibleTarget = HasLocalDataPoolIF* possibleTarget =
objectManager->get<HasLocalDataPoolIF>(*objectId); objectManager->get<HasLocalDataPoolIF>(*objectId);
if(possibleTarget == nullptr){ if(possibleTarget == nullptr){
return CommandingServiceBase::INVALID_OBJECT; return CommandingServiceBase::INVALID_OBJECT;
} }
*messageQueueToSet = possibleTarget->getCommandQueue(); *messageQueueToSet = possibleTarget->getCommandQueue();
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
ReturnValue_t Service3Housekeeping::prepareCommand(CommandMessage* message, ReturnValue_t Service3Housekeeping::prepareCommand(CommandMessage* message,
uint8_t subservice, const uint8_t *tcData, size_t tcDataLen, uint8_t subservice, const uint8_t *tcData, size_t tcDataLen,
uint32_t *state, object_id_t objectId) { uint32_t *state, object_id_t objectId) {
switch(static_cast<Subservice>(subservice)) { switch(static_cast<Subservice>(subservice)) {
case Subservice::ENABLE_PERIODIC_HK_REPORT_GENERATION: case Subservice::ENABLE_PERIODIC_HK_REPORT_GENERATION:
return prepareReportingTogglingCommand(message, objectId, true, false, return prepareReportingTogglingCommand(message, objectId, true, false,
tcData, tcDataLen); tcData, tcDataLen);
case Subservice::DISABLE_PERIODIC_HK_REPORT_GENERATION: case Subservice::DISABLE_PERIODIC_HK_REPORT_GENERATION:
return prepareReportingTogglingCommand(message, objectId, false, false, return prepareReportingTogglingCommand(message, objectId, false, false,
tcData, tcDataLen); tcData, tcDataLen);
case Subservice::ENABLE_PERIODIC_DIAGNOSTICS_REPORT_GENERATION: case Subservice::ENABLE_PERIODIC_DIAGNOSTICS_REPORT_GENERATION:
return prepareReportingTogglingCommand(message, objectId, true, true, return prepareReportingTogglingCommand(message, objectId, true, true,
tcData, tcDataLen); tcData, tcDataLen);
case Subservice::DISABLE_PERIODIC_DIAGNOSTICS_REPORT_GENERATION: case Subservice::DISABLE_PERIODIC_DIAGNOSTICS_REPORT_GENERATION:
return prepareReportingTogglingCommand(message, objectId, false, true, return prepareReportingTogglingCommand(message, objectId, false, true,
tcData, tcDataLen); tcData, tcDataLen);
case Subservice::REPORT_HK_REPORT_STRUCTURES: case Subservice::REPORT_HK_REPORT_STRUCTURES:
return prepareStructureReportingCommand(message, objectId, false, tcData, return prepareStructureReportingCommand(message, objectId, false, tcData,
tcDataLen); tcDataLen);
case Subservice::REPORT_DIAGNOSTICS_REPORT_STRUCTURES: case Subservice::REPORT_DIAGNOSTICS_REPORT_STRUCTURES:
return prepareStructureReportingCommand(message, objectId, true, tcData, return prepareStructureReportingCommand(message, objectId, true, tcData,
tcDataLen); tcDataLen);
case Subservice::GENERATE_ONE_PARAMETER_REPORT: case Subservice::GENERATE_ONE_PARAMETER_REPORT:
return prepareOneShotReportCommand(message, objectId, false, return prepareOneShotReportCommand(message, objectId, false,
tcData, tcDataLen); tcData, tcDataLen);
case Subservice::GENERATE_ONE_DIAGNOSTICS_REPORT: case Subservice::GENERATE_ONE_DIAGNOSTICS_REPORT:
return prepareOneShotReportCommand(message, objectId, true, return prepareOneShotReportCommand(message, objectId, true,
tcData, tcDataLen); tcData, tcDataLen);
case Subservice::MODIFY_PARAMETER_REPORT_COLLECTION_INTERVAL: case Subservice::MODIFY_PARAMETER_REPORT_COLLECTION_INTERVAL:
return prepareCollectionIntervalModificationCommand(message, objectId, return prepareCollectionIntervalModificationCommand(message, objectId,
false, tcData, tcDataLen); false, tcData, tcDataLen);
case Subservice::MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL: case Subservice::MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL:
return prepareCollectionIntervalModificationCommand(message, objectId, return prepareCollectionIntervalModificationCommand(message, objectId,
true, tcData, tcDataLen); true, tcData, tcDataLen);
case Subservice::HK_DEFINITIONS_REPORT: case Subservice::HK_DEFINITIONS_REPORT:
case Subservice::DIAGNOSTICS_DEFINITION_REPORT: case Subservice::DIAGNOSTICS_DEFINITION_REPORT:
case Subservice::HK_REPORT: case Subservice::HK_REPORT:
case Subservice::DIAGNOSTICS_REPORT: case Subservice::DIAGNOSTICS_REPORT:
// Those are telemetry packets. // Those are telemetry packets.
return CommandingServiceBase::INVALID_TC; return CommandingServiceBase::INVALID_TC;
default: default:
// should never happen, subservice was already checked. // should never happen, subservice was already checked.
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
ReturnValue_t Service3Housekeeping::prepareReportingTogglingCommand( ReturnValue_t Service3Housekeeping::prepareReportingTogglingCommand(
CommandMessage *command, object_id_t objectId, CommandMessage *command, object_id_t objectId,
bool enableReporting, bool isDiagnostics, bool enableReporting, bool isDiagnostics,
const uint8_t* tcData, size_t tcDataLen) { const uint8_t* tcData, size_t tcDataLen) {
if(tcDataLen < sizeof(sid_t)) { if(tcDataLen < sizeof(sid_t)) {
// TC data should consist of object ID and set ID. // TC data should consist of object ID and set ID.
return CommandingServiceBase::INVALID_TC; return CommandingServiceBase::INVALID_TC;
} }
sid_t targetSid = buildSid(objectId, &tcData, &tcDataLen); sid_t targetSid = buildSid(objectId, &tcData, &tcDataLen);
HousekeepingMessage::setToggleReportingCommand(command, targetSid, HousekeepingMessage::setToggleReportingCommand(command, targetSid,
enableReporting, isDiagnostics); enableReporting, isDiagnostics);
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
ReturnValue_t Service3Housekeeping::prepareStructureReportingCommand( ReturnValue_t Service3Housekeeping::prepareStructureReportingCommand(
CommandMessage *command, object_id_t objectId, bool isDiagnostics, CommandMessage *command, object_id_t objectId, bool isDiagnostics,
const uint8_t* tcData, size_t tcDataLen) { const uint8_t* tcData, size_t tcDataLen) {
if(tcDataLen < sizeof(sid_t)) { if(tcDataLen < sizeof(sid_t)) {
// TC data should consist of object ID and set ID. // TC data should consist of object ID and set ID.
return CommandingServiceBase::INVALID_TC; return CommandingServiceBase::INVALID_TC;
} }
sid_t targetSid = buildSid(objectId, &tcData, &tcDataLen); sid_t targetSid = buildSid(objectId, &tcData, &tcDataLen);
HousekeepingMessage::setStructureReportingCommand(command, targetSid, HousekeepingMessage::setStructureReportingCommand(command, targetSid,
isDiagnostics); isDiagnostics);
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
ReturnValue_t Service3Housekeeping::prepareOneShotReportCommand( ReturnValue_t Service3Housekeeping::prepareOneShotReportCommand(
CommandMessage *command, object_id_t objectId, bool isDiagnostics, CommandMessage *command, object_id_t objectId, bool isDiagnostics,
const uint8_t *tcData, size_t tcDataLen) { const uint8_t *tcData, size_t tcDataLen) {
if(tcDataLen < sizeof(sid_t)) { if(tcDataLen < sizeof(sid_t)) {
// TC data should consist of object ID and set ID. // TC data should consist of object ID and set ID.
return CommandingServiceBase::INVALID_TC; return CommandingServiceBase::INVALID_TC;
} }
sid_t targetSid = buildSid(objectId, &tcData, &tcDataLen); sid_t targetSid = buildSid(objectId, &tcData, &tcDataLen);
HousekeepingMessage::setOneShotReportCommand(command, targetSid, HousekeepingMessage::setOneShotReportCommand(command, targetSid,
isDiagnostics); isDiagnostics);
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
ReturnValue_t Service3Housekeeping::prepareCollectionIntervalModificationCommand( ReturnValue_t Service3Housekeeping::prepareCollectionIntervalModificationCommand(
CommandMessage *command, object_id_t objectId, bool isDiagnostics, CommandMessage *command, object_id_t objectId, bool isDiagnostics,
const uint8_t *tcData, size_t tcDataLen) { const uint8_t *tcData, size_t tcDataLen) {
if(tcDataLen < sizeof(sid_t) + sizeof(float)) { if(tcDataLen < sizeof(sid_t) + sizeof(float)) {
// SID plus the size of the new collection intervL. // SID plus the size of the new collection intervL.
return CommandingServiceBase::INVALID_TC; return CommandingServiceBase::INVALID_TC;
} }
sid_t targetSid = buildSid(objectId, &tcData, &tcDataLen); sid_t targetSid = buildSid(objectId, &tcData, &tcDataLen);
float newCollectionInterval = 0; float newCollectionInterval = 0;
SerializeAdapter::deSerialize(&newCollectionInterval, &tcData, &tcDataLen, SerializeAdapter::deSerialize(&newCollectionInterval, &tcData, &tcDataLen,
SerializeIF::Endianness::BIG); SerializeIF::Endianness::BIG);
HousekeepingMessage::setCollectionIntervalModificationCommand(command, HousekeepingMessage::setCollectionIntervalModificationCommand(command,
targetSid, newCollectionInterval, isDiagnostics); targetSid, newCollectionInterval, isDiagnostics);
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
ReturnValue_t Service3Housekeeping::handleReply(const CommandMessage* reply, ReturnValue_t Service3Housekeeping::handleReply(const CommandMessage* reply,
Command_t previousCommand, uint32_t *state, Command_t previousCommand, uint32_t *state,
CommandMessage* optionalNextCommand, object_id_t objectId, CommandMessage* optionalNextCommand, object_id_t objectId,
bool *isStep) { bool *isStep) {
Command_t command = reply->getCommand(); Command_t command = reply->getCommand();
switch(command) { switch(command) {
case(HousekeepingMessage::HK_REPORT): { case(HousekeepingMessage::HK_REPORT): {
ReturnValue_t result = generateHkReply(reply, ReturnValue_t result = generateHkReply(reply,
static_cast<uint8_t>(Subservice::HK_REPORT)); static_cast<uint8_t>(Subservice::HK_REPORT));
if(result != HasReturnvaluesIF::RETURN_OK) { if(result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
return CommandingServiceBase::EXECUTION_COMPLETE; return CommandingServiceBase::EXECUTION_COMPLETE;
} }
case(HousekeepingMessage::DIAGNOSTICS_REPORT): { case(HousekeepingMessage::DIAGNOSTICS_REPORT): {
ReturnValue_t result = generateHkReply(reply, ReturnValue_t result = generateHkReply(reply,
static_cast<uint8_t>(Subservice::DIAGNOSTICS_REPORT)); static_cast<uint8_t>(Subservice::DIAGNOSTICS_REPORT));
if(result != HasReturnvaluesIF::RETURN_OK) { if(result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
return CommandingServiceBase::EXECUTION_COMPLETE; return CommandingServiceBase::EXECUTION_COMPLETE;
} }
case(HousekeepingMessage::HK_DEFINITIONS_REPORT): { case(HousekeepingMessage::HK_DEFINITIONS_REPORT): {
return generateHkReply(reply, static_cast<uint8_t>( return generateHkReply(reply, static_cast<uint8_t>(
@ -209,93 +209,110 @@ ReturnValue_t Service3Housekeeping::handleReply(const CommandMessage* reply,
break; break;
} }
case(HousekeepingMessage::HK_REQUEST_SUCCESS): { case(HousekeepingMessage::HK_REQUEST_SUCCESS): {
return CommandingServiceBase::EXECUTION_COMPLETE; return CommandingServiceBase::EXECUTION_COMPLETE;
} }
case(HousekeepingMessage::HK_REQUEST_FAILURE): { case(HousekeepingMessage::HK_REQUEST_FAILURE): {
failureParameter1 = objectId; failureParameter1 = objectId;
ReturnValue_t error = HasReturnvaluesIF::RETURN_FAILED; ReturnValue_t error = HasReturnvaluesIF::RETURN_FAILED;
HousekeepingMessage::getHkRequestFailureReply(reply,&error); HousekeepingMessage::getHkRequestFailureReply(reply,&error);
failureParameter2 = error; failureParameter2 = error;
return CommandingServiceBase::EXECUTION_COMPLETE; return CommandingServiceBase::EXECUTION_COMPLETE;
} }
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;
} }
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
void Service3Housekeeping::handleUnrequestedReply( void Service3Housekeeping::handleUnrequestedReply(
CommandMessage* reply) { CommandMessage* reply) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
Command_t command = reply->getCommand(); Command_t command = reply->getCommand();
switch(command) { switch(command) {
case(HousekeepingMessage::DIAGNOSTICS_REPORT): { case(HousekeepingMessage::DIAGNOSTICS_REPORT): {
result = generateHkReply(reply, result = generateHkReply(reply,
static_cast<uint8_t>(Subservice::DIAGNOSTICS_REPORT)); static_cast<uint8_t>(Subservice::DIAGNOSTICS_REPORT));
break; break;
} }
case(HousekeepingMessage::HK_REPORT): { case(HousekeepingMessage::HK_REPORT): {
result = generateHkReply(reply, result = generateHkReply(reply,
static_cast<uint8_t>(Subservice::HK_REPORT)); static_cast<uint8_t>(Subservice::HK_REPORT));
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
} }
} }
MessageQueueId_t Service3Housekeeping::getHkQueue() const { MessageQueueId_t Service3Housekeeping::getHkQueue() const {
return commandQueue->getId(); return commandQueue->getId();
} }
ReturnValue_t Service3Housekeeping::generateHkReply( ReturnValue_t Service3Housekeeping::generateHkReply(
const CommandMessage* hkMessage, uint8_t subserviceId) { const CommandMessage* hkMessage, uint8_t subserviceId) {
store_address_t storeId; store_address_t storeId;
sid_t sid = HousekeepingMessage::getHkDataReply(hkMessage, &storeId); sid_t sid = HousekeepingMessage::getHkDataReply(hkMessage, &storeId);
auto resultPair = IPCStore->getData(storeId); auto resultPair = IPCStore->getData(storeId);
if(resultPair.first != HasReturnvaluesIF::RETURN_OK) { if(resultPair.first != HasReturnvaluesIF::RETURN_OK) {
return resultPair.first; return resultPair.first;
} }
HkPacket hkPacket(sid, resultPair.second.data(), resultPair.second.size()); HkPacket hkPacket(sid, resultPair.second.data(), resultPair.second.size());
return sendTmPacket(static_cast<uint8_t>(subserviceId), return sendTmPacket(static_cast<uint8_t>(subserviceId),
hkPacket.hkData, hkPacket.hkSize, nullptr, 0); hkPacket.hkData, hkPacket.hkSize, nullptr, 0);
} }
sid_t Service3Housekeeping::buildSid(object_id_t objectId, sid_t Service3Housekeeping::buildSid(object_id_t objectId,
const uint8_t** tcData, size_t* tcDataLen) { const uint8_t** tcData, size_t* tcDataLen) {
sid_t targetSid; sid_t targetSid;
targetSid.objectId = objectId; targetSid.objectId = objectId;
// skip deserialization of object ID, was already done. // skip deserialization of object ID, was already done.
*tcData += sizeof(object_id_t); *tcData += sizeof(object_id_t);
*tcDataLen -= sizeof(object_id_t); *tcDataLen -= sizeof(object_id_t);
// size check is expected to be performed beforehand! // size check is expected to be performed beforehand!
SerializeAdapter::deSerialize(&targetSid.ownerSetId, tcData, tcDataLen, SerializeAdapter::deSerialize(&targetSid.ownerSetId, tcData, tcDataLen,
SerializeIF::Endianness::BIG); SerializeIF::Endianness::BIG);
return targetSid; return targetSid;
} }