diff --git a/CHANGELOG.md b/CHANGELOG.md index 85f6ef282..2091ed75d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - `oneShotAction` flag in the `TestTask` class is not static anymore - HAL Linux Uart: Baudrate and bits per word are enums now, avoiding misconfigurations PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/585 +- IPC Message Queue Handling: Allow passing an optional `MqArgs` argument into the MessageQueue + creation call. It allows passing context information and an arbitrary user argument into + the message queue. Also streamlined and simplified `MessageQueue` implementation for all OSALs + PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/583 ## Removed diff --git a/src/fsfw/ipc/CMakeLists.txt b/src/fsfw/ipc/CMakeLists.txt index 6a3afe33e..3bfe510dd 100644 --- a/src/fsfw/ipc/CMakeLists.txt +++ b/src/fsfw/ipc/CMakeLists.txt @@ -1,6 +1,6 @@ -target_sources(${LIB_FSFW_NAME} - PRIVATE - CommandMessage.cpp - CommandMessageCleaner.cpp - MessageQueueMessage.cpp +target_sources(${LIB_FSFW_NAME} PRIVATE + CommandMessage.cpp + CommandMessageCleaner.cpp + MessageQueueMessage.cpp + MessageQueueBase.cpp ) \ No newline at end of file diff --git a/src/fsfw/ipc/MessageQueueBase.cpp b/src/fsfw/ipc/MessageQueueBase.cpp new file mode 100644 index 000000000..1b0934ff3 --- /dev/null +++ b/src/fsfw/ipc/MessageQueueBase.cpp @@ -0,0 +1,64 @@ +#include "MessageQueueBase.h" + +MessageQueueBase::MessageQueueBase(MessageQueueId_t id, MessageQueueId_t defaultDest, + MqArgs* args): id(id) { + this->defaultDest = defaultDest; + if(args != nullptr) { + this->args = *args; + } +} + +MessageQueueBase::~MessageQueueBase() {} + +ReturnValue_t MessageQueueBase::sendToDefault(MessageQueueMessageIF* message) { + return sendToDefaultFrom(message, this->getId(), false); +} + +ReturnValue_t MessageQueueBase::reply(MessageQueueMessageIF* message) { + if (this->last != MessageQueueIF::NO_QUEUE) { + return sendMessageFrom(this->last, message, this->getId()); + } else { + return NO_REPLY_PARTNER; + } +} + +ReturnValue_t MessageQueueBase::receiveMessage(MessageQueueMessageIF* message, + MessageQueueId_t* receivedFrom) { + ReturnValue_t status = this->receiveMessage(message); + *receivedFrom = this->last; + return status; +} + +MessageQueueId_t MessageQueueBase::getLastPartner() const { + return last; +} + +MessageQueueId_t MessageQueueBase::getId() const { + return id; +} + +MqArgs& MessageQueueBase::getMqArgs() { + return args; +} + +void MessageQueueBase::setDefaultDestination(MessageQueueId_t defaultDestination) { + this->defaultDest = defaultDestination; +} + +MessageQueueId_t MessageQueueBase::getDefaultDestination() const { + return defaultDest; +} + +bool MessageQueueBase::isDefaultDestinationSet() const { + return (defaultDest != NO_QUEUE); +} + +ReturnValue_t MessageQueueBase::sendMessage(MessageQueueId_t sendTo, MessageQueueMessageIF* message, + bool ignoreFault) { + return sendMessageFrom(sendTo, message, this->getId(), false); +} + +ReturnValue_t MessageQueueBase::sendToDefaultFrom(MessageQueueMessageIF* message, + MessageQueueId_t sentFrom, bool ignoreFault) { + return sendMessageFrom(defaultDest, message, sentFrom, ignoreFault); +} diff --git a/src/fsfw/ipc/MessageQueueBase.h b/src/fsfw/ipc/MessageQueueBase.h new file mode 100644 index 000000000..8313f69ac --- /dev/null +++ b/src/fsfw/ipc/MessageQueueBase.h @@ -0,0 +1,41 @@ +#ifndef FSFW_SRC_FSFW_IPC_MESSAGEQUEUEBASE_H_ +#define FSFW_SRC_FSFW_IPC_MESSAGEQUEUEBASE_H_ + +#include +#include + +class MessageQueueBase: public MessageQueueIF { +public: + MessageQueueBase(MessageQueueId_t id, MessageQueueId_t defaultDest, MqArgs* mqArgs); + virtual ~MessageQueueBase(); + + // Default implementations for MessageQueueIF where possible + virtual MessageQueueId_t getLastPartner() const override; + virtual MessageQueueId_t getId() const override; + virtual MqArgs& getMqArgs() override; + virtual void setDefaultDestination(MessageQueueId_t defaultDestination) override; + virtual MessageQueueId_t getDefaultDestination() const override; + virtual bool isDefaultDestinationSet() const override; + virtual ReturnValue_t sendMessage(MessageQueueId_t sendTo, MessageQueueMessageIF* message, + bool ignoreFault) override; + virtual ReturnValue_t sendToDefault(MessageQueueMessageIF* message) override; + virtual ReturnValue_t reply(MessageQueueMessageIF* message) override; + virtual ReturnValue_t receiveMessage(MessageQueueMessageIF* message, + MessageQueueId_t* receivedFrom) override; + virtual ReturnValue_t sendToDefaultFrom(MessageQueueMessageIF* message, + MessageQueueId_t sentFrom, bool ignoreFault = false) override; + + // OSAL specific, forward the abstract function + virtual ReturnValue_t receiveMessage(MessageQueueMessageIF* message) = 0; + virtual ReturnValue_t sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message, + MessageQueueId_t sentFrom, bool ignoreFault = false) = 0; +protected: + MessageQueueId_t id = MessageQueueIF::NO_QUEUE; + MessageQueueId_t last = MessageQueueIF::NO_QUEUE; + MessageQueueId_t defaultDest = MessageQueueIF::NO_QUEUE; + MqArgs args = {}; +}; + + + +#endif /* FSFW_SRC_FSFW_IPC_MESSAGEQUEUEBASE_H_ */ diff --git a/src/fsfw/ipc/MessageQueueIF.h b/src/fsfw/ipc/MessageQueueIF.h index 9aef58b78..d7b6889b6 100644 --- a/src/fsfw/ipc/MessageQueueIF.h +++ b/src/fsfw/ipc/MessageQueueIF.h @@ -1,6 +1,7 @@ #ifndef FSFW_IPC_MESSAGEQUEUEIF_H_ #define FSFW_IPC_MESSAGEQUEUEIF_H_ +#include #include #include "../returnvalues/HasReturnvaluesIF.h" @@ -44,8 +45,7 @@ class MessageQueueIF { virtual ReturnValue_t reply(MessageQueueMessageIF* message) = 0; /** - * @brief This function reads available messages from the message queue - * and returns the sender. + * @brief This function reads available messages from the message queue and returns the sender. * @details * It works identically to the other receiveMessage call, but in addition * returns the sender's queue id. @@ -78,19 +78,16 @@ class MessageQueueIF { */ virtual ReturnValue_t flush(uint32_t* count) = 0; /** - * @brief This method returns the message queue - * id of the last communication partner. + * @brief This method returns the message queue ID of the last communication partner. */ virtual MessageQueueId_t getLastPartner() const = 0; /** - * @brief This method returns the message queue - * id of this class's message queue. + * @brief This method returns the message queue ID of this class's message queue. */ virtual MessageQueueId_t getId() const = 0; /** - * @brief With the sendMessage call, a queue message - * is sent to a receiving queue. + * @brief With the sendMessage call, a queue message is sent to a receiving queue. * @details * This method takes the message provided, adds the sentFrom information * and passes it on to the destination provided with an operating system @@ -129,8 +126,7 @@ class MessageQueueIF { bool ignoreFault = false) = 0; /** - * @brief The sendToDefaultFrom method sends a queue message - * to the default destination. + * @brief The sendToDefaultFrom method sends a queue message to the default destination. * @details * In all other aspects, it works identical to the sendMessage method. * @param message @@ -164,6 +160,8 @@ class MessageQueueIF { virtual MessageQueueId_t getDefaultDestination() const = 0; virtual bool isDefaultDestinationSet() const = 0; + + virtual MqArgs& getMqArgs() = 0; }; #endif /* FSFW_IPC_MESSAGEQUEUEIF_H_ */ diff --git a/src/fsfw/ipc/QueueFactory.h b/src/fsfw/ipc/QueueFactory.h index 864c456d4..8069d8369 100644 --- a/src/fsfw/ipc/QueueFactory.h +++ b/src/fsfw/ipc/QueueFactory.h @@ -5,6 +5,7 @@ #include "MessageQueueIF.h" #include "MessageQueueMessage.h" +#include "definitions.h" /** * Creates message queues. @@ -22,7 +23,8 @@ class QueueFactory { static QueueFactory* instance(); MessageQueueIF* createMessageQueue(uint32_t messageDepth = 3, - size_t maxMessageSize = MessageQueueMessage::MAX_MESSAGE_SIZE); + size_t maxMessageSize = MessageQueueMessage::MAX_MESSAGE_SIZE, + MqArgs* args = nullptr); void deleteMessageQueue(MessageQueueIF* queue); diff --git a/src/fsfw/ipc/definitions.h b/src/fsfw/ipc/definitions.h new file mode 100644 index 000000000..150502bbe --- /dev/null +++ b/src/fsfw/ipc/definitions.h @@ -0,0 +1,14 @@ +#ifndef FSFW_SRC_FSFW_IPC_DEFINITIONS_H_ +#define FSFW_SRC_FSFW_IPC_DEFINITIONS_H_ + +#include +#include + +struct MqArgs { + MqArgs(){}; + MqArgs(object_id_t objectId, void* args = nullptr) : objectId(objectId), args(args) {} + object_id_t objectId = objects::NO_OBJECT; + void* args = nullptr; +}; + +#endif /* FSFW_SRC_FSFW_IPC_DEFINITIONS_H_ */ diff --git a/src/fsfw/osal/freertos/MessageQueue.cpp b/src/fsfw/osal/freertos/MessageQueue.cpp index a8333fe55..d1a7f691c 100644 --- a/src/fsfw/osal/freertos/MessageQueue.cpp +++ b/src/fsfw/osal/freertos/MessageQueue.cpp @@ -4,8 +4,9 @@ #include "fsfw/osal/freertos/QueueMapManager.h" #include "fsfw/serviceinterface/ServiceInterface.h" -MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize) - : maxMessageSize(maxMessageSize) { +MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize, MqArgs* args) + : MessageQueueBase(MessageQueueIF::NO_QUEUE, MessageQueueIF::NO_QUEUE, args), + maxMessageSize(maxMessageSize) { handle = xQueueCreate(messageDepth, maxMessageSize); if (handle == nullptr) { #if FSFW_CPP_OSTREAM_ENABLED == 1 @@ -15,10 +16,10 @@ MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize) #else sif::printError("MessageQueue::MessageQueue: Creation failed\n"); sif::printError("Specified Message Depth: %d\n", messageDepth); - sif::printError("Specified MAximum Message Size: %d\n", maxMessageSize); + sif::printError("Specified Maximum Message Size: %d\n", maxMessageSize); #endif } - QueueMapManager::instance()->addMessageQueue(handle, &queueId); + QueueMapManager::instance()->addMessageQueue(handle, &id); } MessageQueue::~MessageQueue() { @@ -29,28 +30,6 @@ MessageQueue::~MessageQueue() { void MessageQueue::switchSystemContext(CallContext callContext) { this->callContext = callContext; } -ReturnValue_t MessageQueue::sendMessage(MessageQueueId_t sendTo, MessageQueueMessageIF* message, - bool ignoreFault) { - return sendMessageFrom(sendTo, message, this->getId(), ignoreFault); -} - -ReturnValue_t MessageQueue::sendToDefault(MessageQueueMessageIF* message) { - return sendToDefaultFrom(message, this->getId()); -} - -ReturnValue_t MessageQueue::sendToDefaultFrom(MessageQueueMessageIF* message, - MessageQueueId_t sentFrom, bool ignoreFault) { - return sendMessageFrom(defaultDestination, message, sentFrom, ignoreFault); -} - -ReturnValue_t MessageQueue::reply(MessageQueueMessageIF* message) { - if (this->lastPartner != MessageQueueIF::NO_QUEUE) { - return sendMessageFrom(this->lastPartner, message, this->getId()); - } else { - return NO_REPLY_PARTNER; - } -} - ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message, MessageQueueId_t sentFrom, bool ignoreFault) { return sendMessageFromMessageQueue(sendTo, message, sentFrom, ignoreFault, callContext); @@ -72,27 +51,16 @@ ReturnValue_t MessageQueue::handleSendResult(BaseType_t result, bool ignoreFault return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message, - MessageQueueId_t* receivedFrom) { - ReturnValue_t status = this->receiveMessage(message); - if (status == HasReturnvaluesIF::RETURN_OK) { - *receivedFrom = this->lastPartner; - } - return status; -} - ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) { BaseType_t result = xQueueReceive(handle, reinterpret_cast(message->getBuffer()), 0); if (result == pdPASS) { - this->lastPartner = message->getSender(); + this->last = message->getSender(); return HasReturnvaluesIF::RETURN_OK; } else { return MessageQueueIF::EMPTY; } } -MessageQueueId_t MessageQueue::getLastPartner() const { return lastPartner; } - ReturnValue_t MessageQueue::flush(uint32_t* count) { // TODO FreeRTOS does not support flushing partially // Is always successful @@ -100,17 +68,6 @@ ReturnValue_t MessageQueue::flush(uint32_t* count) { return HasReturnvaluesIF::RETURN_OK; } -MessageQueueId_t MessageQueue::getId() const { return queueId; } - -void MessageQueue::setDefaultDestination(MessageQueueId_t defaultDestination) { - defaultDestinationSet = true; - this->defaultDestination = defaultDestination; -} - -MessageQueueId_t MessageQueue::getDefaultDestination() const { return defaultDestination; } - -bool MessageQueue::isDefaultDestinationSet() const { return defaultDestinationSet; } - // static core function to send messages. ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, MessageQueueMessageIF* message, diff --git a/src/fsfw/osal/freertos/MessageQueue.h b/src/fsfw/osal/freertos/MessageQueue.h index 1cb343d13..00dfea680 100644 --- a/src/fsfw/osal/freertos/MessageQueue.h +++ b/src/fsfw/osal/freertos/MessageQueue.h @@ -1,12 +1,14 @@ #ifndef FSFW_OSAL_FREERTOS_MESSAGEQUEUE_H_ #define FSFW_OSAL_FREERTOS_MESSAGEQUEUE_H_ +#include #include "FreeRTOS.h" #include "TaskManagement.h" #include "fsfw/internalerror/InternalErrorReporterIF.h" #include "fsfw/ipc/MessageQueueIF.h" #include "fsfw/ipc/MessageQueueMessage.h" #include "fsfw/ipc/MessageQueueMessageIF.h" +#include "fsfw/ipc/definitions.h" #include "queue.h" /** @@ -32,7 +34,7 @@ * @ingroup osal * @ingroup message_queue */ -class MessageQueue : public MessageQueueIF { +class MessageQueue : public MessageQueueBase { friend class MessageQueueSenderIF; public: @@ -53,7 +55,8 @@ class MessageQueue : public MessageQueueIF { * This should be left default. */ MessageQueue(size_t messageDepth = 3, - size_t maxMessageSize = MessageQueueMessage::MAX_MESSAGE_SIZE); + size_t maxMessageSize = MessageQueueMessage::MAX_MESSAGE_SIZE, + MqArgs* args = nullptr); /** Copying message queues forbidden */ MessageQueue(const MessageQueue&) = delete; @@ -73,40 +76,15 @@ class MessageQueue : public MessageQueueIF { */ void switchSystemContext(CallContext callContext); - /** MessageQueueIF implementation */ - ReturnValue_t sendMessage(MessageQueueId_t sendTo, MessageQueueMessageIF* message, - bool ignoreFault = false) override; + QueueHandle_t getNativeQueueHandle(); - ReturnValue_t sendToDefault(MessageQueueMessageIF* message) override; - - ReturnValue_t reply(MessageQueueMessageIF* message) override; + // Implement non-generic MessageQueueIF functions not handled by MessageQueueBase virtual ReturnValue_t sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message, MessageQueueId_t sentFrom = NO_QUEUE, bool ignoreFault = false) override; - - virtual ReturnValue_t sendToDefaultFrom(MessageQueueMessageIF* message, - MessageQueueId_t sentFrom = NO_QUEUE, - bool ignoreFault = false) override; - - ReturnValue_t receiveMessage(MessageQueueMessageIF* message, - MessageQueueId_t* receivedFrom) override; - ReturnValue_t receiveMessage(MessageQueueMessageIF* message) override; - ReturnValue_t flush(uint32_t* count) override; - MessageQueueId_t getLastPartner() const override; - - MessageQueueId_t getId() const override; - - void setDefaultDestination(MessageQueueId_t defaultDestination) override; - - MessageQueueId_t getDefaultDestination() const override; - - bool isDefaultDestinationSet() const override; - - QueueHandle_t getNativeQueueHandle(); - protected: /** * @brief Implementation to be called from any send Call within @@ -136,12 +114,8 @@ class MessageQueue : public MessageQueueIF { static ReturnValue_t handleSendResult(BaseType_t result, bool ignoreFault); private: - bool defaultDestinationSet = false; QueueHandle_t handle; - MessageQueueId_t queueId = MessageQueueIF::NO_QUEUE; - MessageQueueId_t defaultDestination = MessageQueueIF::NO_QUEUE; - MessageQueueId_t lastPartner = MessageQueueIF::NO_QUEUE; const size_t maxMessageSize; //! Stores the current system context CallContext callContext = CallContext::TASK; diff --git a/src/fsfw/osal/freertos/QueueFactory.cpp b/src/fsfw/osal/freertos/QueueFactory.cpp index f4941481d..8424123cc 100644 --- a/src/fsfw/osal/freertos/QueueFactory.cpp +++ b/src/fsfw/osal/freertos/QueueFactory.cpp @@ -22,8 +22,9 @@ QueueFactory::QueueFactory() {} QueueFactory::~QueueFactory() {} -MessageQueueIF* QueueFactory::createMessageQueue(uint32_t messageDepth, size_t maxMessageSize) { - return new MessageQueue(messageDepth, maxMessageSize); +MessageQueueIF* QueueFactory::createMessageQueue(uint32_t messageDepth, size_t maxMessageSize, + MqArgs* args) { + return new MessageQueue(messageDepth, maxMessageSize, args); } void QueueFactory::deleteMessageQueue(MessageQueueIF* queue) { delete queue; } diff --git a/src/fsfw/osal/host/MessageQueue.cpp b/src/fsfw/osal/host/MessageQueue.cpp index d328fb820..d0a128505 100644 --- a/src/fsfw/osal/host/MessageQueue.cpp +++ b/src/fsfw/osal/host/MessageQueue.cpp @@ -8,10 +8,12 @@ #include "fsfw/osal/host/QueueMapManager.h" #include "fsfw/serviceinterface/ServiceInterface.h" -MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize) - : messageSize(maxMessageSize), messageDepth(messageDepth) { +MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize, MqArgs* args) + : MessageQueueBase(MessageQueueIF::NO_QUEUE, MessageQueueIF::NO_QUEUE, args), + messageSize(maxMessageSize), + messageDepth(messageDepth) { queueLock = MutexFactory::instance()->createMutex(); - auto result = QueueMapManager::instance()->addMessageQueue(this, &mqId); + auto result = QueueMapManager::instance()->addMessageQueue(this, &id); if (result != HasReturnvaluesIF::RETURN_OK) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::error << "MessageQueue::MessageQueue: Could not be created" << std::endl; @@ -23,42 +25,11 @@ MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize) MessageQueue::~MessageQueue() { MutexFactory::instance()->deleteMutex(queueLock); } -ReturnValue_t MessageQueue::sendMessage(MessageQueueId_t sendTo, MessageQueueMessageIF* message, - bool ignoreFault) { - return sendMessageFrom(sendTo, message, this->getId(), ignoreFault); -} - -ReturnValue_t MessageQueue::sendToDefault(MessageQueueMessageIF* message) { - return sendToDefaultFrom(message, this->getId()); -} - -ReturnValue_t MessageQueue::sendToDefaultFrom(MessageQueueMessageIF* message, - MessageQueueId_t sentFrom, bool ignoreFault) { - return sendMessageFrom(defaultDestination, message, sentFrom, ignoreFault); -} - -ReturnValue_t MessageQueue::reply(MessageQueueMessageIF* message) { - if (this->lastPartner != MessageQueueIF::NO_QUEUE) { - return sendMessageFrom(this->lastPartner, message, this->getId()); - } else { - return MessageQueueIF::NO_REPLY_PARTNER; - } -} - ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message, MessageQueueId_t sentFrom, bool ignoreFault) { return sendMessageFromMessageQueue(sendTo, message, sentFrom, ignoreFault); } -ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message, - MessageQueueId_t* receivedFrom) { - ReturnValue_t status = this->receiveMessage(message); - if (status == HasReturnvaluesIF::RETURN_OK) { - *receivedFrom = this->lastPartner; - } - return status; -} - ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) { if (messageQueue.empty()) { return MessageQueueIF::EMPTY; @@ -68,12 +39,10 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) { message->getBuffer()); messageQueue.pop(); // The last partner is the first uint32_t field in the message - this->lastPartner = message->getSender(); + this->last = message->getSender(); return HasReturnvaluesIF::RETURN_OK; } -MessageQueueId_t MessageQueue::getLastPartner() const { return lastPartner; } - ReturnValue_t MessageQueue::flush(uint32_t* count) { *count = messageQueue.size(); // Clears the queue. @@ -81,17 +50,6 @@ ReturnValue_t MessageQueue::flush(uint32_t* count) { return HasReturnvaluesIF::RETURN_OK; } -MessageQueueId_t MessageQueue::getId() const { return mqId; } - -void MessageQueue::setDefaultDestination(MessageQueueId_t defaultDestination) { - defaultDestinationSet = true; - this->defaultDestination = defaultDestination; -} - -MessageQueueId_t MessageQueue::getDefaultDestination() const { return defaultDestination; } - -bool MessageQueue::isDefaultDestinationSet() const { return defaultDestinationSet; } - // static core function to send messages. ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, MessageQueueMessageIF* message, diff --git a/src/fsfw/osal/host/MessageQueue.h b/src/fsfw/osal/host/MessageQueue.h index 49375bb56..bb4f26a10 100644 --- a/src/fsfw/osal/host/MessageQueue.h +++ b/src/fsfw/osal/host/MessageQueue.h @@ -1,15 +1,17 @@ #ifndef FRAMEWORK_OSAL_HOST_MESSAGEQUEUE_H_ #define FRAMEWORK_OSAL_HOST_MESSAGEQUEUE_H_ -#include -#include - +#include "fsfw/ipc/MessageQueueBase.h" #include "fsfw/internalerror/InternalErrorReporterIF.h" #include "fsfw/ipc/MessageQueueIF.h" #include "fsfw/ipc/MessageQueueMessage.h" #include "fsfw/ipc/MutexIF.h" +#include "fsfw/ipc/definitions.h" #include "fsfw/timemanager/Clock.h" +#include +#include + /** * @brief This class manages sending and receiving of * message queue messages. @@ -33,7 +35,7 @@ * @ingroup osal * @ingroup message_queue */ -class MessageQueue : public MessageQueueIF { +class MessageQueue : public MessageQueueBase { friend class MessageQueueSenderIF; public: @@ -54,7 +56,8 @@ class MessageQueue : public MessageQueueIF { * This should be left default. */ MessageQueue(size_t messageDepth = 3, - size_t maxMessageSize = MessageQueueMessage::MAX_MESSAGE_SIZE); + size_t maxMessageSize = MessageQueueMessage::MAX_MESSAGE_SIZE, + MqArgs* args = nullptr); /** Copying message queues forbidden */ MessageQueue(const MessageQueue&) = delete; @@ -67,121 +70,12 @@ class MessageQueue : public MessageQueueIF { */ virtual ~MessageQueue(); - /** - * @brief This operation sends a message to the given destination. - * @details It directly uses the sendMessage call of the MessageQueueSender - * parent, but passes its queue id as "sentFrom" parameter. - * @param sendTo This parameter specifies the message queue id of the - * destination message queue. - * @param message A pointer to a previously created message, which is sent. - * @param ignoreFault If set to true, the internal software fault counter - * is not incremented if queue is full. - */ - ReturnValue_t sendMessage(MessageQueueId_t sendTo, MessageQueueMessageIF* message, - bool ignoreFault = false) override; - /** - * @brief This operation sends a message to the default destination. - * @details As in the sendMessage method, this function uses the - * sendToDefault call of the MessageQueueSender parent class and adds its - * queue id as "sentFrom" information. - * @param message A pointer to a previously created message, which is sent. - */ - ReturnValue_t sendToDefault(MessageQueueMessageIF* message) override; - /** - * @brief This operation sends a message to the last communication partner. - * @details This operation simplifies answering an incoming message by using - * the stored lastPartner information as destination. If there was no - * message received yet (i.e. lastPartner is zero), an error code is returned. - * @param message A pointer to a previously created message, which is sent. - */ - ReturnValue_t reply(MessageQueueMessageIF* message) override; - - /** - * @brief With the sendMessage call, a queue message is sent to a - * receiving queue. - * @details - * This method takes the message provided, adds the sentFrom information and - * passes it on to the destination provided with an operating system call. - * The OS's return value is returned. - * @param sendTo This parameter specifies the message queue id to send - * the message to. - * @param message This is a pointer to a previously created message, - * which is sent. - * @param sentFrom The sentFrom information can be set to inject the - * sender's queue id into the message. This variable is set to zero by - * default. - * @param ignoreFault If set to true, the internal software fault counter - * is not incremented if queue is full. - */ + // Implement non-generic MessageQueueIF functions not handled by MessageQueueBase virtual ReturnValue_t sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message, MessageQueueId_t sentFrom = NO_QUEUE, bool ignoreFault = false) override; - - /** - * @brief The sendToDefault method sends a queue message to the default - * destination. - * @details - * In all other aspects, it works identical to the sendMessage method. - * @param message This is a pointer to a previously created message, - * which is sent. - * @param sentFrom The sentFrom information can be set to inject the - * sender's queue id into the message. This variable is set to zero by - * default. - */ - virtual ReturnValue_t sendToDefaultFrom(MessageQueueMessageIF* message, - MessageQueueId_t sentFrom = NO_QUEUE, - bool ignoreFault = false) override; - - /** - * @brief This function reads available messages from the message queue - * and returns the sender. - * @details - * It works identically to the other receiveMessage call, but in addition - * returns the sender's queue id. - * @param message A pointer to a message in which the received data is stored. - * @param receivedFrom A pointer to a queue id in which the sender's id is stored. - */ - ReturnValue_t receiveMessage(MessageQueueMessageIF* message, - MessageQueueId_t* receivedFrom) override; - - /** - * @brief This function reads available messages from the message queue. - * @details - * If data is available it is stored in the passed message pointer. - * The message's original content is overwritten and the sendFrom - * information is stored in the lastPartner attribute. Else, the lastPartner - * information remains untouched, the message's content is cleared and the - * function returns immediately. - * @param message A pointer to a message in which the received data is stored. - */ ReturnValue_t receiveMessage(MessageQueueMessageIF* message) override; - /** - * Deletes all pending messages in the queue. - * @param count The number of flushed messages. - * @return RETURN_OK on success. - */ ReturnValue_t flush(uint32_t* count) override; - /** - * @brief This method returns the message queue id of the last - * communication partner. - */ - MessageQueueId_t getLastPartner() const override; - /** - * @brief This method returns the message queue id of this class's - * message queue. - */ - MessageQueueId_t getId() const override; - - /** - * @brief This method is a simple setter for the default destination. - */ - void setDefaultDestination(MessageQueueId_t defaultDestination) override; - /** - * @brief This method is a simple getter for the default destination. - */ - MessageQueueId_t getDefaultDestination() const override; - - bool isDefaultDestinationSet() const override; ReturnValue_t lockQueue(MutexIF::TimeoutType timeoutType, dur_millis_t lockTimeout); ReturnValue_t unlockQueue(); @@ -211,23 +105,14 @@ class MessageQueue : public MessageQueueIF { MessageQueueId_t sentFrom = NO_QUEUE, bool ignoreFault = false); - // static ReturnValue_t handleSendResult(BaseType_t result, bool ignoreFault); - private: std::queue> messageQueue; - /** - * @brief The class stores the queue id it got assigned. - * If initialization fails, the queue id is set to zero. - */ - MessageQueueId_t mqId = MessageQueueIF::NO_QUEUE; size_t messageSize = 0; size_t messageDepth = 0; MutexIF* queueLock; - bool defaultDestinationSet = false; MessageQueueId_t defaultDestination = MessageQueueIF::NO_QUEUE; - MessageQueueId_t lastPartner = MessageQueueIF::NO_QUEUE; }; #endif /* FRAMEWORK_OSAL_HOST_MESSAGEQUEUE_H_ */ diff --git a/src/fsfw/osal/host/QueueFactory.cpp b/src/fsfw/osal/host/QueueFactory.cpp index 3c63e6c9a..732892caf 100644 --- a/src/fsfw/osal/host/QueueFactory.cpp +++ b/src/fsfw/osal/host/QueueFactory.cpp @@ -27,12 +27,13 @@ QueueFactory::QueueFactory() {} QueueFactory::~QueueFactory() {} -MessageQueueIF* QueueFactory::createMessageQueue(uint32_t messageDepth, size_t maxMessageSize) { +MessageQueueIF* QueueFactory::createMessageQueue(uint32_t messageDepth, size_t maxMessageSize, + MqArgs* args) { // A thread-safe queue can be implemented by using a combination // of std::queue and std::mutex. This uses dynamic memory allocation // which could be alleviated by using a custom allocator, external library // (etl::queue) or simply using std::queue, we're on a host machine anyway. - return new MessageQueue(messageDepth, maxMessageSize); + return new MessageQueue(messageDepth, maxMessageSize, args); } void QueueFactory::deleteMessageQueue(MessageQueueIF* queue) { delete queue; } diff --git a/src/fsfw/osal/linux/CMakeLists.txt b/src/fsfw/osal/linux/CMakeLists.txt index dcdade67f..679b29319 100644 --- a/src/fsfw/osal/linux/CMakeLists.txt +++ b/src/fsfw/osal/linux/CMakeLists.txt @@ -1,29 +1,29 @@ target_sources(${LIB_FSFW_NAME} PRIVATE Clock.cpp - BinarySemaphore.cpp - CountingSemaphore.cpp - FixedTimeslotTask.cpp - InternalErrorCodes.cpp - MessageQueue.cpp - Mutex.cpp - MutexFactory.cpp - PeriodicPosixTask.cpp - PosixThread.cpp - QueueFactory.cpp - SemaphoreFactory.cpp - TaskFactory.cpp - tcpipHelpers.cpp - unixUtility.cpp + BinarySemaphore.cpp + CountingSemaphore.cpp + FixedTimeslotTask.cpp + InternalErrorCodes.cpp + MessageQueue.cpp + Mutex.cpp + MutexFactory.cpp + PeriodicPosixTask.cpp + PosixThread.cpp + QueueFactory.cpp + SemaphoreFactory.cpp + TaskFactory.cpp + tcpipHelpers.cpp + unixUtility.cpp ) find_package(Threads REQUIRED) target_link_libraries(${LIB_FSFW_NAME} PRIVATE - ${CMAKE_THREAD_LIBS_INIT} - rt + ${CMAKE_THREAD_LIBS_INIT} + rt ) target_link_libraries(${LIB_FSFW_NAME} INTERFACE - ${CMAKE_THREAD_LIBS_INIT} + ${CMAKE_THREAD_LIBS_INIT} ) diff --git a/src/fsfw/osal/linux/MessageQueue.cpp b/src/fsfw/osal/linux/MessageQueue.cpp index f876ec6e9..378f4e744 100644 --- a/src/fsfw/osal/linux/MessageQueue.cpp +++ b/src/fsfw/osal/linux/MessageQueue.cpp @@ -11,13 +11,10 @@ #include "fsfw/osal/linux/unixUtility.h" #include "fsfw/serviceinterface/ServiceInterface.h" -MessageQueue::MessageQueue(uint32_t messageDepth, size_t maxMessageSize) - : id(MessageQueueIF::NO_QUEUE), - lastPartner(MessageQueueIF::NO_QUEUE), - defaultDestination(MessageQueueIF::NO_QUEUE), +MessageQueue::MessageQueue(uint32_t messageDepth, size_t maxMessageSize, MqArgs* args) + : MessageQueueBase(MessageQueueIF::NO_QUEUE, MessageQueueIF::NO_QUEUE, args), maxMessageSize(maxMessageSize) { mq_attr attributes; - this->id = 0; // Set attributes attributes.mq_curmsgs = 0; attributes.mq_maxmsg = messageDepth; @@ -50,30 +47,6 @@ MessageQueue::~MessageQueue() { } } -ReturnValue_t MessageQueue::sendMessage(MessageQueueId_t sendTo, MessageQueueMessageIF* message, - bool ignoreFault) { - return sendMessageFrom(sendTo, message, this->getId(), false); -} - -ReturnValue_t MessageQueue::sendToDefault(MessageQueueMessageIF* message) { - return sendToDefaultFrom(message, this->getId()); -} - -ReturnValue_t MessageQueue::reply(MessageQueueMessageIF* message) { - if (this->lastPartner != 0) { - return sendMessageFrom(this->lastPartner, message, this->getId()); - } else { - return NO_REPLY_PARTNER; - } -} - -ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message, - MessageQueueId_t* receivedFrom) { - ReturnValue_t status = this->receiveMessage(message); - *receivedFrom = this->lastPartner; - return status; -} - ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) { if (message == nullptr) { #if FSFW_CPP_OSTREAM_ENABLED == 1 @@ -96,7 +69,7 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) { int status = mq_receive(id, reinterpret_cast(message->getBuffer()), message->getMaximumMessageSize(), &messagePriority); if (status > 0) { - this->lastPartner = message->getSender(); + this->last = message->getSender(); // Check size of incoming message. if (message->getMessageSize() < message->getMinimumMessageSize()) { return HasReturnvaluesIF::RETURN_FAILED; @@ -164,8 +137,6 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) { } } -MessageQueueId_t MessageQueue::getLastPartner() const { return this->lastPartner; } - ReturnValue_t MessageQueue::flush(uint32_t* count) { mq_attr attrib; int status = mq_getattr(id, &attrib); @@ -212,26 +183,11 @@ ReturnValue_t MessageQueue::flush(uint32_t* count) { return HasReturnvaluesIF::RETURN_OK; } -MessageQueueId_t MessageQueue::getId() const { return this->id; } - -void MessageQueue::setDefaultDestination(MessageQueueId_t defaultDestination) { - this->defaultDestination = defaultDestination; -} - -ReturnValue_t MessageQueue::sendToDefaultFrom(MessageQueueMessageIF* message, - MessageQueueId_t sentFrom, bool ignoreFault) { - return sendMessageFrom(defaultDestination, message, sentFrom, ignoreFault); -} - ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message, MessageQueueId_t sentFrom, bool ignoreFault) { return sendMessageFromMessageQueue(sendTo, message, sentFrom, ignoreFault); } -MessageQueueId_t MessageQueue::getDefaultDestination() const { return this->defaultDestination; } - -bool MessageQueue::isDefaultDestinationSet() const { return (defaultDestination != NO_QUEUE); } - uint16_t MessageQueue::queueCounter = 0; ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, @@ -240,9 +196,9 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, bool ignoreFault) { if (message == nullptr) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "MessageQueue::sendMessageFromMessageQueue: Message is nullptr!" << std::endl; + sif::error << "MessageQueue::sendMessageFromMessageQueue: Message is nullptr" << std::endl; #else - sif::printError("MessageQueue::sendMessageFromMessageQueue: Message is nullptr!\n"); + sif::printError("MessageQueue::sendMessageFromMessageQueue: Message is nullptr\n"); #endif return HasReturnvaluesIF::RETURN_FAILED; } @@ -256,7 +212,7 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, if (!ignoreFault) { InternalErrorReporterIF* internalErrorReporter = ObjectManager::instance()->get(objects::INTERNAL_ERROR_REPORTER); - if (internalErrorReporter != NULL) { + if (internalErrorReporter != nullptr) { internalErrorReporter->queueMessageNotSent(); } } diff --git a/src/fsfw/osal/linux/MessageQueue.h b/src/fsfw/osal/linux/MessageQueue.h index dbf6555e8..8614d101b 100644 --- a/src/fsfw/osal/linux/MessageQueue.h +++ b/src/fsfw/osal/linux/MessageQueue.h @@ -1,11 +1,13 @@ #ifndef FSFW_OSAL_LINUX_MESSAGEQUEUE_H_ #define FSFW_OSAL_LINUX_MESSAGEQUEUE_H_ +#include #include #include "fsfw/internalerror/InternalErrorReporterIF.h" #include "fsfw/ipc/MessageQueueIF.h" #include "fsfw/ipc/MessageQueueMessage.h" +#include "fsfw/ipc/definitions.h" /** * @brief This class manages sending and receiving of message queue messages. * @@ -25,7 +27,7 @@ * makes use of the operating system calls provided. * @ingroup message_queue */ -class MessageQueue : public MessageQueueIF { +class MessageQueue : public MessageQueueBase { friend class MessageQueueSenderIF; public: @@ -42,104 +44,25 @@ class MessageQueue : public MessageQueueIF { * This should be left default. */ MessageQueue(uint32_t messageDepth = 3, - size_t maxMessageSize = MessageQueueMessage::MAX_MESSAGE_SIZE); + size_t maxMessageSize = MessageQueueMessage::MAX_MESSAGE_SIZE, + MqArgs* args = nullptr); + + /** Copying message queues forbidden */ + MessageQueue(const MessageQueue&) = delete; + MessageQueue& operator=(const MessageQueue&) = delete; + /** * @brief The destructor deletes the formerly created message queue. * @details This is accomplished by using the delete call provided by the operating system. */ virtual ~MessageQueue(); - /** - * @brief This operation sends a message to the given destination. - * @details It directly uses the sendMessage call of the MessageQueueSender parent, but passes - * its queue id as "sentFrom" parameter. - * @param sendTo This parameter specifies the message queue id of the destination message - * queue. - * @param message A pointer to a previously created message, which is sent. - * @param ignoreFault If set to true, the internal software fault counter is not incremented if - * queue is full. - */ - virtual ReturnValue_t sendMessage(MessageQueueId_t sendTo, MessageQueueMessageIF* message, - bool ignoreFault = false); - /** - * @brief This operation sends a message to the default destination. - * @details As in the sendMessage method, this function uses the sendToDefault call of the - * MessageQueueSender parent class and adds its queue id as "sentFrom" - * information. - * @param message A pointer to a previously created message, which is sent. - */ - virtual ReturnValue_t sendToDefault(MessageQueueMessageIF* message); - /** - * @brief This operation sends a message to the last communication partner. - * @details This operation simplifies answering an incoming message by using the stored - * lastParnter information as destination. If there was no message received yet - * (i.e. lastPartner is zero), an error code is returned. - * @param message A pointer to a previously created message, which is sent. - */ - ReturnValue_t reply(MessageQueueMessageIF* message); - /** - * @brief This function reads available messages from the message queue and returns the - * sender. - * @details It works identically to the other receiveMessage call, but in addition returns the - * sender's queue id. - * @param message A pointer to a message in which the received data is stored. - * @param receivedFrom A pointer to a queue id in which the sender's id is stored. - */ - ReturnValue_t receiveMessage(MessageQueueMessageIF* message, MessageQueueId_t* receivedFrom); - - /** - * @brief This function reads available messages from the message queue. - * @details If data is available it is stored in the passed message pointer. The message's - * original content is overwritten and the sendFrom information is stored in - * the lastPartner attribute. Else, the lastPartner information remains untouched, the message's - * content is cleared and the function returns immediately. - * @param message A pointer to a message in which the received data is stored. - */ - ReturnValue_t receiveMessage(MessageQueueMessageIF* message); - /** - * Deletes all pending messages in the queue. - * @param count The number of flushed messages. - * @return RETURN_OK on success. - */ - ReturnValue_t flush(uint32_t* count); - /** - * @brief This method returns the message queue id of the last communication partner. - */ - MessageQueueId_t getLastPartner() const; - /** - * @brief This method returns the message queue id of this class's message queue. - */ - MessageQueueId_t getId() const; - /** - * \brief With the sendMessage call, a queue message is sent to a receiving queue. - * \param sendTo This parameter specifies the message queue id to send the message to. - * \param message This is a pointer to a previously created message, which is sent. - * \param sentFrom The sentFrom information can be set to inject the sender's queue id into the - * message. This variable is set to zero by default. \param ignoreFault If set to true, the - * internal software fault counter is not incremented if queue is full. - */ - virtual ReturnValue_t sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message, - MessageQueueId_t sentFrom, bool ignoreFault = false); - /** - * \brief The sendToDefault method sends a queue message to the default destination. - * \details In all other aspects, it works identical to the sendMessage method. - * \param message This is a pointer to a previously created message, which is sent. - * \param sentFrom The sentFrom information can be set to inject the sender's queue id into the - * message. This variable is set to zero by default. - */ - virtual ReturnValue_t sendToDefaultFrom(MessageQueueMessageIF* message, - MessageQueueId_t sentFrom = NO_QUEUE, - bool ignoreFault = false); - /** - * \brief This method is a simple setter for the default destination. - */ - void setDefaultDestination(MessageQueueId_t defaultDestination); - /** - * \brief This method is a simple getter for the default destination. - */ - MessageQueueId_t getDefaultDestination() const; - - bool isDefaultDestinationSet() const; + // Implement non-generic MessageQueueIF functions not handled by MessageQueueBase + ReturnValue_t receiveMessage(MessageQueueMessageIF* message) override; + ReturnValue_t flush(uint32_t* count) override; + ReturnValue_t sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message, + MessageQueueId_t sentFrom, + bool ignoreFault = false) override; protected: /** @@ -158,31 +81,10 @@ class MessageQueue : public MessageQueueIF { bool ignoreFault = false); private: - /** - * @brief The class stores the queue id it got assigned from the operating system in this - * attribute. If initialization fails, the queue id is set to zero. - */ - MessageQueueId_t id; - /** - * @brief In this attribute, the queue id of the last communication partner is stored - * to allow for replying. - */ - MessageQueueId_t lastPartner; - /** - * @brief The message queue's name -a user specific information for the operating system- is - * generated automatically with the help of this static counter. - */ - /** - * \brief This attribute stores a default destination to send messages to. - * \details It is stored to simplify sending to always-the-same receiver. The attribute may - * be set in the constructor or by a setter call to setDefaultDestination. - */ - MessageQueueId_t defaultDestination; - /** * The name of the message queue, stored for unlinking */ - char name[16]; + char name[16] = {}; static uint16_t queueCounter; const size_t maxMessageSize; diff --git a/src/fsfw/osal/linux/QueueFactory.cpp b/src/fsfw/osal/linux/QueueFactory.cpp index d1b1cfdb7..24ace1ae3 100644 --- a/src/fsfw/osal/linux/QueueFactory.cpp +++ b/src/fsfw/osal/linux/QueueFactory.cpp @@ -28,8 +28,9 @@ QueueFactory::QueueFactory() {} QueueFactory::~QueueFactory() {} -MessageQueueIF* QueueFactory::createMessageQueue(uint32_t messageDepth, size_t maxMessageSize) { - return new MessageQueue(messageDepth, maxMessageSize); +MessageQueueIF* QueueFactory::createMessageQueue(uint32_t messageDepth, size_t maxMessageSize, + MqArgs* args) { + return new MessageQueue(messageDepth, maxMessageSize, args); } void QueueFactory::deleteMessageQueue(MessageQueueIF* queue) { delete queue; } diff --git a/src/fsfw/osal/rtems/MessageQueue.cpp b/src/fsfw/osal/rtems/MessageQueue.cpp index e45679d52..f52f18522 100644 --- a/src/fsfw/osal/rtems/MessageQueue.cpp +++ b/src/fsfw/osal/rtems/MessageQueue.cpp @@ -6,8 +6,9 @@ #include "fsfw/osal/rtems/RtemsBasic.h" #include "fsfw/serviceinterface/ServiceInterface.h" -MessageQueue::MessageQueue(size_t message_depth, size_t max_message_size) - : id(0), lastPartner(0), defaultDestination(NO_QUEUE), internalErrorReporter(nullptr) { +MessageQueue::MessageQueue(size_t message_depth, size_t max_message_size, MqArgs* args) + : MessageQueueBase(MessageQueueIF::NO_QUEUE, MessageQueueIF::NO_QUEUE, args), + internalErrorReporter(nullptr) { rtems_name name = ('Q' << 24) + (queueCounter++ << 8); rtems_status_code status = rtems_message_queue_create(name, message_depth, max_message_size, 0, &(this->id)); @@ -16,43 +17,19 @@ MessageQueue::MessageQueue(size_t message_depth, size_t max_message_size) sif::error << "MessageQueue::MessageQueue: Creating Queue " << std::hex << name << std::dec << " failed with status:" << (uint32_t)status << std::endl; #endif - this->id = 0; + this->id = MessageQueueIF::NO_QUEUE; } } MessageQueue::~MessageQueue() { rtems_message_queue_delete(id); } -ReturnValue_t MessageQueue::sendMessage(MessageQueueId_t sendTo, MessageQueueMessageIF* message, - bool ignoreFault) { - return sendMessageFrom(sendTo, message, this->getId(), ignoreFault); -} - -ReturnValue_t MessageQueue::sendToDefault(MessageQueueMessageIF* message) { - return sendToDefaultFrom(message, this->getId()); -} - -ReturnValue_t MessageQueue::reply(MessageQueueMessageIF* message) { - if (this->lastPartner != 0) { - return sendMessage(this->lastPartner, message, this->getId()); - } else { - return NO_REPLY_PARTNER; - } -} - -ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message, - MessageQueueId_t* receivedFrom) { - ReturnValue_t status = this->receiveMessage(message); - *receivedFrom = this->lastPartner; - return status; -} - ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) { size_t size = 0; rtems_status_code status = rtems_message_queue_receive(id, message->getBuffer(), &size, RTEMS_NO_WAIT, 1); if (status == RTEMS_SUCCESSFUL) { message->setMessageSize(size); - this->lastPartner = message->getSender(); + this->last = message->getSender(); // Check size of incoming message. if (message->getMessageSize() < message->getMinimumMessageSize()) { return HasReturnvaluesIF::RETURN_FAILED; @@ -65,19 +42,11 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) { return convertReturnCode(status); } -MessageQueueId_t MessageQueue::getLastPartner() const { return this->lastPartner; } - ReturnValue_t MessageQueue::flush(uint32_t* count) { rtems_status_code status = rtems_message_queue_flush(id, count); return convertReturnCode(status); } -MessageQueueId_t MessageQueue::getId() const { return this->id; } - -void MessageQueue::setDefaultDestination(MessageQueueId_t defaultDestination) { - this->defaultDestination = defaultDestination; -} - ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message, MessageQueueId_t sentFrom, bool ignoreFault) { message->setSender(sentFrom); @@ -103,15 +72,6 @@ ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo, MessageQueu return returnCode; } -ReturnValue_t MessageQueue::sendToDefaultFrom(MessageQueueMessageIF* message, - MessageQueueId_t sentFrom, bool ignoreFault) { - return sendMessageFrom(defaultDestination, message, sentFrom, ignoreFault); -} - -MessageQueueId_t MessageQueue::getDefaultDestination() const { return this->defaultDestination; } - -bool MessageQueue::isDefaultDestinationSet() const { return (defaultDestination != NO_QUEUE); } - ReturnValue_t MessageQueue::convertReturnCode(rtems_status_code inValue) { switch (inValue) { case RTEMS_SUCCESSFUL: diff --git a/src/fsfw/osal/rtems/MessageQueue.h b/src/fsfw/osal/rtems/MessageQueue.h index 89aae2adb..4648fdfa5 100644 --- a/src/fsfw/osal/rtems/MessageQueue.h +++ b/src/fsfw/osal/rtems/MessageQueue.h @@ -1,10 +1,12 @@ #ifndef FSFW_OSAL_RTEMS_MESSAGEQUEUE_H_ #define FSFW_OSAL_RTEMS_MESSAGEQUEUE_H_ +#include #include "RtemsBasic.h" #include "fsfw/internalerror/InternalErrorReporterIF.h" #include "fsfw/ipc/MessageQueueIF.h" #include "fsfw/ipc/MessageQueueMessage.h" +#include "fsfw/ipc/definitions.h" /** * @brief This class manages sending and receiving of message queue messages. @@ -19,7 +21,7 @@ *as well as sending and receiving messages, the class makes use of the operating system calls *provided. \ingroup message_queue */ -class MessageQueue : public MessageQueueIF { +class MessageQueue : public MessageQueueBase { public: /** * @brief The constructor initializes and configures the message queue. @@ -34,131 +36,26 @@ class MessageQueue : public MessageQueueIF { * This should be left default. */ MessageQueue(size_t message_depth = 3, - size_t max_message_size = MessageQueueMessage::MAX_MESSAGE_SIZE); + size_t max_message_size = MessageQueueMessage::MAX_MESSAGE_SIZE, + MqArgs* args = nullptr); + + /** Copying message queues forbidden */ + MessageQueue(const MessageQueue&) = delete; + MessageQueue& operator=(const MessageQueue&) = delete; + /** * @brief The destructor deletes the formerly created message queue. * @details This is accomplished by using the delete call provided by the operating system. */ virtual ~MessageQueue(); - /** - * @brief This operation sends a message to the given destination. - * @details It directly uses the sendMessage call of the MessageQueueSender parent, but passes - * its queue id as "sentFrom" parameter. - * @param sendTo This parameter specifies the message queue id of the destination message - * queue. - * @param message A pointer to a previously created message, which is sent. - * @param ignoreFault If set to true, the internal software fault counter is not incremented if - * queue is full. - */ - ReturnValue_t sendMessage(MessageQueueId_t sendTo, MessageQueueMessageIF* message, - bool ignoreFault = false); - /** - * @brief This operation sends a message to the default destination. - * @details As in the sendMessage method, this function uses the sendToDefault call of the - * MessageQueueSender parent class and adds its queue id as "sentFrom" - * information. - * @param message A pointer to a previously created message, which is sent. - */ - ReturnValue_t sendToDefault(MessageQueueMessageIF* message); - /** - * @brief This operation sends a message to the last communication partner. - * @details This operation simplifies answering an incoming message by using the stored - * lastParnter information as destination. If there was no message received yet - * (i.e. lastPartner is zero), an error code is returned. - * @param message A pointer to a previously created message, which is sent. - */ - ReturnValue_t reply(MessageQueueMessageIF* message); - /** - * @brief This function reads available messages from the message queue and returns the - * sender. - * @details It works identically to the other receiveMessage call, but in addition returns the - * sender's queue id. - * @param message A pointer to a message in which the received data is stored. - * @param receivedFrom A pointer to a queue id in which the sender's id is stored. - */ - ReturnValue_t receiveMessage(MessageQueueMessageIF* message, MessageQueueId_t* receivedFrom); - - /** - * @brief This function reads available messages from the message queue. - * @details If data is available it is stored in the passed message pointer. The message's - * original content is overwritten and the sendFrom information is stored in - * the lastPartner attribute. Else, the lastPartner information remains untouched, the message's - * content is cleared and the function returns immediately. - * @param message A pointer to a message in which the received data is stored. - */ - ReturnValue_t receiveMessage(MessageQueueMessageIF* message); - /** - * Deletes all pending messages in the queue. - * @param count The number of flushed messages. - * @return RETURN_OK on success. - */ - ReturnValue_t flush(uint32_t* count); - /** - * @brief This method returns the message queue id of the last communication partner. - */ - MessageQueueId_t getLastPartner() const; - /** - * @brief This method returns the message queue id of this class's message queue. - */ - MessageQueueId_t getId() const; - /** - * \brief With the sendMessage call, a queue message is sent to a receiving queue. - * \details This method takes the message provided, adds the sentFrom information and passes - * it on to the destination provided with an operating system call. The OS's - * return value is returned. - * \param sendTo This parameter specifies the message queue id to send the message to. - * \param message This is a pointer to a previously created message, which is sent. - * \param sentFrom The sentFrom information can be set to inject the sender's queue id into the - * message. This variable is set to zero by default. \param ignoreFault If set to true, the - * internal software fault counter is not incremented if queue is full. - */ - virtual ReturnValue_t sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message, + // Implement non-generic MessageQueueIF functions not handled by MessageQueueBase + ReturnValue_t flush(uint32_t* count) override; + ReturnValue_t sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message, MessageQueueId_t sentFrom = NO_QUEUE, - bool ignoreFault = false); - /** - * \brief The sendToDefault method sends a queue message to the default destination. - * \details In all other aspects, it works identical to the sendMessage method. - * \param message This is a pointer to a previously created message, which is sent. - * \param sentFrom The sentFrom information can be set to inject the sender's queue id into the - * message. This variable is set to zero by default. - */ - virtual ReturnValue_t sendToDefaultFrom(MessageQueueMessageIF* message, - MessageQueueId_t sentFrom = NO_QUEUE, - bool ignoreFault = false); - /** - * \brief This method is a simple setter for the default destination. - */ - void setDefaultDestination(MessageQueueId_t defaultDestination); - /** - * \brief This method is a simple getter for the default destination. - */ - MessageQueueId_t getDefaultDestination() const; - - bool isDefaultDestinationSet() const; + bool ignoreFault = false) override; private: - /** - * @brief The class stores the queue id it got assigned from the operating system in this - * attribute. If initialization fails, the queue id is set to zero. - */ - MessageQueueId_t id; - /** - * @brief In this attribute, the queue id of the last communication partner is stored - * to allow for replying. - */ - MessageQueueId_t lastPartner; - /** - * @brief The message queue's name -a user specific information for the operating system- is - * generated automatically with the help of this static counter. - */ - /** - * \brief This attribute stores a default destination to send messages to. - * \details It is stored to simplify sending to always-the-same receiver. The attribute may - * be set in the constructor or by a setter call to setDefaultDestination. - */ - MessageQueueId_t defaultDestination; - /** * \brief This attribute stores a reference to the internal error reporter for reporting full * queues. \details In the event of a full destination queue, the reporter will be notified. The diff --git a/src/fsfw/osal/rtems/QueueFactory.cpp b/src/fsfw/osal/rtems/QueueFactory.cpp index 3d517f609..2519f444b 100644 --- a/src/fsfw/osal/rtems/QueueFactory.cpp +++ b/src/fsfw/osal/rtems/QueueFactory.cpp @@ -49,8 +49,9 @@ QueueFactory::QueueFactory() {} QueueFactory::~QueueFactory() {} -MessageQueueIF* QueueFactory::createMessageQueue(uint32_t messageDepth, size_t maxMessageSize) { - return new MessageQueue(messageDepth, maxMessageSize); +MessageQueueIF* QueueFactory::createMessageQueue(uint32_t messageDepth, size_t maxMessageSize, + MqArgs* args) { + return new MessageQueue(messageDepth, maxMessageSize, args); } void QueueFactory::deleteMessageQueue(MessageQueueIF* queue) { delete queue; } diff --git a/tests/src/fsfw_tests/unit/datapoollocal/LocalPoolManagerTest.cpp b/tests/src/fsfw_tests/unit/datapoollocal/LocalPoolManagerTest.cpp index 077625959..f2a5c18a9 100644 --- a/tests/src/fsfw_tests/unit/datapoollocal/LocalPoolManagerTest.cpp +++ b/tests/src/fsfw_tests/unit/datapoollocal/LocalPoolManagerTest.cpp @@ -21,8 +21,10 @@ TEST_CASE("LocalPoolManagerTest", "[LocManTest]") { REQUIRE(poolOwner->initializeHkManager() == retval::CATCH_OK); REQUIRE(poolOwner->initializeHkManagerAfterTaskCreation() == retval::CATCH_OK); - MessageQueueMockBase* mqMock = poolOwner->getMockQueueHandle(); - REQUIRE(mqMock != nullptr); + MessageQueueMockBase* poolOwnerMock = poolOwner->getMockQueueHandle(); + REQUIRE(poolOwnerMock != nullptr); + + // MessageQueueIF* hkCommander = QueueFactory::instance()->createMessageQueue(); CommandMessage messageSent; uint8_t messagesSent = 0; @@ -41,9 +43,9 @@ TEST_CASE("LocalPoolManagerTest", "[LocManTest]") { poolOwner->dataset.setChanged(true); /* Now the update message should be generated. */ REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK); - REQUIRE(mqMock->wasMessageSent() == true); + REQUIRE(poolOwnerMock->wasMessageSent() == true); - REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK); + REQUIRE(poolOwnerMock->receiveMessage(&messageSent) == retval::CATCH_OK); CHECK(messageSent.getCommand() == static_cast(HousekeepingMessage::UPDATE_NOTIFICATION_SET)); @@ -53,9 +55,9 @@ TEST_CASE("LocalPoolManagerTest", "[LocManTest]") { poolOwner->dataset.setChanged(true); REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK); - REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); + REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true); CHECK(messagesSent == 1); - REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK); + REQUIRE(poolOwnerMock->receiveMessage(&messageSent) == retval::CATCH_OK); CHECK(messageSent.getCommand() == static_cast(HousekeepingMessage::UPDATE_NOTIFICATION_SET)); @@ -63,15 +65,15 @@ TEST_CASE("LocalPoolManagerTest", "[LocManTest]") { REQUIRE(poolOwner->subscribeWrapperSetUpdateHk() == retval::CATCH_OK); poolOwner->dataset.setChanged(true); REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK); - REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); + REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true); CHECK(messagesSent == 2); /* first message sent should be the update notification, considering the internal list is a vector checked in insertion order. */ - REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK); + REQUIRE(poolOwnerMock->receiveMessage(&messageSent) == retval::CATCH_OK); CHECK(messageSent.getCommand() == static_cast(HousekeepingMessage::UPDATE_NOTIFICATION_SET)); - REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK); + REQUIRE(poolOwnerMock->receiveMessage(&messageSent) == retval::CATCH_OK); CHECK(messageSent.getCommand() == static_cast(HousekeepingMessage::HK_REPORT)); /* Clear message to avoid memory leak, our mock won't do it for us (yet) */ CommandMessageCleaner::clearCommandMessage(&messageSent); @@ -99,9 +101,9 @@ TEST_CASE("LocalPoolManagerTest", "[LocManTest]") { /* Trigger generation of snapshot */ REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK); - REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); + REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true); CHECK(messagesSent == 1); - REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK); + REQUIRE(poolOwnerMock->receiveMessage(&messageSent) == retval::CATCH_OK); /* Check that snapshot was generated */ CHECK(messageSent.getCommand() == static_cast(HousekeepingMessage::UPDATE_SNAPSHOT_SET)); /* Now we deserialize the snapshot into a new dataset instance */ @@ -162,12 +164,12 @@ TEST_CASE("LocalPoolManagerTest", "[LocManTest]") { REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK); /* Check update snapshot was sent. */ - REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); + REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true); CHECK(messagesSent == 1); /* Should have been reset. */ CHECK(poolVar->hasChanged() == false); - REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK); + REQUIRE(poolOwnerMock->receiveMessage(&messageSent) == retval::CATCH_OK); CHECK(messageSent.getCommand() == static_cast(HousekeepingMessage::UPDATE_SNAPSHOT_VARIABLE)); /* Now we deserialize the snapshot into a new dataset instance */ @@ -209,11 +211,11 @@ TEST_CASE("LocalPoolManagerTest", "[LocManTest]") { REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK); /* Check update notification was sent. */ - REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); + REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true); CHECK(messagesSent == 1); /* Should have been reset. */ CHECK(poolVar->hasChanged() == false); - REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK); + REQUIRE(poolOwnerMock->receiveMessage(&messageSent) == retval::CATCH_OK); CHECK(messageSent.getCommand() == static_cast(HousekeepingMessage::UPDATE_NOTIFICATION_VARIABLE)); /* Now subscribe for the dataset update (HK and update) again with subscription interface */ @@ -225,26 +227,26 @@ TEST_CASE("LocalPoolManagerTest", "[LocManTest]") { poolOwner->dataset.setChanged(true); REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK); /* Now two messages should be sent. */ - REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); + REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true); CHECK(messagesSent == 2); - mqMock->clearMessages(true); + poolOwnerMock->clearMessages(true); poolOwner->dataset.setChanged(true); poolVar->setChanged(true); REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK); /* Now three messages should be sent. */ - REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); + REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true); CHECK(messagesSent == 3); - REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK); + REQUIRE(poolOwnerMock->receiveMessage(&messageSent) == retval::CATCH_OK); CHECK(messageSent.getCommand() == static_cast(HousekeepingMessage::UPDATE_NOTIFICATION_VARIABLE)); - REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK); + REQUIRE(poolOwnerMock->receiveMessage(&messageSent) == retval::CATCH_OK); CHECK(messageSent.getCommand() == static_cast(HousekeepingMessage::UPDATE_NOTIFICATION_SET)); - REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK); + REQUIRE(poolOwnerMock->receiveMessage(&messageSent) == retval::CATCH_OK); CHECK(messageSent.getCommand() == static_cast(HousekeepingMessage::HK_REPORT)); CommandMessageCleaner::clearCommandMessage(&messageSent); - REQUIRE(mqMock->receiveMessage(&messageSent) == static_cast(MessageQueueIF::EMPTY)); + REQUIRE(poolOwnerMock->receiveMessage(&messageSent) == static_cast(MessageQueueIF::EMPTY)); } SECTION("PeriodicHKAndMessaging") { @@ -255,38 +257,38 @@ TEST_CASE("LocalPoolManagerTest", "[LocManTest]") { REQUIRE(poolOwner->subscribePeriodicHk(true) == retval::CATCH_OK); REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK); /* Now HK packet should be sent as message immediately. */ - REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); + REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true); CHECK(messagesSent == 1); - CHECK(mqMock->popMessage() == retval::CATCH_OK); + CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK); LocalPoolDataSetBase* setHandle = poolOwner->getDataSetHandle(lpool::testSid); REQUIRE(setHandle != nullptr); CHECK(poolOwner->poolManager.generateHousekeepingPacket(lpool::testSid, setHandle, false) == retval::CATCH_OK); - REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); + REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true); CHECK(messagesSent == 1); - CHECK(mqMock->popMessage() == retval::CATCH_OK); + CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK); CHECK(setHandle->getReportingEnabled() == true); CommandMessage hkCmd; HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, false, false); CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK); CHECK(setHandle->getReportingEnabled() == false); - REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); + REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true); CHECK(messagesSent == 1); - CHECK(mqMock->popMessage() == retval::CATCH_OK); + CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK); HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, true, false); CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK); CHECK(setHandle->getReportingEnabled() == true); - REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); - CHECK(mqMock->popMessage() == retval::CATCH_OK); + REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true); + CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK); HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, false, false); CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK); CHECK(setHandle->getReportingEnabled() == false); - REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); - CHECK(mqMock->popMessage() == retval::CATCH_OK); + REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true); + CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK); HousekeepingMessage::setCollectionIntervalModificationCommand(&hkCmd, lpool::testSid, 0.4, false); @@ -294,23 +296,23 @@ TEST_CASE("LocalPoolManagerTest", "[LocManTest]") { /* For non-diagnostics and a specified minimum frequency of 0.2 seconds, the resulting collection interval should be 1.0 second */ CHECK(poolOwner->dataset.getCollectionInterval() == 1.0); - REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); + REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true); CHECK(messagesSent == 1); - CHECK(mqMock->popMessage() == retval::CATCH_OK); + CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK); HousekeepingMessage::setStructureReportingCommand(&hkCmd, lpool::testSid, false); REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK); CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK); /* Now HK packet should be sent as message. */ - REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); + REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true); CHECK(messagesSent == 1); - CHECK(mqMock->popMessage() == retval::CATCH_OK); + CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK); HousekeepingMessage::setOneShotReportCommand(&hkCmd, lpool::testSid, false); CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK); - REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); + REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true); CHECK(messagesSent == 1); - CHECK(mqMock->popMessage() == retval::CATCH_OK); + CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK); HousekeepingMessage::setUpdateNotificationSetCommand(&hkCmd, lpool::testSid); sid_t sidToCheck; @@ -326,62 +328,62 @@ TEST_CASE("LocalPoolManagerTest", "[LocManTest]") { CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == static_cast(LocalDataPoolManager::WRONG_HK_PACKET_TYPE)); /* We still expect a failure message being sent */ - REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); + REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true); CHECK(messagesSent == 1); - CHECK(mqMock->popMessage() == retval::CATCH_OK); + CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK); HousekeepingMessage::setCollectionIntervalModificationCommand(&hkCmd, lpool::testSid, 0.4, false); CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == static_cast(LocalDataPoolManager::WRONG_HK_PACKET_TYPE)); - REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); + REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true); CHECK(messagesSent == 1); - CHECK(mqMock->popMessage() == retval::CATCH_OK); + CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK); HousekeepingMessage::setStructureReportingCommand(&hkCmd, lpool::testSid, false); CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == static_cast(LocalDataPoolManager::WRONG_HK_PACKET_TYPE)); - REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); + REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true); CHECK(messagesSent == 1); - CHECK(mqMock->popMessage() == retval::CATCH_OK); + CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK); HousekeepingMessage::setStructureReportingCommand(&hkCmd, lpool::testSid, true); CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK); - REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); + REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true); CHECK(messagesSent == 1); - CHECK(mqMock->popMessage() == retval::CATCH_OK); + CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK); HousekeepingMessage::setCollectionIntervalModificationCommand(&hkCmd, lpool::testSid, 0.4, true); CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK); - REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); + REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true); CHECK(messagesSent == 1); - CHECK(mqMock->popMessage() == retval::CATCH_OK); + CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK); HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, true, true); CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK); - REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); + REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true); CHECK(messagesSent == 1); - CHECK(mqMock->popMessage() == retval::CATCH_OK); + CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK); HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, false, true); CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK); - REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); + REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true); CHECK(messagesSent == 1); - CHECK(mqMock->popMessage() == retval::CATCH_OK); + CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK); HousekeepingMessage::setOneShotReportCommand(&hkCmd, lpool::testSid, false); CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == static_cast(LocalDataPoolManager::WRONG_HK_PACKET_TYPE)); - REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); + REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true); CHECK(messagesSent == 1); - CHECK(mqMock->popMessage() == retval::CATCH_OK); + CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK); HousekeepingMessage::setOneShotReportCommand(&hkCmd, lpool::testSid, true); CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK); - REQUIRE(mqMock->wasMessageSent(&messagesSent) == true); + REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true); CHECK(messagesSent == 1); - CHECK(mqMock->popMessage() == retval::CATCH_OK); + CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK); HousekeepingMessage::setUpdateNotificationVariableCommand(&hkCmd, lpool::uint8VarGpid); gp_id_t gpidToCheck; @@ -407,5 +409,5 @@ TEST_CASE("LocalPoolManagerTest", "[LocManTest]") { /* we need to reset the subscription list because the pool owner is a global object. */ CHECK(poolOwner->reset() == retval::CATCH_OK); - mqMock->clearMessages(true); + poolOwnerMock->clearMessages(true); } diff --git a/tests/src/fsfw_tests/unit/mocks/MessageQueueMockBase.h b/tests/src/fsfw_tests/unit/mocks/MessageQueueMockBase.h index f60c74028..c3d08a86e 100644 --- a/tests/src/fsfw_tests/unit/mocks/MessageQueueMockBase.h +++ b/tests/src/fsfw_tests/unit/mocks/MessageQueueMockBase.h @@ -4,16 +4,18 @@ #include #include +#include "fsfw/ipc/MessageQueueBase.h" #include "fsfw/ipc/CommandMessage.h" #include "fsfw/ipc/MessageQueueIF.h" #include "fsfw/ipc/MessageQueueMessage.h" #include "fsfw_tests/unit/CatchDefinitions.h" -class MessageQueueMockBase : public MessageQueueIF { +class MessageQueueMockBase : public MessageQueueBase { public: - MessageQueueId_t myQueueId = tconst::testQueueId; + MessageQueueMockBase() + : MessageQueueBase(MessageQueueIF::NO_QUEUE, MessageQueueIF::NO_QUEUE, nullptr) {} + uint8_t messageSentCounter = 0; - bool defaultDestSet = false; bool messageSent = false; bool wasMessageSent(uint8_t* messageSentCounter = nullptr, bool resetCounter = true) { @@ -38,53 +40,30 @@ class MessageQueueMockBase : public MessageQueueIF { return receiveMessage(&message); } - virtual ReturnValue_t reply(MessageQueueMessageIF* message) { - return sendMessage(myQueueId, message); - }; - virtual ReturnValue_t receiveMessage(MessageQueueMessageIF* message, - MessageQueueId_t* receivedFrom) { - return receiveMessage(message); - } - - virtual ReturnValue_t receiveMessage(MessageQueueMessageIF* message) { + virtual ReturnValue_t receiveMessage(MessageQueueMessageIF* message) override { if (messagesSentQueue.empty()) { return MessageQueueIF::EMPTY; } - + this->last = message->getSender(); std::memcpy(message->getBuffer(), messagesSentQueue.front().getBuffer(), message->getMessageSize()); messagesSentQueue.pop(); return HasReturnvaluesIF::RETURN_OK; } virtual ReturnValue_t flush(uint32_t* count) { return HasReturnvaluesIF::RETURN_OK; } - virtual MessageQueueId_t getLastPartner() const { return myQueueId; } - virtual MessageQueueId_t getId() const { return myQueueId; } virtual ReturnValue_t sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message, - MessageQueueId_t sentFrom, bool ignoreFault = false) { - return sendMessage(sendTo, message); - } - virtual ReturnValue_t sendToDefaultFrom(MessageQueueMessageIF* message, MessageQueueId_t sentFrom, - bool ignoreFault = false) { - return sendMessage(myQueueId, message); - } - virtual ReturnValue_t sendToDefault(MessageQueueMessageIF* message) { - return sendMessage(myQueueId, message); - } - virtual ReturnValue_t sendMessage(MessageQueueId_t sendTo, MessageQueueMessageIF* message, - bool ignoreFault = false) override { + MessageQueueId_t sentFrom, + bool ignoreFault = false) override { messageSent = true; messageSentCounter++; MessageQueueMessage& messageRef = *(dynamic_cast(message)); messagesSentQueue.push(messageRef); return HasReturnvaluesIF::RETURN_OK; } - virtual void setDefaultDestination(MessageQueueId_t defaultDestination) { - myQueueId = defaultDestination; - defaultDestSet = true; - } - virtual MessageQueueId_t getDefaultDestination() const { return myQueueId; } - virtual bool isDefaultDestinationSet() const { return defaultDestSet; } + virtual ReturnValue_t reply(MessageQueueMessageIF* message) override { + return sendMessageFrom(MessageQueueIF::NO_QUEUE, message, this->getId(), false); + } void clearMessages(bool clearCommandMessages = true) { while (not messagesSentQueue.empty()) {