diff --git a/devicehandlers/ChildHandlerBase.cpp b/devicehandlers/ChildHandlerBase.cpp index cee2a349..e800cd56 100644 --- a/devicehandlers/ChildHandlerBase.cpp +++ b/devicehandlers/ChildHandlerBase.cpp @@ -1,17 +1,19 @@ #include "../subsystem/SubsystemBase.h" -#include "ChildHandlerBase.h" +#include "../devicehandlers/ChildHandlerBase.h" #include "../subsystem/SubsystemBase.h" ChildHandlerBase::ChildHandlerBase(object_id_t setObjectId, - object_id_t deviceCommunication, CookieIF * comCookie, - uint8_t setDeviceSwitch, uint32_t thermalStatePoolId, - uint32_t thermalRequestPoolId, uint32_t parent, - FailureIsolationBase* customFdir, size_t cmdQueueSize) : - DeviceHandlerBase(setObjectId, deviceCommunication, comCookie, - setDeviceSwitch, thermalStatePoolId,thermalRequestPoolId, - (customFdir == nullptr? &childHandlerFdir : customFdir), - cmdQueueSize), + object_id_t deviceCommunication, CookieIF * cookie, + uint32_t thermalStatePoolId, uint32_t thermalRequestPoolId, + object_id_t parent, FailureIsolationBase* customFdir, + size_t cmdQueueSize) : + DeviceHandlerBase(setObjectId, deviceCommunication, cookie, + (customFdir == nullptr? &childHandlerFdir : customFdir), + cmdQueueSize), parentId(parent), childHandlerFdir(setObjectId) { + this->setThermalStateRequestPoolIds(thermalStatePoolId, + thermalRequestPoolId); + } ChildHandlerBase::~ChildHandlerBase() { @@ -25,7 +27,7 @@ ReturnValue_t ChildHandlerBase::initialize() { MessageQueueId_t parentQueue = 0; - if (parentId != 0) { + if (parentId != objects::NO_OBJECT) { SubsystemBase *parent = objectManager->get(parentId); if (parent == NULL) { return RETURN_FAILED; diff --git a/devicehandlers/ChildHandlerBase.h b/devicehandlers/ChildHandlerBase.h index 005e8065..f6bf318a 100644 --- a/devicehandlers/ChildHandlerBase.h +++ b/devicehandlers/ChildHandlerBase.h @@ -1,15 +1,15 @@ -#ifndef PAYLOADHANDLERBASE_H_ -#define PAYLOADHANDLERBASE_H_ +#ifndef FSFW_DEVICES_CHILDHANDLERBASE_H_ +#define FSFW_DEVICES_CHILDHANDLERBASE_H_ #include "ChildHandlerFDIR.h" #include "DeviceHandlerBase.h" class ChildHandlerBase: public DeviceHandlerBase { public: - ChildHandlerBase(object_id_t setObjectId, - object_id_t deviceCommunication, CookieIF * comCookie, - uint8_t setDeviceSwitch, uint32_t thermalStatePoolId, - uint32_t thermalRequestPoolId, uint32_t parent, + ChildHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication, + CookieIF * cookie, uint32_t thermalStatePoolId, + uint32_t thermalRequestPoolId, + object_id_t parent = objects::NO_OBJECT, FailureIsolationBase* customFdir = nullptr, size_t cmdQueueSize = 20); virtual ~ChildHandlerBase(); @@ -22,4 +22,5 @@ protected: }; -#endif /* PAYLOADHANDLERBASE_H_ */ +#endif /* FSFW_DEVICES_CHILDHANDLERBASE_H_ */ + diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index a87b6de1..017ea8d2 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -1,12 +1,12 @@ #include "DeviceHandlerBase.h" +#include "AcceptsDeviceResponsesIF.h" +#include "DeviceTmReportingWrapper.h" + #include "../objectmanager/ObjectManager.h" #include "../storagemanager/StorageManagerIF.h" #include "../thermal/ThermalComponentIF.h" -#include "AcceptsDeviceResponsesIF.h" - #include "../datapool/DataSet.h" #include "../datapool/PoolVariable.h" -#include "DeviceTmReportingWrapper.h" #include "../globalfunctions/CRC.h" #include "../subsystem/SubsystemBase.h" #include "../ipc/QueueFactory.h" @@ -14,45 +14,47 @@ #include -object_id_t DeviceHandlerBase::powerSwitcherId = 0; -object_id_t DeviceHandlerBase::rawDataReceiverId = 0; -object_id_t DeviceHandlerBase::defaultFDIRParentId = 0; +object_id_t DeviceHandlerBase::powerSwitcherId = objects::NO_OBJECT; +object_id_t DeviceHandlerBase::rawDataReceiverId = objects::NO_OBJECT; +object_id_t DeviceHandlerBase::defaultFdirParentId = objects::NO_OBJECT; DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication, CookieIF * comCookie, - uint8_t setDeviceSwitch, uint32_t thermalStatePoolId, - uint32_t thermalRequestPoolId, FailureIsolationBase* fdirInstance, - size_t cmdQueueSize) : + FailureIsolationBase* fdirInstance, size_t cmdQueueSize) : SystemObject(setObjectId), mode(MODE_OFF), submode(SUBMODE_NONE), wiretappingMode(OFF), storedRawData(StorageManagerIF::INVALID_ADDRESS), deviceCommunicationId(deviceCommunication), comCookie(comCookie), - deviceThermalStatePoolId(thermalStatePoolId), - deviceThermalRequestPoolId(thermalRequestPoolId), healthHelper(this,setObjectId), modeHelper(this), parameterHelper(this), - childTransitionFailure(RETURN_OK), fdirInstance(fdirInstance), - hkSwitcher(this), defaultFDIRUsed(fdirInstance == nullptr), - switchOffWasReported(false), actionHelper(this, nullptr), - childTransitionDelay(5000), - transitionSourceMode(_MODE_POWER_DOWN), transitionSourceSubMode( - SUBMODE_NONE), deviceSwitch(setDeviceSwitch) { + actionHelper(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, - CommandMessage::MAX_MESSAGE_SIZE); + MessageQueueMessage::MAX_MESSAGE_SIZE); insertInCommandMap(RAW_COMMAND_ID); cookieInfo.state = COOKIE_UNUSED; cookieInfo.pendingCommand = deviceCommandMap.end(); if (comCookie == nullptr) { - sif::error << "DeviceHandlerBase: ObjectID 0x" << std::hex << - std::setw(8) << std::setfill('0') << this->getObjectId() << - std::dec << ": Do not pass nullptr as a cookie, consider " - << std::setfill(' ') << "passing a dummy cookie instead!" << - std::endl; + sif::error << "DeviceHandlerBase: ObjectID 0x" << std::hex + << std::setw(8) << std::setfill('0') << this->getObjectId() + << std::dec << ": Do not pass nullptr as a cookie, consider " + << std::setfill(' ') << "passing a dummy cookie instead!" + << std::endl; } if (this->fdirInstance == nullptr) { this->fdirInstance = new DeviceHandlerFailureIsolation(setObjectId, - defaultFDIRParentId); + defaultFdirParentId); } } +void DeviceHandlerBase::setThermalStateRequestPoolIds( + uint32_t thermalStatePoolId, uint32_t thermalRequestPoolId) { + this->deviceThermalRequestPoolId = thermalStatePoolId; + this->deviceThermalRequestPoolId = thermalRequestPoolId; +} + + DeviceHandlerBase::~DeviceHandlerBase() { delete comCookie; if (defaultFDIRUsed) { @@ -108,8 +110,12 @@ ReturnValue_t DeviceHandlerBase::initialize() { communicationInterface = objectManager->get( deviceCommunicationId); - if (communicationInterface == NULL) { - return RETURN_FAILED; + if (communicationInterface == nullptr) { + 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); @@ -118,27 +124,40 @@ ReturnValue_t DeviceHandlerBase::initialize() { } IPCStore = objectManager->get(objects::IPC_STORE); - if (IPCStore == NULL) { - return RETURN_FAILED; + if (IPCStore == nullptr) { + sif::error << "DeviceHandlerBase::initialize: IPC store not set up in " + "factory." << std::endl; + return ObjectManagerIF::CHILD_INIT_FAILED; } - AcceptsDeviceResponsesIF *rawReceiver = objectManager->get< - AcceptsDeviceResponsesIF>(rawDataReceiverId); + if(rawDataReceiverId != objects::NO_OBJECT) { + AcceptsDeviceResponsesIF *rawReceiver = objectManager->get< + AcceptsDeviceResponsesIF>(rawDataReceiverId); - if (rawReceiver == NULL) { - return RETURN_FAILED; + if (rawReceiver == nullptr) { + 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(); - - powerSwitcher = objectManager->get(powerSwitcherId); - if (powerSwitcher == NULL) { - return RETURN_FAILED; + if(powerSwitcherId != objects::NO_OBJECT) { + powerSwitcher = objectManager->get(powerSwitcherId); + if (powerSwitcher == nullptr) { + 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(); if (result != RETURN_OK) { - return result; + return result; } result = modeHelper.initialize(); @@ -168,7 +187,7 @@ ReturnValue_t DeviceHandlerBase::initialize() { //Set temperature target state to NON_OP. DataSet mySet; - PoolVariable thermalRequest(deviceThermalRequestPoolId, &mySet, + db_int8_t thermalRequest(deviceThermalRequestPoolId, &mySet, PoolVariableIF::VAR_WRITE); mySet.read(); thermalRequest = ThermalComponentIF::STATE_REQUEST_NON_OPERATIONAL; @@ -200,38 +219,43 @@ void DeviceHandlerBase::readCommandQueue() { return; } - CommandMessage message; - ReturnValue_t result = commandQueue->receiveMessage(&message); + CommandMessage command; + ReturnValue_t result = commandQueue->receiveMessage(&command); if (result != RETURN_OK) { return; } - result = healthHelper.handleHealthCommand(&message); + result = healthHelper.handleHealthCommand(&command); + if (result == RETURN_OK) { + return; + } + + result = modeHelper.handleModeCommand(&command); if (result == RETURN_OK) { return; } - result = modeHelper.handleModeCommand(&message); + result = actionHelper.handleActionMessage(&command); if (result == RETURN_OK) { return; } - result = actionHelper.handleActionMessage(&message); + result = parameterHelper.handleParameterMessage(&command); if (result == RETURN_OK) { return; } - result = parameterHelper.handleParameterMessage(&message); +// result = hkManager.handleHousekeepingMessage(&command); +// if (result == RETURN_OK) { +// return; +// } + + result = handleDeviceHandlerMessage(&command); if (result == RETURN_OK) { return; } - result = handleDeviceHandlerMessage(&message); - if (result == RETURN_OK) { - return; - } - - result = letChildHandleMessage(&message); + result = letChildHandleMessage(&command); if (result == RETURN_OK) { return; } @@ -273,7 +297,8 @@ void DeviceHandlerBase::doStateMachine() { case _MODE_WAIT_ON: { uint32_t currentUptime; Clock::getUptime(¤tUptime); - if (currentUptime - timeoutStart >= powerSwitcher->getSwitchDelayMs()) { + if (powerSwitcher != nullptr and currentUptime - timeoutStart >= + powerSwitcher->getSwitchDelayMs()) { triggerEvent(MODE_TRANSITION_FAILED, PowerSwitchIF::SWITCH_TIMEOUT, 0); setMode(_MODE_POWER_DOWN); @@ -293,6 +318,12 @@ void DeviceHandlerBase::doStateMachine() { case _MODE_WAIT_OFF: { uint32_t currentUptime; Clock::getUptime(¤tUptime); + + if(powerSwitcher == nullptr) { + setMode(MODE_OFF); + break; + } + if (currentUptime - timeoutStart >= powerSwitcher->getSwitchDelayMs()) { triggerEvent(MODE_TRANSITION_FAILED, PowerSwitchIF::SWITCH_TIMEOUT, 0); @@ -343,9 +374,10 @@ 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) { +ReturnValue_t DeviceHandlerBase::insertInCommandAndReplyMap( + DeviceCommandId_t deviceCommand, uint16_t maxDelayCycles, + 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) { @@ -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; info.expectedReplies = 0; info.isExecuting = false; @@ -419,7 +452,7 @@ void DeviceHandlerBase::setTransition(Mode_t modeTo, Submode_t submodeTo) { transitionSourceSubMode = submode; childTransitionFailure = CHILD_TIMEOUT; -//transitionTargetMode is set by setMode + // transitionTargetMode is set by setMode setMode((modeTo | TRANSITION_MODE_CHILD_ACTION_MASK), submodeTo); } @@ -437,7 +470,7 @@ void DeviceHandlerBase::setMode(Mode_t newMode, uint8_t newSubmode) { if (mode == MODE_OFF) { DataSet mySet; - PoolVariable thermalRequest(deviceThermalRequestPoolId, &mySet, + db_int8_t thermalRequest(deviceThermalRequestPoolId, &mySet, PoolVariableIF::VAR_READ_WRITE); mySet.read(); if (thermalRequest != ThermalComponentIF::STATE_REQUEST_IGNORE) { @@ -578,11 +611,8 @@ void DeviceHandlerBase::doSendRead() { } void DeviceHandlerBase::doGetRead() { - size_t receivedDataLen; - uint8_t *receivedData; - DeviceCommandId_t foundId = 0xFFFFFFFF; - size_t foundLen = 0; - ReturnValue_t result; + size_t receivedDataLen = 0; + uint8_t *receivedData = nullptr; if (cookieInfo.state != COOKIE_READ_SENT) { cookieInfo.state = COOKIE_UNUSED; @@ -591,8 +621,8 @@ void DeviceHandlerBase::doGetRead() { cookieInfo.state = COOKIE_UNUSED; - result = communicationInterface->readReceivedMessage(comCookie, - &receivedData, &receivedDataLen); + ReturnValue_t result = communicationInterface->readReceivedMessage( + comCookie, &receivedData, &receivedDataLen); if (result != RETURN_OK) { triggerEvent(DEVICE_REQUESTING_REPLY_FAILED, result); @@ -608,51 +638,101 @@ void DeviceHandlerBase::doGetRead() { replyRawData(receivedData, receivedDataLen, requestedRawTraffic); } - if (mode == MODE_RAW) { + if (mode == MODE_RAW and defaultRawReceiver != MessageQueueIF::NO_QUEUE) { replyRawReplyIfnotWiretapped(receivedData, receivedDataLen); - } else { - //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 (seen in bug 1077). - uint32_t remainingLength = receivedDataLen; - for (uint32_t count = 0; count < receivedDataLen; count++) { - result = scanForReply(receivedData, remainingLength, &foundId, - &foundLen); - switch (result) { - case RETURN_OK: - handleReply(receivedData, foundId, foundLen); - break; - case APERIODIC_REPLY: { - result = interpretDeviceReply(foundId, receivedData); - if (result != RETURN_OK) { - replyRawReplyIfnotWiretapped(receivedData, foundLen); - triggerEvent(DEVICE_INTERPRETING_REPLY_FAILED, result, - foundId); - } - } - break; - case IGNORE_REPLY_DATA: - break; - case IGNORE_FULL_PACKET: - return; - default: - //We need to wait for timeout.. don't know what command failed and who sent it. + } + else { + 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; + for (uint32_t count = 0; count < receivedDataLen; count++) { + result = scanForReply(receivedData, remainingLength, &foundId, + &foundLen); + switch (result) { + case RETURN_OK: + handleReply(receivedData, foundId, foundLen); + break; + case APERIODIC_REPLY: { + result = interpretDeviceReply(foundId, receivedData); + if (result != RETURN_OK) { replyRawReplyIfnotWiretapped(receivedData, foundLen); - triggerEvent(DEVICE_READING_REPLY_FAILED, result, foundLen); - break; - } - receivedData += foundLen; - if (remainingLength > foundLen) { - remainingLength -= foundLen; - } else { - return; + triggerEvent(DEVICE_INTERPRETING_REPLY_FAILED, result, + foundId); } } + break; + case IGNORE_REPLY_DATA: + break; + case IGNORE_FULL_PACKET: + return; + default: + //We need to wait for timeout.. don't know what command failed and who sent it. + replyRawReplyIfnotWiretapped(receivedData, foundLen); + triggerEvent(DEVICE_READING_REPLY_FAILED, result, foundLen); + break; + } + receivedData += foundLen; + if (remainingLength > foundLen) { + remainingLength -= foundLen; + } else { + 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); + } } } ReturnValue_t DeviceHandlerBase::getStorageData(store_address_t storageAddress, - uint8_t * *data, uint32_t * len) { + uint8_t** data, uint32_t * len) { size_t lenTmp; if (IPCStore == nullptr) { @@ -675,7 +755,7 @@ ReturnValue_t DeviceHandlerBase::getStorageData(store_address_t storageAddress, void DeviceHandlerBase::replyRawData(const uint8_t *data, size_t len, MessageQueueId_t sendTo, bool isCommand) { - if (IPCStore == NULL || len == 0) { + if (IPCStore == nullptr or len == 0 or sendTo == MessageQueueIF::NO_QUEUE) { return; } store_address_t address; @@ -686,18 +766,17 @@ void DeviceHandlerBase::replyRawData(const uint8_t *data, size_t len, return; } - CommandMessage message; + CommandMessage command; - DeviceHandlerMessage::setDeviceHandlerRawReplyMessage(&message, + DeviceHandlerMessage::setDeviceHandlerRawReplyMessage(&command, getObjectId(), address, isCommand); -// this->DeviceHandlerCommand = CommandMessage::CMD_NONE; - - result = commandQueue->sendMessage(sendTo, &message); + result = commandQueue->sendMessage(sendTo, &command); if (result != RETURN_OK) { 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(); } -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) { storedRawData = DeviceHandlerMessage::getStoreAddress(commandMessage); ReturnValue_t result = getStorageData(storedRawData, &rawPacket, @@ -793,6 +821,9 @@ void DeviceHandlerBase::buildRawDeviceCommand(CommandMessage* commandMessage) { } void DeviceHandlerBase::commandSwitch(ReturnValue_t onOff) { + if(powerSwitcher == nullptr) { + return; + } const uint8_t *switches; uint8_t numberOfSwitches = 0; ReturnValue_t result = getSwitches(&switches, &numberOfSwitches); @@ -807,9 +838,7 @@ void DeviceHandlerBase::commandSwitch(ReturnValue_t onOff) { ReturnValue_t DeviceHandlerBase::getSwitches(const uint8_t **switches, uint8_t *numberOfSwitches) { - *switches = &deviceSwitch; - *numberOfSwitches = 1; - return RETURN_OK; + return DeviceHandlerBase::NO_SWITCH; } void DeviceHandlerBase::modeChanged(void) { @@ -845,6 +874,9 @@ uint32_t DeviceHandlerBase::getTransitionDelayMs(Mode_t modeFrom, } ReturnValue_t DeviceHandlerBase::getStateOfSwitches(void) { + if(powerSwitcher == nullptr) { + return NO_SWITCH; + } uint8_t numberOfSwitches = 0; const uint8_t *switches; @@ -895,9 +927,9 @@ ReturnValue_t DeviceHandlerBase::checkModeCommand(Mode_t commandedMode, if ((commandedMode == MODE_ON) && (mode == MODE_OFF) && (deviceThermalStatePoolId != PoolVariableIF::NO_PARAMETER)) { DataSet mySet; - PoolVariable thermalState(deviceThermalStatePoolId, &mySet, + db_int8_t thermalState(deviceThermalStatePoolId, &mySet, PoolVariableIF::VAR_READ); - PoolVariable thermalRequest(deviceThermalRequestPoolId, &mySet, + db_int8_t thermalRequest(deviceThermalRequestPoolId, &mySet, PoolVariableIF::VAR_READ); mySet.read(); if (thermalRequest != ThermalComponentIF::STATE_REQUEST_IGNORE) { @@ -925,7 +957,7 @@ void DeviceHandlerBase::startTransition(Mode_t commandedMode, MODE_ON); triggerEvent(CHANGING_MODE, commandedMode, commandedSubmode); DataSet mySet; - PoolVariable thermalRequest(deviceThermalRequestPoolId, + db_int8_t thermalRequest(deviceThermalRequestPoolId, &mySet, PoolVariableIF::VAR_READ_WRITE); mySet.read(); if (thermalRequest != ThermalComponentIF::STATE_REQUEST_IGNORE) { @@ -997,8 +1029,8 @@ HasHealthIF::HealthState DeviceHandlerBase::getHealth() { } ReturnValue_t DeviceHandlerBase::setHealth(HealthState health) { - healthHelper.setHealth(health); - return HasReturnvaluesIF::RETURN_OK; + healthHelper.setHealth(health); + return HasReturnvaluesIF::RETURN_OK; } void DeviceHandlerBase::checkSwitchState() { @@ -1111,35 +1143,47 @@ void DeviceHandlerBase::handleDeviceTM(SerializeIF* data, return; } 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; if (queueId != NO_COMMANDER) { //This may fail, but we'll ignore the fault. actionHelper.reportData(queueId, replyId, data); } + //This check should make sure we get any TM but don't get anything doubled. if (wiretappingMode == TM && (requestedRawTraffic != queueId)) { actionHelper.reportData(requestedRawTraffic, replyId, &wrapper); - } else if (forceDirectTm && (defaultRawReceiver != queueId)) { - - // 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, - true); - } - } else { //unrequested/aperiodic replies - if (wiretappingMode == TM) { - 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 - //(progress or completed) it is in + else if (forceDirectTm and (defaultRawReceiver != queueId) and + (defaultRawReceiver != 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, - true); + true); } } -//Try to cast to DataSet and commit data. + //unrequested/aperiodic replies + else + { + if (wiretappingMode == TM) { + actionHelper.reportData(requestedRawTraffic, replyId, &wrapper); + } + else if (forceDirectTm and defaultRawReceiver != + 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, + true); + } + } + //Try to cast to GlobDataSet and commit data. if (!neverInDataPool) { DataSet* dataSet = dynamic_cast(data); if (dataSet != NULL) { @@ -1178,18 +1222,23 @@ void DeviceHandlerBase::buildInternalCommand(void) { if (mode == MODE_NORMAL) { result = buildNormalDeviceCommand(&deviceCommandId); if (result == BUSY) { + //so we can track misconfigurations 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 } - } else if (mode == MODE_RAW) { + } + else if (mode == MODE_RAW) { result = buildChildRawCommand(); deviceCommandId = RAW_COMMAND_ID; - } else if (mode & TRANSITION_MODE_CHILD_ACTION_MASK) { + } + else if (mode & TRANSITION_MODE_CHILD_ACTION_MASK) { result = buildTransitionDeviceCommand(&deviceCommandId); - } else { + } + else { return; } + if (result == NOTHING_TO_SEND) { return; } @@ -1281,11 +1330,22 @@ void DeviceHandlerBase::changeHK(Mode_t mode, Submode_t submode, bool enable) { } void DeviceHandlerBase::setTaskIF(PeriodicTaskIF* task_){ - executingTask = task_; + executingTask = task_; } // Default implementations empty. void DeviceHandlerBase::debugInterface(uint8_t positionTracker, 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; +} + diff --git a/devicehandlers/DeviceHandlerBase.h b/devicehandlers/DeviceHandlerBase.h index 7c68ce06..5666f35e 100644 --- a/devicehandlers/DeviceHandlerBase.h +++ b/devicehandlers/DeviceHandlerBase.h @@ -1,22 +1,23 @@ -#ifndef DEVICEHANDLERBASE_H_ -#define DEVICEHANDLERBASE_H_ +#ifndef FRAMEWORK_DEVICEHANDLERS_DEVICEHANDLERBASE_H_ +#define FRAMEWORK_DEVICEHANDLERS_DEVICEHANDLERBASE_H_ + +#include "DeviceHandlerIF.h" +#include "DeviceCommunicationIF.h" +#include "DeviceHandlerFailureIsolation.h" #include "../objectmanager/SystemObject.h" +#include "../tasks/PeriodicTaskIF.h" #include "../tasks/ExecutableObjectIF.h" -#include "DeviceHandlerIF.h" #include "../returnvalues/HasReturnvaluesIF.h" #include "../action/HasActionsIF.h" #include "../datapool/PoolVariableIF.h" -#include "DeviceCommunicationIF.h" #include "../modes/HasModesIF.h" #include "../power/PowerSwitchIF.h" #include "../ipc/MessageQueueIF.h" - #include "../action/ActionHelper.h" #include "../health/HealthHelper.h" #include "../parameters/ParameterHelper.h" #include "../datapool/HkSwitchHelper.h" -#include "DeviceHandlerFailureIsolation.h" #include @@ -46,14 +47,16 @@ class StorageManagerIF; * 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 * 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. * However, the communication principles are similar to RMAP as there are * two write and two send calls involved. * - * Device handler instances should extend this class and implement the abstract functions. - * Components and drivers can send so called cookies which are used for communication - * and contain information about the communcation (e.g. slave address for I2C or RMAP structs). + * Device handler instances should extend this class and implement the abstract + * functions. Components and drivers can send so called cookies which are used + * 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: * 1. doStartUp() * 2. doShutDown() @@ -100,12 +103,12 @@ public: * @param cmdQueueSize */ DeviceHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication, - CookieIF * comCookie, uint8_t setDeviceSwitch, - uint32_t thermalStatePoolId = PoolVariableIF::NO_PARAMETER, - uint32_t thermalRequestPoolId = PoolVariableIF::NO_PARAMETER, - FailureIsolationBase* fdirInstance = nullptr, + CookieIF * comCookie, FailureIsolationBase* fdirInstance = nullptr, size_t cmdQueueSize = 20); + void setThermalStateRequestPoolIds(uint32_t thermalStatePoolId, + uint32_t thermalRequestPoolId); + /** * @brief This function is the device handler base core component and is * called periodically. @@ -150,11 +153,9 @@ public: * @return */ virtual ReturnValue_t initialize(); - - /** - * Destructor. - */ + /** Destructor. */ virtual ~DeviceHandlerBase(); + protected: /** * @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. * * 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() - * and doShutDown() as well as doTransition() + * @c _MODE_START_UP and @c _MODE_SHUT_DOWN. So it is used by doStartUp() + * 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 * 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, * e.g. logical errors or range violations occurred */ - virtual ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) = 0; /** - * @brief fill the #deviceCommandMap + * @brief fill the #DeviceCommandMap and #DeviceReplyMap * called by the initialize() of the base class * @details * This is used to let the base class know which replies are expected. @@ -470,6 +471,18 @@ protected: virtual ReturnValue_t getSwitches(const uint8_t **switches, 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 * performOperation(). Default implementation is empty. @@ -493,7 +506,7 @@ public: ReturnValue_t setHealth(HealthState health); virtual ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId, ParameterWrapper *parameterWrapper, - const ParameterWrapper *newValues, uint16_t startAtIndex); + const ParameterWrapper *newValues, uint16_t startAtIndex) override; /** * Implementation of ExecutableObjectIF function * @@ -505,7 +518,7 @@ public: 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; @@ -527,114 +540,138 @@ protected: static const DeviceCommandId_t NO_COMMAND_ID = -2; static const MessageQueueId_t NO_COMMANDER = 0; - /** - * Pointer to the raw packet that will be sent. - */ + /** Pointer to the raw packet that will be sent.*/ uint8_t *rawPacket = nullptr; - /** - * Size of the #rawPacket. - */ + /** Size of the #rawPacket. */ uint32_t rawPacketLen = 0; /** * The mode the device handler is currently in. - * * This should never be changed directly but only with setMode() */ Mode_t mode; - /** * The submode the device handler is currently in. - * * This should never be changed directly but only with setMode() */ Submode_t submode; - /** - * This is the counter value from performOperation(). - */ + /** This is the counter value from performOperation(). */ 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 - * or that all device TM should be downlinked to #theOneWhoWantsToReadRawTraffic + * indicates either that all raw messages to and from the device should be + * sent to #defaultRawReceiver + * or that all device TM should be downlinked to #defaultRawReceiver. */ enum WiretappingMode { OFF = 0, RAW = 1, TM = 2 } 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 - * of finding a recipient, ie raw mode and reporting erreonous replies + * Statically initialized in initialize() to a configurable object. + * 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; /** - * the message queue which wants to read all raw traffic - * - * if #isWiretappingActive all raw communication from and to the device will be sent to this queue + * @brief The message queue which wants to read all raw traffic + * If #isWiretappingActive all raw communication from and to the device + * will be sent to this queue */ MessageQueueId_t requestedRawTraffic = 0; - /** - * the object used to set power switches - */ - PowerSwitchIF *powerSwitcher = nullptr; - /** * Pointer to the IPCStore. - * * This caches the pointer received from the objectManager in the constructor. */ StorageManagerIF *IPCStore = nullptr; - - /** - * cached for init - */ + /** The comIF object ID is cached for the intialize() function */ object_id_t deviceCommunicationId; - - /** - * Communication object used for device communication - */ + /** Communication object used for device communication */ DeviceCommunicationIF * communicationInterface = nullptr; - - /** - * Cookie used for communication - */ + /** Cookie used for communication */ 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 { - bool isExecuting; //!< Indicates if the command is already executing. - uint8_t expectedReplies; //!< Dynamic value to indicate how many replies are expected. Inititated with 0. - MessageQueueId_t sendReplyTo; //!< if this is != NO_COMMANDER, DHB was commanded externally and shall report everything to commander. + //! Indicates if the command is already executing. + bool isExecuting; + //! 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 ; + /** + * Information about commands + */ + DeviceCommandMap deviceCommandMap; /** * @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 { - uint16_t maxDelayCycles; //!< The maximum number of cycles the handler should wait for a reply to this command. - uint16_t delayCycles; //!< The currently remaining cycles the handler should wait for a reply, 0 means there is no reply expected + //! The maximum number of cycles the handler should wait for a reply + //! 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. - bool periodic; //!< if this is !=0, the delayCycles will not be reset to 0 but to maxDelayCycles - DeviceCommandMap::iterator command; //!< The command that expects this reply. + //! if this is !=0, the delayCycles will not be reset to 0 but to + //! 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 ; 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; /** @@ -642,23 +679,14 @@ protected: * * 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 * * can be set to PoolVariableIF::NO_PARAMETER to deactivate thermal checking */ - uint32_t deviceThermalRequestPoolId; - - /** - * Taking care of the health - */ - HealthHelper healthHelper; - - ModeHelper modeHelper; - - ParameterHelper parameterHelper; + uint32_t deviceThermalRequestPoolId = PoolVariableIF::NO_PARAMETER; /** * Optional Error code @@ -676,13 +704,15 @@ protected: 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 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 * @@ -730,28 +760,40 @@ protected: /** * 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] * - * 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 - * or setting the mode to an transitional mode (TO_ON, TO_NORMAL, TO_RAW) if the device needs to be reconfigured. + * If the transition can not be completed, the child class can try to reach + * 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). * - * The intended way to send commands is to set a flag (enum) indicating which command is to be sent here - * and then to check in 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. + * The intended way to send commands is to set a flag (enum) indicating + * which command is to be sent here and then to check in + * 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 */ virtual void doTransition(Mode_t modeFrom, Submode_t subModeFrom); @@ -953,24 +995,11 @@ protected: 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: - * - 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 + * @param onOff on == @c SWITCH_ON; off != @c SWITCH_ON */ - DeviceReplyMap deviceReplyMap; - - /** - * Information about commands - */ - DeviceCommandMap deviceCommandMap; - - ActionHelper actionHelper; + void commandSwitch(ReturnValue_t onOff); private: /** @@ -997,15 +1026,16 @@ private: }; /** - * Info about the #cookie - * + * @brief Info about the #cookie * Used to track the state of the communication */ 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. */ uint32_t timeoutStart = 0; @@ -1016,11 +1046,12 @@ private: 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 * - * 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] */ @@ -1031,13 +1062,6 @@ private: */ Submode_t transitionSourceSubMode; - /** - * the switch of the device - * - * for devices using two switches override getSwitches() - */ - const uint8_t deviceSwitch; - /** * read the command queue */ @@ -1135,12 +1159,6 @@ private: ReturnValue_t getStorageData(store_address_t storageAddress, uint8_t **data, 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!!! @@ -1165,7 +1183,12 @@ private: ReturnValue_t switchCookieChannel(object_id_t newChannelId); 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_ */