diff --git a/devicehandlers/DeviceCommunicationIF.h b/devicehandlers/DeviceCommunicationIF.h index bb095116..20565025 100644 --- a/devicehandlers/DeviceCommunicationIF.h +++ b/devicehandlers/DeviceCommunicationIF.h @@ -1,5 +1,5 @@ -#ifndef DEVICECOMMUNICATIONIF_H_ -#define DEVICECOMMUNICATIONIF_H_ +#ifndef FRAMEWORK_DEVICES_DEVICECOMMUNICATIONIF_H_ +#define FRAMEWORK_DEVICES_DEVICECOMMUNICATIONIF_H_ #include #include @@ -19,8 +19,8 @@ * 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: + * 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 @@ -77,8 +77,8 @@ public: * - @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; + virtual ReturnValue_t sendMessage(CookieIF *cookie, + const uint8_t * sendData, size_t sendLen) = 0; /** * Called by DHB in the GET_WRITE doGetWrite(). @@ -103,7 +103,8 @@ public: * - Everything else triggers failure event with * returnvalue as parameter 1 */ - virtual ReturnValue_t requestReceiveMessage(CookieIF *cookie, size_t requestLen) = 0; + virtual ReturnValue_t requestReceiveMessage(CookieIF *cookie, + size_t requestLen) = 0; /** * Called by DHB in the GET_WRITE doGetRead(). @@ -119,8 +120,8 @@ public: * - Everything else triggers failure event with * returnvalue as parameter 1 */ - virtual ReturnValue_t readReceivedMessage(CookieIF *cookie, uint8_t **buffer, - size_t *size) = 0; + virtual ReturnValue_t readReceivedMessage(CookieIF *cookie, + uint8_t **buffer, size_t *size) = 0; }; #endif /* DEVICECOMMUNICATIONIF_H_ */ diff --git a/housekeeping/HousekeepingMessage.cpp b/housekeeping/HousekeepingMessage.cpp index 6dd1a711..d47fb92a 100644 --- a/housekeeping/HousekeepingMessage.cpp +++ b/housekeeping/HousekeepingMessage.cpp @@ -3,9 +3,25 @@ HousekeepingMessage::HousekeepingMessage(MessageQueueMessageIF* message): CommandMessageBase(message) { + if(message->getMaximumMessageSize() < HK_MESSAGE_SIZE) { + sif::error << "CommandMessage::ComandMessage: Passed message buffer" + " can not hold minimum "<< HK_MESSAGE_SIZE + << " bytes!" << std::endl; + return; + } + message->setMessageSize(HK_MESSAGE_SIZE); } -HousekeepingMessage::~HousekeepingMessage() { +HousekeepingMessage::~HousekeepingMessage() {} + +void HousekeepingMessage::setParameter(uint32_t parameter) { + std::memcpy(getData(), ¶meter, sizeof(parameter)); +} + +uint32_t HousekeepingMessage::getParameter() const { + uint32_t parameter; + std::memcpy(¶meter, getData(), sizeof(parameter)); + return parameter; } void HousekeepingMessage::setHkReportMessage(sid_t sid, @@ -15,32 +31,45 @@ void HousekeepingMessage::setHkReportMessage(sid_t sid, setParameter(storeId.raw); } +void HousekeepingMessage::setHkDiagnosticsMessage(sid_t sid, + store_address_t storeId) { + CommandMessageBase::setCommand(DIAGNOSTICS_REPORT); + setSid(sid); + setParameter(storeId.raw); +} + size_t HousekeepingMessage::getMinimumMessageSize() const { return HK_MESSAGE_SIZE; } -size_t HousekeepingMessage::getMaximumMessageSize() const { - return MessageQueueMessage::MAX_MESSAGE_SIZE; -} - -void HousekeepingMessage::clear() { - // clear IPC store where it is needed. -} - sid_t HousekeepingMessage::getSid() const { sid_t sid; std::memcpy(&sid.raw, CommandMessageBase::getData(), sizeof(sid.raw)); return sid; } -uint8_t* HousekeepingMessage::getData() { - return internalMessage->getBuffer() + sizeof(sid_t); -} -void HousekeepingMessage::setParameter(uint32_t parameter) { - memcpy(getData(), ¶meter, sizeof(parameter)); +sid_t HousekeepingMessage::getHkReportMessage( + store_address_t *storeIdToSet) const { + if(storeIdToSet != nullptr) { + *storeIdToSet = getParameter(); + } + return getSid(); } void HousekeepingMessage::setSid(sid_t sid) { std::memcpy(CommandMessageBase::getData(), &sid.raw, sizeof(sid.raw)); } + + +uint8_t* HousekeepingMessage::getData() { + return CommandMessageBase::getData() + sizeof(sid_t); +} + +const uint8_t* HousekeepingMessage::getData() const { + return CommandMessageBase::getData() + sizeof(sid_t); +} + +void HousekeepingMessage::clear() { + // clear IPC store where it is needed. +} diff --git a/housekeeping/HousekeepingMessage.h b/housekeeping/HousekeepingMessage.h index 4e9d4553..c5e31fda 100644 --- a/housekeeping/HousekeepingMessage.h +++ b/housekeeping/HousekeepingMessage.h @@ -27,14 +27,22 @@ union sid_t { }; +/** + * @brief Special command message type for housekeeping messages + * @details + * This message is slightly larger than regular command messages to accomodate + * the uint64_t structure ID (SID). + */ class HousekeepingMessage : public CommandMessageBase { public: static constexpr size_t HK_MESSAGE_SIZE = sizeof(MessageQueueId_t) + sizeof(Command_t) + sizeof(sid_t) * sizeof(uint32_t); + /** - * No instances of a message shall be created, instead - * a CommandMessage instance is manipulated. + * The HK message is initialized with a pointer to a message which holds + * the message data, see CommandMessageIF and getInternalMessage(). + * @param message */ HousekeepingMessage(MessageQueueMessageIF* message); virtual ~HousekeepingMessage(); @@ -85,18 +93,24 @@ public: static constexpr Command_t MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL = MAKE_COMMAND_ID(32); - void setHkReportMessage(sid_t sid, store_address_t storeId); void setParameter(uint32_t parameter); + uint32_t getParameter() const; + + void setHkReportMessage(sid_t sid, store_address_t storeId); + void setHkDiagnosticsMessage(sid_t sid, store_address_t storeId); + //! Get the respective SID and store ID. Command ID can be used beforehand + //! to distinguish between diagnostics and regular HK packets + sid_t getHkReportMessage(store_address_t * storeIdToSet) const; - virtual void clear() override; virtual size_t getMinimumMessageSize() const override; - virtual size_t getMaximumMessageSize() const override; - - virtual uint8_t* getData() override; + virtual void clear() override; private: sid_t getSid() const; void setSid(sid_t sid); + + virtual uint8_t* getData() override; + virtual const uint8_t* getData() const override; }; diff --git a/ipc/CommandMessage.cpp b/ipc/CommandMessage.cpp index 39290688..163a6a2d 100644 --- a/ipc/CommandMessage.cpp +++ b/ipc/CommandMessage.cpp @@ -10,31 +10,18 @@ CommandMessage::CommandMessage(MessageQueueMessageIF* receiverMessage): return; } if(receiverMessage->getMaximumMessageSize() < - MINIMUM_COMMAND_MESSAGE_SIZE) { + getMinimumMessageSize()) { sif::error << "CommandMessage::ComandMessage: Passed message buffer" " can not hold minimum "<< MINIMUM_COMMAND_MESSAGE_SIZE << " bytes!" << std::endl; return; } - internalMessage->setMessageSize(MINIMUM_COMMAND_MESSAGE_SIZE); + internalMessage->setMessageSize(getMinimumMessageSize()); } CommandMessage::CommandMessage(MessageQueueMessageIF* messageToSet, Command_t command, uint32_t parameter1, uint32_t parameter2): - CommandMessageBase(messageToSet) { - if(messageToSet == nullptr) { - sif::error << "CommandMessage::CommandMessage: Don't pass a nullptr" - " as the message queue message, pass the address of an actual" - " message!" << std::endl; - } - if(messageToSet->getMaximumMessageSize() < - MINIMUM_COMMAND_MESSAGE_SIZE) { - sif::error << "CommandMessage::ComandMessage: Passed message buffer" - " can not hold minimum "<< MINIMUM_COMMAND_MESSAGE_SIZE - << " bytes!" << std::endl; - return; - } - internalMessage->setMessageSize(MINIMUM_COMMAND_MESSAGE_SIZE); + CommandMessage(messageToSet) { setCommand(command); setParameter(parameter1); setParameter2(parameter2); @@ -66,10 +53,6 @@ size_t CommandMessage::getMinimumMessageSize() const { return MINIMUM_COMMAND_MESSAGE_SIZE; } -size_t CommandMessage::getMaximumMessageSize() const { - return MessageQueueMessage::MAX_MESSAGE_SIZE; -} - bool CommandMessage::isClearedCommandMessage() { return getCommand() == CMD_NONE; } diff --git a/ipc/CommandMessage.h b/ipc/CommandMessage.h index 72f39357..a09494c6 100644 --- a/ipc/CommandMessage.h +++ b/ipc/CommandMessage.h @@ -24,11 +24,11 @@ class CommandMessage: public CommandMessageBase { public: /** * This is the size of a message as it is seen by the MessageQueue. + * It can hold the CommandMessage header plus 2 4-byte parameters. * 14 of the 24 available MessageQueueMessage bytes are used. */ static const size_t MINIMUM_COMMAND_MESSAGE_SIZE = - MessageQueueMessage::HEADER_SIZE + sizeof(Command_t) + - 2 * sizeof(uint32_t); + CommandMessageIF::HEADER_SIZE + 2 * sizeof(uint32_t); /** * Default Constructor, does not initialize anything. @@ -55,8 +55,6 @@ public: /** MessageQueueMessageIF functions used for minimum size check. */ size_t getMinimumMessageSize() const override; - /** MessageQueueMessageIF functions used for maximum size check. */ - size_t getMaximumMessageSize() const override; /** * Get the first parameter of the message diff --git a/ipc/CommandMessageBase.cpp b/ipc/CommandMessageBase.cpp index 7085ab88..80f9d378 100644 --- a/ipc/CommandMessageBase.cpp +++ b/ipc/CommandMessageBase.cpp @@ -55,10 +55,18 @@ size_t CommandMessageBase::getMessageSize() const { return internalMessage->getMessageSize(); } +size_t CommandMessageBase::getMaximumMessageSize() const { + return internalMessage->getMaximumMessageSize(); +} + MessageQueueMessageIF* CommandMessageBase::getInternalMessage() const { return internalMessage; } +size_t CommandMessageBase::getMinimumMessageSize() const { + return MINIMUM_COMMAND_MESSAGE_BASE_SIZE; +} + void CommandMessageBase::setReplyRejected(ReturnValue_t reason, Command_t initialCommand) { std::memcpy(getData(), &reason, sizeof(reason)); diff --git a/ipc/CommandMessageBase.h b/ipc/CommandMessageBase.h index d2f24c7e..b237b68f 100644 --- a/ipc/CommandMessageBase.h +++ b/ipc/CommandMessageBase.h @@ -15,13 +15,21 @@ * size checks: * * 1. getMinimumMessageSize() - * 2. getMaximumMessageSize() * + * The maximum message size generally depends on the buffer size of the passed + * internal message. * Don't forget to set the message size of the passed message in the concrete * commandmessage implementation! */ class CommandMessageBase: public CommandMessageIF { public: + //! This minimum size is derived from the interface requirement to be able + //! to set a rejected reply, which contains a returnvalue and the initial + //! command. + static constexpr size_t MINIMUM_COMMAND_MESSAGE_BASE_SIZE = + CommandMessageIF::HEADER_SIZE + sizeof(ReturnValue_t) + + sizeof(Command_t); + CommandMessageBase(MessageQueueMessageIF* message); /** @@ -58,6 +66,12 @@ public: virtual void setMessageSize(size_t messageSize) override; virtual size_t getMessageSize() const override; + //! This depends on the maximum message size of the passed internal message. + virtual size_t getMaximumMessageSize() const override; + + //! Return the constant minimum message size. + virtual size_t getMinimumMessageSize() const override; + /** * A command message can be rejected and needs to offer a function * to set a rejected reply diff --git a/ipc/MutexHelper.h b/ipc/MutexHelper.h index 20760b32..c9579e9b 100644 --- a/ipc/MutexHelper.h +++ b/ipc/MutexHelper.h @@ -10,7 +10,7 @@ public: internalMutex(mutex) { ReturnValue_t status = mutex->lockMutex(timeoutMs); if(status == MutexIF::MUTEX_TIMEOUT) { - sif::error << "MutexHelper: Lock of mutex failed with timeout of" + sif::error << "MutexHelper: Lock of mutex failed with timeout of " << timeoutMs << " milliseconds!" << std::endl; } else if(status != HasReturnvaluesIF::RETURN_OK){