From 7b538e9750001a7b91a89fbde5a47f9b619674eb Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 12 Jun 2020 20:23:39 +0200 Subject: [PATCH] introduced command message base and command message IF --- housekeeping/HousekeepingMessage.cpp | 17 +--- housekeeping/HousekeepingMessage.h | 13 ++- ipc/CommandMessage.cpp | 128 +++++++++------------------ ipc/CommandMessage.h | 79 +++++------------ ipc/CommandMessageBase.cpp | 55 ++++++++++++ ipc/CommandMessageBase.h | 73 +++++++++++++++ ipc/CommandMessageIF.h | 25 ++++++ ipc/MessageQueueMessage.cpp | 4 + ipc/MessageQueueMessage.h | 3 +- ipc/MessageQueueMessageIF.h | 4 +- 10 files changed, 232 insertions(+), 169 deletions(-) create mode 100644 ipc/CommandMessageBase.cpp create mode 100644 ipc/CommandMessageBase.h create mode 100644 ipc/CommandMessageIF.h diff --git a/housekeeping/HousekeepingMessage.cpp b/housekeeping/HousekeepingMessage.cpp index c94a69d7..d9daf974 100644 --- a/housekeeping/HousekeepingMessage.cpp +++ b/housekeeping/HousekeepingMessage.cpp @@ -1,18 +1,7 @@ #include -HousekeepingMessage::HousekeepingMessage() { +HousekeepingMessage::HousekeepingMessage(MessageQueueMessage *message): + CommandMessageBase (message) {} -} +HousekeepingMessage::~HousekeepingMessage() {} -void HousekeepingMessage::setHkReportMessage() { -} - - -//void HousekeepingMessage::setAddHkReportStructMessage(CommandMessage *message, -// set_t setId, store_address_t packet) { -// message->setCommand(ADD_HK_REPORT_STRUCT); -// message->setParameter(setId); -// message->setParameter2(packet.raw); -//} - -//void Housekeeping diff --git a/housekeeping/HousekeepingMessage.h b/housekeeping/HousekeepingMessage.h index 3ba6f94d..d0cbd0eb 100644 --- a/housekeeping/HousekeepingMessage.h +++ b/housekeeping/HousekeepingMessage.h @@ -1,6 +1,8 @@ #ifndef FRAMEWORK_HK_HOUSEKEEPINGMESSAGE_H_ #define FRAMEWORK_HK_HOUSEKEEPINGMESSAGE_H_ -#include +#include +#include +#include #include #include @@ -23,15 +25,14 @@ union sid_t { }; -class HousekeepingMessage: public MessageQueueMessage { +class HousekeepingMessage : public CommandMessageBase { public: /** * No instances of a message shall be created, instead * a CommandMessage instance is manipulated. */ - HousekeepingMessage(); -// HousekeepingMessage(const HousekeepingMessage&) = delete; -// HousekeepingMessage operator=(const HousekeepingMessage &) = delete; + HousekeepingMessage(MessageQueueMessage* message); + virtual ~HousekeepingMessage(); static constexpr uint8_t MESSAGE_ID = messagetypes::HOUSEKEEPING; static constexpr Command_t ADD_HK_REPORT_STRUCT = @@ -78,8 +79,6 @@ public: static constexpr Command_t MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL = MAKE_COMMAND_ID(32); -// static void setAddHkReportStructMessage(CommandMessage* message, -// DevisetId, store_address_t packet); static void setHkReportMessage(); }; diff --git a/ipc/CommandMessage.cpp b/ipc/CommandMessage.cpp index 7d2ecc9b..8f53b77c 100644 --- a/ipc/CommandMessage.cpp +++ b/ipc/CommandMessage.cpp @@ -1,6 +1,7 @@ +#include + #include #include -#include #include #include #include @@ -8,82 +9,86 @@ #include #include -namespace messagetypes { -// Implemented in config. -void clearMissionMessage(CommandMessage* message); -} - - CommandMessage::CommandMessage(MessageQueueMessage* receiverMessage): - internalMessage(receiverMessage) { + CommandMessageBase(receiverMessage) { if(receiverMessage == nullptr) { sif::error << "CommandMessage::CommandMessage: Don't pass a nullptr" " as the message queue message, pass the address of an actual" " message!" << std::endl; } - internalMessage->messageSize = COMMAND_MESSAGE_SIZE; + internalMessage->setMessageSize(COMMAND_MESSAGE_SIZE); setCommand(CMD_NONE); } CommandMessage::CommandMessage(MessageQueueMessage* messageToSet, Command_t command, uint32_t parameter1, uint32_t parameter2): - internalMessage(messageToSet) { + 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; } - internalMessage->messageSize = COMMAND_MESSAGE_SIZE; + internalMessage->setMessageSize(COMMAND_MESSAGE_SIZE); setCommand(command); setParameter(parameter1); setParameter2(parameter2); } -Command_t CommandMessage::getCommand() const { - Command_t command; - memcpy(&command, internalMessage->getData(), sizeof(Command_t)); - return command; -} - -uint8_t CommandMessage::getMessageType() const { - return getCommand() >> 8 & 0xff; -} - -void CommandMessage::setCommand(Command_t command) { - memcpy(internalMessage->getData(), &command, sizeof(command)); -} - uint32_t CommandMessage::getParameter() const { uint32_t parameter1; - memcpy(¶meter1, internalMessage->getData() + sizeof(Command_t), - sizeof(parameter1)); + memcpy(¶meter1, CommandMessageBase::getData(), sizeof(parameter1)); return parameter1; } void CommandMessage::setParameter(uint32_t parameter1) { - memcpy(internalMessage->getData() + sizeof(Command_t), - ¶meter1, sizeof(parameter1)); + memcpy(CommandMessageBase::getData(), ¶meter1, sizeof(parameter1)); } uint32_t CommandMessage::getParameter2() const { uint32_t parameter2; - memcpy(¶meter2, internalMessage->getData() + sizeof(Command_t) - + sizeof(uint32_t), sizeof(parameter2)); + memcpy(¶meter2, CommandMessageBase::getData() + sizeof(uint32_t), + sizeof(parameter2)); return parameter2; } void CommandMessage::setParameter2(uint32_t parameter2) { - memcpy(internalMessage-> getData() + sizeof(Command_t) + sizeof(uint32_t), - ¶meter2, sizeof(parameter2)); + memcpy(CommandMessageBase::getData() + sizeof(uint32_t), ¶meter2, + sizeof(parameter2)); } +size_t CommandMessage::getMinimumMessageSize() const { + return COMMAND_MESSAGE_SIZE; +} + +size_t CommandMessage::getMaximumMessageSize() const { + return MessageQueueMessage::MAX_MESSAGE_SIZE; +} + +bool CommandMessage::isClearedCommandMessage() { + return getCommand() == CMD_NONE; +} + +void CommandMessage::setToUnknownCommand() { + Command_t initialCommand = getCommand(); + clearCommandMessage(); + setReplyRejected(UNKNOWN_COMMAND, initialCommand); +} + +void CommandMessage::setReplyRejected(ReturnValue_t reason, + Command_t initialCommand) { + setCommand(REPLY_REJECTED); + setParameter(reason); + setParameter2(initialCommand); +} + + void CommandMessage::clear() { clearCommandMessage(); } void CommandMessage::clearCommandMessage() { - switch(getMessageType()){ - case messagetypes::MODE_COMMAND: + switch(this->getMessageType()){ + case messagetypes::MODE_COMMAND: ModeMessage::clear(this); break; case messagetypes::HEALTH_COMMAND: @@ -115,56 +120,3 @@ void CommandMessage::clearCommandMessage() { break; } } - -bool CommandMessage::isClearedCommandMessage() { - return getCommand() == CMD_NONE; -} - -size_t CommandMessage::getMinimumMessageSize() const { - return COMMAND_MESSAGE_SIZE; -} - -void CommandMessage::setToUnknownCommand() { - Command_t initialCommand = getCommand(); - clearCommandMessage(); - setReplyRejected(UNKNOWN_COMMAND, initialCommand); -} - -void CommandMessage::setReplyRejected(ReturnValue_t reason, - Command_t initialCommand) { - setCommand(REPLY_REJECTED); - setParameter(reason); - setParameter2(initialCommand); -} - -MessageQueueId_t CommandMessage::getSender() const { - return internalMessage->getSender(); -} - -uint8_t* CommandMessage::getBuffer() { - return internalMessage->getBuffer(); -} - -void CommandMessage::setSender(MessageQueueId_t setId) { - internalMessage->setSender(setId); -} - -const uint8_t* CommandMessage::getBuffer() const { - return internalMessage->getBuffer(); -} - -uint8_t* CommandMessage::getData() { - return internalMessage->getData(); -} - -const uint8_t* CommandMessage::getData() const { - return internalMessage->getData(); -} - -size_t CommandMessage::getMessageSize() const { - return COMMAND_MESSAGE_SIZE; -} - -size_t CommandMessage::getMaximumMessageSize() const { - return MessageQueueMessage::MAX_MESSAGE_SIZE; -} diff --git a/ipc/CommandMessage.h b/ipc/CommandMessage.h index 25d608f0..434f8c8c 100644 --- a/ipc/CommandMessage.h +++ b/ipc/CommandMessage.h @@ -1,33 +1,35 @@ #ifndef FRAMEWORK_IPC_COMMANDMESSAGE_H_ #define FRAMEWORK_IPC_COMMANDMESSAGE_H_ +#include #include #include -#include - - -#define MAKE_COMMAND_ID( number ) ((MESSAGE_ID << 8) + (number)) -typedef uint16_t Command_t; +namespace messagetypes { +// Implemented in config. +void clearMissionMessage(CommandMessageIF* message); +} /** - * @brief Used to pass command messages between tasks. Primary message type - * for IPC. Contains sender, 2-byte command field, and 2 4-byte - * parameters. + * @brief Default command message used to pass command messages between tasks. + * Primary message type for IPC. Contains sender, 2-byte command ID + * field, and 2 4-byte parameters. * @details * It operates on an external memory which is contained inside a - * MessageQueueMessage by taking its address. + * class implementing MessageQueueMessageIF by taking its address. * This allows for a more flexible designs of message implementations. * The pointer can be passed to different message implementations without * the need of unnecessary copying. + * + * The command message is based of the generic MessageQueueMessage which + * currently has an internal message size of 28 bytes. * @author Bastian Baetz */ -class CommandMessage: public MessageQueueMessageIF { +class CommandMessage: public CommandMessageBase { public: static const uint8_t INTERFACE_ID = CLASS_ID::COMMAND_MESSAGE; static const ReturnValue_t UNKNOWN_COMMAND = MAKE_RETURN_CODE(0x01); - static const uint8_t MESSAGE_ID = messagetypes::COMMAND; //! Used internally, will be ignored static const Command_t CMD_NONE = MAKE_COMMAND_ID( 0 ); @@ -66,39 +68,11 @@ public: */ virtual ~CommandMessage() {} - /** - * Read the DeviceHandlerCommand_t that is stored in the message, - * usually used after receiving. - * - * @return the Command stored in the Message - */ - Command_t getCommand() const; - - /* - * MessageQueueMessageIF functions, which generally just call the - * respective functions of the internal message - */ - uint8_t * getBuffer() override; - const uint8_t * getBuffer() const override; - void setSender(MessageQueueId_t setId) override; - MessageQueueId_t getSender() const override; - uint8_t * getData() override; - const uint8_t* getData() const override; + /** MessageQueueMessageIF functions used for minimum size check. */ size_t getMinimumMessageSize() const override; - size_t getMessageSize() const override; + /** MessageQueueMessageIF functions used for maximum size check. */ size_t getMaximumMessageSize() const override; - /** - * Extract message ID, which is the first byte of the command ID. - * @return - */ - uint8_t getMessageType() const; - /** - * Set the command type of the message - * @param the Command to be sent - */ - void setCommand(Command_t command); - /** * Get the first parameter of the message * @return the first Parameter of the message @@ -123,19 +97,17 @@ public: */ void setParameter2(uint32_t parameter2); + void clear() override; /** - * Set the command to CMD_NONE and try to find - * the correct class to handle a more detailed - * clear. - * Also, calls a mission-specific clearMissionMessage - * function to separate between framework and mission - * messages. Not optimal, may be replaced by totally - * different auto-delete solution (e.g. smart pointers). + * Set the command to CMD_NONE and try to find the correct class to handle + * a more detailed clear. + * Also, calls a mission-specific clearMissionMessage function to separate + * between framework and mission messages. Not optimal, may be replaced by + * totally different auto-delete solution (e.g. smart pointers). * */ void clearCommandMessage(); - void clear() override; /** * check if a message was cleared @@ -151,15 +123,6 @@ public: void setToUnknownCommand(); void setReplyRejected(ReturnValue_t reason, Command_t initialCommand = CMD_NONE); - -private: - /** - * @brief Pointer to the message containing the data. - * @details - * The command message does not actually own the memory containing a - * message, it just oprates on it via a pointer to a message queue message. - */ - MessageQueueMessage* internalMessage; }; diff --git a/ipc/CommandMessageBase.cpp b/ipc/CommandMessageBase.cpp new file mode 100644 index 00000000..aa84bd1e --- /dev/null +++ b/ipc/CommandMessageBase.cpp @@ -0,0 +1,55 @@ +#include +#include + +CommandMessageBase::CommandMessageBase(MessageQueueMessageIF *message): + internalMessage(message) { +} + +Command_t CommandMessageBase::getCommand() const { + Command_t command; + std::memcpy(&command, internalMessage->getData(), sizeof(Command_t)); + return command; +} + +void CommandMessageBase::setCommand(Command_t command) { + std::memcpy(internalMessage->getData(), &command, sizeof(command)); +} + +uint8_t CommandMessageBase::getMessageType() const { + // first byte of command ID. + return getCommand() >> 8 & 0xff; +} + +MessageQueueId_t CommandMessageBase::getSender() const { + return internalMessage->getSender(); +} + +uint8_t* CommandMessageBase::getBuffer() { + return internalMessage->getBuffer(); +} + +void CommandMessageBase::setSender(MessageQueueId_t setId) { + internalMessage->setSender(setId); +} + +const uint8_t* CommandMessageBase::getBuffer() const { + return internalMessage->getBuffer(); +} + +// Header includes command ID. +uint8_t* CommandMessageBase::getData() { + return internalMessage->getData() + sizeof(Command_t); +} + +// Header includes command ID. +const uint8_t* CommandMessageBase::getData() const { + return internalMessage->getData() + sizeof(Command_t); +} + +void CommandMessageBase::setMessageSize(size_t messageSize) { + internalMessage->setMessageSize(messageSize); +} + +size_t CommandMessageBase::getMessageSize() const { + return internalMessage->getMessageSize(); +} diff --git a/ipc/CommandMessageBase.h b/ipc/CommandMessageBase.h new file mode 100644 index 00000000..fa3fd477 --- /dev/null +++ b/ipc/CommandMessageBase.h @@ -0,0 +1,73 @@ +#ifndef FRAMEWORK_IPC_COMMANDMESSAGEBASE_H_ +#define FRAMEWORK_IPC_COMMANDMESSAGEBASE_H_ +#include +#include + +/** + * @brief Base implementation of a generic command message, which has + * a Command_t ID and message type ID in the header in addition + * to the sender message queue ID. + * @details + * This is the base implementation serves as a base for other command messages + * and which implements most functions required for MessageQueueMessageIF. + * The only functions which have to be supplied by a specific command message + * impelementations are the size related functions which are used for + * size checks: + * + * 1. getMinimumMessageSize() + * 2. getMaximumMessageSize() + * + * Don't forget to set the message size of the passed message in the concrete + * commandmessage implementation! + */ +class CommandMessageBase: public CommandMessageIF { +public: + CommandMessageBase(MessageQueueMessageIF* message); + + /** + * Read the DeviceHandlerCommand_t that is stored in the message, + * usually used after receiving. + * + * @return the Command stored in the Message + */ + virtual Command_t getCommand() const override; + /** + * Set the command type of the message. Default implementation also + * sets the message type, which will be the first byte of the command ID. + * @param the Command to be sent + */ + virtual void setCommand(Command_t command); + + /** + * Extract message ID, which is the first byte of the command ID for the + * default implementation. + * @return + */ + virtual uint8_t getMessageType() const override; + + /* + * MessageQueueMessageIF functions, which generally just call the + * respective functions of the internal message queue message. + */ + virtual uint8_t * getBuffer() override; + virtual const uint8_t * getBuffer() const override; + virtual void setSender(MessageQueueId_t setId) override; + virtual MessageQueueId_t getSender() const override; + virtual uint8_t * getData() override; + virtual const uint8_t* getData() const override; + virtual void setMessageSize(size_t messageSize) override; + virtual size_t getMessageSize() const override; + +protected: + /** + * @brief Pointer to the message containing the data. + * @details + * The command message does not actually own the memory containing a + * message, it just oprates on it via a pointer to a message queue message. + */ + MessageQueueMessageIF* internalMessage; +}; + + + +#endif /* FRAMEWORK_IPC_COMMANDMESSAGEBASE_H_ */ diff --git a/ipc/CommandMessageIF.h b/ipc/CommandMessageIF.h new file mode 100644 index 00000000..fbc40f88 --- /dev/null +++ b/ipc/CommandMessageIF.h @@ -0,0 +1,25 @@ +#ifndef FRAMEWORK_IPC_COMMANDMESSAGEIF_H_ +#define FRAMEWORK_IPC_COMMANDMESSAGEIF_H_ + +#include + +#define MAKE_COMMAND_ID( number ) ((MESSAGE_ID << 8) + (number)) +typedef uint16_t Command_t; + +class CommandMessageIF: public MessageQueueMessageIF { +public: + virtual ~CommandMessageIF() {}; + + /** + * A command message shall have a uint16_t command ID field. + * @return + */ + virtual Command_t getCommand() const = 0; + /** + * A command message shall have a uint8_t message type ID field. + * @return + */ + virtual uint8_t getMessageType() const = 0; +}; + +#endif /* FRAMEWORK_IPC_COMMANDMESSAGEIF_H_ */ diff --git a/ipc/MessageQueueMessage.cpp b/ipc/MessageQueueMessage.cpp index 8430a8ea..b173f2c4 100644 --- a/ipc/MessageQueueMessage.cpp +++ b/ipc/MessageQueueMessage.cpp @@ -75,3 +75,7 @@ size_t MessageQueueMessage::getMessageSize() const { size_t MessageQueueMessage::getMaximumMessageSize() const { return this->MAX_MESSAGE_SIZE; } + +void MessageQueueMessage::setMessageSize(size_t messageSize) { + this->messageSize = messageSize; +} diff --git a/ipc/MessageQueueMessage.h b/ipc/MessageQueueMessage.h index 31a43f66..2eb1f4f5 100644 --- a/ipc/MessageQueueMessage.h +++ b/ipc/MessageQueueMessage.h @@ -3,7 +3,7 @@ #include #include -#include +#include /** * @brief This class is the representation and data organizer @@ -150,6 +150,7 @@ public: virtual size_t getMinimumMessageSize() const override; virtual size_t getMessageSize() const override; + virtual void setMessageSize(size_t messageSize) override; virtual size_t getMaximumMessageSize() const override; diff --git a/ipc/MessageQueueMessageIF.h b/ipc/MessageQueueMessageIF.h index 05330ce9..f34cab98 100644 --- a/ipc/MessageQueueMessageIF.h +++ b/ipc/MessageQueueMessageIF.h @@ -24,7 +24,8 @@ public: /** * @brief With this method, the whole content and the message - * size is set to zero. + * size is set to zero. Implementations should also take care + * to clear data which is stored indirectly (e.g. storage data). */ virtual void clear() = 0; @@ -77,6 +78,7 @@ public: * @return */ virtual size_t getMessageSize() const = 0; + virtual void setMessageSize(size_t messageSize) = 0; /** * Get maximum allowed size of current message implementation.