Merge branch 'master' into mueller_FIFO_static_normal

This commit is contained in:
Steffen Gaisser 2020-09-01 12:24:41 +02:00
commit e949637271
9 changed files with 566 additions and 400 deletions

View File

@ -1,17 +1,19 @@
#include "../subsystem/SubsystemBase.h" #include "../subsystem/SubsystemBase.h"
#include "ChildHandlerBase.h" #include "../devicehandlers/ChildHandlerBase.h"
#include "../subsystem/SubsystemBase.h" #include "../subsystem/SubsystemBase.h"
ChildHandlerBase::ChildHandlerBase(object_id_t setObjectId, ChildHandlerBase::ChildHandlerBase(object_id_t setObjectId,
object_id_t deviceCommunication, CookieIF * comCookie, object_id_t deviceCommunication, CookieIF * cookie,
uint8_t setDeviceSwitch, uint32_t thermalStatePoolId, uint32_t thermalStatePoolId, uint32_t thermalRequestPoolId,
uint32_t thermalRequestPoolId, uint32_t parent, object_id_t parent, FailureIsolationBase* customFdir,
FailureIsolationBase* customFdir, size_t cmdQueueSize) : size_t cmdQueueSize) :
DeviceHandlerBase(setObjectId, deviceCommunication, comCookie, DeviceHandlerBase(setObjectId, deviceCommunication, cookie,
setDeviceSwitch, thermalStatePoolId,thermalRequestPoolId,
(customFdir == nullptr? &childHandlerFdir : customFdir), (customFdir == nullptr? &childHandlerFdir : customFdir),
cmdQueueSize), cmdQueueSize),
parentId(parent), childHandlerFdir(setObjectId) { parentId(parent), childHandlerFdir(setObjectId) {
this->setThermalStateRequestPoolIds(thermalStatePoolId,
thermalRequestPoolId);
} }
ChildHandlerBase::~ChildHandlerBase() { ChildHandlerBase::~ChildHandlerBase() {
@ -25,7 +27,7 @@ ReturnValue_t ChildHandlerBase::initialize() {
MessageQueueId_t parentQueue = 0; MessageQueueId_t parentQueue = 0;
if (parentId != 0) { if (parentId != objects::NO_OBJECT) {
SubsystemBase *parent = objectManager->get<SubsystemBase>(parentId); SubsystemBase *parent = objectManager->get<SubsystemBase>(parentId);
if (parent == NULL) { if (parent == NULL) {
return RETURN_FAILED; return RETURN_FAILED;

View File

@ -1,15 +1,15 @@
#ifndef PAYLOADHANDLERBASE_H_ #ifndef FSFW_DEVICES_CHILDHANDLERBASE_H_
#define PAYLOADHANDLERBASE_H_ #define FSFW_DEVICES_CHILDHANDLERBASE_H_
#include "ChildHandlerFDIR.h" #include "ChildHandlerFDIR.h"
#include "DeviceHandlerBase.h" #include "DeviceHandlerBase.h"
class ChildHandlerBase: public DeviceHandlerBase { class ChildHandlerBase: public DeviceHandlerBase {
public: public:
ChildHandlerBase(object_id_t setObjectId, ChildHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication,
object_id_t deviceCommunication, CookieIF * comCookie, CookieIF * cookie, uint32_t thermalStatePoolId,
uint8_t setDeviceSwitch, uint32_t thermalStatePoolId, uint32_t thermalRequestPoolId,
uint32_t thermalRequestPoolId, uint32_t parent, object_id_t parent = objects::NO_OBJECT,
FailureIsolationBase* customFdir = nullptr, FailureIsolationBase* customFdir = nullptr,
size_t cmdQueueSize = 20); size_t cmdQueueSize = 20);
virtual ~ChildHandlerBase(); virtual ~ChildHandlerBase();
@ -22,4 +22,5 @@ protected:
}; };
#endif /* PAYLOADHANDLERBASE_H_ */ #endif /* FSFW_DEVICES_CHILDHANDLERBASE_H_ */

View File

@ -1,12 +1,12 @@
#include "DeviceHandlerBase.h" #include "DeviceHandlerBase.h"
#include "AcceptsDeviceResponsesIF.h"
#include "DeviceTmReportingWrapper.h"
#include "../objectmanager/ObjectManager.h" #include "../objectmanager/ObjectManager.h"
#include "../storagemanager/StorageManagerIF.h" #include "../storagemanager/StorageManagerIF.h"
#include "../thermal/ThermalComponentIF.h" #include "../thermal/ThermalComponentIF.h"
#include "AcceptsDeviceResponsesIF.h"
#include "../datapool/DataSet.h" #include "../datapool/DataSet.h"
#include "../datapool/PoolVariable.h" #include "../datapool/PoolVariable.h"
#include "DeviceTmReportingWrapper.h"
#include "../globalfunctions/CRC.h" #include "../globalfunctions/CRC.h"
#include "../subsystem/SubsystemBase.h" #include "../subsystem/SubsystemBase.h"
#include "../ipc/QueueFactory.h" #include "../ipc/QueueFactory.h"
@ -14,45 +14,47 @@
#include <iomanip> #include <iomanip>
object_id_t DeviceHandlerBase::powerSwitcherId = 0; object_id_t DeviceHandlerBase::powerSwitcherId = objects::NO_OBJECT;
object_id_t DeviceHandlerBase::rawDataReceiverId = 0; object_id_t DeviceHandlerBase::rawDataReceiverId = objects::NO_OBJECT;
object_id_t DeviceHandlerBase::defaultFDIRParentId = 0; object_id_t DeviceHandlerBase::defaultFdirParentId = objects::NO_OBJECT;
DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId,
object_id_t deviceCommunication, CookieIF * comCookie, object_id_t deviceCommunication, CookieIF * comCookie,
uint8_t setDeviceSwitch, uint32_t thermalStatePoolId, FailureIsolationBase* fdirInstance, size_t cmdQueueSize) :
uint32_t thermalRequestPoolId, FailureIsolationBase* fdirInstance,
size_t cmdQueueSize) :
SystemObject(setObjectId), mode(MODE_OFF), submode(SUBMODE_NONE), SystemObject(setObjectId), mode(MODE_OFF), submode(SUBMODE_NONE),
wiretappingMode(OFF), storedRawData(StorageManagerIF::INVALID_ADDRESS), wiretappingMode(OFF), storedRawData(StorageManagerIF::INVALID_ADDRESS),
deviceCommunicationId(deviceCommunication), comCookie(comCookie), deviceCommunicationId(deviceCommunication), comCookie(comCookie),
deviceThermalStatePoolId(thermalStatePoolId),
deviceThermalRequestPoolId(thermalRequestPoolId),
healthHelper(this,setObjectId), modeHelper(this), parameterHelper(this), healthHelper(this,setObjectId), modeHelper(this), parameterHelper(this),
childTransitionFailure(RETURN_OK), fdirInstance(fdirInstance), actionHelper(this, nullptr), childTransitionFailure(RETURN_OK),
hkSwitcher(this), defaultFDIRUsed(fdirInstance == nullptr), fdirInstance(fdirInstance), hkSwitcher(this),
switchOffWasReported(false), actionHelper(this, nullptr), defaultFDIRUsed(fdirInstance == nullptr), switchOffWasReported(false),
childTransitionDelay(5000), childTransitionDelay(5000), transitionSourceMode(_MODE_POWER_DOWN),
transitionSourceMode(_MODE_POWER_DOWN), transitionSourceSubMode( transitionSourceSubMode(SUBMODE_NONE) {
SUBMODE_NONE), deviceSwitch(setDeviceSwitch) {
commandQueue = QueueFactory::instance()->createMessageQueue(cmdQueueSize, commandQueue = QueueFactory::instance()->createMessageQueue(cmdQueueSize,
CommandMessage::MAX_MESSAGE_SIZE); MessageQueueMessage::MAX_MESSAGE_SIZE);
insertInCommandMap(RAW_COMMAND_ID); insertInCommandMap(RAW_COMMAND_ID);
cookieInfo.state = COOKIE_UNUSED; cookieInfo.state = COOKIE_UNUSED;
cookieInfo.pendingCommand = deviceCommandMap.end(); cookieInfo.pendingCommand = deviceCommandMap.end();
if (comCookie == nullptr) { if (comCookie == nullptr) {
sif::error << "DeviceHandlerBase: ObjectID 0x" << std::hex << sif::error << "DeviceHandlerBase: ObjectID 0x" << std::hex
std::setw(8) << std::setfill('0') << this->getObjectId() << << std::setw(8) << std::setfill('0') << this->getObjectId()
std::dec << ": Do not pass nullptr as a cookie, consider " << std::dec << ": Do not pass nullptr as a cookie, consider "
<< std::setfill(' ') << "passing a dummy cookie instead!" << << std::setfill(' ') << "passing a dummy cookie instead!"
std::endl; << std::endl;
} }
if (this->fdirInstance == nullptr) { if (this->fdirInstance == nullptr) {
this->fdirInstance = new DeviceHandlerFailureIsolation(setObjectId, this->fdirInstance = new DeviceHandlerFailureIsolation(setObjectId,
defaultFDIRParentId); defaultFdirParentId);
} }
} }
void DeviceHandlerBase::setThermalStateRequestPoolIds(
uint32_t thermalStatePoolId, uint32_t thermalRequestPoolId) {
this->deviceThermalRequestPoolId = thermalStatePoolId;
this->deviceThermalRequestPoolId = thermalRequestPoolId;
}
DeviceHandlerBase::~DeviceHandlerBase() { DeviceHandlerBase::~DeviceHandlerBase() {
delete comCookie; delete comCookie;
if (defaultFDIRUsed) { if (defaultFDIRUsed) {
@ -108,8 +110,12 @@ ReturnValue_t DeviceHandlerBase::initialize() {
communicationInterface = objectManager->get<DeviceCommunicationIF>( communicationInterface = objectManager->get<DeviceCommunicationIF>(
deviceCommunicationId); deviceCommunicationId);
if (communicationInterface == NULL) { if (communicationInterface == nullptr) {
return RETURN_FAILED; sif::error << "DeviceHandlerBase::initialize: Communication interface "
"invalid." << std::endl;
sif::error << "Make sure it is set up properly and implements"
" DeviceCommunicationIF" << std::endl;
return ObjectManagerIF::CHILD_INIT_FAILED;
} }
result = communicationInterface->initializeInterface(comCookie); result = communicationInterface->initializeInterface(comCookie);
@ -118,22 +124,35 @@ ReturnValue_t DeviceHandlerBase::initialize() {
} }
IPCStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE); IPCStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
if (IPCStore == NULL) { if (IPCStore == nullptr) {
return RETURN_FAILED; sif::error << "DeviceHandlerBase::initialize: IPC store not set up in "
"factory." << std::endl;
return ObjectManagerIF::CHILD_INIT_FAILED;
} }
if(rawDataReceiverId != objects::NO_OBJECT) {
AcceptsDeviceResponsesIF *rawReceiver = objectManager->get< AcceptsDeviceResponsesIF *rawReceiver = objectManager->get<
AcceptsDeviceResponsesIF>(rawDataReceiverId); AcceptsDeviceResponsesIF>(rawDataReceiverId);
if (rawReceiver == NULL) { if (rawReceiver == nullptr) {
return RETURN_FAILED; sif::error << "DeviceHandlerBase::initialize: Raw receiver object "
"ID set but no valid object found." << std::endl;
sif::error << "Make sure the raw receiver object is set up properly"
" and implements AcceptsDeviceResponsesIF" << std::endl;
return ObjectManagerIF::CHILD_INIT_FAILED;
}
defaultRawReceiver = rawReceiver->getDeviceQueue();
} }
defaultRawReceiver = rawReceiver->getDeviceQueue(); if(powerSwitcherId != objects::NO_OBJECT) {
powerSwitcher = objectManager->get<PowerSwitchIF>(powerSwitcherId); powerSwitcher = objectManager->get<PowerSwitchIF>(powerSwitcherId);
if (powerSwitcher == NULL) { if (powerSwitcher == nullptr) {
return RETURN_FAILED; sif::error << "DeviceHandlerBase::initialize: Power switcher "
<< "object ID set but no valid object found." << std::endl;
sif::error << "Make sure the raw receiver object is set up properly"
<< " and implements PowerSwitchIF" << std::endl;
return ObjectManagerIF::CHILD_INIT_FAILED;
}
} }
result = healthHelper.initialize(); result = healthHelper.initialize();
@ -168,7 +187,7 @@ ReturnValue_t DeviceHandlerBase::initialize() {
//Set temperature target state to NON_OP. //Set temperature target state to NON_OP.
DataSet mySet; DataSet mySet;
PoolVariable<int8_t> thermalRequest(deviceThermalRequestPoolId, &mySet, db_int8_t thermalRequest(deviceThermalRequestPoolId, &mySet,
PoolVariableIF::VAR_WRITE); PoolVariableIF::VAR_WRITE);
mySet.read(); mySet.read();
thermalRequest = ThermalComponentIF::STATE_REQUEST_NON_OPERATIONAL; thermalRequest = ThermalComponentIF::STATE_REQUEST_NON_OPERATIONAL;
@ -200,38 +219,43 @@ void DeviceHandlerBase::readCommandQueue() {
return; return;
} }
CommandMessage message; CommandMessage command;
ReturnValue_t result = commandQueue->receiveMessage(&message); ReturnValue_t result = commandQueue->receiveMessage(&command);
if (result != RETURN_OK) { if (result != RETURN_OK) {
return; return;
} }
result = healthHelper.handleHealthCommand(&message); result = healthHelper.handleHealthCommand(&command);
if (result == RETURN_OK) { if (result == RETURN_OK) {
return; return;
} }
result = modeHelper.handleModeCommand(&message); result = modeHelper.handleModeCommand(&command);
if (result == RETURN_OK) { if (result == RETURN_OK) {
return; return;
} }
result = actionHelper.handleActionMessage(&message); result = actionHelper.handleActionMessage(&command);
if (result == RETURN_OK) { if (result == RETURN_OK) {
return; return;
} }
result = parameterHelper.handleParameterMessage(&message); result = parameterHelper.handleParameterMessage(&command);
if (result == RETURN_OK) { if (result == RETURN_OK) {
return; return;
} }
result = handleDeviceHandlerMessage(&message); // result = hkManager.handleHousekeepingMessage(&command);
// if (result == RETURN_OK) {
// return;
// }
result = handleDeviceHandlerMessage(&command);
if (result == RETURN_OK) { if (result == RETURN_OK) {
return; return;
} }
result = letChildHandleMessage(&message); result = letChildHandleMessage(&command);
if (result == RETURN_OK) { if (result == RETURN_OK) {
return; return;
} }
@ -273,7 +297,8 @@ void DeviceHandlerBase::doStateMachine() {
case _MODE_WAIT_ON: { case _MODE_WAIT_ON: {
uint32_t currentUptime; uint32_t currentUptime;
Clock::getUptime(&currentUptime); Clock::getUptime(&currentUptime);
if (currentUptime - timeoutStart >= powerSwitcher->getSwitchDelayMs()) { if (powerSwitcher != nullptr and currentUptime - timeoutStart >=
powerSwitcher->getSwitchDelayMs()) {
triggerEvent(MODE_TRANSITION_FAILED, PowerSwitchIF::SWITCH_TIMEOUT, triggerEvent(MODE_TRANSITION_FAILED, PowerSwitchIF::SWITCH_TIMEOUT,
0); 0);
setMode(_MODE_POWER_DOWN); setMode(_MODE_POWER_DOWN);
@ -293,6 +318,12 @@ void DeviceHandlerBase::doStateMachine() {
case _MODE_WAIT_OFF: { case _MODE_WAIT_OFF: {
uint32_t currentUptime; uint32_t currentUptime;
Clock::getUptime(&currentUptime); Clock::getUptime(&currentUptime);
if(powerSwitcher == nullptr) {
setMode(MODE_OFF);
break;
}
if (currentUptime - timeoutStart >= powerSwitcher->getSwitchDelayMs()) { if (currentUptime - timeoutStart >= powerSwitcher->getSwitchDelayMs()) {
triggerEvent(MODE_TRANSITION_FAILED, PowerSwitchIF::SWITCH_TIMEOUT, triggerEvent(MODE_TRANSITION_FAILED, PowerSwitchIF::SWITCH_TIMEOUT,
0); 0);
@ -343,9 +374,10 @@ ReturnValue_t DeviceHandlerBase::isModeCombinationValid(Mode_t mode,
} }
} }
ReturnValue_t DeviceHandlerBase::insertInCommandAndReplyMap(DeviceCommandId_t deviceCommand, ReturnValue_t DeviceHandlerBase::insertInCommandAndReplyMap(
uint16_t maxDelayCycles, size_t replyLen, bool periodic, DeviceCommandId_t deviceCommand, uint16_t maxDelayCycles,
bool hasDifferentReplyId, DeviceCommandId_t replyId) { size_t replyLen, bool periodic, bool hasDifferentReplyId,
DeviceCommandId_t replyId) {
//No need to check, as we may try to insert multiple times. //No need to check, as we may try to insert multiple times.
insertInCommandMap(deviceCommand); insertInCommandMap(deviceCommand);
if (hasDifferentReplyId) { if (hasDifferentReplyId) {
@ -371,7 +403,8 @@ ReturnValue_t DeviceHandlerBase::insertInReplyMap(DeviceCommandId_t replyId,
} }
} }
ReturnValue_t DeviceHandlerBase::insertInCommandMap(DeviceCommandId_t deviceCommand) { ReturnValue_t DeviceHandlerBase::insertInCommandMap(
DeviceCommandId_t deviceCommand) {
DeviceCommandInfo info; DeviceCommandInfo info;
info.expectedReplies = 0; info.expectedReplies = 0;
info.isExecuting = false; info.isExecuting = false;
@ -437,7 +470,7 @@ void DeviceHandlerBase::setMode(Mode_t newMode, uint8_t newSubmode) {
if (mode == MODE_OFF) { if (mode == MODE_OFF) {
DataSet mySet; DataSet mySet;
PoolVariable<int8_t> thermalRequest(deviceThermalRequestPoolId, &mySet, db_int8_t thermalRequest(deviceThermalRequestPoolId, &mySet,
PoolVariableIF::VAR_READ_WRITE); PoolVariableIF::VAR_READ_WRITE);
mySet.read(); mySet.read();
if (thermalRequest != ThermalComponentIF::STATE_REQUEST_IGNORE) { if (thermalRequest != ThermalComponentIF::STATE_REQUEST_IGNORE) {
@ -578,11 +611,8 @@ void DeviceHandlerBase::doSendRead() {
} }
void DeviceHandlerBase::doGetRead() { void DeviceHandlerBase::doGetRead() {
size_t receivedDataLen; size_t receivedDataLen = 0;
uint8_t *receivedData; uint8_t *receivedData = nullptr;
DeviceCommandId_t foundId = 0xFFFFFFFF;
size_t foundLen = 0;
ReturnValue_t result;
if (cookieInfo.state != COOKIE_READ_SENT) { if (cookieInfo.state != COOKIE_READ_SENT) {
cookieInfo.state = COOKIE_UNUSED; cookieInfo.state = COOKIE_UNUSED;
@ -591,8 +621,8 @@ void DeviceHandlerBase::doGetRead() {
cookieInfo.state = COOKIE_UNUSED; cookieInfo.state = COOKIE_UNUSED;
result = communicationInterface->readReceivedMessage(comCookie, ReturnValue_t result = communicationInterface->readReceivedMessage(
&receivedData, &receivedDataLen); comCookie, &receivedData, &receivedDataLen);
if (result != RETURN_OK) { if (result != RETURN_OK) {
triggerEvent(DEVICE_REQUESTING_REPLY_FAILED, result); triggerEvent(DEVICE_REQUESTING_REPLY_FAILED, result);
@ -608,11 +638,22 @@ void DeviceHandlerBase::doGetRead() {
replyRawData(receivedData, receivedDataLen, requestedRawTraffic); replyRawData(receivedData, receivedDataLen, requestedRawTraffic);
} }
if (mode == MODE_RAW) { if (mode == MODE_RAW and defaultRawReceiver != MessageQueueIF::NO_QUEUE) {
replyRawReplyIfnotWiretapped(receivedData, receivedDataLen); replyRawReplyIfnotWiretapped(receivedData, receivedDataLen);
} else { }
//The loop may not execute more often than the number of received bytes (worst case). else {
//This approach avoids infinite loops due to buggy scanForReply routines (seen in bug 1077). parseReply(receivedData, receivedDataLen);
}
}
void DeviceHandlerBase::parseReply(const uint8_t* receivedData,
size_t receivedDataLen) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED;
DeviceCommandId_t foundId = 0xFFFFFFFF;
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.
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,
@ -647,7 +688,46 @@ void DeviceHandlerBase::doGetRead() {
return; return;
} }
} }
}
void DeviceHandlerBase::handleReply(const uint8_t* receivedData,
DeviceCommandId_t foundId, uint32_t foundLen) {
ReturnValue_t result;
DeviceReplyMap::iterator iter = deviceReplyMap.find(foundId);
if (iter == deviceReplyMap.end()) {
replyRawReplyIfnotWiretapped(receivedData, foundLen);
triggerEvent(DEVICE_UNKNOWN_REPLY, foundId);
return;
}
DeviceReplyInfo *info = &(iter->second);
if (info->delayCycles != 0) {
if (info->periodic != false) {
info->delayCycles = info->maxDelayCycles;
}
else {
info->delayCycles = 0;
}
result = interpretDeviceReply(foundId, receivedData);
if (result != RETURN_OK) {
// Report failed interpretation to FDIR.
replyRawReplyIfnotWiretapped(receivedData, foundLen);
triggerEvent(DEVICE_INTERPRETING_REPLY_FAILED, result, foundId);
}
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.
if (mode != _MODE_WAIT_OFF) {
triggerEvent(DEVICE_UNREQUESTED_REPLY, foundId);
}
} }
} }
@ -675,7 +755,7 @@ ReturnValue_t DeviceHandlerBase::getStorageData(store_address_t storageAddress,
void DeviceHandlerBase::replyRawData(const uint8_t *data, size_t len, void DeviceHandlerBase::replyRawData(const uint8_t *data, size_t len,
MessageQueueId_t sendTo, bool isCommand) { MessageQueueId_t sendTo, bool isCommand) {
if (IPCStore == NULL || len == 0) { if (IPCStore == nullptr or len == 0 or sendTo == MessageQueueIF::NO_QUEUE) {
return; return;
} }
store_address_t address; store_address_t address;
@ -686,18 +766,17 @@ void DeviceHandlerBase::replyRawData(const uint8_t *data, size_t len,
return; return;
} }
CommandMessage message; CommandMessage command;
DeviceHandlerMessage::setDeviceHandlerRawReplyMessage(&message, DeviceHandlerMessage::setDeviceHandlerRawReplyMessage(&command,
getObjectId(), address, isCommand); getObjectId(), address, isCommand);
// this->DeviceHandlerCommand = CommandMessage::CMD_NONE; result = commandQueue->sendMessage(sendTo, &command);
result = commandQueue->sendMessage(sendTo, &message);
if (result != RETURN_OK) { if (result != RETURN_OK) {
IPCStore->deleteData(address); IPCStore->deleteData(address);
//Silently discard data, this indicates heavy TM traffic which should not be increased by additional events. // Silently discard data, this indicates heavy TM traffic which
// should not be increased by additional events.
} }
} }
@ -726,57 +805,6 @@ MessageQueueId_t DeviceHandlerBase::getCommandQueue() const {
return commandQueue->getId(); return commandQueue->getId();
} }
void DeviceHandlerBase::handleReply(const uint8_t* receivedData,
DeviceCommandId_t foundId, uint32_t foundLen) {
ReturnValue_t result;
DeviceReplyMap::iterator iter = deviceReplyMap.find(foundId);
if (iter == deviceReplyMap.end()) {
replyRawReplyIfnotWiretapped(receivedData, foundLen);
triggerEvent(DEVICE_UNKNOWN_REPLY, foundId);
return;
}
DeviceReplyInfo *info = &(iter->second);
if (info->delayCycles != 0) {
if (info->periodic) {
info->delayCycles = info->maxDelayCycles;
} else {
info->delayCycles = 0;
}
result = interpretDeviceReply(foundId, receivedData);
if (result != RETURN_OK) {
//Report failed interpretation to FDIR.
replyRawReplyIfnotWiretapped(receivedData, foundLen);
triggerEvent(DEVICE_INTERPRETING_REPLY_FAILED, result, foundId);
}
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.
if (mode != _MODE_WAIT_OFF) {
triggerEvent(DEVICE_UNREQUESTED_REPLY, foundId);
}
}
}
//ReturnValue_t DeviceHandlerBase::switchCookieChannel(object_id_t newChannelId) {
// DeviceCommunicationIF *newCommunication = objectManager->get<
// DeviceCommunicationIF>(newChannelId);
//
// if (newCommunication != NULL) {
// ReturnValue_t result = newCommunication->reOpen(cookie, ioBoardAddress,
// maxDeviceReplyLen);
// if (result != RETURN_OK) {
// return result;
// }
// return RETURN_OK;
// }
// return RETURN_FAILED;
//}
void DeviceHandlerBase::buildRawDeviceCommand(CommandMessage* commandMessage) { void DeviceHandlerBase::buildRawDeviceCommand(CommandMessage* commandMessage) {
storedRawData = DeviceHandlerMessage::getStoreAddress(commandMessage); storedRawData = DeviceHandlerMessage::getStoreAddress(commandMessage);
ReturnValue_t result = getStorageData(storedRawData, &rawPacket, ReturnValue_t result = getStorageData(storedRawData, &rawPacket,
@ -793,6 +821,9 @@ void DeviceHandlerBase::buildRawDeviceCommand(CommandMessage* commandMessage) {
} }
void DeviceHandlerBase::commandSwitch(ReturnValue_t onOff) { void DeviceHandlerBase::commandSwitch(ReturnValue_t onOff) {
if(powerSwitcher == nullptr) {
return;
}
const uint8_t *switches; const uint8_t *switches;
uint8_t numberOfSwitches = 0; uint8_t numberOfSwitches = 0;
ReturnValue_t result = getSwitches(&switches, &numberOfSwitches); ReturnValue_t result = getSwitches(&switches, &numberOfSwitches);
@ -807,9 +838,7 @@ void DeviceHandlerBase::commandSwitch(ReturnValue_t onOff) {
ReturnValue_t DeviceHandlerBase::getSwitches(const uint8_t **switches, ReturnValue_t DeviceHandlerBase::getSwitches(const uint8_t **switches,
uint8_t *numberOfSwitches) { uint8_t *numberOfSwitches) {
*switches = &deviceSwitch; return DeviceHandlerBase::NO_SWITCH;
*numberOfSwitches = 1;
return RETURN_OK;
} }
void DeviceHandlerBase::modeChanged(void) { void DeviceHandlerBase::modeChanged(void) {
@ -845,6 +874,9 @@ uint32_t DeviceHandlerBase::getTransitionDelayMs(Mode_t modeFrom,
} }
ReturnValue_t DeviceHandlerBase::getStateOfSwitches(void) { ReturnValue_t DeviceHandlerBase::getStateOfSwitches(void) {
if(powerSwitcher == nullptr) {
return NO_SWITCH;
}
uint8_t numberOfSwitches = 0; uint8_t numberOfSwitches = 0;
const uint8_t *switches; const uint8_t *switches;
@ -895,9 +927,9 @@ ReturnValue_t DeviceHandlerBase::checkModeCommand(Mode_t commandedMode,
if ((commandedMode == MODE_ON) && (mode == MODE_OFF) if ((commandedMode == MODE_ON) && (mode == MODE_OFF)
&& (deviceThermalStatePoolId != PoolVariableIF::NO_PARAMETER)) { && (deviceThermalStatePoolId != PoolVariableIF::NO_PARAMETER)) {
DataSet mySet; DataSet mySet;
PoolVariable<int8_t> thermalState(deviceThermalStatePoolId, &mySet, db_int8_t thermalState(deviceThermalStatePoolId, &mySet,
PoolVariableIF::VAR_READ); PoolVariableIF::VAR_READ);
PoolVariable<int8_t> thermalRequest(deviceThermalRequestPoolId, &mySet, db_int8_t thermalRequest(deviceThermalRequestPoolId, &mySet,
PoolVariableIF::VAR_READ); PoolVariableIF::VAR_READ);
mySet.read(); mySet.read();
if (thermalRequest != ThermalComponentIF::STATE_REQUEST_IGNORE) { if (thermalRequest != ThermalComponentIF::STATE_REQUEST_IGNORE) {
@ -925,7 +957,7 @@ void DeviceHandlerBase::startTransition(Mode_t commandedMode,
MODE_ON); MODE_ON);
triggerEvent(CHANGING_MODE, commandedMode, commandedSubmode); triggerEvent(CHANGING_MODE, commandedMode, commandedSubmode);
DataSet mySet; DataSet mySet;
PoolVariable<int8_t> thermalRequest(deviceThermalRequestPoolId, db_int8_t thermalRequest(deviceThermalRequestPoolId,
&mySet, PoolVariableIF::VAR_READ_WRITE); &mySet, PoolVariableIF::VAR_READ_WRITE);
mySet.read(); mySet.read();
if (thermalRequest != ThermalComponentIF::STATE_REQUEST_IGNORE) { if (thermalRequest != ThermalComponentIF::STATE_REQUEST_IGNORE) {
@ -1111,35 +1143,47 @@ void DeviceHandlerBase::handleDeviceTM(SerializeIF* data,
return; return;
} }
DeviceTmReportingWrapper wrapper(getObjectId(), replyId, data); DeviceTmReportingWrapper wrapper(getObjectId(), replyId, data);
if (iter->second.command != deviceCommandMap.end()) {//replies to a command //replies to a command
if (iter->second.command != deviceCommandMap.end())
{
MessageQueueId_t queueId = iter->second.command->second.sendReplyTo; MessageQueueId_t queueId = iter->second.command->second.sendReplyTo;
if (queueId != NO_COMMANDER) { if (queueId != NO_COMMANDER) {
//This may fail, but we'll ignore the fault. //This may fail, but we'll ignore the fault.
actionHelper.reportData(queueId, replyId, data); actionHelper.reportData(queueId, replyId, data);
} }
//This check should make sure we get any TM but don't get anything doubled. //This check should make sure we get any TM but don't get anything doubled.
if (wiretappingMode == TM && (requestedRawTraffic != queueId)) { if (wiretappingMode == TM && (requestedRawTraffic != queueId)) {
actionHelper.reportData(requestedRawTraffic, replyId, &wrapper); actionHelper.reportData(requestedRawTraffic, replyId, &wrapper);
} else if (forceDirectTm && (defaultRawReceiver != queueId)) { }
else if (forceDirectTm and (defaultRawReceiver != queueId) and
// hiding of sender needed so the service will handle it as unexpected Data, no matter what state (defaultRawReceiver != MessageQueueIF::NO_QUEUE))
//(progress or completed) it is in {
// hiding of sender needed so the service will handle it as
// unexpected Data, no matter what state (progress or completed)
// it is in
actionHelper.reportData(defaultRawReceiver, replyId, &wrapper, actionHelper.reportData(defaultRawReceiver, replyId, &wrapper,
true); true);
} }
} else { //unrequested/aperiodic replies }
//unrequested/aperiodic replies
else
{
if (wiretappingMode == TM) { if (wiretappingMode == TM) {
actionHelper.reportData(requestedRawTraffic, replyId, &wrapper); actionHelper.reportData(requestedRawTraffic, replyId, &wrapper);
} else if (forceDirectTm) { }
// hiding of sender needed so the service will handle it as unexpected Data, no matter what state else if (forceDirectTm and defaultRawReceiver !=
//(progress or completed) it is in MessageQueueIF::NO_QUEUE)
{
// hiding of sender needed so the service will handle it as
// unexpected Data, no matter what state (progress or completed)
// it is in
actionHelper.reportData(defaultRawReceiver, replyId, &wrapper, actionHelper.reportData(defaultRawReceiver, replyId, &wrapper,
true); true);
} }
} }
//Try to cast to DataSet and commit data. //Try to cast to GlobDataSet and commit data.
if (!neverInDataPool) { if (!neverInDataPool) {
DataSet* dataSet = dynamic_cast<DataSet*>(data); DataSet* dataSet = dynamic_cast<DataSet*>(data);
if (dataSet != NULL) { if (dataSet != NULL) {
@ -1178,18 +1222,23 @@ void DeviceHandlerBase::buildInternalCommand(void) {
if (mode == MODE_NORMAL) { if (mode == MODE_NORMAL) {
result = buildNormalDeviceCommand(&deviceCommandId); result = buildNormalDeviceCommand(&deviceCommandId);
if (result == BUSY) { if (result == BUSY) {
//so we can track misconfigurations
sif::debug << std::hex << getObjectId() sif::debug << std::hex << getObjectId()
<< ": DHB::buildInternalCommand busy" << std::endl; //so we can track misconfigurations << ": DHB::buildInternalCommand: Busy" << std::endl;
result = NOTHING_TO_SEND; //no need to report this result = NOTHING_TO_SEND; //no need to report this
} }
} else if (mode == MODE_RAW) { }
else if (mode == MODE_RAW) {
result = buildChildRawCommand(); result = buildChildRawCommand();
deviceCommandId = RAW_COMMAND_ID; deviceCommandId = RAW_COMMAND_ID;
} else if (mode & TRANSITION_MODE_CHILD_ACTION_MASK) { }
else if (mode & TRANSITION_MODE_CHILD_ACTION_MASK) {
result = buildTransitionDeviceCommand(&deviceCommandId); result = buildTransitionDeviceCommand(&deviceCommandId);
} else { }
else {
return; return;
} }
if (result == NOTHING_TO_SEND) { if (result == NOTHING_TO_SEND) {
return; return;
} }
@ -1288,4 +1337,15 @@ void DeviceHandlerBase::setTaskIF(PeriodicTaskIF* task_){
void DeviceHandlerBase::debugInterface(uint8_t positionTracker, void DeviceHandlerBase::debugInterface(uint8_t positionTracker,
object_id_t objectId, uint32_t parameter) {} object_id_t objectId, uint32_t parameter) {}
void DeviceHandlerBase::performOperationHook() {} void DeviceHandlerBase::performOperationHook() {
}
ReturnValue_t DeviceHandlerBase::initializeAfterTaskCreation() {
// In this function, the task handle should be valid if the task
// was implemented correctly. We still check to be 1000 % sure :-)
if(executingTask != nullptr) {
pstIntervalMs = executingTask->getPeriodMs();
}
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -1,22 +1,23 @@
#ifndef DEVICEHANDLERBASE_H_ #ifndef FRAMEWORK_DEVICEHANDLERS_DEVICEHANDLERBASE_H_
#define DEVICEHANDLERBASE_H_ #define FRAMEWORK_DEVICEHANDLERS_DEVICEHANDLERBASE_H_
#include "DeviceHandlerIF.h"
#include "DeviceCommunicationIF.h"
#include "DeviceHandlerFailureIsolation.h"
#include "../objectmanager/SystemObject.h" #include "../objectmanager/SystemObject.h"
#include "../tasks/PeriodicTaskIF.h"
#include "../tasks/ExecutableObjectIF.h" #include "../tasks/ExecutableObjectIF.h"
#include "DeviceHandlerIF.h"
#include "../returnvalues/HasReturnvaluesIF.h" #include "../returnvalues/HasReturnvaluesIF.h"
#include "../action/HasActionsIF.h" #include "../action/HasActionsIF.h"
#include "../datapool/PoolVariableIF.h" #include "../datapool/PoolVariableIF.h"
#include "DeviceCommunicationIF.h"
#include "../modes/HasModesIF.h" #include "../modes/HasModesIF.h"
#include "../power/PowerSwitchIF.h" #include "../power/PowerSwitchIF.h"
#include "../ipc/MessageQueueIF.h" #include "../ipc/MessageQueueIF.h"
#include "../action/ActionHelper.h" #include "../action/ActionHelper.h"
#include "../health/HealthHelper.h" #include "../health/HealthHelper.h"
#include "../parameters/ParameterHelper.h" #include "../parameters/ParameterHelper.h"
#include "../datapool/HkSwitchHelper.h" #include "../datapool/HkSwitchHelper.h"
#include "DeviceHandlerFailureIsolation.h"
#include <map> #include <map>
@ -46,14 +47,16 @@ class StorageManagerIF;
* If data has been received (GET_READ), the data will be interpreted. * If data has been received (GET_READ), the data will be interpreted.
* The action for each step can be defined by the child class but as most * The action for each step can be defined by the child class but as most
* device handlers share a 4-call (sendRead-getRead-sendWrite-getWrite) structure, * device handlers share a 4-call (sendRead-getRead-sendWrite-getWrite) structure,
* a default implementation is provided. NOTE: RMAP is a standard which is used for FLP. * a default implementation is provided.
* NOTE: RMAP is a standard which is used for FLP.
* RMAP communication is not mandatory for projects implementing the FSFW. * RMAP communication is not mandatory for projects implementing the FSFW.
* However, the communication principles are similar to RMAP as there are * However, the communication principles are similar to RMAP as there are
* two write and two send calls involved. * two write and two send calls involved.
* *
* Device handler instances should extend this class and implement the abstract functions. * Device handler instances should extend this class and implement the abstract
* Components and drivers can send so called cookies which are used for communication * functions. Components and drivers can send so called cookies which are used
* and contain information about the communcation (e.g. slave address for I2C or RMAP structs). * for communication and contain information about the communcation (e.g. slave
* address for I2C or RMAP structs).
* The following abstract methods must be implemented by a device handler: * The following abstract methods must be implemented by a device handler:
* 1. doStartUp() * 1. doStartUp()
* 2. doShutDown() * 2. doShutDown()
@ -100,12 +103,12 @@ public:
* @param cmdQueueSize * @param cmdQueueSize
*/ */
DeviceHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication, DeviceHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication,
CookieIF * comCookie, uint8_t setDeviceSwitch, CookieIF * comCookie, FailureIsolationBase* fdirInstance = nullptr,
uint32_t thermalStatePoolId = PoolVariableIF::NO_PARAMETER,
uint32_t thermalRequestPoolId = PoolVariableIF::NO_PARAMETER,
FailureIsolationBase* fdirInstance = nullptr,
size_t cmdQueueSize = 20); size_t cmdQueueSize = 20);
void setThermalStateRequestPoolIds(uint32_t thermalStatePoolId,
uint32_t thermalRequestPoolId);
/** /**
* @brief This function is the device handler base core component and is * @brief This function is the device handler base core component and is
* called periodically. * called periodically.
@ -150,11 +153,9 @@ public:
* @return * @return
*/ */
virtual ReturnValue_t initialize(); virtual ReturnValue_t initialize();
/** Destructor. */
/**
* Destructor.
*/
virtual ~DeviceHandlerBase(); virtual ~DeviceHandlerBase();
protected: protected:
/** /**
* @brief This is used to let the child class handle the transition from * @brief This is used to let the child class handle the transition from
@ -232,8 +233,9 @@ protected:
* Build the device command to send for a transitional mode. * Build the device command to send for a transitional mode.
* *
* This is only called in @c _MODE_TO_NORMAL, @c _MODE_TO_ON, @c _MODE_TO_RAW, * This is only called in @c _MODE_TO_NORMAL, @c _MODE_TO_ON, @c _MODE_TO_RAW,
* @c _MODE_START_UP and @c _MODE_TO_POWER_DOWN. So it is used by doStartUp() * @c _MODE_START_UP and @c _MODE_SHUT_DOWN. So it is used by doStartUp()
* and doShutDown() as well as doTransition() * and doShutDown() as well as doTransition(), by setting those
* modes in the respective functions.
* *
* A good idea is to implement a flag indicating a command has to be built * A good idea is to implement a flag indicating a command has to be built
* and a variable containing the command number to be built * and a variable containing the command number to be built
@ -321,12 +323,11 @@ protected:
* - @c RETURN_FAILED when the reply could not be interpreted, * - @c RETURN_FAILED when the reply could not be interpreted,
* e.g. logical errors or range violations occurred * e.g. logical errors or range violations occurred
*/ */
virtual ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, virtual ReturnValue_t interpretDeviceReply(DeviceCommandId_t id,
const uint8_t *packet) = 0; const uint8_t *packet) = 0;
/** /**
* @brief fill the #deviceCommandMap * @brief fill the #DeviceCommandMap and #DeviceReplyMap
* called by the initialize() of the base class * called by the initialize() of the base class
* @details * @details
* This is used to let the base class know which replies are expected. * This is used to let the base class know which replies are expected.
@ -470,6 +471,18 @@ protected:
virtual ReturnValue_t getSwitches(const uint8_t **switches, virtual ReturnValue_t getSwitches(const uint8_t **switches,
uint8_t *numberOfSwitches); uint8_t *numberOfSwitches);
/**
* This function is used to initialize the local housekeeping pool
* entries. The default implementation leaves the pool empty.
* @param localDataPoolMap
* @return
*/
//virtual ReturnValue_t initializePoolEntries(
// LocalDataPool& localDataPoolMap) override;
/** Get the HK manager object handle */
//virtual LocalDataPoolManager* getHkManagerHandle() override;
/** /**
* @brief Hook function for child handlers which is called once per * @brief Hook function for child handlers which is called once per
* performOperation(). Default implementation is empty. * performOperation(). Default implementation is empty.
@ -493,7 +506,7 @@ public:
ReturnValue_t setHealth(HealthState health); ReturnValue_t setHealth(HealthState health);
virtual ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId, virtual ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId,
ParameterWrapper *parameterWrapper, ParameterWrapper *parameterWrapper,
const ParameterWrapper *newValues, uint16_t startAtIndex); const ParameterWrapper *newValues, uint16_t startAtIndex) override;
/** /**
* Implementation of ExecutableObjectIF function * Implementation of ExecutableObjectIF function
* *
@ -505,7 +518,7 @@ public:
protected: protected:
/** /**
* The Returnvalues ID of this class, required by HasReturnvaluesIF * The Returnvalues id of this class, required by HasReturnvaluesIF
*/ */
static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_BASE; static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_BASE;
@ -527,114 +540,138 @@ protected:
static const DeviceCommandId_t NO_COMMAND_ID = -2; static const DeviceCommandId_t NO_COMMAND_ID = -2;
static const MessageQueueId_t NO_COMMANDER = 0; static const MessageQueueId_t NO_COMMANDER = 0;
/** /** Pointer to the raw packet that will be sent.*/
* Pointer to the raw packet that will be sent.
*/
uint8_t *rawPacket = nullptr; uint8_t *rawPacket = nullptr;
/** /** Size of the #rawPacket. */
* Size of the #rawPacket.
*/
uint32_t rawPacketLen = 0; uint32_t rawPacketLen = 0;
/** /**
* The mode the device handler is currently in. * The mode the device handler is currently in.
*
* This should never be changed directly but only with setMode() * This should never be changed directly but only with setMode()
*/ */
Mode_t mode; Mode_t mode;
/** /**
* The submode the device handler is currently in. * The submode the device handler is currently in.
*
* This should never be changed directly but only with setMode() * This should never be changed directly but only with setMode()
*/ */
Submode_t submode; Submode_t submode;
/** /** This is the counter value from performOperation(). */
* This is the counter value from performOperation().
*/
uint8_t pstStep = 0; uint8_t pstStep = 0;
uint32_t pstIntervalMs = 0;
/** /**
* wiretapping flag: * Wiretapping flag:
* *
* indicates either that all raw messages to and from the device should be sent to #theOneWhoWantsToReadRawTraffic * indicates either that all raw messages to and from the device should be
* or that all device TM should be downlinked to #theOneWhoWantsToReadRawTraffic * sent to #defaultRawReceiver
* or that all device TM should be downlinked to #defaultRawReceiver.
*/ */
enum WiretappingMode { enum WiretappingMode {
OFF = 0, RAW = 1, TM = 2 OFF = 0, RAW = 1, TM = 2
} wiretappingMode; } wiretappingMode;
/** /**
* A message queue that accepts raw replies * @brief A message queue that accepts raw replies
* *
* Statically initialized in initialize() to a configurable object. Used when there is no method * Statically initialized in initialize() to a configurable object.
* of finding a recipient, ie raw mode and reporting erreonous replies * Used when there is no method of finding a recipient, ie raw mode and
* reporting erroneous replies
*/ */
MessageQueueId_t defaultRawReceiver = 0; MessageQueueId_t defaultRawReceiver = MessageQueueIF::NO_QUEUE;
store_address_t storedRawData; store_address_t storedRawData;
/** /**
* the message queue which wants to read all raw traffic * @brief The message queue which wants to read all raw traffic
* * If #isWiretappingActive all raw communication from and to the device
* if #isWiretappingActive all raw communication from and to the device will be sent to this queue * will be sent to this queue
*/ */
MessageQueueId_t requestedRawTraffic = 0; MessageQueueId_t requestedRawTraffic = 0;
/**
* the object used to set power switches
*/
PowerSwitchIF *powerSwitcher = nullptr;
/** /**
* Pointer to the IPCStore. * Pointer to the IPCStore.
*
* This caches the pointer received from the objectManager in the constructor. * This caches the pointer received from the objectManager in the constructor.
*/ */
StorageManagerIF *IPCStore = nullptr; StorageManagerIF *IPCStore = nullptr;
/** The comIF object ID is cached for the intialize() function */
/**
* cached for init
*/
object_id_t deviceCommunicationId; object_id_t deviceCommunicationId;
/** Communication object used for device communication */
/**
* Communication object used for device communication
*/
DeviceCommunicationIF * communicationInterface = nullptr; DeviceCommunicationIF * communicationInterface = nullptr;
/** Cookie used for communication */
/**
* Cookie used for communication
*/
CookieIF * comCookie; CookieIF * comCookie;
/** Health helper for HasHealthIF */
HealthHelper healthHelper;
/** Mode helper for HasModesIF */
ModeHelper modeHelper;
/** Parameter helper for ReceivesParameterMessagesIF */
ParameterHelper parameterHelper;
/** Action helper for HasActionsIF */
ActionHelper actionHelper;
/** Housekeeping Manager */
//LocalDataPoolManager hkManager;
/**
* @brief Information about commands
*/
struct DeviceCommandInfo { struct DeviceCommandInfo {
bool isExecuting; //!< Indicates if the command is already executing. //! Indicates if the command is already executing.
uint8_t expectedReplies; //!< Dynamic value to indicate how many replies are expected. Inititated with 0. bool isExecuting;
MessageQueueId_t sendReplyTo; //!< if this is != NO_COMMANDER, DHB was commanded externally and shall report everything to commander. //! Dynamic value to indicate how many replies are expected.
//! Inititated with 0.
uint8_t expectedReplies;
//! if this is != NO_COMMANDER, DHB was commanded externally and shall
//! report everything to commander.
MessageQueueId_t sendReplyTo;
}; };
using DeviceCommandMap = std::map<DeviceCommandId_t, DeviceCommandInfo> ; using DeviceCommandMap = std::map<DeviceCommandId_t, DeviceCommandInfo> ;
/**
* Information about commands
*/
DeviceCommandMap deviceCommandMap;
/** /**
* @brief Information about expected replies * @brief Information about expected replies
* * This is used to keep track of pending replies.
* This is used to keep track of pending replies
*/ */
struct DeviceReplyInfo { struct DeviceReplyInfo {
uint16_t maxDelayCycles; //!< The maximum number of cycles the handler should wait for a reply to this command. //! The maximum number of cycles the handler should wait for a reply
uint16_t delayCycles; //!< The currently remaining cycles the handler should wait for a reply, 0 means there is no reply expected //! to this command.
uint16_t maxDelayCycles;
//! The currently remaining cycles the handler should wait for a reply,
//! 0 means there is no reply expected
uint16_t delayCycles;
size_t replyLen = 0; //!< Expected size of the reply. size_t replyLen = 0; //!< Expected size of the reply.
bool periodic; //!< if this is !=0, the delayCycles will not be reset to 0 but to maxDelayCycles //! if this is !=0, the delayCycles will not be reset to 0 but to
DeviceCommandMap::iterator command; //!< The command that expects this reply. //! maxDelayCycles
bool periodic = false;
//! The dataset used to access housekeeping data related to the
//! respective device reply. Will point to a dataset held by
//! the child handler (if one is specified)
// DataSetIF* dataSet = nullptr;
//! The command that expects this reply.
DeviceCommandMap::iterator command;
}; };
using DeviceReplyMap = std::map<DeviceCommandId_t, DeviceReplyInfo> ; using DeviceReplyMap = std::map<DeviceCommandId_t, DeviceReplyInfo> ;
using DeviceReplyIter = DeviceReplyMap::iterator; using DeviceReplyIter = DeviceReplyMap::iterator;
/** /**
* The MessageQueue used to receive device handler commands and to send replies. * This map is used to check and track correct reception of all replies.
*
* It has multiple use:
* - It stores the information on pending replies. If a command is sent,
* the DeviceCommandInfo.count is incremented.
* - It is used to time-out missing replies. If a command is sent, the
* DeviceCommandInfo.DelayCycles is set to MaxDelayCycles.
* - It is queried to check if a reply from the device can be interpreted.
* scanForReply() returns the id of the command a reply was found for.
* The reply is ignored in the following cases:
* - No entry for the returned id was found
* - The deviceReplyInfo.delayCycles is == 0
*/ */
DeviceReplyMap deviceReplyMap;
//! The MessageQueue used to receive device handler commands
//! and to send replies.
MessageQueueIF* commandQueue = nullptr; MessageQueueIF* commandQueue = nullptr;
/** /**
@ -642,23 +679,14 @@ protected:
* *
* can be set to PoolVariableIF::NO_PARAMETER to deactivate thermal checking * can be set to PoolVariableIF::NO_PARAMETER to deactivate thermal checking
*/ */
uint32_t deviceThermalStatePoolId; uint32_t deviceThermalStatePoolId = PoolVariableIF::NO_PARAMETER;
/** /**
* this is the datapool variable with the thermal request of the device * this is the datapool variable with the thermal request of the device
* *
* can be set to PoolVariableIF::NO_PARAMETER to deactivate thermal checking * can be set to PoolVariableIF::NO_PARAMETER to deactivate thermal checking
*/ */
uint32_t deviceThermalRequestPoolId; uint32_t deviceThermalRequestPoolId = PoolVariableIF::NO_PARAMETER;
/**
* Taking care of the health
*/
HealthHelper healthHelper;
ModeHelper modeHelper;
ParameterHelper parameterHelper;
/** /**
* Optional Error code * Optional Error code
@ -676,13 +704,15 @@ protected:
bool switchOffWasReported; //!< Indicates if SWITCH_WENT_OFF was already thrown. bool switchOffWasReported; //!< Indicates if SWITCH_WENT_OFF was already thrown.
PeriodicTaskIF* executingTask = nullptr;//!< 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;
static object_id_t powerSwitcherId; //!< Object which switches power on and off. static object_id_t powerSwitcherId; //!< Object which switches power on and off.
static object_id_t rawDataReceiverId; //!< Object which receives RAW data by default. static object_id_t rawDataReceiverId; //!< Object which receives RAW data by default.
static object_id_t defaultFDIRParentId; //!< Object which may be the root cause of an identified fault. static object_id_t defaultFdirParentId; //!< Object which may be the root cause of an identified fault.
/** /**
* Helper function to report a missed reply * Helper function to report a missed reply
* *
@ -730,28 +760,40 @@ protected:
/** /**
* Do the transition to the main modes (MODE_ON, MODE_NORMAL and MODE_RAW). * Do the transition to the main modes (MODE_ON, MODE_NORMAL and MODE_RAW).
* *
* If the transition is complete, the mode should be set to the target mode, which can be deduced from the current mode which is * If the transition is complete, the mode should be set to the target mode,
* which can be deduced from the current mode which is
* [_MODE_TO_ON, _MODE_TO_NORMAL, _MODE_TO_RAW] * [_MODE_TO_ON, _MODE_TO_NORMAL, _MODE_TO_RAW]
* *
* The intended target submode is already set. The origin submode can be read in subModeFrom. * The intended target submode is already set.
* The origin submode can be read in subModeFrom.
* *
* If the transition can not be completed, the child class can try to reach an working mode by setting the mode either directly * If the transition can not be completed, the child class can try to reach
* or setting the mode to an transitional mode (TO_ON, TO_NORMAL, TO_RAW) if the device needs to be reconfigured. * an working mode by setting the mode either directly
* or setting the mode to an transitional mode (TO_ON, TO_NORMAL, TO_RAW)
* if the device needs to be reconfigured.
* *
* If nothing works, the child class can wait for the timeout and the base class will reset the mode to the mode where the transition * If nothing works, the child class can wait for the timeout and the base
* class will reset the mode to the mode where the transition
* originated from (the child should report the reason for the failed transition). * originated from (the child should report the reason for the failed transition).
* *
* The intended way to send commands is to set a flag (enum) indicating which command is to be sent here * The intended way to send commands is to set a flag (enum) indicating
* and then to check in buildTransitionCommand() for the flag. This flag can also be used by doStartUp() and * which command is to be sent here and then to check in
* doShutDown() to get a nice and clean implementation of buildTransitionCommand() without switching through modes. * buildTransitionCommand() for the flag. This flag can also be used by
* doStartUp() and doShutDown() to get a nice and clean implementation of
* buildTransitionCommand() without switching through modes.
* *
* When the the condition for the completion of the transition is met, the mode can be set, for example in the parseReply() function. * When the the condition for the completion of the transition is met, the
* mode can be set, for example in the scanForReply() function.
* *
* The default implementation goes into the target mode; * The default implementation goes into the target mode directly.
* *
* #transitionFailure can be set to a failure code indicating the reason for a failed transition * #transitionFailure can be set to a failure code indicating the reason
* for a failed transition
* *
* @param modeFrom the mode the transition originated from: [MODE_ON, MODE_NORMAL, MODE_RAW and _MODE_POWER_DOWN (if the mode changed from _MODE_START_UP to _MODE_TO_ON)] * @param modeFrom
* The mode the transition originated from:
* [MODE_ON, MODE_NORMAL, MODE_RAW and _MODE_POWER_DOWN (if the mode changed
* from _MODE_START_UP to _MODE_TO_ON)]
* @param subModeFrom the subMode of modeFrom * @param subModeFrom the subMode of modeFrom
*/ */
virtual void doTransition(Mode_t modeFrom, Submode_t subModeFrom); virtual void doTransition(Mode_t modeFrom, Submode_t subModeFrom);
@ -953,24 +995,11 @@ protected:
bool commandIsExecuting(DeviceCommandId_t commandId); bool commandIsExecuting(DeviceCommandId_t commandId);
/** /**
* This map is used to check and track correct reception of all replies. * set all switches returned by getSwitches()
* *
* It has multiple use: * @param onOff on == @c SWITCH_ON; off != @c SWITCH_ON
* - it stores the information on pending replies. If a command is sent, the DeviceCommandInfo.count is incremented.
* - it is used to time-out missing replies. If a command is sent, the DeviceCommandInfo.DelayCycles is set to MaxDelayCycles.
* - it is queried to check if a reply from the device can be interpreted. scanForReply() returns the id of the command a reply was found for.
* The reply is ignored in the following cases:
* - No entry for the returned id was found
* - The deviceReplyInfo.delayCycles is == 0
*/ */
DeviceReplyMap deviceReplyMap; void commandSwitch(ReturnValue_t onOff);
/**
* Information about commands
*/
DeviceCommandMap deviceCommandMap;
ActionHelper actionHelper;
private: private:
/** /**
@ -997,15 +1026,16 @@ private:
}; };
/** /**
* Info about the #cookie * @brief Info about the #cookie
*
* Used to track the state of the communication * Used to track the state of the communication
*/ */
CookieInfo cookieInfo; CookieInfo cookieInfo;
/** the object used to set power switches */
PowerSwitchIF *powerSwitcher = nullptr;
/** /**
* Used for timing out mode transitions. * @brief Used for timing out mode transitions.
*
* Set when setMode() is called. * Set when setMode() is called.
*/ */
uint32_t timeoutStart = 0; uint32_t timeoutStart = 0;
@ -1016,11 +1046,12 @@ private:
uint32_t childTransitionDelay; uint32_t childTransitionDelay;
/** /**
* The mode the current transition originated from * @brief The mode the current transition originated from
* *
* This is private so the child can not change it and fuck up the timeouts * This is private so the child can not change it and fuck up the timeouts
* *
* IMPORTANT: This is not valid during _MODE_SHUT_DOWN and _MODE_START_UP!! (it is _MODE_POWER_DOWN during this modes) * IMPORTANT: This is not valid during _MODE_SHUT_DOWN and _MODE_START_UP!!
* (it is _MODE_POWER_DOWN during this modes)
* *
* is element of [MODE_ON, MODE_NORMAL, MODE_RAW] * is element of [MODE_ON, MODE_NORMAL, MODE_RAW]
*/ */
@ -1031,13 +1062,6 @@ private:
*/ */
Submode_t transitionSourceSubMode; Submode_t transitionSourceSubMode;
/**
* the switch of the device
*
* for devices using two switches override getSwitches()
*/
const uint8_t deviceSwitch;
/** /**
* read the command queue * read the command queue
*/ */
@ -1135,12 +1159,6 @@ private:
ReturnValue_t getStorageData(store_address_t storageAddress, uint8_t **data, ReturnValue_t getStorageData(store_address_t storageAddress, uint8_t **data,
uint32_t *len); uint32_t *len);
/**
* set all switches returned by getSwitches()
*
* @param onOff on == @c SWITCH_ON; off != @c SWITCH_ON
*/
void commandSwitch(ReturnValue_t onOff);
/** /**
* @param modeTo either @c MODE_ON, MODE_NORMAL or MODE_RAW NOTHING ELSE!!! * @param modeTo either @c MODE_ON, MODE_NORMAL or MODE_RAW NOTHING ELSE!!!
@ -1165,7 +1183,12 @@ private:
ReturnValue_t switchCookieChannel(object_id_t newChannelId); ReturnValue_t switchCookieChannel(object_id_t newChannelId);
ReturnValue_t handleDeviceHandlerMessage(CommandMessage *message); ReturnValue_t handleDeviceHandlerMessage(CommandMessage *message);
virtual ReturnValue_t initializeAfterTaskCreation() override;
void parseReply(const uint8_t* receivedData,
size_t receivedDataLen);
}; };
#endif /* DEVICEHANDLERBASE_H_ */ #endif /* FRAMEWORK_DEVICEHANDLERS_DEVICEHANDLERBASE_H_ */

View File

@ -1,19 +1,27 @@
#include "DeviceHandlerBase.h"
#include "DeviceHandlerFailureIsolation.h" #include "DeviceHandlerFailureIsolation.h"
#include "../devicehandlers/DeviceHandlerIF.h"
#include "../modes/HasModesIF.h"
#include "../health/HealthTableIF.h" #include "../health/HealthTableIF.h"
#include "../power/Fuse.h" #include "../power/Fuse.h"
#include "../serviceinterface/ServiceInterfaceStream.h" #include "../serviceinterface/ServiceInterfaceStream.h"
#include "../thermal/ThermalComponentIF.h" #include "../thermal/ThermalComponentIF.h"
object_id_t DeviceHandlerFailureIsolation::powerConfirmationId = 0; object_id_t DeviceHandlerFailureIsolation::powerConfirmationId =
objects::NO_OBJECT;
DeviceHandlerFailureIsolation::DeviceHandlerFailureIsolation(object_id_t owner, object_id_t parent) : DeviceHandlerFailureIsolation::DeviceHandlerFailureIsolation(object_id_t owner,
FailureIsolationBase(owner, parent), strangeReplyCount(MAX_STRANGE_REPLIES, object_id_t parent) :
STRANGE_REPLIES_TIME_MS, parameterDomainBase++), missedReplyCount( FailureIsolationBase(owner, parent),
MAX_MISSED_REPLY_COUNT, MISSED_REPLY_TIME_MS, strangeReplyCount(DEFAULT_MAX_STRANGE_REPLIES,
parameterDomainBase++), recoveryCounter(MAX_REBOOT, DEFAULT_STRANGE_REPLIES_TIME_MS,
REBOOT_TIME_MS, parameterDomainBase++), fdirState(NONE), powerConfirmation( parameterDomainBase++),
0) { missedReplyCount( DEFAULT_MAX_MISSED_REPLY_COUNT,
DEFAULT_MISSED_REPLY_TIME_MS,
parameterDomainBase++),
recoveryCounter(DEFAULT_MAX_REBOOT, DEFAULT_REBOOT_TIME_MS,
parameterDomainBase++),
fdirState(NONE) {
} }
DeviceHandlerFailureIsolation::~DeviceHandlerFailureIsolation() { DeviceHandlerFailureIsolation::~DeviceHandlerFailureIsolation() {
@ -68,10 +76,12 @@ ReturnValue_t DeviceHandlerFailureIsolation::eventReceived(EventMessage* event)
break; break;
//****Power***** //****Power*****
case PowerSwitchIF::SWITCH_WENT_OFF: case PowerSwitchIF::SWITCH_WENT_OFF:
if(powerConfirmation != MessageQueueIF::NO_QUEUE) {
result = sendConfirmationRequest(event, powerConfirmation); result = sendConfirmationRequest(event, powerConfirmation);
if (result == RETURN_OK) { if (result == RETURN_OK) {
setFdirState(DEVICE_MIGHT_BE_OFF); setFdirState(DEVICE_MIGHT_BE_OFF);
} }
}
break; break;
case Fuse::FUSE_WENT_OFF: case Fuse::FUSE_WENT_OFF:
//Not so good, because PCDU reacted. //Not so good, because PCDU reacted.
@ -133,7 +143,7 @@ void DeviceHandlerFailureIsolation::decrementFaultCounters() {
void DeviceHandlerFailureIsolation::handleRecovery(Event reason) { void DeviceHandlerFailureIsolation::handleRecovery(Event reason) {
clearFaultCounters(); clearFaultCounters();
if (!recoveryCounter.incrementAndCheck()) { if (not recoveryCounter.incrementAndCheck()) {
startRecovery(reason); startRecovery(reason);
} else { } else {
setFaulty(reason); setFaulty(reason);
@ -142,7 +152,8 @@ void DeviceHandlerFailureIsolation::handleRecovery(Event reason) {
void DeviceHandlerFailureIsolation::wasParentsFault(EventMessage* event) { void DeviceHandlerFailureIsolation::wasParentsFault(EventMessage* event) {
//We'll better ignore the SWITCH_WENT_OFF event and await a system-wide reset. //We'll better ignore the SWITCH_WENT_OFF event and await a system-wide reset.
//This means, no fault message will come through until a MODE_ or HEALTH_INFO message comes through -> Is that ok? //This means, no fault message will come through until a MODE_ or
//HEALTH_INFO message comes through -> Is that ok?
//Same issue in TxFailureIsolation! //Same issue in TxFailureIsolation!
// if ((event->getEvent() == PowerSwitchIF::SWITCH_WENT_OFF) // if ((event->getEvent() == PowerSwitchIF::SWITCH_WENT_OFF)
// && (fdirState != RECOVERY_ONGOING)) { // && (fdirState != RECOVERY_ONGOING)) {
@ -158,14 +169,16 @@ void DeviceHandlerFailureIsolation::clearFaultCounters() {
ReturnValue_t DeviceHandlerFailureIsolation::initialize() { ReturnValue_t DeviceHandlerFailureIsolation::initialize() {
ReturnValue_t result = FailureIsolationBase::initialize(); ReturnValue_t result = FailureIsolationBase::initialize();
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
sif::error << "DeviceHandlerFailureIsolation::initialize: Could not"
" initialize FailureIsolationBase." << std::endl;
return result; return result;
} }
ConfirmsFailuresIF* power = objectManager->get<ConfirmsFailuresIF>( ConfirmsFailuresIF* power = objectManager->get<ConfirmsFailuresIF>(
powerConfirmationId); powerConfirmationId);
if (power == NULL) { if (power != nullptr) {
return RETURN_FAILED;
}
powerConfirmation = power->getEventReceptionQueue(); powerConfirmation = power->getEventReceptionQueue();
}
return RETURN_OK; return RETURN_OK;
} }

View File

@ -1,13 +1,13 @@
#ifndef FRAMEWORK_DEVICEHANDLERS_DEVICEHANDLERFAILUREISOLATION_H_ #ifndef FSFW_DEVICEHANDLERS_DEVICEHANDLERFAILUREISOLATION_H_
#define FRAMEWORK_DEVICEHANDLERS_DEVICEHANDLERFAILUREISOLATION_H_ #define FSFW_DEVICEHANDLERS_DEVICEHANDLERFAILUREISOLATION_H_
#include "../fdir/FaultCounter.h" #include "../fdir/FaultCounter.h"
#include "../fdir/FailureIsolationBase.h" #include "../fdir/FailureIsolationBase.h"
namespace Factory{ namespace Factory{
void setStaticFrameworkObjectIds(); void setStaticFrameworkObjectIds();
} }
class DeviceHandlerFailureIsolation: public FailureIsolationBase { class DeviceHandlerFailureIsolation: public FailureIsolationBase {
friend void (Factory::setStaticFrameworkObjectIds)(); friend void (Factory::setStaticFrameworkObjectIds)();
friend class Heater; friend class Heater;
@ -20,22 +20,27 @@ public:
virtual ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId, virtual ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId,
ParameterWrapper *parameterWrapper, ParameterWrapper *parameterWrapper,
const ParameterWrapper *newValues, uint16_t startAtIndex); const ParameterWrapper *newValues, uint16_t startAtIndex);
protected: protected:
FaultCounter strangeReplyCount; FaultCounter strangeReplyCount;
FaultCounter missedReplyCount; FaultCounter missedReplyCount;
FaultCounter recoveryCounter; FaultCounter recoveryCounter;
enum FDIRState { enum FDIRState {
NONE, RECOVERY_ONGOING, DEVICE_MIGHT_BE_OFF, AWAIT_SHUTDOWN NONE, RECOVERY_ONGOING, DEVICE_MIGHT_BE_OFF, AWAIT_SHUTDOWN
}; };
FDIRState fdirState; FDIRState fdirState;
MessageQueueId_t powerConfirmation;
MessageQueueId_t powerConfirmation = MessageQueueIF::NO_QUEUE;
static object_id_t powerConfirmationId; static object_id_t powerConfirmationId;
static const uint32_t MAX_REBOOT = 1;
static const uint32_t REBOOT_TIME_MS = 180000; static const uint32_t DEFAULT_MAX_REBOOT = 1;
static const uint32_t MAX_STRANGE_REPLIES = 10; static const uint32_t DEFAULT_REBOOT_TIME_MS = 180000;
static const uint32_t STRANGE_REPLIES_TIME_MS = 10000; static const uint32_t DEFAULT_MAX_STRANGE_REPLIES = 10;
static const uint32_t MAX_MISSED_REPLY_COUNT = 5; static const uint32_t DEFAULT_STRANGE_REPLIES_TIME_MS = 10000;
static const uint32_t MISSED_REPLY_TIME_MS = 10000; static const uint32_t DEFAULT_MAX_MISSED_REPLY_COUNT = 5;
static const uint32_t DEFAULT_MISSED_REPLY_TIME_MS = 10000;
virtual ReturnValue_t eventReceived(EventMessage* event); virtual ReturnValue_t eventReceived(EventMessage* event);
virtual void eventConfirmed(EventMessage* event); virtual void eventConfirmed(EventMessage* event);
void wasParentsFault(EventMessage* event); void wasParentsFault(EventMessage* event);
@ -49,4 +54,4 @@ protected:
bool isFdirInActionOrAreWeFaulty(EventMessage* event); bool isFdirInActionOrAreWeFaulty(EventMessage* event);
}; };
#endif /* FRAMEWORK_DEVICEHANDLERS_DEVICEHANDLERFAILUREISOLATION_H_ */ #endif /* FSFW_DEVICEHANDLERS_DEVICEHANDLERFAILUREISOLATION_H_ */

View File

@ -5,10 +5,12 @@
#include "../ipc/QueueFactory.h" #include "../ipc/QueueFactory.h"
#include "../objectmanager/ObjectManagerIF.h" #include "../objectmanager/ObjectManagerIF.h"
FailureIsolationBase::FailureIsolationBase(object_id_t owner, object_id_t parent, uint8_t messageDepth, uint8_t parameterDomainBase) : FailureIsolationBase::FailureIsolationBase(object_id_t owner,
eventQueue(NULL), ownerId( object_id_t parent, uint8_t messageDepth, uint8_t parameterDomainBase) :
owner), owner(NULL), faultTreeParent(parent), parameterDomainBase(parameterDomainBase) { ownerId(owner), faultTreeParent(parent),
eventQueue = QueueFactory::instance()->createMessageQueue(messageDepth, EventMessage::EVENT_MESSAGE_SIZE); parameterDomainBase(parameterDomainBase) {
eventQueue = QueueFactory::instance()->createMessageQueue(messageDepth,
EventMessage::EVENT_MESSAGE_SIZE);
} }
FailureIsolationBase::~FailureIsolationBase() { FailureIsolationBase::~FailureIsolationBase() {
@ -18,27 +20,36 @@ FailureIsolationBase::~FailureIsolationBase() {
ReturnValue_t FailureIsolationBase::initialize() { ReturnValue_t FailureIsolationBase::initialize() {
EventManagerIF* manager = objectManager->get<EventManagerIF>( EventManagerIF* manager = objectManager->get<EventManagerIF>(
objects::EVENT_MANAGER); objects::EVENT_MANAGER);
if (manager == NULL) { if (manager == nullptr) {
sif::error << "FailureIsolationBase::initialize: Event Manager has not"
" been initialized!" << std::endl;
return RETURN_FAILED; return RETURN_FAILED;
} }
ReturnValue_t result = manager->registerListener(eventQueue->getId()); ReturnValue_t result = manager->registerListener(eventQueue->getId());
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
if (ownerId != 0) { if (ownerId != objects::NO_OBJECT) {
result = manager->subscribeToAllEventsFrom(eventQueue->getId(), ownerId); result = manager->subscribeToAllEventsFrom(eventQueue->getId(), ownerId);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
owner = objectManager->get<HasHealthIF>(ownerId); owner = objectManager->get<HasHealthIF>(ownerId);
if (owner == NULL) { if (owner == nullptr) {
return RETURN_FAILED; sif::error << "FailureIsolationBase::intialize: Owner object "
"invalid. Make sure it implements HasHealthIF" << std::endl;
return ObjectManagerIF::CHILD_INIT_FAILED;
} }
} }
if (faultTreeParent != 0) { if (faultTreeParent != objects::NO_OBJECT) {
ConfirmsFailuresIF* parentIF = objectManager->get<ConfirmsFailuresIF>( ConfirmsFailuresIF* parentIF = objectManager->get<ConfirmsFailuresIF>(
faultTreeParent); faultTreeParent);
if (parentIF == NULL) { if (parentIF == nullptr) {
sif::error << "FailureIsolationBase::intialize: Parent object"
<< "invalid." << std::endl;
sif::error << "Make sure it implements ConfirmsFailuresIF."
<< std::endl;
return ObjectManagerIF::CHILD_INIT_FAILED;
return RETURN_FAILED; return RETURN_FAILED;
} }
eventQueue->setDefaultDestination(parentIF->getEventReceptionQueue()); eventQueue->setDefaultDestination(parentIF->getEventReceptionQueue());
@ -93,9 +104,9 @@ MessageQueueId_t FailureIsolationBase::getEventReceptionQueue() {
ReturnValue_t FailureIsolationBase::sendConfirmationRequest(EventMessage* event, ReturnValue_t FailureIsolationBase::sendConfirmationRequest(EventMessage* event,
MessageQueueId_t destination) { MessageQueueId_t destination) {
event->setMessageId(EventMessage::CONFIRMATION_REQUEST); event->setMessageId(EventMessage::CONFIRMATION_REQUEST);
if (destination != 0) { if (destination != MessageQueueIF::NO_QUEUE) {
return eventQueue->sendMessage(destination, event); return eventQueue->sendMessage(destination, event);
} else if (faultTreeParent != 0) { } else if (faultTreeParent != objects::NO_OBJECT) {
return eventQueue->sendToDefault(event); return eventQueue->sendToDefault(event);
} }
return RETURN_FAILED; return RETURN_FAILED;

View File

@ -17,18 +17,25 @@ public:
static const Event FDIR_CHANGED_STATE = MAKE_EVENT(1, SEVERITY::INFO); //!< FDIR has an internal state, which changed from par2 (oldState) to par1 (newState). static const Event FDIR_CHANGED_STATE = MAKE_EVENT(1, SEVERITY::INFO); //!< FDIR has an internal state, which changed from par2 (oldState) to par1 (newState).
static const Event FDIR_STARTS_RECOVERY = MAKE_EVENT(2, SEVERITY::MEDIUM); //!< FDIR tries to restart device. Par1: event that caused recovery. static const Event FDIR_STARTS_RECOVERY = MAKE_EVENT(2, SEVERITY::MEDIUM); //!< FDIR tries to restart device. Par1: event that caused recovery.
static const Event FDIR_TURNS_OFF_DEVICE = MAKE_EVENT(3, SEVERITY::MEDIUM); //!< FDIR turns off device. Par1: event that caused recovery. static const Event FDIR_TURNS_OFF_DEVICE = MAKE_EVENT(3, SEVERITY::MEDIUM); //!< FDIR turns off device. Par1: event that caused recovery.
FailureIsolationBase(object_id_t owner, object_id_t parent = 0,
FailureIsolationBase(object_id_t owner,
object_id_t parent = objects::NO_OBJECT,
uint8_t messageDepth = 10, uint8_t parameterDomainBase = 0xF0); uint8_t messageDepth = 10, uint8_t parameterDomainBase = 0xF0);
virtual ~FailureIsolationBase(); virtual ~FailureIsolationBase();
virtual ReturnValue_t initialize(); virtual ReturnValue_t initialize();
/**
* This is called by the DHB in performOperation()
*/
void checkForFailures(); void checkForFailures();
MessageQueueId_t getEventReceptionQueue(); MessageQueueId_t getEventReceptionQueue() override;
virtual void triggerEvent(Event event, uint32_t parameter1 = 0, virtual void triggerEvent(Event event, uint32_t parameter1 = 0,
uint32_t parameter2 = 0); uint32_t parameter2 = 0);
protected: protected:
MessageQueueIF* eventQueue; MessageQueueIF* eventQueue = nullptr;
object_id_t ownerId; object_id_t ownerId;
HasHealthIF* owner; HasHealthIF* owner = nullptr;
object_id_t faultTreeParent; object_id_t faultTreeParent;
uint8_t parameterDomainBase; uint8_t parameterDomainBase;
void setOwnerHealth(HasHealthIF::HealthState health); void setOwnerHealth(HasHealthIF::HealthState health);
@ -38,7 +45,7 @@ protected:
virtual ReturnValue_t confirmFault(EventMessage* event); virtual ReturnValue_t confirmFault(EventMessage* event);
virtual void decrementFaultCounters() = 0; virtual void decrementFaultCounters() = 0;
ReturnValue_t sendConfirmationRequest(EventMessage* event, ReturnValue_t sendConfirmationRequest(EventMessage* event,
MessageQueueId_t destination = 0); MessageQueueId_t destination = MessageQueueIF::NO_QUEUE);
void throwFdirEvent(Event event, uint32_t parameter1 = 0, void throwFdirEvent(Event event, uint32_t parameter1 = 0,
uint32_t parameter2 = 0); uint32_t parameter2 = 0);
private: private:

View File

@ -1,17 +1,17 @@
#ifndef SERIALIZEIF_H_ #ifndef FSFW_SERIALIZE_SERIALIZEIF_H_
#define SERIALIZEIF_H_ #define FSFW_SERIALIZE_SERIALIZEIF_H_
#include "../returnvalues/HasReturnvaluesIF.h" #include "../returnvalues/HasReturnvaluesIF.h"
#include <stddef.h> #include <stddef.h>
/** /**
* \defgroup serialize Serialization * @defgroup serialize Serialization
* Contains serialisation services. * Contains serialization services.
*/ */
/** /**
* Translation of objects into data streams. * Translation of objects into data streams and from data streams.
* \ingroup serialize * @ingroup serialize
*/ */
class SerializeIF { class SerializeIF {
public: public:
@ -20,21 +20,65 @@ public:
}; };
static const uint8_t INTERFACE_ID = CLASS_ID::SERIALIZE_IF; static const uint8_t INTERFACE_ID = CLASS_ID::SERIALIZE_IF;
static const ReturnValue_t BUFFER_TOO_SHORT = MAKE_RETURN_CODE(1); static const ReturnValue_t BUFFER_TOO_SHORT = MAKE_RETURN_CODE(1); // !< The given buffer in serialize is too short
static const ReturnValue_t STREAM_TOO_SHORT = MAKE_RETURN_CODE(2); static const ReturnValue_t STREAM_TOO_SHORT = MAKE_RETURN_CODE(2); // !< The input stream in deserialize is too short
static const ReturnValue_t TOO_MANY_ELEMENTS = MAKE_RETURN_CODE(3); static const ReturnValue_t TOO_MANY_ELEMENTS = MAKE_RETURN_CODE(3);// !< There are too many elements to be deserialized
virtual ~SerializeIF() { virtual ~SerializeIF() {
} }
/**
* @brief
* Function to serialize the object into a buffer with maxSize. Size represents the written amount.
* If a part of the buffer has been used already, size must be set to the used amount of bytes.
*
* @details
* Implementations of this function must increase the size variable and move the buffer pointer.
* MaxSize must be checked by implementations of this function
* and BUFFER_TOO_SHORT has to be returned if size would be larger than maxSize.
*
* Custom implementations might use additional return values.
*
* @param[in/out] buffer Buffer to serialize into, will be set to the current write location
* @param[in/out] size Size that has been used in the buffer already, will be increased by the function
* @param[in] maxSize The size of the buffer that is allowed to be used for serialize.
* @param[in] streamEndianness Endianness of the serialized data according to SerializeIF::Endianness
* @return
* - @¢ BUFFER_TOO_SHORT The given buffer in is too short
* - @c RETURN_FAILED Generic error
* - @c RETURN_OK Successful serialization
*/
virtual ReturnValue_t serialize(uint8_t **buffer, size_t *size, virtual ReturnValue_t serialize(uint8_t **buffer, size_t *size,
size_t maxSize, Endianness streamEndianness) const = 0; size_t maxSize, Endianness streamEndianness) const = 0;
/**
* Gets the size of a object if it would be serialized in a buffer
* @return Size of serialized object
*/
virtual size_t getSerializedSize() const = 0; virtual size_t getSerializedSize() const = 0;
/**
* @brief
* Deserializes a object from a given buffer of given size.
*
* @details
* Buffer must be moved to the current read location by the implementation
* of this function. Size must be decreased by the implementation.
* Implementations are not allowed to alter the buffer as indicated by const pointer.
*
* Custom implementations might use additional return values.
*
* @param[in/out] buffer Buffer to deSerialize from. Will be moved by the function.
* @param[in/out] size Remaining size of the buffer to read from. Will be decreased by function.
* @param[in] streamEndianness Endianness as in according to SerializeIF::Endianness
* @return
* - @c STREAM_TOO_SHORT The input stream is too short to deSerialize the object
* - @c TOO_MANY_ELEMENTS The buffer has more inputs than expected
* - @c RETURN_FAILED Generic Error
* - @c RETURN_OK Successful deserialization
*/
virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size, virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
Endianness streamEndianness) = 0; Endianness streamEndianness) = 0;
}; };
#endif /* SERIALIZEIF_H_ */ #endif /* FSFW_SERIALIZE_SERIALIZEIF_H_ */