Merge remote-tracking branch 'origin/master' into mohr_serialize

This commit is contained in:
Ulrich Mohr 2020-07-03 11:59:15 +02:00
commit 8c68895c06
86 changed files with 2218 additions and 1538 deletions

View File

@ -49,7 +49,7 @@ void ActionHelper::setQueueToUse(MessageQueueIF* queue) {
void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId,
store_address_t dataAddress) {
const uint8_t* dataPtr = NULL;
uint32_t size = 0;
size_t size = 0;
ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size);
if (result != HasReturnvaluesIF::RETURN_OK) {
CommandMessage reply;

View File

@ -115,10 +115,9 @@ uint8_t CommandActionHelper::getCommandCount() const {
return commandCount;
}
void CommandActionHelper::extractDataForOwner(ActionId_t actionId,
store_address_t storeId) {
const uint8_t *data = NULL;
uint32_t size = 0;
void CommandActionHelper::extractDataForOwner(ActionId_t actionId, store_address_t storeId) {
const uint8_t * data = NULL;
size_t size = 0;
ReturnValue_t result = ipcStore->getData(storeId, &data, &size);
if (result != HasReturnvaluesIF::RETURN_OK) {
return;

View File

@ -44,7 +44,7 @@ void SimpleActionHelper::prepareExecution(MessageQueueId_t commandedBy,
queueToUse->sendMessage(commandedBy, &reply);
}
const uint8_t* dataPtr = NULL;
uint32_t size = 0;
size_t size = 0;
ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size);
if (result != HasReturnvaluesIF::RETURN_OK) {
ActionMessage::setStepReply(&reply, actionId, 0, result);

View File

@ -3,6 +3,11 @@
#include <framework/returnvalues/HasReturnvaluesIF.h>
/**
* @brief Simple First-In-First-Out data structure
* @tparam T Entry Type
* @tparam capacity Maximum capacity
*/
template<typename T, uint8_t capacity>
class FIFO {
private:
@ -54,6 +59,21 @@ public:
return HasReturnvaluesIF::RETURN_OK;
}
}
ReturnValue_t peek(T * value) {
if(empty()) {
return EMPTY;
} else {
*value = data[readIndex];
return HasReturnvaluesIF::RETURN_OK;
}
}
ReturnValue_t pop() {
T value;
return this->retrieve(&value);
}
static const uint8_t INTERFACE_ID = CLASS_ID::FIFO_CLASS;
static const ReturnValue_t FULL = MAKE_RETURN_CODE(1);
static const ReturnValue_t EMPTY = MAKE_RETURN_CODE(2);

View File

@ -55,7 +55,7 @@ void Clcw::setBitLock(bool bitLock) {
}
void Clcw::print() {
debug << "Clcw::print: Clcw is: " << std::hex << getAsWhole() << std::dec << std::endl;
sif::debug << "Clcw::print: Clcw is: " << std::hex << getAsWhole() << std::dec << std::endl;
}
void Clcw::setWhole(uint32_t rawClcw) {

View File

@ -98,8 +98,8 @@ ReturnValue_t DataLinkLayer::processFrame(uint16_t length) {
receivedDataLength = length;
ReturnValue_t status = allFramesReception();
if (status != RETURN_OK) {
error << "DataLinkLayer::processFrame: frame reception failed. Error code: " << std::hex
<< status << std::dec << std::endl;
sif::error << "DataLinkLayer::processFrame: frame reception failed. "
"Error code: " << std::hex << status << std::dec << std::endl;
// currentFrame.print();
return status;
} else {
@ -124,7 +124,7 @@ ReturnValue_t DataLinkLayer::initialize() {
if ( virtualChannels.begin() != virtualChannels.end() ) {
clcw->setVirtualChannel( virtualChannels.begin()->second->getChannelId() );
} else {
error << "DataLinkLayer::initialize: No VC assigned to this DLL instance! " << std::endl;
sif::error << "DataLinkLayer::initialize: No VC assigned to this DLL instance! " << std::endl;
return RETURN_FAILED;
}

View File

@ -36,7 +36,7 @@ ReturnValue_t MapPacketExtraction::extractPackets(TcTransferFrame* frame) {
bufferPosition = &packetBuffer[packetLength];
status = RETURN_OK;
} else {
error
sif::error
<< "MapPacketExtraction::extractPackets. Packet too large! Size: "
<< packetLength << std::endl;
clearBuffers();
@ -58,14 +58,14 @@ ReturnValue_t MapPacketExtraction::extractPackets(TcTransferFrame* frame) {
}
status = RETURN_OK;
} else {
error
sif::error
<< "MapPacketExtraction::extractPackets. Packet too large! Size: "
<< packetLength << std::endl;
clearBuffers();
status = CONTENT_TOO_LARGE;
}
} else {
error
sif::error
<< "MapPacketExtraction::extractPackets. Illegal segment! Last flag: "
<< (int) lastSegmentationFlag << std::endl;
clearBuffers();
@ -73,7 +73,7 @@ ReturnValue_t MapPacketExtraction::extractPackets(TcTransferFrame* frame) {
}
break;
default:
error
sif::error
<< "MapPacketExtraction::extractPackets. Illegal segmentationFlag: "
<< (int) segmentationFlag << std::endl;
clearBuffers();
@ -142,9 +142,9 @@ ReturnValue_t MapPacketExtraction::initialize() {
}
void MapPacketExtraction::printPacketBuffer(void) {
debug << "DLL: packet_buffer contains: " << std::endl;
sif::debug << "DLL: packet_buffer contains: " << std::endl;
for (uint32_t i = 0; i < this->packetLength; ++i) {
debug << "packet_buffer[" << std::dec << i << "]: 0x" << std::hex
sif::debug << "packet_buffer[" << std::dec << i << "]: 0x" << std::hex
<< (uint16_t) this->packetBuffer[i] << std::endl;
}
}

View File

@ -87,11 +87,11 @@ uint8_t* TcTransferFrame::getFullDataField() {
}
void TcTransferFrame::print() {
debug << "Raw Frame: " << std::hex << std::endl;
sif::debug << "Raw Frame: " << std::hex << std::endl;
for (uint16_t count = 0; count < this->getFullSize(); count++ ) {
debug << (uint16_t)this->getFullFrame()[count] << " ";
sif::debug << (uint16_t)this->getFullFrame()[count] << " ";
}
debug << std::dec << std::endl;
sif::debug << std::dec << std::endl;
// debug << "Frame Header:" << std::endl;
// debug << "Version Number: " << std::hex << (uint16_t)this->current_frame.getVersionNumber() << std::endl;
// debug << "Bypass Flag set?| Ctrl Cmd Flag set?: " << (uint16_t)this->current_frame.bypassFlagSet() << " | " << (uint16_t)this->current_frame.controlCommandFlagSet() << std::endl;

View File

@ -37,7 +37,7 @@ TcTransferFrameLocal::TcTransferFrameLocal(bool bypass, bool controlCommand, uin
this->getFullFrame()[getFullSize()-2] = (crc & 0xFF00) >> 8;
this->getFullFrame()[getFullSize()-1] = (crc & 0x00FF);
} else {
debug << "TcTransferFrameLocal: dataSize too large: " << dataSize << std::endl;
sif::debug << "TcTransferFrameLocal: dataSize too large: " << dataSize << std::endl;
}
} else {
//No data in frame

View File

@ -102,7 +102,7 @@ uint8_t VirtualChannelReception::getChannelId() const {
ReturnValue_t VirtualChannelReception::initialize() {
ReturnValue_t returnValue = RETURN_FAILED;
if ((slidingWindowWidth > 254) || (slidingWindowWidth % 2 != 0)) {
error << "VirtualChannelReception::initialize: Illegal sliding window width: "
sif::error << "VirtualChannelReception::initialize: Illegal sliding window width: "
<< (int) slidingWindowWidth << std::endl;
return RETURN_FAILED;
}

View File

@ -55,7 +55,7 @@ PoolEntryIF* DataPool::getRawData( uint32_t data_pool_id ) {
ReturnValue_t DataPool::freeDataPoolLock() {
ReturnValue_t status = mutex->unlockMutex();
if ( status != RETURN_OK ) {
error << "DataPool::DataPool: unlock of mutex failed with error code: " << status << std::endl;
sif::error << "DataPool::DataPool: unlock of mutex failed with error code: " << status << std::endl;
}
return status;
}
@ -63,17 +63,17 @@ ReturnValue_t DataPool::freeDataPoolLock() {
ReturnValue_t DataPool::lockDataPool() {
ReturnValue_t status = mutex->lockMutex(MutexIF::NO_TIMEOUT);
if ( status != RETURN_OK ) {
error << "DataPool::DataPool: lock of mutex failed with error code: " << status << std::endl;
sif::error << "DataPool::DataPool: lock of mutex failed with error code: " << status << std::endl;
}
return status;
}
void DataPool::print() {
debug << "DataPool contains: " << std::endl;
sif::debug << "DataPool contains: " << std::endl;
std::map<uint32_t, PoolEntryIF*>::iterator dataPoolIt;
dataPoolIt = this->data_pool.begin();
while( dataPoolIt != this->data_pool.end() ) {
debug << std::hex << dataPoolIt->first << std::dec << " |";
sif::debug << std::hex << dataPoolIt->first << std::dec << " |";
dataPoolIt->second->print();
dataPoolIt++;
}

View File

@ -215,7 +215,7 @@ ReturnValue_t DataPoolAdmin::handleParameterCommand(CommandMessage* command) {
ParameterMessage::getParameterId(command));
const uint8_t *storedStream;
uint32_t storedStreamSize;
size_t storedStreamSize;
result = storage->getData(ParameterMessage::getStoreId(command),
&storedStream, &storedStreamSize);
if (result != HasReturnvaluesIF::RETURN_OK) {

View File

@ -31,7 +31,7 @@ ReturnValue_t DataSet::read() {
state = DATA_SET_WAS_READ;
freeDataPoolLock();
} else {
error << "DataSet::read(): Call made in wrong position." << std::endl;
sif::error << "DataSet::read(): Call made in wrong position." << std::endl;
result = SET_WAS_ALREADY_READ;
}
return result;
@ -68,9 +68,9 @@ ReturnValue_t DataSet::commit() {
} else if (registeredVariables[count]->getDataPoolId()
!= PoolVariableIF::NO_PARAMETER) {
if (result != COMMITING_WITHOUT_READING) {
error
<< "DataSet::commit(): commit-without-read call made with non write-only variable."
<< std::endl;
sif::error <<
"DataSet::commit(): commit-without-read "
"call made with non write-only variable." << std::endl;
result = COMMITING_WITHOUT_READING;
}
}
@ -92,7 +92,7 @@ void DataSet::registerVariable(PoolVariableIF* variable) {
}
}
}
error
sif::error
<< "DataSet::registerVariable: failed. Either NULL, or set is full, or call made in wrong position."
<< std::endl;
return;

View File

@ -26,7 +26,7 @@ protected:
} else {
value = 0;
valid = false;
error << "PIDReader: read of PID 0x" << std::hex << parameterId
sif::error << "PIDReader: read of PID 0x" << std::hex << parameterId
<< std::dec << " failed." << std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}

View File

@ -46,9 +46,10 @@ uint8_t PoolEntry<T>::getValid() {
template <typename T>
void PoolEntry<T>::print() {
for (uint8_t size = 0; size < this->length; size++ ) {
debug << "| " << std::hex << (double)this->address[size] << (this->valid? " (valid) " : " (invalid) ");
sif::debug << "| " << std::hex << (double)this->address[size]
<< (this->valid? " (valid) " : " (invalid) ");
}
debug << std::dec << std::endl;
sif::debug << std::dec << std::endl;
}
template<typename T>

View File

@ -42,7 +42,7 @@ ReturnValue_t PoolRawAccess::read() {
} else {
//Error entry does not exist.
}
error << "PoolRawAccess: read of DP Variable 0x" << std::hex << dataPoolId
sif::error << "PoolRawAccess: read of DP Variable 0x" << std::hex << dataPoolId
<< std::dec << " failed." << std::endl;
valid = INVALID;
typeSize = 0;
@ -123,7 +123,7 @@ ReturnValue_t PoolRawAccess::setEntryFromBigEndian(const uint8_t* buffer,
#endif
return HasReturnvaluesIF::RETURN_OK;
} else {
error << "PoolRawAccess::setEntryFromBigEndian: Illegal sizes: Internal"
sif::error << "PoolRawAccess::setEntryFromBigEndian: Illegal sizes: Internal"
<< (uint32_t) typeSize << ", Requested: " << setSize
<< std::endl;
return INCORRECT_SIZE;

View File

@ -66,7 +66,7 @@ protected:
} else {
value = 0;
valid = false;
error << "PoolVariable: read of DP Variable 0x" << std::hex
sif::error << "PoolVariable: read of DP Variable 0x" << std::hex
<< dataPoolId << std::dec << " failed." << std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}

View File

@ -70,7 +70,7 @@ protected:
} else {
memset(this->value, 0, vector_size * sizeof(T));
error << "PoolVector: read of DP Variable 0x" << std::hex
sif::error << "PoolVector: read of DP Variable 0x" << std::hex
<< dataPoolId << std::dec << " failed." << std::endl;
this->valid = INVALID;
return HasReturnvaluesIF::RETURN_FAILED;

View File

@ -2,15 +2,16 @@
#include <framework/devicehandlers/ChildHandlerBase.h>
#include <framework/subsystem/SubsystemBase.h>
ChildHandlerBase::ChildHandlerBase(uint32_t ioBoardAddress,
object_id_t setObjectId, object_id_t deviceCommunication,
uint32_t maxDeviceReplyLen, uint8_t setDeviceSwitch,
uint32_t thermalStatePoolId, uint32_t thermalRequestPoolId,
uint32_t parent, FailureIsolationBase* customFdir, uint32_t cmdQueueSize) :
DeviceHandlerBase(ioBoardAddress, setObjectId, maxDeviceReplyLen,
setDeviceSwitch, deviceCommunication, thermalStatePoolId,
thermalRequestPoolId, (customFdir == NULL? &childHandlerFdir : customFdir), cmdQueueSize), parentId(
parent), childHandlerFdir(setObjectId) {
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),
parentId(parent), childHandlerFdir(setObjectId) {
}
ChildHandlerBase::~ChildHandlerBase() {

View File

@ -6,12 +6,12 @@
class ChildHandlerBase: public DeviceHandlerBase {
public:
ChildHandlerBase(uint32_t ioBoardAddress, object_id_t setObjectId,
object_id_t deviceCommunication, uint32_t maxDeviceReplyLen,
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 = NULL,
uint32_t cmdQueueSize = 20);
FailureIsolationBase* customFdir = nullptr,
size_t cmdQueueSize = 20);
virtual ~ChildHandlerBase();
virtual ReturnValue_t initialize();

View File

@ -1,10 +0,0 @@
#ifndef COOKIE_H_
#define COOKIE_H_
class Cookie{
public:
virtual ~Cookie(){}
};
#endif /* COOKIE_H_ */

34
devicehandlers/CookieIF.h Normal file
View File

@ -0,0 +1,34 @@
#ifndef COOKIE_H_
#define COOKIE_H_
#include <cstdint>
/**
* @brief Physical address type
*/
typedef std::uint32_t address_t;
/**
* @brief This datatype is used to identify different connection over a
* single interface (like RMAP or I2C)
* @details
* To use this class, implement a communication specific child cookie which
* inherits Cookie. Cookie instances are created in config/Factory.cpp by
* calling @code{.cpp} CookieIF* childCookie = new ChildCookie(...)
* @endcode .
*
* [not implemented yet]
* This cookie is then passed to the child device handlers, which stores the
* pointer and passes it to the communication interface functions.
*
* The cookie can be used to store all kinds of information
* about the communication, like slave addresses, communication status,
* communication parameters etc.
*
* @ingroup comm
*/
class CookieIF {
public:
virtual ~CookieIF() {};
};
#endif /* COOKIE_H_ */

View File

@ -1,63 +1,131 @@
#ifndef DEVICECOMMUNICATIONIF_H_
#define DEVICECOMMUNICATIONIF_H_
#include <framework/devicehandlers/Cookie.h>
#include <framework/devicehandlers/CookieIF.h>
#include <framework/returnvalues/HasReturnvaluesIF.h>
#include <cstddef>
/**
* @defgroup interfaces Interfaces
* @brief Interfaces for flight software objects
*/
/**
* @defgroup comm Communication
* @brief Communication software components.
*/
/**
* @brief This is an interface to decouple device communication from
* the device handler to allow reuse of these components.
* @details
* Documentation: Dissertation Baetz p.138.
* It works with the assumption that received data
* is polled by a component. There are four generic steps of device communication:
*
* 1. Send data to a device
* 2. Get acknowledgement for sending
* 3. Request reading data from a device
* 4. Read received data
*
* To identify different connection over a single interface can return
* so-called cookies to components.
* The CommunicationMessage message type can be used to extend the
* functionality of the ComIF if a separate polling task is required.
* @ingroup interfaces
* @ingroup comm
*/
class DeviceCommunicationIF: public HasReturnvaluesIF {
public:
static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_COMMUNICATION_IF;
static const ReturnValue_t INVALID_COOKIE_TYPE = MAKE_RETURN_CODE(0x01);
static const ReturnValue_t NOT_ACTIVE = MAKE_RETURN_CODE(0x02);
static const ReturnValue_t INVALID_ADDRESS = MAKE_RETURN_CODE(0x03);
static const ReturnValue_t TOO_MUCH_DATA = MAKE_RETURN_CODE(0x04);
static const ReturnValue_t NULLPOINTER = MAKE_RETURN_CODE(0x05);
static const ReturnValue_t PROTOCOL_ERROR = MAKE_RETURN_CODE(0x06);
static const ReturnValue_t CANT_CHANGE_REPLY_LEN = MAKE_RETURN_CODE(0x07);
//! Standard Error Codes
//! General protocol error. Define more concrete errors in child handler
static const ReturnValue_t PROTOCOL_ERROR = MAKE_RETURN_CODE(0x01);
//! If cookie is a null pointer
static const ReturnValue_t NULLPOINTER = MAKE_RETURN_CODE(0x02);
static const ReturnValue_t INVALID_COOKIE_TYPE = MAKE_RETURN_CODE(0x03);
// is this needed if there is no open/close call?
static const ReturnValue_t NOT_ACTIVE = MAKE_RETURN_CODE(0x05);
static const ReturnValue_t INVALID_ADDRESS = MAKE_RETURN_CODE(0x06);
static const ReturnValue_t TOO_MUCH_DATA = MAKE_RETURN_CODE(0x07);
static const ReturnValue_t CANT_CHANGE_REPLY_LEN = MAKE_RETURN_CODE(0x08);
virtual ~DeviceCommunicationIF() {
//! Can be used in readReceivedMessage() if no reply was received.
static const ReturnValue_t NO_REPLY_RECEIVED = MAKE_RETURN_CODE(0xA1);
}
virtual ~DeviceCommunicationIF() {}
virtual ReturnValue_t open(Cookie **cookie, uint32_t address,
uint32_t maxReplyLen) = 0;
/**
* Use an existing cookie to open a connection to a new DeviceCommunication.
* The previous connection must not be closed.
* If the returnvalue is not RETURN_OK, the cookie is unchanged and
* can be used with the previous connection.
* @brief Device specific initialization, using the cookie.
* @details
* The cookie is already prepared in the factory. If the communication
* interface needs to be set up in some way and requires cookie information,
* this can be performed in this function, which is called on device handler
* initialization.
* @param cookie
* @return
* - @c RETURN_OK if initialization was successfull
* - Everything else triggers failure event with returnvalue as parameter 1
*/
virtual ReturnValue_t initializeInterface(CookieIF * cookie) = 0;
/**
* Called by DHB in the SEND_WRITE doSendWrite().
* This function is used to send data to the physical device
* by implementing and calling related drivers or wrapper functions.
* @param cookie
* @param data
* @param len
* @return
* - @c RETURN_OK for successfull send
* - Everything else triggers failure event with returnvalue as parameter 1
*/
virtual ReturnValue_t sendMessage(CookieIF *cookie, const uint8_t * sendData,
size_t sendLen) = 0;
/**
* Called by DHB in the GET_WRITE doGetWrite().
* Get send confirmation that the data in sendMessage() was sent successfully.
* @param cookie
* @return - @c RETURN_OK if data was sent successfull
* - Everything else triggers falure event with
* returnvalue as parameter 1
*/
virtual ReturnValue_t getSendSuccess(CookieIF *cookie) = 0;
/**
* Called by DHB in the SEND_WRITE doSendRead().
* It is assumed that it is always possible to request a reply
* from a device. If a requestLen of 0 is supplied, no reply was enabled
* and communication specific action should be taken (e.g. read nothing
* or read everything).
*
* @param cookie
* @param address
* @param maxReplyLen
* @return
* @param requestLen Size of data to read
* @return - @c RETURN_OK to confirm the request for data has been sent.
* - Everything else triggers failure event with
* returnvalue as parameter 1
*/
virtual ReturnValue_t reOpen(Cookie *cookie, uint32_t address,
uint32_t maxReplyLen) = 0;
virtual void close(Cookie *cookie) = 0;
//SHOULDDO can data be const?
virtual ReturnValue_t sendMessage(Cookie *cookie, uint8_t *data,
uint32_t len) = 0;
virtual ReturnValue_t getSendSuccess(Cookie *cookie) = 0;
virtual ReturnValue_t requestReceiveMessage(Cookie *cookie) = 0;
virtual ReturnValue_t readReceivedMessage(Cookie *cookie, uint8_t **buffer,
uint32_t *size) = 0;
virtual ReturnValue_t setAddress(Cookie *cookie, uint32_t address) = 0;
virtual uint32_t getAddress(Cookie *cookie) = 0;
virtual ReturnValue_t setParameter(Cookie *cookie, uint32_t parameter) = 0;
virtual uint32_t getParameter(Cookie *cookie) = 0;
virtual ReturnValue_t requestReceiveMessage(CookieIF *cookie,
size_t requestLen) = 0;
/**
* Called by DHB in the GET_WRITE doGetRead().
* This function is used to receive data from the physical device
* by implementing and calling related drivers or wrapper functions.
* @param cookie
* @param buffer [out] Set reply here (by using *buffer = ...)
* @param size [out] size pointer to set (by using *size = ...).
* Set to 0 if no reply was received
* @return - @c RETURN_OK for successfull receive
* - @c NO_REPLY_RECEIVED if not reply was received. Setting size to
* 0 has the same effect
* - Everything else triggers failure event with
* returnvalue as parameter 1
*/
virtual ReturnValue_t readReceivedMessage(CookieIF *cookie, uint8_t **buffer,
size_t *size) = 0;
};
#endif /* DEVICECOMMUNICATIONIF_H_ */

View File

@ -1,52 +1,60 @@
#include <framework/datapool/DataSet.h>
#include <framework/datapool/PoolVariable.h>
#include <framework/datapool/PoolVector.h>
#include <framework/devicehandlers/AcceptsDeviceResponsesIF.h>
#include <framework/devicehandlers/DeviceHandlerBase.h>
#include <framework/devicehandlers/DeviceTmReportingWrapper.h>
#include <framework/globalfunctions/CRC.h>
#include <framework/objectmanager/ObjectManager.h>
#include <framework/storagemanager/StorageManagerIF.h>
#include <framework/subsystem/SubsystemBase.h>
#include <framework/thermal/ThermalComponentIF.h>
#include <framework/devicehandlers/AcceptsDeviceResponsesIF.h>
#include <framework/datapool/DataSet.h>
#include <framework/datapool/PoolVariable.h>
#include <framework/devicehandlers/DeviceTmReportingWrapper.h>
#include <framework/globalfunctions/CRC.h>
#include <framework/subsystem/SubsystemBase.h>
#include <framework/ipc/QueueFactory.h>
#include <framework/serviceinterface/ServiceInterfaceStream.h>
#include <iomanip>
object_id_t DeviceHandlerBase::powerSwitcherId = 0;
object_id_t DeviceHandlerBase::rawDataReceiverId = 0;
object_id_t DeviceHandlerBase::defaultFDIRParentId = 0;
DeviceHandlerBase::DeviceHandlerBase(uint32_t ioBoardAddress,
object_id_t setObjectId, uint32_t maxDeviceReplyLen,
uint8_t setDeviceSwitch, object_id_t deviceCommunication,
uint32_t thermalStatePoolId, uint32_t thermalRequestPoolId,
FailureIsolationBase* fdirInstance, uint32_t cmdQueueSize) :
SystemObject(setObjectId), rawPacket(0), rawPacketLen(0), mode(
MODE_OFF), submode(SUBMODE_NONE), pstStep(0), maxDeviceReplyLen(
maxDeviceReplyLen), wiretappingMode(OFF), defaultRawReceiver(0), storedRawData(
StorageManagerIF::INVALID_ADDRESS), requestedRawTraffic(0), powerSwitcher(
NULL), IPCStore(NULL), deviceCommunicationId(deviceCommunication), communicationInterface(
NULL), cookie(
NULL), commandQueue(NULL), deviceThermalStatePoolId(thermalStatePoolId), deviceThermalRequestPoolId(
thermalRequestPoolId), healthHelper(this, setObjectId), modeHelper(
this), parameterHelper(this), childTransitionFailure(RETURN_OK), ignoreMissedRepliesCount(
0), fdirInstance(fdirInstance), hkSwitcher(this), defaultFDIRUsed(
fdirInstance == NULL), switchOffWasReported(false),executingTask(NULL), actionHelper(this, NULL), cookieInfo(), ioBoardAddress(
ioBoardAddress), timeoutStart(0), childTransitionDelay(5000), transitionSourceMode(
_MODE_POWER_DOWN), transitionSourceSubMode(SUBMODE_NONE), deviceSwitch(
setDeviceSwitch) {
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) :
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) {
commandQueue = QueueFactory::instance()->createMessageQueue(cmdQueueSize,
CommandMessage::MAX_MESSAGE_SIZE);
cookieInfo.state = COOKIE_UNUSED;
insertInCommandMap(RAW_COMMAND_ID);
if (this->fdirInstance == NULL) {
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;
}
if (this->fdirInstance == nullptr) {
this->fdirInstance = new DeviceHandlerFailureIsolation(setObjectId,
defaultFDIRParentId);
}
}
DeviceHandlerBase::~DeviceHandlerBase() {
communicationInterface->close(cookie);
delete comCookie;
if (defaultFDIRUsed) {
delete fdirInstance;
}
@ -56,7 +64,7 @@ DeviceHandlerBase::~DeviceHandlerBase() {
ReturnValue_t DeviceHandlerBase::performOperation(uint8_t counter) {
this->pstStep = counter;
if (counter == 0) {
if (getComAction() == SEND_WRITE) {
cookieInfo.state = COOKIE_UNUSED;
readCommandQueue();
doStateMachine();
@ -64,11 +72,12 @@ ReturnValue_t DeviceHandlerBase::performOperation(uint8_t counter) {
decrementDeviceReplyMap();
fdirInstance->checkForFailures();
hkSwitcher.performOperation();
performOperationHook();
}
if (mode == MODE_OFF) {
return RETURN_OK;
}
switch (getRmapAction()) {
switch (getComAction()) {
case SEND_WRITE:
if ((cookieInfo.state == COOKIE_UNUSED)) {
buildInternalCommand();
@ -91,13 +100,91 @@ ReturnValue_t DeviceHandlerBase::performOperation(uint8_t counter) {
return RETURN_OK;
}
ReturnValue_t DeviceHandlerBase::initialize() {
ReturnValue_t result = SystemObject::initialize();
if (result != RETURN_OK) {
return result;
}
communicationInterface = objectManager->get<DeviceCommunicationIF>(
deviceCommunicationId);
if (communicationInterface == NULL) {
return RETURN_FAILED;
}
result = communicationInterface->initializeInterface(comCookie);
if (result != RETURN_OK) {
return result;
}
IPCStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
if (IPCStore == NULL) {
return RETURN_FAILED;
}
AcceptsDeviceResponsesIF *rawReceiver = objectManager->get<
AcceptsDeviceResponsesIF>(rawDataReceiverId);
if (rawReceiver == NULL) {
return RETURN_FAILED;
}
defaultRawReceiver = rawReceiver->getDeviceQueue();
powerSwitcher = objectManager->get<PowerSwitchIF>(powerSwitcherId);
if (powerSwitcher == NULL) {
return RETURN_FAILED;
}
result = healthHelper.initialize();
if (result != RETURN_OK) {
return result;
}
result = modeHelper.initialize();
if (result != RETURN_OK) {
return result;
}
result = actionHelper.initialize(commandQueue);
if (result != RETURN_OK) {
return result;
}
result = fdirInstance->initialize();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = parameterHelper.initialize();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = hkSwitcher.initialize();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
fillCommandAndReplyMap();
//Set temperature target state to NON_OP.
DataSet mySet;
PoolVariable<int8_t> thermalRequest(deviceThermalRequestPoolId, &mySet,
PoolVariableIF::VAR_WRITE);
mySet.read();
thermalRequest = ThermalComponentIF::STATE_REQUEST_NON_OPERATIONAL;
mySet.commit(PoolVariableIF::VALID);
return RETURN_OK;
}
void DeviceHandlerBase::decrementDeviceReplyMap() {
for (std::map<DeviceCommandId_t, DeviceReplyInfo>::iterator iter =
deviceReplyMap.begin(); iter != deviceReplyMap.end(); iter++) {
if (iter->second.delayCycles != 0) {
iter->second.delayCycles--;
if (iter->second.delayCycles == 0) {
if (iter->second.periodic != 0) {
if (iter->second.periodic) {
iter->second.delayCycles = iter->second.maxDelayCycles;
}
replyToReply(iter, TIMEOUT);
@ -256,55 +343,49 @@ ReturnValue_t DeviceHandlerBase::isModeCombinationValid(Mode_t mode,
}
}
ReturnValue_t DeviceHandlerBase::insertInCommandAndReplyMap(
DeviceCommandId_t deviceCommand, uint16_t maxDelayCycles,
uint8_t periodic, bool hasDifferentReplyId, DeviceCommandId_t replyId) {
//No need to check, as we may try to insert multiple times.
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) {
return insertInReplyMap(replyId, maxDelayCycles, periodic);
return insertInReplyMap(replyId, maxDelayCycles, replyLen, periodic);
} else {
return insertInReplyMap(deviceCommand, maxDelayCycles, periodic);
return insertInReplyMap(deviceCommand, maxDelayCycles, replyLen, periodic);
}
}
ReturnValue_t DeviceHandlerBase::insertInReplyMap(DeviceCommandId_t replyId,
uint16_t maxDelayCycles, uint8_t periodic) {
uint16_t maxDelayCycles, size_t replyLen, bool periodic) {
DeviceReplyInfo info;
info.maxDelayCycles = maxDelayCycles;
info.periodic = periodic;
info.delayCycles = 0;
info.replyLen = replyLen;
info.command = deviceCommandMap.end();
std::pair<std::map<DeviceCommandId_t, DeviceReplyInfo>::iterator, bool> returnValue;
returnValue = deviceReplyMap.insert(
std::pair<DeviceCommandId_t, DeviceReplyInfo>(replyId, info));
if (returnValue.second) {
auto resultPair = deviceReplyMap.emplace(replyId, info);
if (resultPair.second) {
return RETURN_OK;
} else {
return RETURN_FAILED;
}
}
ReturnValue_t DeviceHandlerBase::insertInCommandMap(
DeviceCommandId_t deviceCommand) {
ReturnValue_t DeviceHandlerBase::insertInCommandMap(DeviceCommandId_t deviceCommand) {
DeviceCommandInfo info;
info.expectedReplies = 0;
info.isExecuting = false;
info.sendReplyTo = NO_COMMANDER;
std::pair<std::map<DeviceCommandId_t, DeviceCommandInfo>::iterator, bool> returnValue;
returnValue = deviceCommandMap.insert(
std::pair<DeviceCommandId_t, DeviceCommandInfo>(deviceCommand,
info));
if (returnValue.second) {
auto resultPair = deviceCommandMap.emplace(deviceCommand, info);
if (resultPair.second) {
return RETURN_OK;
} else {
return RETURN_FAILED;
}
}
ReturnValue_t DeviceHandlerBase::updateReplyMapEntry(
DeviceCommandId_t deviceReply, uint16_t delayCycles,
uint16_t maxDelayCycles, uint8_t periodic) {
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()) {
@ -429,7 +510,7 @@ void DeviceHandlerBase::replyToReply(DeviceReplyMap::iterator iter,
void DeviceHandlerBase::doSendWrite() {
if (cookieInfo.state == COOKIE_WRITE_READY) {
ReturnValue_t result = communicationInterface->sendMessage(cookie,
ReturnValue_t result = communicationInterface->sendMessage(comCookie,
rawPacket, rawPacketLen);
if (result == RETURN_OK) {
@ -450,12 +531,14 @@ void DeviceHandlerBase::doGetWrite() {
return;
}
cookieInfo.state = COOKIE_UNUSED;
ReturnValue_t result = communicationInterface->getSendSuccess(cookie);
ReturnValue_t result = communicationInterface->getSendSuccess(comCookie);
if (result == RETURN_OK) {
if (wiretappingMode == RAW) {
replyRawData(rawPacket, rawPacketLen, requestedRawTraffic, true);
}
//We need to distinguish here, because a raw command never expects a reply. (Could be done in eRIRM, but then child implementations need to be careful.
//We need to distinguish here, because a raw command never expects a reply.
//(Could be done in eRIRM, but then child implementations need to be careful.
result = enableReplyInReplyMap(cookieInfo.pendingCommand);
} else {
//always generate a failure event, so that FDIR knows what's up
@ -471,7 +554,17 @@ void DeviceHandlerBase::doGetWrite() {
void DeviceHandlerBase::doSendRead() {
ReturnValue_t result;
result = communicationInterface->requestReceiveMessage(cookie);
size_t requestLen = 0;
if(cookieInfo.pendingCommand != deviceCommandMap.end()) {
DeviceReplyIter iter = deviceReplyMap.find(
cookieInfo.pendingCommand->first);
if(iter != deviceReplyMap.end()) {
requestLen = iter->second.replyLen;
}
}
result = communicationInterface->requestReceiveMessage(comCookie, requestLen);
if (result == RETURN_OK) {
cookieInfo.state = COOKIE_READ_SENT;
} else {
@ -485,10 +578,10 @@ void DeviceHandlerBase::doSendRead() {
}
void DeviceHandlerBase::doGetRead() {
uint32_t receivedDataLen;
size_t receivedDataLen;
uint8_t *receivedData;
DeviceCommandId_t foundId = 0xFFFFFFFF;
uint32_t foundLen = 0;
size_t foundLen = 0;
ReturnValue_t result;
if (cookieInfo.state != COOKIE_READ_SENT) {
@ -498,8 +591,8 @@ void DeviceHandlerBase::doGetRead() {
cookieInfo.state = COOKIE_UNUSED;
result = communicationInterface->readReceivedMessage(cookie, &receivedData,
&receivedDataLen);
result = communicationInterface->readReceivedMessage(comCookie,
&receivedData, &receivedDataLen);
if (result != RETURN_OK) {
triggerEvent(DEVICE_REQUESTING_REPLY_FAILED, result);
@ -508,7 +601,7 @@ void DeviceHandlerBase::doGetRead() {
return;
}
if (receivedDataLen == 0)
if (receivedDataLen == 0 or result == DeviceCommunicationIF::NO_REPLY_RECEIVED)
return;
if (wiretappingMode == RAW) {
@ -539,6 +632,8 @@ void DeviceHandlerBase::doGetRead() {
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);
@ -558,10 +653,10 @@ void DeviceHandlerBase::doGetRead() {
ReturnValue_t DeviceHandlerBase::getStorageData(store_address_t storageAddress,
uint8_t * *data, uint32_t * len) {
uint32_t lenTmp;
size_t lenTmp;
if (IPCStore == NULL) {
*data = NULL;
if (IPCStore == nullptr) {
*data = nullptr;
*len = 0;
return RETURN_FAILED;
}
@ -572,90 +667,10 @@ ReturnValue_t DeviceHandlerBase::getStorageData(store_address_t storageAddress,
} else {
triggerEvent(StorageManagerIF::GET_DATA_FAILED, result,
storageAddress.raw);
*data = NULL;
*data = nullptr;
*len = 0;
return result;
}
}
ReturnValue_t DeviceHandlerBase::initialize() {
ReturnValue_t result = SystemObject::initialize();
if (result != RETURN_OK) {
return result;
}
communicationInterface = objectManager->get<DeviceCommunicationIF>(
deviceCommunicationId);
if (communicationInterface == NULL) {
return RETURN_FAILED;
}
result = communicationInterface->open(&cookie, ioBoardAddress,
maxDeviceReplyLen);
if (result != RETURN_OK) {
return result;
}
IPCStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
if (IPCStore == NULL) {
return RETURN_FAILED;
}
AcceptsDeviceResponsesIF *rawReceiver = objectManager->get<
AcceptsDeviceResponsesIF>(rawDataReceiverId);
if (rawReceiver == NULL) {
return RETURN_FAILED;
}
defaultRawReceiver = rawReceiver->getDeviceQueue();
powerSwitcher = objectManager->get<PowerSwitchIF>(powerSwitcherId);
if (powerSwitcher == NULL) {
return RETURN_FAILED;
}
result = healthHelper.initialize();
if (result != RETURN_OK) {
return result;
}
result = modeHelper.initialize();
if (result != RETURN_OK) {
return result;
}
result = actionHelper.initialize(commandQueue);
if (result != RETURN_OK) {
return result;
}
result = fdirInstance->initialize();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = parameterHelper.initialize();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = hkSwitcher.initialize();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
fillCommandAndReplyMap();
//Set temperature target state to NON_OP.
DataSet mySet;
PoolVariable<int8_t> thermalRequest(deviceThermalRequestPoolId, &mySet,
PoolVariableIF::VAR_WRITE);
mySet.read();
thermalRequest = ThermalComponentIF::STATE_REQUEST_NON_OPERATIONAL;
mySet.commit(PoolVariableIF::VALID);
return RETURN_OK;
}
void DeviceHandlerBase::replyRawData(const uint8_t *data, size_t len,
@ -687,8 +702,7 @@ void DeviceHandlerBase::replyRawData(const uint8_t *data, size_t len,
}
//Default child implementations
DeviceHandlerBase::RmapAction_t DeviceHandlerBase::getRmapAction() {
DeviceHandlerIF::CommunicationAction_t DeviceHandlerBase::getComAction() {
switch (pstStep) {
case 0:
return SEND_WRITE;
@ -727,7 +741,7 @@ void DeviceHandlerBase::handleReply(const uint8_t* receivedData,
if (info->delayCycles != 0) {
if (info->periodic != 0) {
if (info->periodic) {
info->delayCycles = info->maxDelayCycles;
} else {
info->delayCycles = 0;
@ -748,20 +762,20 @@ void DeviceHandlerBase::handleReply(const uint8_t* receivedData,
}
}
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;
}
//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);
@ -1022,7 +1036,6 @@ void DeviceHandlerBase::replyRawReplyIfnotWiretapped(const uint8_t* data,
ReturnValue_t DeviceHandlerBase::handleDeviceHandlerMessage(
CommandMessage * message) {
ReturnValue_t result;
switch (message->getCommand()) {
case DeviceHandlerMessage::CMD_WIRETAPPING:
switch (DeviceHandlerMessage::getWiretappingMode(message)) {
@ -1044,19 +1057,19 @@ 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_IOBOARD);
}
}
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);
@ -1165,7 +1178,7 @@ void DeviceHandlerBase::buildInternalCommand(void) {
if (mode == MODE_NORMAL) {
result = buildNormalDeviceCommand(&deviceCommandId);
if (result == BUSY) {
debug << std::hex << getObjectId()
sif::debug << std::hex << getObjectId()
<< ": DHB::buildInternalCommand busy" << std::endl; //so we can track misconfigurations
result = NOTHING_TO_SEND; //no need to report this
}
@ -1186,7 +1199,7 @@ void DeviceHandlerBase::buildInternalCommand(void) {
if (iter == deviceCommandMap.end()) {
result = COMMAND_NOT_SUPPORTED;
} else if (iter->second.isExecuting) {
debug << std::hex << getObjectId()
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
@ -1270,3 +1283,9 @@ void DeviceHandlerBase::changeHK(Mode_t mode, Submode_t submode, bool enable) {
void DeviceHandlerBase::setTaskIF(PeriodicTaskIF* task_){
executingTask = task_;
}
// Default implementations empty.
void DeviceHandlerBase::debugInterface(uint8_t positionTracker,
object_id_t objectId, uint32_t parameter) {}
void DeviceHandlerBase::performOperationHook() {}

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,8 @@
#include <framework/ipc/MessageQueueSenderIF.h>
/**
* This is the Interface used to communicate with a device handler.
* @brief This is the Interface used to communicate with a device handler.
* @details Includes all expected return values, events and modes.
*
*/
class DeviceHandlerIF {
@ -22,93 +23,127 @@ public:
*
* @details The mode of the device handler must not be confused with the mode the device is in.
* The mode of the device itself is transparent to the user but related to the mode of the handler.
* MODE_ON and MODE_OFF are included in hasModesIF.h
*/
// MODE_ON = 0, //!< The device is powered and ready to perform operations. In this mode, no commands are sent by the device handler itself, but direct commands van be commanded and will be interpreted
// MODE_OFF = 1, //!< The device is powered off. The only command accepted in this mode is a mode change to on.
static const Mode_t MODE_NORMAL = 2; //!< The device is powered on and the device handler periodically sends commands. The commands to be sent are selected by the handler according to the submode.