1
0
forked from fsfw/fsfw

form improvements DHB

This commit is contained in:
2020-10-12 18:18:41 +02:00
parent 335e146735
commit 140aa3ab42
19 changed files with 403 additions and 303 deletions

View File

@ -2,15 +2,17 @@
#include "AcceptsDeviceResponsesIF.h"
#include "DeviceTmReportingWrapper.h"
#include "../serviceinterface/ServiceInterfaceStream.h"
#include "../datapoolglob/GlobalDataSet.h"
#include "../datapoolglob/GlobalPoolVariable.h"
#include "../objectmanager/ObjectManager.h"
#include "../storagemanager/StorageManagerIF.h"
#include "../thermal/ThermalComponentIF.h"
#include "../datapool/DataSet.h"
#include "../datapool/PoolVariable.h"
#include "../globalfunctions/CRC.h"
#include "../subsystem/SubsystemBase.h"
#include "../housekeeping/HousekeepingMessage.h"
#include "../ipc/MessageQueueMessage.h"
#include "../ipc/QueueFactory.h"
#include "../serviceinterface/ServiceInterfaceStream.h"
#include "../subsystem/SubsystemBase.h"
#include <iomanip>
@ -25,10 +27,11 @@ DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId,
wiretappingMode(OFF), storedRawData(StorageManagerIF::INVALID_ADDRESS),
deviceCommunicationId(deviceCommunication), comCookie(comCookie),
healthHelper(this,setObjectId), modeHelper(this), parameterHelper(this),
actionHelper(this, nullptr), childTransitionFailure(RETURN_OK),
fdirInstance(fdirInstance), hkSwitcher(this),
defaultFDIRUsed(fdirInstance == nullptr), switchOffWasReported(false),
childTransitionDelay(5000), transitionSourceMode(_MODE_POWER_DOWN),
actionHelper(this, nullptr), hkManager(this, nullptr),
childTransitionFailure(RETURN_OK), fdirInstance(fdirInstance),
hkSwitcher(this), defaultFDIRUsed(fdirInstance == nullptr),
switchOffWasReported(false), childTransitionDelay(5000),
transitionSourceMode(_MODE_POWER_DOWN),
transitionSourceSubMode(SUBMODE_NONE) {
commandQueue = QueueFactory::instance()->createMessageQueue(cmdQueueSize,
MessageQueueMessage::MAX_MESSAGE_SIZE);
@ -48,6 +51,10 @@ DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId,
}
}
void DeviceHandlerBase::setHkDestination(object_id_t hkDestination) {
this->hkDestination = hkDestination;
}
void DeviceHandlerBase::setThermalStateRequestPoolIds(
uint32_t thermalStatePoolId, uint32_t thermalRequestPoolId) {
this->deviceThermalRequestPoolId = thermalStatePoolId;
@ -74,6 +81,7 @@ ReturnValue_t DeviceHandlerBase::performOperation(uint8_t counter) {
decrementDeviceReplyMap();
fdirInstance->checkForFailures();
hkSwitcher.performOperation();
hkManager.performHkOperation();
performOperationHook();
}
if (mode == MODE_OFF) {
@ -120,7 +128,9 @@ ReturnValue_t DeviceHandlerBase::initialize() {
result = communicationInterface->initializeInterface(comCookie);
if (result != RETURN_OK) {
return result;
sif::error << "DeviceHandlerBase::initialize: Initializing "
"communication interface failed!" << std::endl;
return result;
}
IPCStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
@ -183,11 +193,16 @@ ReturnValue_t DeviceHandlerBase::initialize() {
return result;
}
result = hkManager.initialize(commandQueue);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
fillCommandAndReplyMap();
//Set temperature target state to NON_OP.
DataSet mySet;
db_int8_t thermalRequest(deviceThermalRequestPoolId, &mySet,
GlobDataSet mySet;
gp_uint8_t thermalRequest(deviceThermalRequestPoolId, &mySet,
PoolVariableIF::VAR_WRITE);
mySet.read();
thermalRequest = ThermalComponentIF::STATE_REQUEST_NON_OPERATIONAL;
@ -245,10 +260,10 @@ void DeviceHandlerBase::readCommandQueue() {
return;
}
// result = hkManager.handleHousekeepingMessage(&command);
// if (result == RETURN_OK) {
// return;
// }
result = hkManager.handleHousekeepingMessage(&command);
if (result == RETURN_OK) {
return;
}
result = handleDeviceHandlerMessage(&command);
if (result == RETURN_OK) {
@ -376,24 +391,28 @@ ReturnValue_t DeviceHandlerBase::isModeCombinationValid(Mode_t mode,
ReturnValue_t DeviceHandlerBase::insertInCommandAndReplyMap(
DeviceCommandId_t deviceCommand, uint16_t maxDelayCycles,
size_t replyLen, bool periodic, bool hasDifferentReplyId,
DeviceCommandId_t replyId) {
LocalPoolDataSetBase* replyDataSet, size_t replyLen, bool periodic,
bool hasDifferentReplyId, DeviceCommandId_t replyId) {
//No need to check, as we may try to insert multiple times.
insertInCommandMap(deviceCommand);
if (hasDifferentReplyId) {
return insertInReplyMap(replyId, maxDelayCycles, replyLen, periodic);
return insertInReplyMap(replyId, maxDelayCycles,
replyDataSet, replyLen, periodic);
} else {
return insertInReplyMap(deviceCommand, maxDelayCycles, replyLen, periodic);
return insertInReplyMap(deviceCommand, maxDelayCycles,
replyDataSet, replyLen, periodic);
}
}
ReturnValue_t DeviceHandlerBase::insertInReplyMap(DeviceCommandId_t replyId,
uint16_t maxDelayCycles, size_t replyLen, bool periodic) {
uint16_t maxDelayCycles, LocalPoolDataSetBase* dataSet,
size_t replyLen, bool periodic) {
DeviceReplyInfo info;
info.maxDelayCycles = maxDelayCycles;
info.periodic = periodic;
info.delayCycles = 0;
info.replyLen = replyLen;
info.dataSet = dataSet;
info.command = deviceCommandMap.end();
auto resultPair = deviceReplyMap.emplace(replyId, info);
if (resultPair.second) {
@ -419,13 +438,12 @@ ReturnValue_t DeviceHandlerBase::insertInCommandMap(
ReturnValue_t DeviceHandlerBase::updateReplyMapEntry(DeviceCommandId_t deviceReply,
uint16_t delayCycles, uint16_t maxDelayCycles, bool periodic) {
std::map<DeviceCommandId_t, DeviceReplyInfo>::iterator iter =
deviceReplyMap.find(deviceReply);
if (iter == deviceReplyMap.end()) {
auto replyIter = deviceReplyMap.find(deviceReply);
if (replyIter == deviceReplyMap.end()) {
triggerEvent(INVALID_DEVICE_COMMAND, deviceReply);
return RETURN_FAILED;
} else {
DeviceReplyInfo *info = &(iter->second);
DeviceReplyInfo *info = &(replyIter->second);
if (maxDelayCycles != 0) {
info->maxDelayCycles = maxDelayCycles;
}
@ -435,6 +453,17 @@ ReturnValue_t DeviceHandlerBase::updateReplyMapEntry(DeviceCommandId_t deviceRep
}
}
ReturnValue_t DeviceHandlerBase::setReplyDataset(DeviceCommandId_t replyId,
LocalPoolDataSetBase *dataSet) {
auto replyIter = deviceReplyMap.find(replyId);
if(replyIter == deviceReplyMap.end()) {
return HasReturnvaluesIF::RETURN_FAILED;
}
replyIter->second.dataSet = dataSet;
return HasReturnvaluesIF::RETURN_OK;
}
void DeviceHandlerBase::callChildStatemachine() {
if (mode == _MODE_START_UP) {
doStartUp();
@ -469,8 +498,8 @@ void DeviceHandlerBase::setMode(Mode_t newMode, uint8_t newSubmode) {
Clock::getUptime(&timeoutStart);
if (mode == MODE_OFF) {
DataSet mySet;
db_int8_t thermalRequest(deviceThermalRequestPoolId, &mySet,
GlobDataSet mySet;
gp_uint8_t thermalRequest(deviceThermalRequestPoolId, &mySet,
PoolVariableIF::VAR_READ_WRITE);
mySet.read();
if (thermalRequest != ThermalComponentIF::STATE_REQUEST_IGNORE) {
@ -649,7 +678,7 @@ void DeviceHandlerBase::doGetRead() {
void DeviceHandlerBase::parseReply(const uint8_t* receivedData,
size_t receivedDataLen) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED;
DeviceCommandId_t foundId = 0xFFFFFFFF;
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
@ -661,18 +690,26 @@ void DeviceHandlerBase::parseReply(const uint8_t* receivedData,
switch (result) {
case RETURN_OK:
handleReply(receivedData, foundId, foundLen);
if(foundLen == 0) {
sif::warning << "DeviceHandlerBase::parseReply: foundLen is 0!"
" Packet parsing will be stuck." << std::endl;
}
break;
case APERIODIC_REPLY: {
result = interpretDeviceReply(foundId, receivedData);
if (result != RETURN_OK) {
replyRawReplyIfnotWiretapped(receivedData, foundLen);
triggerEvent(DEVICE_INTERPRETING_REPLY_FAILED, result,
foundId);
replyRawReplyIfnotWiretapped(receivedData, foundLen);
triggerEvent(DEVICE_INTERPRETING_REPLY_FAILED, result,
foundId);
}
if(foundLen == 0) {
sif::warning << "DeviceHandlerBase::parseReply: foundLen is 0!"
" Packet parsing will be stuck." << std::endl;
}
}
break;
case IGNORE_REPLY_DATA:
break;
}
case IGNORE_REPLY_DATA:
continue;
case IGNORE_FULL_PACKET:
return;
default:
@ -704,16 +741,19 @@ void DeviceHandlerBase::handleReply(const uint8_t* receivedData,
DeviceReplyInfo *info = &(iter->second);
if (info->delayCycles != 0) {
result = interpretDeviceReply(foundId, receivedData);
if (info->periodic != false) {
if(result == IGNORE_REPLY_DATA) {
return;
}
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);
@ -926,10 +966,10 @@ ReturnValue_t DeviceHandlerBase::checkModeCommand(Mode_t commandedMode,
if ((commandedMode == MODE_ON) && (mode == MODE_OFF)
&& (deviceThermalStatePoolId != PoolVariableIF::NO_PARAMETER)) {
DataSet mySet;
db_int8_t thermalState(deviceThermalStatePoolId, &mySet,
GlobDataSet mySet;
gp_uint8_t thermalState(deviceThermalStatePoolId, &mySet,
PoolVariableIF::VAR_READ);
db_int8_t thermalRequest(deviceThermalRequestPoolId, &mySet,
gp_uint8_t thermalRequest(deviceThermalRequestPoolId, &mySet,
PoolVariableIF::VAR_READ);
mySet.read();
if (thermalRequest != ThermalComponentIF::STATE_REQUEST_IGNORE) {
@ -956,8 +996,8 @@ void DeviceHandlerBase::startTransition(Mode_t commandedMode,
childTransitionDelay = getTransitionDelayMs(_MODE_START_UP,
MODE_ON);
triggerEvent(CHANGING_MODE, commandedMode, commandedSubmode);
DataSet mySet;
db_int8_t thermalRequest(deviceThermalRequestPoolId,
GlobDataSet mySet;
gp_int8_t thermalRequest(deviceThermalRequestPoolId,
&mySet, PoolVariableIF::VAR_READ_WRITE);
mySet.read();
if (thermalRequest != ThermalComponentIF::STATE_REQUEST_IGNORE) {
@ -1089,19 +1129,6 @@ ReturnValue_t DeviceHandlerBase::handleDeviceHandlerMessage(
}
replyReturnvalueToCommand(RETURN_OK);
return RETURN_OK;
// case DeviceHandlerMessage::CMD_SWITCH_IOBOARD:
// if (mode != MODE_OFF) {
// replyReturnvalueToCommand(WRONG_MODE_FOR_COMMAND);
// } else {
// result = switchCookieChannel(
// DeviceHandlerMessage::getIoBoardObjectId(message));
// if (result == RETURN_OK) {
// replyReturnvalueToCommand(RETURN_OK);
// } else {
// replyReturnvalueToCommand(CANT_SWITCH_IO_ADDRESS);
// }
// }
// return RETURN_OK;
case DeviceHandlerMessage::CMD_RAW:
if ((mode != MODE_RAW)) {
DeviceHandlerMessage::clear(message);
@ -1185,7 +1212,7 @@ void DeviceHandlerBase::handleDeviceTM(SerializeIF* data,
}
//Try to cast to GlobDataSet and commit data.
if (!neverInDataPool) {
DataSet* dataSet = dynamic_cast<DataSet*>(data);
GlobDataSet* dataSet = dynamic_cast<GlobDataSet*>(data);
if (dataSet != NULL) {
dataSet->commit(PoolVariableIF::VALID);
}
@ -1248,10 +1275,14 @@ void DeviceHandlerBase::buildInternalCommand(void) {
if (iter == deviceCommandMap.end()) {
result = COMMAND_NOT_SUPPORTED;
} else if (iter->second.isExecuting) {
//so we can track misconfigurations
sif::debug << std::hex << getObjectId()
<< ": DHB::buildInternalCommand: Command "
<< deviceCommandId << " isExecuting" << std::endl; //so we can track misconfigurations
return; //this is an internal command, no need to report a failure here, missed reply will track if a reply is too late, otherwise, it's ok
<< deviceCommandId << " isExecuting" << std::dec
<< std::endl;
// this is an internal command, no need to report a failure here,
// missed reply will track if a reply is too late, otherwise, it's ok
return;
} else {
iter->second.sendReplyTo = NO_COMMANDER;
iter->second.isExecuting = true;
@ -1340,12 +1371,50 @@ void DeviceHandlerBase::debugInterface(uint8_t positionTracker,
void DeviceHandlerBase::performOperationHook() {
}
ReturnValue_t DeviceHandlerBase::initializeLocalDataPool(
LocalDataPool &localDataPoolMap,
LocalDataPoolManager& poolManager) {
return RETURN_OK;
}
LocalDataPoolManager* DeviceHandlerBase::getHkManagerHandle() {
return &hkManager;
}
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();
}
this->hkManager.initializeAfterTaskCreation();
if(setStartupImmediately) {
startTransition(MODE_ON, SUBMODE_NONE);
}
return HasReturnvaluesIF::RETURN_OK;
}
LocalPoolDataSetBase* DeviceHandlerBase::getDataSetHandle(sid_t sid) {
auto iter = deviceReplyMap.find(sid.ownerSetId);
if(iter != deviceReplyMap.end()) {
return iter->second.dataSet;
}
else {
return nullptr;
}
}
object_id_t DeviceHandlerBase::getObjectId() const {
return SystemObject::getObjectId();
}
void DeviceHandlerBase::setStartUpImmediately() {
this->setStartupImmediately = true;
}
dur_millis_t DeviceHandlerBase::getPeriodicOperationFrequency() const {
return pstIntervalMs;
}