diff --git a/datapoollocal/LocalDataPoolManager.cpp b/datapoollocal/LocalDataPoolManager.cpp index 37dbed36..58694508 100644 --- a/datapoollocal/LocalDataPoolManager.cpp +++ b/datapoollocal/LocalDataPoolManager.cpp @@ -41,8 +41,8 @@ ReturnValue_t LocalDataPoolManager::initializeHousekeepingPoolEntriesOnce() { } ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage( - MessageQueueMessage *message) { - return HasReturnvaluesIF::RETURN_OK; + HousekeepingMessage& message) { + return HasReturnvaluesIF::RETURN_FAILED; } ReturnValue_t LocalDataPoolManager::printPoolEntry( diff --git a/datapoollocal/LocalDataPoolManager.h b/datapoollocal/LocalDataPoolManager.h index 1d25fa48..d1a2d410 100644 --- a/datapoollocal/LocalDataPoolManager.h +++ b/datapoollocal/LocalDataPoolManager.h @@ -46,7 +46,7 @@ public: LocalDataPoolManager operator=(const LocalDataPoolManager&) = delete; ReturnValue_t generateHousekeepingPacket(sid_t sid); - ReturnValue_t handleHousekeepingMessage(MessageQueueMessage* message); + ReturnValue_t handleHousekeepingMessage(HousekeepingMessage& message); /** * This function is used to fill the local data pool map with pool diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index 11cffc74..bf699848 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -225,15 +225,6 @@ void DeviceHandlerBase::readCommandQueue() { return; } - // This is really annoying. I can't cast a parent object to a child. - // But I want to use another message format.. -// CommandMessage* cmdMessage = dynamic_cast(msgPtr); -// if(cmdMessage == nullptr) { -// sif::error << "DeviceHandlerBase::readCommandQueue: Could not cast" -// " message to CommandMessage!" << std::endl; -// return; -// } - if(healthHelperActive) { result = healthHelper.handleHealthCommand(&command); if (result == RETURN_OK) { @@ -256,11 +247,11 @@ void DeviceHandlerBase::readCommandQueue() { return; } -// HousekeepingMessage* hkMessage = dynamic_cast(msgPtr); -// result = hkManager.handleHousekeepingMessage(hkMessage); -// if (result == RETURN_OK) { -// return; -// } + HousekeepingMessage hkMessage(&message); + result = hkManager.handleHousekeepingMessage(hkMessage); + if (result == RETURN_OK) { + return; + } result = handleDeviceHandlerMessage(&command); if (result == RETURN_OK) { @@ -758,7 +749,7 @@ ReturnValue_t DeviceHandlerBase::getStorageData(store_address_t storageAddress, void DeviceHandlerBase::replyRawData(const uint8_t *data, size_t len, MessageQueueId_t sendTo, bool isCommand) { - if (IPCStore == NULL || len == 0 || sendTo == MessageQueueIF::NO_QUEUE) { + if (IPCStore == nullptr or len == 0 or sendTo == MessageQueueIF::NO_QUEUE) { return; } store_address_t address; @@ -775,13 +766,12 @@ void DeviceHandlerBase::replyRawData(const uint8_t *data, size_t len, DeviceHandlerMessage::setDeviceHandlerRawReplyMessage(&command, getObjectId(), address, isCommand); -// this->DeviceHandlerCommand = CommandMessage::CMD_NONE; - - result = commandQueue->sendMessage(sendTo, &message); + result = commandQueue->sendMessage(sendTo, &command); if (result != RETURN_OK) { IPCStore->deleteData(address); - //Silently discard data, this indicates heavy TM traffic which should not be increased by additional events. + // Silently discard data, this indicates heavy TM traffic which + // should not be increased by additional events. } } diff --git a/devicehandlers/HealthDevice.cpp b/devicehandlers/HealthDevice.cpp index 1c9d18f6..7e3a59bd 100644 --- a/devicehandlers/HealthDevice.cpp +++ b/devicehandlers/HealthDevice.cpp @@ -5,7 +5,7 @@ HealthDevice::HealthDevice(object_id_t setObjectId, MessageQueueId_t parentQueue) : SystemObject(setObjectId), lastHealth(HEALTHY), parentQueue( parentQueue), commandQueue(), healthHelper(this, setObjectId) { - commandQueue = QueueFactory::instance()->createMessageQueue(3, CommandMessage::COMMAND_MESSAGE_SIZE); + commandQueue = QueueFactory::instance()->createMessageQueue(3, CommandMessage::MINIMUM_COMMAND_MESSAGE_SIZE); } HealthDevice::~HealthDevice() { diff --git a/housekeeping/HousekeepingMessage.cpp b/housekeeping/HousekeepingMessage.cpp index d9daf974..6dd1a711 100644 --- a/housekeeping/HousekeepingMessage.cpp +++ b/housekeeping/HousekeepingMessage.cpp @@ -1,7 +1,46 @@ #include +#include -HousekeepingMessage::HousekeepingMessage(MessageQueueMessage *message): - CommandMessageBase (message) {} +HousekeepingMessage::HousekeepingMessage(MessageQueueMessageIF* message): + CommandMessageBase(message) { +} -HousekeepingMessage::~HousekeepingMessage() {} +HousekeepingMessage::~HousekeepingMessage() { +} +void HousekeepingMessage::setHkReportMessage(sid_t sid, + store_address_t storeId) { + CommandMessageBase::setCommand(HK_REPORT); + setSid(sid); + setParameter(storeId.raw); +} + +size_t HousekeepingMessage::getMinimumMessageSize() const { + return HK_MESSAGE_SIZE; +} + +size_t HousekeepingMessage::getMaximumMessageSize() const { + return MessageQueueMessage::MAX_MESSAGE_SIZE; +} + +void HousekeepingMessage::clear() { + // clear IPC store where it is needed. +} + +sid_t HousekeepingMessage::getSid() const { + sid_t sid; + std::memcpy(&sid.raw, CommandMessageBase::getData(), sizeof(sid.raw)); + return sid; +} + +uint8_t* HousekeepingMessage::getData() { + return internalMessage->getBuffer() + sizeof(sid_t); +} + +void HousekeepingMessage::setParameter(uint32_t parameter) { + memcpy(getData(), ¶meter, sizeof(parameter)); +} + +void HousekeepingMessage::setSid(sid_t sid) { + std::memcpy(CommandMessageBase::getData(), &sid.raw, sizeof(sid.raw)); +} diff --git a/housekeeping/HousekeepingMessage.h b/housekeeping/HousekeepingMessage.h index d0cbd0eb..4e9d4553 100644 --- a/housekeeping/HousekeepingMessage.h +++ b/housekeeping/HousekeepingMessage.h @@ -13,13 +13,15 @@ union sid_t { struct { object_id_t objectId ; - // A generic 32 bit ID to identify unique HK packets for a single - // object. - // For example, the DeviceCommandId_t is used for DeviceHandlers + /** + * A generic 32 bit ID to identify unique HK packets for a single + * object. For example, the DeviceCommandId_t is used for + * DeviceHandlers + */ uint32_t ownerSetId; }; /** - * Alternative access to the raw value. + * Alternative access to the raw value. This is also the size of the type. */ uint64_t raw; }; @@ -27,14 +29,18 @@ union sid_t { class HousekeepingMessage : public CommandMessageBase { public: + + static constexpr size_t HK_MESSAGE_SIZE = sizeof(MessageQueueId_t) + + sizeof(Command_t) + sizeof(sid_t) * sizeof(uint32_t); /** * No instances of a message shall be created, instead * a CommandMessage instance is manipulated. */ - HousekeepingMessage(MessageQueueMessage* message); + HousekeepingMessage(MessageQueueMessageIF* message); virtual ~HousekeepingMessage(); static constexpr uint8_t MESSAGE_ID = messagetypes::HOUSEKEEPING; + static constexpr Command_t ADD_HK_REPORT_STRUCT = MAKE_COMMAND_ID(1); static constexpr Command_t ADD_DIAGNOSTICS_REPORT_STRUCT = @@ -79,7 +85,18 @@ public: static constexpr Command_t MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL = MAKE_COMMAND_ID(32); - static void setHkReportMessage(); + void setHkReportMessage(sid_t sid, store_address_t storeId); + + void setParameter(uint32_t parameter); + + virtual void clear() override; + virtual size_t getMinimumMessageSize() const override; + virtual size_t getMaximumMessageSize() const override; + + virtual uint8_t* getData() override; +private: + sid_t getSid() const; + void setSid(sid_t sid); }; diff --git a/ipc/CommandMessage.cpp b/ipc/CommandMessage.cpp index 8f53b77c..9d448aed 100644 --- a/ipc/CommandMessage.cpp +++ b/ipc/CommandMessage.cpp @@ -9,18 +9,25 @@ #include #include -CommandMessage::CommandMessage(MessageQueueMessage* receiverMessage): +CommandMessage::CommandMessage(MessageQueueMessageIF* 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; + return; } - internalMessage->setMessageSize(COMMAND_MESSAGE_SIZE); - setCommand(CMD_NONE); + if(receiverMessage->getMaximumMessageSize() < + MINIMUM_COMMAND_MESSAGE_SIZE) { + sif::error << "CommandMessage::ComandMessage: Passed message buffer" + " can not hold minimum "<< MINIMUM_COMMAND_MESSAGE_SIZE + << " bytes!" << std::endl; + return; + } + internalMessage->setMessageSize(MINIMUM_COMMAND_MESSAGE_SIZE); } -CommandMessage::CommandMessage(MessageQueueMessage* messageToSet, +CommandMessage::CommandMessage(MessageQueueMessageIF* messageToSet, Command_t command, uint32_t parameter1, uint32_t parameter2): CommandMessageBase(messageToSet) { if(messageToSet == nullptr) { @@ -28,7 +35,14 @@ CommandMessage::CommandMessage(MessageQueueMessage* messageToSet, " as the message queue message, pass the address of an actual" " message!" << std::endl; } - internalMessage->setMessageSize(COMMAND_MESSAGE_SIZE); + if(messageToSet->getMaximumMessageSize() < + MINIMUM_COMMAND_MESSAGE_SIZE) { + sif::error << "CommandMessage::ComandMessage: Passed message buffer" + " can not hold minimum "<< MINIMUM_COMMAND_MESSAGE_SIZE + << " bytes!" << std::endl; + return; + } + internalMessage->setMessageSize(MINIMUM_COMMAND_MESSAGE_SIZE); setCommand(command); setParameter(parameter1); setParameter2(parameter2); @@ -57,7 +71,7 @@ void CommandMessage::setParameter2(uint32_t parameter2) { } size_t CommandMessage::getMinimumMessageSize() const { - return COMMAND_MESSAGE_SIZE; + return MINIMUM_COMMAND_MESSAGE_SIZE; } size_t CommandMessage::getMaximumMessageSize() const { @@ -81,6 +95,13 @@ void CommandMessage::setReplyRejected(ReturnValue_t reason, setParameter2(initialCommand); } +ReturnValue_t CommandMessage::getRejectedReplyReason( + Command_t* initialCommand) const { + if(initialCommand != nullptr) { + *initialCommand = getParameter2(); + } + return getParameter(); +} void CommandMessage::clear() { clearCommandMessage(); diff --git a/ipc/CommandMessage.h b/ipc/CommandMessage.h index 434f8c8c..8e1e9c8c 100644 --- a/ipc/CommandMessage.h +++ b/ipc/CommandMessage.h @@ -42,8 +42,9 @@ public: * This is the size of a message as it is seen by the MessageQueue. * 14 of the 24 available MessageQueueMessage bytes are used. */ - static const size_t COMMAND_MESSAGE_SIZE = MessageQueueMessage::HEADER_SIZE - + sizeof(Command_t) + 2 * sizeof(uint32_t); + static const size_t MINIMUM_COMMAND_MESSAGE_SIZE = + MessageQueueMessage::HEADER_SIZE + sizeof(Command_t) + + 2 * sizeof(uint32_t); /** * Default Constructor, does not initialize anything. @@ -51,7 +52,7 @@ public: * This constructor should be used when receiving a Message, as the * content is filled by the MessageQueue. */ - CommandMessage(MessageQueueMessage* receiverMessage); + CommandMessage(MessageQueueMessageIF* receiverMessage); /** * This constructor creates a new message with all message content * initialized @@ -60,7 +61,7 @@ public: * @param parameter1 The first parameter * @param parameter2 The second parameter */ - CommandMessage(MessageQueueMessage* messageToSet, Command_t command, + CommandMessage(MessageQueueMessageIF* messageToSet, Command_t command, uint32_t parameter1, uint32_t parameter2); /** @@ -121,8 +122,11 @@ public: * Is needed quite often, so we better code it once only. */ void setToUnknownCommand(); + void setReplyRejected(ReturnValue_t reason, Command_t initialCommand = CMD_NONE); + ReturnValue_t getRejectedReplyReason( + Command_t* initialCommand = nullptr) const; }; diff --git a/ipc/CommandMessageBase.cpp b/ipc/CommandMessageBase.cpp index aa84bd1e..3ffe4daa 100644 --- a/ipc/CommandMessageBase.cpp +++ b/ipc/CommandMessageBase.cpp @@ -12,7 +12,7 @@ Command_t CommandMessageBase::getCommand() const { } void CommandMessageBase::setCommand(Command_t command) { - std::memcpy(internalMessage->getData(), &command, sizeof(command)); + std::memcpy(internalMessage->getData(), &command, sizeof(Command_t)); } uint8_t CommandMessageBase::getMessageType() const { @@ -53,3 +53,7 @@ void CommandMessageBase::setMessageSize(size_t messageSize) { size_t CommandMessageBase::getMessageSize() const { return internalMessage->getMessageSize(); } + +MessageQueueMessageIF* CommandMessageBase::getInternalMessage() const { + return internalMessage; +} diff --git a/ipc/CommandMessageBase.h b/ipc/CommandMessageBase.h index fa3fd477..b2b7d5f2 100644 --- a/ipc/CommandMessageBase.h +++ b/ipc/CommandMessageBase.h @@ -22,6 +22,9 @@ */ class CommandMessageBase: public CommandMessageIF { public: + static constexpr size_t HEADER_SIZE = sizeof(MessageQueueId_t) + + sizeof(Command_t); + CommandMessageBase(MessageQueueMessageIF* message); /** @@ -58,6 +61,7 @@ public: virtual void setMessageSize(size_t messageSize) override; virtual size_t getMessageSize() const override; + virtual MessageQueueMessageIF* getInternalMessage() const override; protected: /** * @brief Pointer to the message containing the data. @@ -65,7 +69,7 @@ protected: * 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; + MessageQueueMessageIF* internalMessage = nullptr; }; diff --git a/ipc/CommandMessageIF.h b/ipc/CommandMessageIF.h index fbc40f88..44853c38 100644 --- a/ipc/CommandMessageIF.h +++ b/ipc/CommandMessageIF.h @@ -6,6 +6,12 @@ #define MAKE_COMMAND_ID( number ) ((MESSAGE_ID << 8) + (number)) typedef uint16_t Command_t; +// TODO: actually, this interface propably does not have to implement +// MQM IF, because there is a getter function for the internal message.. +// But it is also convenient to have the full access to all MQM IF functions. +// That way, I can just pass CommandMessages to functions expecting a MQM IF. +// The command message implementations just forwards the calls. Maybe +// we should just leave it like that. class CommandMessageIF: public MessageQueueMessageIF { public: virtual ~CommandMessageIF() {}; @@ -20,6 +26,16 @@ public: * @return */ virtual uint8_t getMessageType() const = 0; + + /** + * This function is used to get a pointer to the internal message, as + * the command message implementations always operate on the memory + * contained in the message queue message implementation. + * This pointer can be used to set the internal message of different + * command message implementations. + * @return + */ + virtual MessageQueueMessageIF* getInternalMessage() const = 0; }; #endif /* FRAMEWORK_IPC_COMMANDMESSAGEIF_H_ */ diff --git a/ipc/MessageQueueMessage.h b/ipc/MessageQueueMessage.h index 2eb1f4f5..8716df54 100644 --- a/ipc/MessageQueueMessage.h +++ b/ipc/MessageQueueMessage.h @@ -88,12 +88,12 @@ public: * queue in the system. So, a change here may have significant impact on * the required resources. */ - static const size_t MAX_MESSAGE_SIZE = MAX_DATA_SIZE + HEADER_SIZE; + static constexpr size_t MAX_MESSAGE_SIZE = MAX_DATA_SIZE + HEADER_SIZE; /** * @brief Defines the minimum size of a message where only the * header is included */ - static const size_t MIN_MESSAGE_SIZE = HEADER_SIZE; + static constexpr size_t MIN_MESSAGE_SIZE = HEADER_SIZE; private: /** * @brief This is the internal buffer that contains the diff --git a/osal/FreeRTOS/MessageQueue.cpp b/osal/FreeRTOS/MessageQueue.cpp index 8c6ec80b..d44b0bc0 100644 --- a/osal/FreeRTOS/MessageQueue.cpp +++ b/osal/FreeRTOS/MessageQueue.cpp @@ -101,7 +101,7 @@ ReturnValue_t MessageQueue::flush(uint32_t* count) { } MessageQueueId_t MessageQueue::getId() const { - return (MessageQueueId_t) handle; + return reinterpret_cast(handle); } void MessageQueue::setDefaultDestination(MessageQueueId_t defaultDestination) { diff --git a/osal/FreeRTOS/MessageQueue.h b/osal/FreeRTOS/MessageQueue.h index 6165c1cf..c13a8a20 100644 --- a/osal/FreeRTOS/MessageQueue.h +++ b/osal/FreeRTOS/MessageQueue.h @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include @@ -85,14 +85,14 @@ public: * @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 ); + 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 ); + 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 @@ -100,7 +100,7 @@ public: * (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 ); + ReturnValue_t reply(MessageQueueMessageIF* message) override; /** * @brief With the sendMessage call, a queue message is sent to a receiving queue. @@ -113,9 +113,10 @@ public: * 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 = NO_QUEUE, - bool ignoreFault = false ); + 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. @@ -125,7 +126,8 @@ public: * This variable is set to zero by default. */ virtual ReturnValue_t sendToDefaultFrom( MessageQueueMessageIF* message, - MessageQueueId_t sentFrom = NO_QUEUE, bool ignoreFault = false ); + MessageQueueId_t sentFrom = NO_QUEUE, + bool ignoreFault = false) override; /** * @brief This function reads available messages from the message queue and returns the sender. @@ -135,7 +137,7 @@ public: * @param receivedFrom A pointer to a queue id in which the sender's id is stored. */ ReturnValue_t receiveMessage(MessageQueueMessageIF* message, - MessageQueueId_t *receivedFrom); + MessageQueueId_t *receivedFrom) override; /** * @brief This function reads available messages from the message queue. @@ -145,7 +147,7 @@ public: * 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); + ReturnValue_t receiveMessage(MessageQueueMessageIF* message) override; /** * Deletes all pending messages in the queue. * @param count The number of flushed messages. diff --git a/tmtcservices/CommandingServiceBase.cpp b/tmtcservices/CommandingServiceBase.cpp index 72351995..65053cc8 100644 --- a/tmtcservices/CommandingServiceBase.cpp +++ b/tmtcservices/CommandingServiceBase.cpp @@ -81,40 +81,58 @@ void CommandingServiceBase::handleCommandQueue() { ReturnValue_t result = RETURN_FAILED; for (result = commandQueue->receiveMessage(&reply); result == RETURN_OK; result = commandQueue->receiveMessage(&reply)) { - handleCommandMessage(reply); + if(reply.getInternalMessage() == nullptr) { + // This should never happen unless the passed message maximum size + // is too small! + sif::error << "CommandingServiceBase::handleCommandMessage: Reply" + "does not satisfy minimum requirements for a command " + "message!" << std::endl; + continue; + } + handleCommandMessage(&reply); } } -void CommandingServiceBase::handleCommandMessage(CommandMessage& reply) { +void CommandingServiceBase::handleCommandMessage(CommandMessage* reply) { bool isStep = false; MessageQueueMessage message; CommandMessage nextCommand(&message); - CommandMapIter iter; - if (reply.getSender() == MessageQueueIF::NO_QUEUE) { - handleUnrequestedReply(&reply); - return; - } - if ((iter = commandMap.find(reply.getSender())) == commandMap.end()) { - handleUnrequestedReply(&reply); + CommandMapIter iter = commandMap.find(reply->getSender()); + + // handle unrequested reply first + if (reply->getSender() == MessageQueueIF::NO_QUEUE or + iter == commandMap.end()) { + handleUnrequestedReply(reply); return; } nextCommand.setCommand(CommandMessage::CMD_NONE); + // Implemented by child class, specifies what to do with reply. - ReturnValue_t result = handleReply(&reply, iter->command, &iter->state, + ReturnValue_t result = handleReply(reply, iter->command, &iter->state, &nextCommand, iter->objectId, &isStep); + /* If the child implementation does not implement special handling for + * rejected replies (RETURN_FAILED is returned), a failure verification + * will be generated with the reason as the return code and the initial + * command as failure parameter 1 */ + if(reply->getCommand() == CommandMessage::REPLY_REJECTED and + result == RETURN_FAILED) { + result = reply->getRejectedReplyReason( + reinterpret_cast(&failureParameter1)); + } + switch (result) { case EXECUTION_COMPLETE: case RETURN_OK: case NO_STEP_MESSAGE: // handle result of reply handler implemented by developer. - handleReplyHandlerResult(result, iter, nextCommand, reply, isStep); + handleReplyHandlerResult(result, iter, &nextCommand, reply, isStep); break; case INVALID_REPLY: //might be just an unrequested reply at a bad moment - handleUnrequestedReply(&reply); + handleUnrequestedReply(reply); break; default: if (isStep) { @@ -138,17 +156,17 @@ void CommandingServiceBase::handleCommandMessage(CommandMessage& reply) { } void CommandingServiceBase::handleReplyHandlerResult(ReturnValue_t result, - CommandMapIter iter, CommandMessage& nextCommand, CommandMessage& reply, + CommandMapIter iter, CommandMessage* nextCommand, CommandMessage* reply, bool& isStep) { - iter->command = nextCommand.getCommand(); + iter->command = nextCommand->getCommand(); // In case a new command is to be sent immediately, this is performed here. // If no new command is sent, only analyse reply result by initializing // sendResult as RETURN_OK ReturnValue_t sendResult = RETURN_OK; - if (nextCommand.getCommand() != CommandMessage::CMD_NONE) { - sendResult = commandQueue->sendMessage(reply.getSender(), - &nextCommand); + if (nextCommand->getCommand() != CommandMessage::CMD_NONE) { + sendResult = commandQueue->sendMessage(reply->getSender(), + nextCommand); } if (sendResult == RETURN_OK) { @@ -168,14 +186,14 @@ void CommandingServiceBase::handleReplyHandlerResult(ReturnValue_t result, } else { if (isStep) { - nextCommand.clearCommandMessage(); + nextCommand->clearCommandMessage(); verificationReporter.sendFailureReport( TC_VERIFY::PROGRESS_FAILURE, iter->tcInfo.ackFlags, iter->tcInfo.tcPacketId, iter->tcInfo.tcSequenceControl, sendResult, ++iter->step, failureParameter1, failureParameter2); } else { - nextCommand.clearCommandMessage(); + nextCommand->clearCommandMessage(); verificationReporter.sendFailureReport( TC_VERIFY::COMPLETION_FAILURE, iter->tcInfo.ackFlags, iter->tcInfo.tcPacketId, @@ -366,9 +384,9 @@ void CommandingServiceBase::checkAndExecuteFifo(CommandMapIter iter) { } -void CommandingServiceBase::handleUnrequestedReply( - CommandMessage* reply) { - reply->clearCommandMessage(); +void CommandingServiceBase::handleUnrequestedReply(CommandMessageIF* reply) { + CommandMessage commandReply(reply->getInternalMessage()); + commandReply.clear(); } diff --git a/tmtcservices/CommandingServiceBase.h b/tmtcservices/CommandingServiceBase.h index 1dcafff8..5adfe4a6 100644 --- a/tmtcservices/CommandingServiceBase.h +++ b/tmtcservices/CommandingServiceBase.h @@ -147,9 +147,11 @@ protected: /** * This function is implemented by child services to specify how replies - * to a command from another software component are handled + * to a command from another software component are handled. * @param reply - * This is the reply in form of a command message. + * This is the reply which can be accessed via the command message + * interface. The internal message pointer can be passed to different + * command message implementations (see CommandMessageIF) * @param previousCommand * Command_t of related command * @param state [out/in] @@ -163,9 +165,12 @@ protected: * - @c RETURN_OK, @c EXECUTION_COMPLETE or @c NO_STEP_MESSAGE to * generate TC verification success * - @c INVALID_REPLY calls handleUnrequestedReply - * - Anything else triggers a TC verification failure + * - Anything else triggers a TC verification failure. If RETURN_FAILED + * is returned and the command ID is CommandMessage::REPLY_REJECTED, + * a failure verification message with the reason as the error parameter + * and the initial command as failure parameter 1. */ - virtual ReturnValue_t handleReply(const CommandMessage *reply, + virtual ReturnValue_t handleReply(const CommandMessageIF *reply, Command_t previousCommand, uint32_t *state, CommandMessage *optionalNextCommand, object_id_t objectId, bool *isStep) = 0; @@ -173,9 +178,13 @@ protected: /** * This function can be overidden to handle unrequested reply, * when the reply sender ID is unknown or is not found is the command map. + * The default implementation will clear the command message and all + * its contents. * @param reply + * Reply which is non-const so the default implementation can clear the + * message. */ - virtual void handleUnrequestedReply(CommandMessage *reply); + virtual void handleUnrequestedReply(CommandMessageIF *reply); virtual void doPeriodicOperation(); @@ -303,9 +312,9 @@ private: void startExecution(TcPacketStored *storedPacket, CommandMapIter iter); - void handleCommandMessage(CommandMessage& reply); + void handleCommandMessage(CommandMessage* reply); void handleReplyHandlerResult(ReturnValue_t result, CommandMapIter iter, - CommandMessage& nextCommand,CommandMessage& reply, bool& isStep); + CommandMessage* nextCommand,CommandMessage* reply, bool& isStep); void checkTimeout(); }; diff --git a/tmtcservices/VerificationReporter.cpp b/tmtcservices/VerificationReporter.cpp index 4484fb9b..b0247944 100644 --- a/tmtcservices/VerificationReporter.cpp +++ b/tmtcservices/VerificationReporter.cpp @@ -24,9 +24,8 @@ void VerificationReporter::sendSuccessReport(uint8_t set_report_id, current_packet->getPacketSequenceControl(), 0, set_step); ReturnValue_t status = MessageQueueSenderIF::sendMessage(acknowledgeQueue, &message); if (status != HasReturnvaluesIF::RETURN_OK) { - sif::error - << "VerificationReporter::sendSuccessReport: Error writing to queue. Code: " - << (uint16_t) status << std::endl; + sif::error << "VerificationReporter::sendSuccessReport: Error writing " + "to queue. Code: " << std::hex << (uint16_t) status << std::endl; } } @@ -40,9 +39,8 @@ void VerificationReporter::sendSuccessReport(uint8_t set_report_id, tcSequenceControl, 0, set_step); ReturnValue_t status = MessageQueueSenderIF::sendMessage(acknowledgeQueue, &message); if (status != HasReturnvaluesIF::RETURN_OK) { - sif::error - << "VerificationReporter::sendSuccessReport: Error writing to queue. Code: " - << (uint16_t) status << std::endl; + sif::error << "VerificationReporter::sendSuccessReport: Error writing " + "to queue. Code: " << std::hex << (uint16_t) status << std::endl; } }