Merge branch 'mueller_framework' into front_branch

This commit is contained in:
Robin Müller 2020-06-14 17:13:52 +02:00
commit cd424d79e7
24 changed files with 539 additions and 311 deletions

View File

@ -41,8 +41,8 @@ ReturnValue_t LocalDataPoolManager::initializeHousekeepingPoolEntriesOnce() {
} }
ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage( ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage(
MessageQueueMessage *message) { HousekeepingMessage& message) {
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_FAILED;
} }
ReturnValue_t LocalDataPoolManager::printPoolEntry( ReturnValue_t LocalDataPoolManager::printPoolEntry(

View File

@ -46,7 +46,7 @@ public:
LocalDataPoolManager operator=(const LocalDataPoolManager&) = delete; LocalDataPoolManager operator=(const LocalDataPoolManager&) = delete;
ReturnValue_t generateHousekeepingPacket(sid_t sid); 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 * This function is used to fill the local data pool map with pool

View File

@ -225,15 +225,6 @@ void DeviceHandlerBase::readCommandQueue() {
return; 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<CommandMessage*>(msgPtr);
// if(cmdMessage == nullptr) {
// sif::error << "DeviceHandlerBase::readCommandQueue: Could not cast"
// " message to CommandMessage!" << std::endl;
// return;
// }
if(healthHelperActive) { if(healthHelperActive) {
result = healthHelper.handleHealthCommand(&command); result = healthHelper.handleHealthCommand(&command);
if (result == RETURN_OK) { if (result == RETURN_OK) {
@ -256,11 +247,11 @@ void DeviceHandlerBase::readCommandQueue() {
return; return;
} }
// HousekeepingMessage* hkMessage = dynamic_cast<HousekeepingMessage*>(msgPtr); HousekeepingMessage hkMessage(&message);
// result = hkManager.handleHousekeepingMessage(hkMessage); result = hkManager.handleHousekeepingMessage(hkMessage);
// if (result == RETURN_OK) { if (result == RETURN_OK) {
// return; return;
// } }
result = handleDeviceHandlerMessage(&command); result = handleDeviceHandlerMessage(&command);
if (result == RETURN_OK) { 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, void DeviceHandlerBase::replyRawData(const uint8_t *data, size_t len,
MessageQueueId_t sendTo, bool isCommand) { 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; return;
} }
store_address_t address; store_address_t address;
@ -775,13 +766,12 @@ void DeviceHandlerBase::replyRawData(const uint8_t *data, size_t len,
DeviceHandlerMessage::setDeviceHandlerRawReplyMessage(&command, DeviceHandlerMessage::setDeviceHandlerRawReplyMessage(&command,
getObjectId(), address, isCommand); getObjectId(), address, isCommand);
// this->DeviceHandlerCommand = CommandMessage::CMD_NONE; result = commandQueue->sendMessage(sendTo, &command);
result = commandQueue->sendMessage(sendTo, &message);
if (result != RETURN_OK) { if (result != RETURN_OK) {
IPCStore->deleteData(address); 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.
} }
} }

View File

@ -5,7 +5,7 @@ HealthDevice::HealthDevice(object_id_t setObjectId,
MessageQueueId_t parentQueue) : MessageQueueId_t parentQueue) :
SystemObject(setObjectId), lastHealth(HEALTHY), parentQueue( SystemObject(setObjectId), lastHealth(HEALTHY), parentQueue(
parentQueue), commandQueue(), healthHelper(this, setObjectId) { 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() { HealthDevice::~HealthDevice() {

View File

@ -1,18 +1,46 @@
#include <framework/housekeeping/HousekeepingMessage.h> #include <framework/housekeeping/HousekeepingMessage.h>
#include <cstring>
HousekeepingMessage::HousekeepingMessage() { HousekeepingMessage::HousekeepingMessage(MessageQueueMessageIF* message):
CommandMessageBase(message) {
} }
void HousekeepingMessage::setHkReportMessage() { HousekeepingMessage::~HousekeepingMessage() {
} }
void HousekeepingMessage::setHkReportMessage(sid_t sid,
store_address_t storeId) {
CommandMessageBase::setCommand(HK_REPORT);
setSid(sid);
setParameter(storeId.raw);
}
//void HousekeepingMessage::setAddHkReportStructMessage(CommandMessage *message, size_t HousekeepingMessage::getMinimumMessageSize() const {
// set_t setId, store_address_t packet) { return HK_MESSAGE_SIZE;
// message->setCommand(ADD_HK_REPORT_STRUCT); }
// message->setParameter(setId);
// message->setParameter2(packet.raw);
//}
//void Housekeeping 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(), &parameter, sizeof(parameter));
}
void HousekeepingMessage::setSid(sid_t sid) {
std::memcpy(CommandMessageBase::getData(), &sid.raw, sizeof(sid.raw));
}

View File

@ -1,6 +1,8 @@
#ifndef FRAMEWORK_HK_HOUSEKEEPINGMESSAGE_H_ #ifndef FRAMEWORK_HK_HOUSEKEEPINGMESSAGE_H_
#define FRAMEWORK_HK_HOUSEKEEPINGMESSAGE_H_ #define FRAMEWORK_HK_HOUSEKEEPINGMESSAGE_H_
#include <framework/ipc/CommandMessage.h> #include <framework/ipc/CommandMessageBase.h>
#include <framework/ipc/FwMessageTypes.h>
#include <framework/objectmanager/SystemObjectIF.h>
#include <framework/storagemanager/StorageManagerIF.h> #include <framework/storagemanager/StorageManagerIF.h>
#include <limits> #include <limits>
@ -11,29 +13,34 @@ union sid_t {
struct { struct {
object_id_t objectId ; object_id_t objectId ;
// A generic 32 bit ID to identify unique HK packets for a single /**
// object. * A generic 32 bit ID to identify unique HK packets for a single
// For example, the DeviceCommandId_t is used for DeviceHandlers * object. For example, the DeviceCommandId_t is used for
* DeviceHandlers
*/
uint32_t ownerSetId; 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; uint64_t raw;
}; };
class HousekeepingMessage: public MessageQueueMessage { class HousekeepingMessage : public CommandMessageBase {
public: 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 * No instances of a message shall be created, instead
* a CommandMessage instance is manipulated. * a CommandMessage instance is manipulated.
*/ */
HousekeepingMessage(); HousekeepingMessage(MessageQueueMessageIF* message);
// HousekeepingMessage(const HousekeepingMessage&) = delete; virtual ~HousekeepingMessage();
// HousekeepingMessage operator=(const HousekeepingMessage &) = delete;
static constexpr uint8_t MESSAGE_ID = messagetypes::HOUSEKEEPING; static constexpr uint8_t MESSAGE_ID = messagetypes::HOUSEKEEPING;
static constexpr Command_t ADD_HK_REPORT_STRUCT = static constexpr Command_t ADD_HK_REPORT_STRUCT =
MAKE_COMMAND_ID(1); MAKE_COMMAND_ID(1);
static constexpr Command_t ADD_DIAGNOSTICS_REPORT_STRUCT = static constexpr Command_t ADD_DIAGNOSTICS_REPORT_STRUCT =
@ -78,9 +85,18 @@ public:
static constexpr Command_t MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL = static constexpr Command_t MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL =
MAKE_COMMAND_ID(32); MAKE_COMMAND_ID(32);
// static void setAddHkReportStructMessage(CommandMessage* message, void setHkReportMessage(sid_t sid, store_address_t storeId);
// DevisetId, store_address_t packet);
static void setHkReportMessage(); 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);
}; };

View File

@ -1,170 +1,81 @@
#include <framework/devicehandlers/DeviceHandlerMessage.h>
#include <framework/health/HealthMessage.h>
#include <framework/ipc/CommandMessage.h> #include <framework/ipc/CommandMessage.h>
#include <framework/memory/MemoryMessage.h> #include <cstring>
#include <framework/modes/ModeMessage.h>
#include <framework/monitoring/MonitoringMessage.h>
#include <framework/subsystem/modes/ModeSequenceMessage.h>
#include <framework/tmstorage/TmStoreMessage.h>
#include <framework/parameters/ParameterMessage.h>
namespace messagetypes { CommandMessage::CommandMessage(MessageQueueMessageIF* receiverMessage):
// Implemented in config. CommandMessageBase(receiverMessage) {
void clearMissionMessage(CommandMessage* message);
}
CommandMessage::CommandMessage(MessageQueueMessage* receiverMessage):
internalMessage(receiverMessage) {
if(receiverMessage == nullptr) { if(receiverMessage == nullptr) {
sif::error << "CommandMessage::CommandMessage: Don't pass a nullptr" sif::error << "CommandMessage::CommandMessage: Don't pass a nullptr"
" as the message queue message, pass the address of an actual" " as the message queue message, pass the address of an actual"
" message!" << std::endl; " message!" << std::endl;
return;
} }
internalMessage->messageSize = COMMAND_MESSAGE_SIZE; if(receiverMessage->getMaximumMessageSize() <
setCommand(CMD_NONE); 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): Command_t command, uint32_t parameter1, uint32_t parameter2):
internalMessage(messageToSet) { CommandMessageBase(messageToSet) {
if(messageToSet == nullptr) { if(messageToSet == nullptr) {
sif::error << "CommandMessage::CommandMessage: Don't pass a nullptr" sif::error << "CommandMessage::CommandMessage: Don't pass a nullptr"
" as the message queue message, pass the address of an actual" " as the message queue message, pass the address of an actual"
" message!" << std::endl; " message!" << std::endl;
} }
internalMessage->messageSize = 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); setCommand(command);
setParameter(parameter1); setParameter(parameter1);
setParameter2(parameter2); setParameter2(parameter2);
} }
Command_t CommandMessage::getCommand() const {
Command_t command;
memcpy(&command, internalMessage->getData(), sizeof(Command_t));
return command;
}
uint8_t CommandMessage::getMessageType() const {
return getCommand() >> 8 & 0xff;
}
void CommandMessage::setCommand(Command_t command) {
memcpy(internalMessage->getData(), &command, sizeof(command));
}
uint32_t CommandMessage::getParameter() const { uint32_t CommandMessage::getParameter() const {
uint32_t parameter1; uint32_t parameter1;
memcpy(&parameter1, internalMessage->getData() + sizeof(Command_t), std::memcpy(&parameter1, CommandMessageBase::getData(), sizeof(parameter1));
sizeof(parameter1));
return parameter1; return parameter1;
} }
void CommandMessage::setParameter(uint32_t parameter1) { void CommandMessage::setParameter(uint32_t parameter1) {
memcpy(internalMessage->getData() + sizeof(Command_t), std::memcpy(CommandMessageBase::getData(), &parameter1, sizeof(parameter1));
&parameter1, sizeof(parameter1));
} }
uint32_t CommandMessage::getParameter2() const { uint32_t CommandMessage::getParameter2() const {
uint32_t parameter2; uint32_t parameter2;
memcpy(&parameter2, internalMessage->getData() + sizeof(Command_t) std::memcpy(&parameter2, CommandMessageBase::getData() + sizeof(uint32_t),
+ sizeof(uint32_t), sizeof(parameter2)); sizeof(parameter2));
return parameter2; return parameter2;
} }
void CommandMessage::setParameter2(uint32_t parameter2) { void CommandMessage::setParameter2(uint32_t parameter2) {
memcpy(internalMessage-> getData() + sizeof(Command_t) + sizeof(uint32_t), std::memcpy(CommandMessageBase::getData() + sizeof(uint32_t), &parameter2,
&parameter2, sizeof(parameter2)); sizeof(parameter2));
} }
void CommandMessage::clear() { size_t CommandMessage::getMinimumMessageSize() const {
clearCommandMessage(); return MINIMUM_COMMAND_MESSAGE_SIZE;
} }
void CommandMessage::clearCommandMessage() { size_t CommandMessage::getMaximumMessageSize() const {
switch(getMessageType()){ return MessageQueueMessage::MAX_MESSAGE_SIZE;
case messagetypes::MODE_COMMAND:
ModeMessage::clear(this);
break;
case messagetypes::HEALTH_COMMAND:
HealthMessage::clear(this);
break;
case messagetypes::MODE_SEQUENCE:
ModeSequenceMessage::clear(this);
break;
case messagetypes::ACTION:
ActionMessage::clear(this);
break;
case messagetypes::DEVICE_HANDLER_COMMAND:
DeviceHandlerMessage::clear(this);
break;
case messagetypes::MEMORY:
MemoryMessage::clear(this);
break;
case messagetypes::MONITORING:
MonitoringMessage::clear(this);
break;
case messagetypes::TM_STORE:
TmStoreMessage::clear(this);
break;
case messagetypes::PARAMETER:
ParameterMessage::clear(this);
break;
default:
messagetypes::clearMissionMessage(this);
break;
}
} }
bool CommandMessage::isClearedCommandMessage() { bool CommandMessage::isClearedCommandMessage() {
return getCommand() == CMD_NONE; return getCommand() == CMD_NONE;
} }
size_t CommandMessage::getMinimumMessageSize() const {
return COMMAND_MESSAGE_SIZE;
}
void CommandMessage::setToUnknownCommand() { void CommandMessage::setToUnknownCommand() {
Command_t initialCommand = getCommand(); Command_t initialCommand = getCommand();
clearCommandMessage(); this->clear();
setReplyRejected(UNKNOWN_COMMAND, initialCommand); setReplyRejected(UNKNOWN_COMMAND, initialCommand);
} }
void CommandMessage::setReplyRejected(ReturnValue_t reason,
Command_t initialCommand) {
setCommand(REPLY_REJECTED);
setParameter(reason);
setParameter2(initialCommand);
}
MessageQueueId_t CommandMessage::getSender() const {
return internalMessage->getSender();
}
uint8_t* CommandMessage::getBuffer() {
return internalMessage->getBuffer();
}
void CommandMessage::setSender(MessageQueueId_t setId) {
internalMessage->setSender(setId);
}
const uint8_t* CommandMessage::getBuffer() const {
return internalMessage->getBuffer();
}
uint8_t* CommandMessage::getData() {
return internalMessage->getData();
}
const uint8_t* CommandMessage::getData() const {
return internalMessage->getData();
}
size_t CommandMessage::getMessageSize() const {
return COMMAND_MESSAGE_SIZE;
}
size_t CommandMessage::getMaximumMessageSize() const {
return MessageQueueMessage::MAX_MESSAGE_SIZE;
}

View File

@ -1,47 +1,34 @@
#ifndef FRAMEWORK_IPC_COMMANDMESSAGE_H_ #ifndef FRAMEWORK_IPC_COMMANDMESSAGE_H_
#define FRAMEWORK_IPC_COMMANDMESSAGE_H_ #define FRAMEWORK_IPC_COMMANDMESSAGE_H_
#include <framework/ipc/CommandMessageBase.h>
#include <framework/ipc/MessageQueueMessage.h> #include <framework/ipc/MessageQueueMessage.h>
#include <framework/ipc/FwMessageTypes.h> #include <framework/ipc/FwMessageTypes.h>
#include <config/ipc/MissionMessageTypes.h>
#define MAKE_COMMAND_ID( number ) ((MESSAGE_ID << 8) + (number))
typedef uint16_t Command_t;
/** /**
* @brief Used to pass command messages between tasks. Primary message type * @brief Default command message used to pass command messages between tasks.
* for IPC. Contains sender, 2-byte command field, and 2 4-byte * Primary message type for IPC. Contains sender, 2-byte command ID
* parameters. * field, and 2 4-byte parameters.
* @details * @details
* It operates on an external memory which is contained inside a * It operates on an external memory which is contained inside a
* MessageQueueMessage by taking its address. * class implementing MessageQueueMessageIF by taking its address.
* This allows for a more flexible designs of message implementations. * This allows for a more flexible designs of message implementations.
* The pointer can be passed to different message implementations without * The pointer can be passed to different message implementations without
* the need of unnecessary copying. * the need of unnecessary copying.
*
* The command message is based of the generic MessageQueueMessage which
* currently has an internal message size of 28 bytes.
* @author Bastian Baetz * @author Bastian Baetz
*/ */
class CommandMessage: public MessageQueueMessageIF { class CommandMessage: public CommandMessageBase {
public: public:
static const uint8_t INTERFACE_ID = CLASS_ID::COMMAND_MESSAGE;
static const ReturnValue_t UNKNOWN_COMMAND = MAKE_RETURN_CODE(0x01);
static const uint8_t MESSAGE_ID = messagetypes::COMMAND;
//! Used internally, will be ignored
static const Command_t CMD_NONE = MAKE_COMMAND_ID( 0 );
static const Command_t REPLY_COMMAND_OK = MAKE_COMMAND_ID( 3 );
//! Reply indicating that the current command was rejected,
//! par1 should contain the error code
static const Command_t REPLY_REJECTED = MAKE_COMMAND_ID( 0xD1 );
/** /**
* This is the size of a message as it is seen by the MessageQueue. * This is the size of a message as it is seen by the MessageQueue.
* 14 of the 24 available MessageQueueMessage bytes are used. * 14 of the 24 available MessageQueueMessage bytes are used.
*/ */
static const size_t COMMAND_MESSAGE_SIZE = MessageQueueMessage::HEADER_SIZE static const size_t MINIMUM_COMMAND_MESSAGE_SIZE =
+ sizeof(Command_t) + 2 * sizeof(uint32_t); MessageQueueMessage::HEADER_SIZE + sizeof(Command_t) +
2 * sizeof(uint32_t);
/** /**
* Default Constructor, does not initialize anything. * Default Constructor, does not initialize anything.
@ -49,7 +36,7 @@ public:
* This constructor should be used when receiving a Message, as the * This constructor should be used when receiving a Message, as the
* content is filled by the MessageQueue. * content is filled by the MessageQueue.
*/ */
CommandMessage(MessageQueueMessage* receiverMessage); CommandMessage(MessageQueueMessageIF* receiverMessage);
/** /**
* This constructor creates a new message with all message content * This constructor creates a new message with all message content
* initialized * initialized
@ -58,7 +45,7 @@ public:
* @param parameter1 The first parameter * @param parameter1 The first parameter
* @param parameter2 The second parameter * @param parameter2 The second parameter
*/ */
CommandMessage(MessageQueueMessage* messageToSet, Command_t command, CommandMessage(MessageQueueMessageIF* messageToSet, Command_t command,
uint32_t parameter1, uint32_t parameter2); uint32_t parameter1, uint32_t parameter2);
/** /**
@ -66,39 +53,11 @@ public:
*/ */
virtual ~CommandMessage() {} virtual ~CommandMessage() {}
/** /** MessageQueueMessageIF functions used for minimum size check. */
* Read the DeviceHandlerCommand_t that is stored in the message,
* usually used after receiving.
*
* @return the Command stored in the Message
*/
Command_t getCommand() const;
/*
* MessageQueueMessageIF functions, which generally just call the
* respective functions of the internal message
*/
uint8_t * getBuffer() override;
const uint8_t * getBuffer() const override;
void setSender(MessageQueueId_t setId) override;
MessageQueueId_t getSender() const override;
uint8_t * getData() override;
const uint8_t* getData() const override;
size_t getMinimumMessageSize() const override; size_t getMinimumMessageSize() const override;
size_t getMessageSize() const override; /** MessageQueueMessageIF functions used for maximum size check. */
size_t getMaximumMessageSize() const override; size_t getMaximumMessageSize() const override;
/**
* Extract message ID, which is the first byte of the command ID.
* @return
*/
uint8_t getMessageType() const;
/**
* Set the command type of the message
* @param the Command to be sent
*/
void setCommand(Command_t command);
/** /**
* Get the first parameter of the message * Get the first parameter of the message
* @return the first Parameter of the message * @return the first Parameter of the message
@ -123,20 +82,6 @@ public:
*/ */
void setParameter2(uint32_t parameter2); void setParameter2(uint32_t parameter2);
/**
* Set the command to CMD_NONE and try to find
* the correct class to handle a more detailed
* clear.
* Also, calls a mission-specific clearMissionMessage
* function to separate between framework and mission
* messages. Not optimal, may be replaced by totally
* different auto-delete solution (e.g. smart pointers).
*
*/
void clearCommandMessage();
void clear() override;
/** /**
* check if a message was cleared * check if a message was cleared
* *
@ -149,17 +94,6 @@ public:
* Is needed quite often, so we better code it once only. * Is needed quite often, so we better code it once only.
*/ */
void setToUnknownCommand(); void setToUnknownCommand();
void setReplyRejected(ReturnValue_t reason,
Command_t initialCommand = CMD_NONE);
private:
/**
* @brief Pointer to the message containing the data.
* @details
* The command message does not actually own the memory containing a
* message, it just oprates on it via a pointer to a message queue message.
*/
MessageQueueMessage* internalMessage;
}; };

View File

@ -0,0 +1,82 @@
#include <framework/ipc/CommandMessageBase.h>
#include <framework/ipc/CommandMessageCleaner.h>
#include <cstring>
CommandMessageBase::CommandMessageBase(MessageQueueMessageIF *message):
internalMessage(message) {
}
Command_t CommandMessageBase::getCommand() const {
Command_t command;
std::memcpy(&command, internalMessage->getData(), sizeof(Command_t));
return command;
}
void CommandMessageBase::setCommand(Command_t command) {
std::memcpy(internalMessage->getData(), &command, sizeof(Command_t));
}
uint8_t CommandMessageBase::getMessageType() const {
// first byte of command ID.
return getCommand() >> 8 & 0xff;
}
MessageQueueId_t CommandMessageBase::getSender() const {
return internalMessage->getSender();
}
uint8_t* CommandMessageBase::getBuffer() {
return internalMessage->getBuffer();
}
void CommandMessageBase::setSender(MessageQueueId_t setId) {
internalMessage->setSender(setId);
}
const uint8_t* CommandMessageBase::getBuffer() const {
return internalMessage->getBuffer();
}
// Header includes command ID.
uint8_t* CommandMessageBase::getData() {
return internalMessage->getData() + sizeof(Command_t);
}
// Header includes command ID.
const uint8_t* CommandMessageBase::getData() const {
return internalMessage->getData() + sizeof(Command_t);
}
void CommandMessageBase::setMessageSize(size_t messageSize) {
internalMessage->setMessageSize(messageSize);
}
size_t CommandMessageBase::getMessageSize() const {
return internalMessage->getMessageSize();
}
MessageQueueMessageIF* CommandMessageBase::getInternalMessage() const {
return internalMessage;
}
void CommandMessageBase::setReplyRejected(ReturnValue_t reason,
Command_t initialCommand) {
std::memcpy(getData(), &reason, sizeof(reason));
std::memcpy(getData() + sizeof(reason), &initialCommand,
sizeof(initialCommand));
}
ReturnValue_t CommandMessageBase::getReplyRejectedReason(
Command_t *initialCommand) const {
ReturnValue_t reason = HasReturnvaluesIF::RETURN_FAILED;
std::memcpy(&reason, getData(), sizeof(reason));
if(initialCommand != nullptr) {
std::memcpy(initialCommand, getData() + sizeof(reason),
sizeof(Command_t));
}
return reason;
}
void CommandMessageBase::clear() {
CommandMessageCleaner::clearCommandMessage(this);
}

92
ipc/CommandMessageBase.h Normal file
View File

@ -0,0 +1,92 @@
#ifndef FRAMEWORK_IPC_COMMANDMESSAGEBASE_H_
#define FRAMEWORK_IPC_COMMANDMESSAGEBASE_H_
#include <framework/ipc/CommandMessageIF.h>
#include <framework/ipc/MessageQueueMessage.h>
/**
* @brief Base implementation of a generic command message, which has
* a Command_t ID and message type ID in the header in addition
* to the sender message queue ID.
* @details
* This is the base implementation serves as a base for other command messages
* and which implements most functions required for MessageQueueMessageIF.
* The only functions which have to be supplied by a specific command message
* impelementations are the size related functions which are used for
* size checks:
*
* 1. getMinimumMessageSize()
* 2. getMaximumMessageSize()
*
* Don't forget to set the message size of the passed message in the concrete
* commandmessage implementation!
*/
class CommandMessageBase: public CommandMessageIF {
public:
CommandMessageBase(MessageQueueMessageIF* message);
/**
* Read the DeviceHandlerCommand_t that is stored in the message,
* usually used after receiving.
*
* @return the Command stored in the Message
*/
virtual Command_t getCommand() const override;
/**
* Set the command type of the message. Default implementation also
* sets the message type, which will be the first byte of the command ID.
* @param the Command to be sent
*/
virtual void setCommand(Command_t command);
/**
* Extract message ID, which is the first byte of the command ID for the
* default implementation.
* @return
*/
virtual uint8_t getMessageType() const override;
/*
* MessageQueueMessageIF functions, which generally just call the
* respective functions of the internal message queue message.
*/
virtual uint8_t * getBuffer() override;
virtual const uint8_t * getBuffer() const override;
virtual void setSender(MessageQueueId_t setId) override;
virtual MessageQueueId_t getSender() const override;
virtual uint8_t * getData() override;
virtual const uint8_t* getData() const override;
virtual void setMessageSize(size_t messageSize) override;
virtual size_t getMessageSize() const override;
/**
* A command message can be rejected and needs to offer a function
* to set a rejected reply
* @param reason
* @param initialCommand
*/
void setReplyRejected(ReturnValue_t reason,
Command_t initialCommand) override;
/**
* Corrensonding getter function.
* @param initialCommand
* @return
*/
ReturnValue_t getReplyRejectedReason(
Command_t* initialCommand = nullptr) const override;
virtual MessageQueueMessageIF* getInternalMessage() const override;
virtual void clear() override;
protected:
/**
* @brief Pointer to the message containing the data.
* @details
* The command message does not actually own the memory containing a
* message, it just oprates on it via a pointer to a message queue message.
*/
MessageQueueMessageIF* internalMessage = nullptr;
};
#endif /* FRAMEWORK_IPC_COMMANDMESSAGEBASE_H_ */

View File

@ -0,0 +1,45 @@
#include <framework/ipc/CommandMessageCleaner.h>
#include <framework/devicehandlers/DeviceHandlerMessage.h>
#include <framework/health/HealthMessage.h>
#include <framework/memory/MemoryMessage.h>
#include <framework/modes/ModeMessage.h>
#include <framework/monitoring/MonitoringMessage.h>
#include <framework/subsystem/modes/ModeSequenceMessage.h>
#include <framework/tmstorage/TmStoreMessage.h>
#include <framework/parameters/ParameterMessage.h>
void CommandMessageCleaner::clearCommandMessage(CommandMessageIF* message) {
switch(message->getMessageType()){
case messagetypes::MODE_COMMAND:
ModeMessage::clear(dynamic_cast<CommandMessage*>(message));
break;
case messagetypes::HEALTH_COMMAND:
HealthMessage::clear(dynamic_cast<CommandMessage*>(message));
break;
case messagetypes::MODE_SEQUENCE:
ModeSequenceMessage::clear(dynamic_cast<CommandMessage*>(message));
break;
case messagetypes::ACTION:
ActionMessage::clear(dynamic_cast<CommandMessage*>(message));
break;
case messagetypes::DEVICE_HANDLER_COMMAND:
DeviceHandlerMessage::clear(dynamic_cast<CommandMessage*>(message));
break;
case messagetypes::MEMORY:
MemoryMessage::clear(dynamic_cast<CommandMessage*>(message));
break;
case messagetypes::MONITORING:
MonitoringMessage::clear(dynamic_cast<CommandMessage*>(message));
break;
case messagetypes::TM_STORE:
TmStoreMessage::clear(dynamic_cast<CommandMessage*>(message));
break;
case messagetypes::PARAMETER:
ParameterMessage::clear(dynamic_cast<CommandMessage*>(message));
break;
default:
messagetypes::clearMissionMessage(message);
break;
}
}

View File

@ -0,0 +1,16 @@
#ifndef FRAMEWORK_IPC_COMMANDMESSAGECLEANER_H_
#define FRAMEWORK_IPC_COMMANDMESSAGECLEANER_H_
#include <framework/ipc/CommandMessageIF.h>
namespace messagetypes {
// Implemented in config.
void clearMissionMessage(CommandMessageIF* message);
}
class CommandMessageCleaner {
public:
static void clearCommandMessage(CommandMessageIF* message);
};
#endif /* FRAMEWORK_IPC_COMMANDMESSAGECLEANER_H_ */

75
ipc/CommandMessageIF.h Normal file
View File

@ -0,0 +1,75 @@
#ifndef FRAMEWORK_IPC_COMMANDMESSAGEIF_H_
#define FRAMEWORK_IPC_COMMANDMESSAGEIF_H_
#include <framework/ipc/MessageQueueMessageIF.h>
#include <framework/ipc/FwMessageTypes.h>
#include <framework/returnvalues/HasReturnvaluesIF.h>
#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:
static constexpr size_t HEADER_SIZE = sizeof(MessageQueueId_t) +
sizeof(Command_t);
static const uint8_t INTERFACE_ID = CLASS_ID::COMMAND_MESSAGE;
static const ReturnValue_t UNKNOWN_COMMAND = MAKE_RETURN_CODE(0x01);
static const uint8_t MESSAGE_ID = messagetypes::COMMAND;
//! Used internally, shall be ignored
static const Command_t CMD_NONE = MAKE_COMMAND_ID( 0 );
static const Command_t REPLY_COMMAND_OK = MAKE_COMMAND_ID( 1 );
//! Reply indicating that the current command was rejected,
//! par1 should contain the error code
static const Command_t REPLY_REJECTED = MAKE_COMMAND_ID( 2 );
virtual ~CommandMessageIF() {};
/**
* A command message shall have a uint16_t command ID field.
* @return
*/
virtual Command_t getCommand() const = 0;
/**
* A command message shall have a uint8_t message type ID field.
* @return
*/
virtual uint8_t getMessageType() const = 0;
/**
* A command message can be rejected and needs to offer a function
* to set a rejected reply
* @param reason
* @param initialCommand
*/
virtual void setReplyRejected(ReturnValue_t reason,
Command_t initialCommand) = 0;
/**
* Corrensonding getter function.
* @param initialCommand
* @return
*/
virtual ReturnValue_t getReplyRejectedReason(
Command_t* initialCommand = nullptr) 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_ */

View File

@ -75,3 +75,7 @@ size_t MessageQueueMessage::getMessageSize() const {
size_t MessageQueueMessage::getMaximumMessageSize() const { size_t MessageQueueMessage::getMaximumMessageSize() const {
return this->MAX_MESSAGE_SIZE; return this->MAX_MESSAGE_SIZE;
} }
void MessageQueueMessage::setMessageSize(size_t messageSize) {
this->messageSize = messageSize;
}

View File

@ -3,7 +3,7 @@
#include <framework/ipc/MessageQueueMessageIF.h> #include <framework/ipc/MessageQueueMessageIF.h>
#include <framework/ipc/MessageQueueSenderIF.h> #include <framework/ipc/MessageQueueSenderIF.h>
#include <stddef.h> #include <cstddef>
/** /**
* @brief This class is the representation and data organizer * @brief This class is the representation and data organizer
@ -88,12 +88,12 @@ public:
* queue in the system. So, a change here may have significant impact on * queue in the system. So, a change here may have significant impact on
* the required resources. * 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 * @brief Defines the minimum size of a message where only the
* header is included * header is included
*/ */
static const size_t MIN_MESSAGE_SIZE = HEADER_SIZE; static constexpr size_t MIN_MESSAGE_SIZE = HEADER_SIZE;
private: private:
/** /**
* @brief This is the internal buffer that contains the * @brief This is the internal buffer that contains the
@ -150,6 +150,7 @@ public:
virtual size_t getMinimumMessageSize() const override; virtual size_t getMinimumMessageSize() const override;
virtual size_t getMessageSize() const override; virtual size_t getMessageSize() const override;
virtual void setMessageSize(size_t messageSize) override;
virtual size_t getMaximumMessageSize() const override; virtual size_t getMaximumMessageSize() const override;

View File

@ -24,7 +24,8 @@ public:
/** /**
* @brief With this method, the whole content and the message * @brief With this method, the whole content and the message
* size is set to zero. * size is set to zero. Implementations should also take care
* to clear data which is stored indirectly (e.g. storage data).
*/ */
virtual void clear() = 0; virtual void clear() = 0;
@ -77,6 +78,7 @@ public:
* @return * @return
*/ */
virtual size_t getMessageSize() const = 0; virtual size_t getMessageSize() const = 0;
virtual void setMessageSize(size_t messageSize) = 0;
/** /**
* Get maximum allowed size of current message implementation. * Get maximum allowed size of current message implementation.

View File

@ -119,7 +119,7 @@ void MemoryHelper::completeDump(ReturnValue_t errorCode,
break; break;
} }
if (queueToUse->sendMessage(lastSender, &reply) != RETURN_OK) { if (queueToUse->sendMessage(lastSender, &reply) != RETURN_OK) {
reply.clearCommandMessage(); reply.clear();
} }
} }

View File

@ -101,7 +101,7 @@ ReturnValue_t MessageQueue::flush(uint32_t* count) {
} }
MessageQueueId_t MessageQueue::getId() const { MessageQueueId_t MessageQueue::getId() const {
return (MessageQueueId_t) handle; return reinterpret_cast<MessageQueueId_t>(handle);
} }
void MessageQueue::setDefaultDestination(MessageQueueId_t defaultDestination) { void MessageQueue::setDefaultDestination(MessageQueueId_t defaultDestination) {

View File

@ -3,7 +3,7 @@
#include <framework/internalError/InternalErrorReporterIF.h> #include <framework/internalError/InternalErrorReporterIF.h>
#include <framework/ipc/MessageQueueIF.h> #include <framework/ipc/MessageQueueIF.h>
#include <framework/ipc/MessageQueueMessage.h> #include <framework/ipc/MessageQueueMessageIF.h>
#include <framework/osal/FreeRTOS/TaskManagement.h> #include <framework/osal/FreeRTOS/TaskManagement.h>
#include <freertos/FreeRTOS.h> #include <freertos/FreeRTOS.h>
@ -85,14 +85,14 @@ public:
* @param ignoreFault If set to true, the internal software fault counter is not incremented if queue is full. * @param ignoreFault If set to true, the internal software fault counter is not incremented if queue is full.
*/ */
ReturnValue_t sendMessage(MessageQueueId_t sendTo, 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. * @brief This operation sends a message to the default destination.
* @details As in the sendMessage method, this function uses the sendToDefault call of the * @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. * MessageQueueSender parent class and adds its queue id as "sentFrom" information.
* @param message A pointer to a previously created message, which is sent. * @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. * @brief This operation sends a message to the last communication partner.
* @details This operation simplifies answering an incoming message by using the stored * @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. * (i.e. lastPartner is zero), an error code is returned.
* @param message A pointer to a previously created message, which is sent. * @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. * @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. * 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. * @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, virtual ReturnValue_t sendMessageFrom(MessageQueueId_t sendTo,
MessageQueueMessageIF* message, MessageQueueId_t sentFrom = NO_QUEUE, MessageQueueMessageIF* message,
bool ignoreFault = false ); MessageQueueId_t sentFrom = NO_QUEUE,
bool ignoreFault = false) override;
/** /**
* @brief The sendToDefault method sends a queue message to the default destination. * @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. * This variable is set to zero by default.
*/ */
virtual ReturnValue_t sendToDefaultFrom( MessageQueueMessageIF* message, 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. * @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. * @param receivedFrom A pointer to a queue id in which the sender's id is stored.
*/ */
ReturnValue_t receiveMessage(MessageQueueMessageIF* message, ReturnValue_t receiveMessage(MessageQueueMessageIF* message,
MessageQueueId_t *receivedFrom); MessageQueueId_t *receivedFrom) override;
/** /**
* @brief This function reads available messages from the message queue. * @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. * message's content is cleared and the function returns immediately.
* @param message A pointer to a message in which the received data is stored. * @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. * Deletes all pending messages in the queue.
* @param count The number of flushed messages. * @param count The number of flushed messages.

View File

@ -37,9 +37,13 @@ ReturnValue_t SerialBufferAdapter<count_t>::serialize(uint8_t** buffer_,
} }
if (constBuffer != nullptr) { if (constBuffer != nullptr) {
memcpy(*buffer_, this->constBuffer, bufferLength); memcpy(*buffer_, this->constBuffer, bufferLength);
} else if (buffer != nullptr) { }
else if (buffer != nullptr) {
// This will propably be never reached, constBuffer should always be
// set if non-const buffer is set.
memcpy(*buffer_, this->buffer, bufferLength); memcpy(*buffer_, this->buffer, bufferLength);
} else { }
else {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
*size_ += bufferLength; *size_ += bufferLength;
@ -93,7 +97,7 @@ template<typename count_t>
uint8_t * SerialBufferAdapter<count_t>::getBuffer() { uint8_t * SerialBufferAdapter<count_t>::getBuffer() {
if(buffer == nullptr) { if(buffer == nullptr) {
sif::error << "Wrong access function for stored type !" sif::error << "Wrong access function for stored type !"
" Use getConstBuffer()" << std::endl; " Use getConstBuffer()." << std::endl;
return nullptr; return nullptr;
} }
return buffer; return buffer;
@ -110,9 +114,10 @@ const uint8_t * SerialBufferAdapter<count_t>::getConstBuffer() {
template<typename count_t> template<typename count_t>
void SerialBufferAdapter<count_t>::setBuffer(uint8_t* buffer, void SerialBufferAdapter<count_t>::setBuffer(uint8_t* buffer,
count_t buffer_length) { count_t bufferLength) {
this->buffer = buffer; this->buffer = buffer;
bufferLength = buffer_length; this->constBuffer = buffer;
this->bufferLength = bufferLength;
} }

View File

@ -67,7 +67,7 @@ public:
uint8_t * getBuffer(); uint8_t * getBuffer();
const uint8_t * getConstBuffer(); const uint8_t * getConstBuffer();
void setBuffer(uint8_t* buffer_, count_t bufferLength_); void setBuffer(uint8_t* buffer, count_t bufferLength);
private: private:
bool serializeLength = false; bool serializeLength = false;
const uint8_t *constBuffer = nullptr; const uint8_t *constBuffer = nullptr;

View File

@ -81,40 +81,58 @@ void CommandingServiceBase::handleCommandQueue() {
ReturnValue_t result = RETURN_FAILED; ReturnValue_t result = RETURN_FAILED;
for (result = commandQueue->receiveMessage(&reply); result == RETURN_OK; for (result = commandQueue->receiveMessage(&reply); result == RETURN_OK;
result = commandQueue->receiveMessage(&reply)) { 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(CommandMessageIF* reply) {
bool isStep = false; bool isStep = false;
MessageQueueMessage message; MessageQueueMessage message;
CommandMessage nextCommand(&message); CommandMessage nextCommand(&message);
CommandMapIter iter; CommandMapIter iter = commandMap.find(reply->getSender());
if (reply.getSender() == MessageQueueIF::NO_QUEUE) {
handleUnrequestedReply(&reply); // handle unrequested reply first
return; if (reply->getSender() == MessageQueueIF::NO_QUEUE or
} iter == commandMap.end()) {
if ((iter = commandMap.find(reply.getSender())) == commandMap.end()) { handleUnrequestedReply(reply);
handleUnrequestedReply(&reply);
return; return;
} }
nextCommand.setCommand(CommandMessage::CMD_NONE); nextCommand.setCommand(CommandMessage::CMD_NONE);
// Implemented by child class, specifies what to do with reply. // 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); &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->getReplyRejectedReason(
reinterpret_cast<Command_t*>(&failureParameter1));
}
switch (result) { switch (result) {
case EXECUTION_COMPLETE: case EXECUTION_COMPLETE:
case RETURN_OK: case RETURN_OK:
case NO_STEP_MESSAGE: case NO_STEP_MESSAGE:
// handle result of reply handler implemented by developer. // handle result of reply handler implemented by developer.
handleReplyHandlerResult(result, iter, nextCommand, reply, isStep); handleReplyHandlerResult(result, iter, &nextCommand, reply, isStep);
break; break;
case INVALID_REPLY: case INVALID_REPLY:
//might be just an unrequested reply at a bad moment //might be just an unrequested reply at a bad moment
handleUnrequestedReply(&reply); handleUnrequestedReply(reply);
break; break;
default: default:
if (isStep) { if (isStep) {
@ -138,17 +156,17 @@ void CommandingServiceBase::handleCommandMessage(CommandMessage& reply) {
} }
void CommandingServiceBase::handleReplyHandlerResult(ReturnValue_t result, void CommandingServiceBase::handleReplyHandlerResult(ReturnValue_t result,
CommandMapIter iter, CommandMessage& nextCommand, CommandMessage& reply, CommandMapIter iter, CommandMessageIF* nextCommand,
bool& isStep) { CommandMessageIF* 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. // 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 // If no new command is sent, only analyse reply result by initializing
// sendResult as RETURN_OK // sendResult as RETURN_OK
ReturnValue_t sendResult = RETURN_OK; ReturnValue_t sendResult = RETURN_OK;
if (nextCommand.getCommand() != CommandMessage::CMD_NONE) { if (nextCommand->getCommand() != CommandMessage::CMD_NONE) {
sendResult = commandQueue->sendMessage(reply.getSender(), sendResult = commandQueue->sendMessage(reply->getSender(),
&nextCommand); nextCommand);
} }
if (sendResult == RETURN_OK) { if (sendResult == RETURN_OK) {
@ -168,14 +186,14 @@ void CommandingServiceBase::handleReplyHandlerResult(ReturnValue_t result,
} }
else { else {
if (isStep) { if (isStep) {
nextCommand.clearCommandMessage(); nextCommand->clear();
verificationReporter.sendFailureReport( verificationReporter.sendFailureReport(
TC_VERIFY::PROGRESS_FAILURE, iter->tcInfo.ackFlags, TC_VERIFY::PROGRESS_FAILURE, iter->tcInfo.ackFlags,
iter->tcInfo.tcPacketId, iter->tcInfo.tcPacketId,
iter->tcInfo.tcSequenceControl, sendResult, iter->tcInfo.tcSequenceControl, sendResult,
++iter->step, failureParameter1, failureParameter2); ++iter->step, failureParameter1, failureParameter2);
} else { } else {
nextCommand.clearCommandMessage(); nextCommand->clear();
verificationReporter.sendFailureReport( verificationReporter.sendFailureReport(
TC_VERIFY::COMPLETION_FAILURE, TC_VERIFY::COMPLETION_FAILURE,
iter->tcInfo.ackFlags, iter->tcInfo.tcPacketId, iter->tcInfo.ackFlags, iter->tcInfo.tcPacketId,
@ -311,7 +329,7 @@ void CommandingServiceBase::startExecution(TcPacketStored *storedPacket,
storedPacket->getPacketSequenceControl(); storedPacket->getPacketSequenceControl();
acceptPacket(TC_VERIFY::START_SUCCESS, storedPacket); acceptPacket(TC_VERIFY::START_SUCCESS, storedPacket);
} else { } else {
command.clearCommandMessage(); command.clear();
rejectPacket(TC_VERIFY::START_FAILURE, storedPacket, sendResult); rejectPacket(TC_VERIFY::START_FAILURE, storedPacket, sendResult);
checkAndExecuteFifo(iter); checkAndExecuteFifo(iter);
} }
@ -328,7 +346,7 @@ void CommandingServiceBase::startExecution(TcPacketStored *storedPacket,
acceptPacket(TC_VERIFY::COMPLETION_SUCCESS, storedPacket); acceptPacket(TC_VERIFY::COMPLETION_SUCCESS, storedPacket);
checkAndExecuteFifo(iter); checkAndExecuteFifo(iter);
} else { } else {
command.clearCommandMessage(); command.clear();
rejectPacket(TC_VERIFY::START_FAILURE, storedPacket, sendResult); rejectPacket(TC_VERIFY::START_FAILURE, storedPacket, sendResult);
checkAndExecuteFifo(iter); checkAndExecuteFifo(iter);
} }
@ -366,9 +384,9 @@ void CommandingServiceBase::checkAndExecuteFifo(CommandMapIter iter) {
} }
void CommandingServiceBase::handleUnrequestedReply( void CommandingServiceBase::handleUnrequestedReply(CommandMessageIF* reply) {
CommandMessage* reply) { CommandMessage commandReply(reply->getInternalMessage());
reply->clearCommandMessage(); commandReply.clear();
} }

View File

@ -141,15 +141,17 @@ protected:
* @param objectId Target object ID * @param objectId Target object ID
* @return * @return
*/ */
virtual ReturnValue_t prepareCommand(CommandMessage *message, virtual ReturnValue_t prepareCommand(CommandMessageIF *message,
uint8_t subservice, const uint8_t *tcData, size_t tcDataLen, uint8_t subservice, const uint8_t *tcData, size_t tcDataLen,
uint32_t *state, object_id_t objectId) = 0; uint32_t *state, object_id_t objectId) = 0;
/** /**
* This function is implemented by child services to specify how replies * 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 * @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 * @param previousCommand
* Command_t of related command * Command_t of related command
* @param state [out/in] * @param state [out/in]
@ -163,19 +165,26 @@ protected:
* - @c RETURN_OK, @c EXECUTION_COMPLETE or @c NO_STEP_MESSAGE to * - @c RETURN_OK, @c EXECUTION_COMPLETE or @c NO_STEP_MESSAGE to
* generate TC verification success * generate TC verification success
* - @c INVALID_REPLY calls handleUnrequestedReply * - @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, Command_t previousCommand, uint32_t *state,
CommandMessage *optionalNextCommand, object_id_t objectId, CommandMessageIF *optionalNextCommand, object_id_t objectId,
bool *isStep) = 0; bool *isStep) = 0;
/** /**
* This function can be overidden to handle unrequested reply, * This function can be overidden to handle unrequested reply,
* when the reply sender ID is unknown or is not found is the command map. * 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 * @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(); virtual void doPeriodicOperation();
@ -303,9 +312,9 @@ private:
void startExecution(TcPacketStored *storedPacket, CommandMapIter iter); void startExecution(TcPacketStored *storedPacket, CommandMapIter iter);
void handleCommandMessage(CommandMessage& reply); void handleCommandMessage(CommandMessageIF* reply);
void handleReplyHandlerResult(ReturnValue_t result, CommandMapIter iter, void handleReplyHandlerResult(ReturnValue_t result, CommandMapIter iter,
CommandMessage& nextCommand,CommandMessage& reply, bool& isStep); CommandMessageIF* nextCommand,CommandMessageIF* reply, bool& isStep);
void checkTimeout(); void checkTimeout();
}; };

View File

@ -24,9 +24,8 @@ void VerificationReporter::sendSuccessReport(uint8_t set_report_id,
current_packet->getPacketSequenceControl(), 0, set_step); current_packet->getPacketSequenceControl(), 0, set_step);
ReturnValue_t status = MessageQueueSenderIF::sendMessage(acknowledgeQueue, &message); ReturnValue_t status = MessageQueueSenderIF::sendMessage(acknowledgeQueue, &message);
if (status != HasReturnvaluesIF::RETURN_OK) { if (status != HasReturnvaluesIF::RETURN_OK) {
sif::error sif::error << "VerificationReporter::sendSuccessReport: Error writing "
<< "VerificationReporter::sendSuccessReport: Error writing to queue. Code: " "to queue. Code: " << std::hex << (uint16_t) status << std::endl;
<< (uint16_t) status << std::endl;
} }
} }
@ -40,9 +39,8 @@ void VerificationReporter::sendSuccessReport(uint8_t set_report_id,
tcSequenceControl, 0, set_step); tcSequenceControl, 0, set_step);
ReturnValue_t status = MessageQueueSenderIF::sendMessage(acknowledgeQueue, &message); ReturnValue_t status = MessageQueueSenderIF::sendMessage(acknowledgeQueue, &message);
if (status != HasReturnvaluesIF::RETURN_OK) { if (status != HasReturnvaluesIF::RETURN_OK) {
sif::error sif::error << "VerificationReporter::sendSuccessReport: Error writing "
<< "VerificationReporter::sendSuccessReport: Error writing to queue. Code: " "to queue. Code: " << std::hex << (uint16_t) status << std::endl;
<< (uint16_t) status << std::endl;
} }
} }