RTEMS Updates and Bugfixes #363

Merged
gaisser merged 2 commits from mueller/rtems-only into development 2021-02-09 14:14:37 +01:00
35 changed files with 2617 additions and 2587 deletions
Showing only changes of commit 46e4816faf - Show all commits

View File

@ -3,151 +3,119 @@
#include "../ipc/MessageQueueSenderIF.h"
#include "../objectmanager/ObjectManagerIF.h"
#include "../serviceinterface/ServiceInterface.h"
ActionHelper::ActionHelper(HasActionsIF* setOwner,
MessageQueueIF* useThisQueue) :
owner(setOwner), queueToUse(useThisQueue) {
owner(setOwner), queueToUse(useThisQueue) {
}
ActionHelper::~ActionHelper() {
}
ReturnValue_t ActionHelper::handleActionMessage(CommandMessage* command) {
if (command->getCommand() == ActionMessage::EXECUTE_ACTION) {
ActionId_t currentAction = ActionMessage::getActionId(command);
prepareExecution(command->getSender(), currentAction,
ActionMessage::getStoreId(command));
return HasReturnvaluesIF::RETURN_OK;
} else {
return CommandMessage::UNKNOWN_COMMAND;
}
if (command->getCommand() == ActionMessage::EXECUTE_ACTION) {
ActionId_t currentAction = ActionMessage::getActionId(command);
prepareExecution(command->getSender(), currentAction,
ActionMessage::getStoreId(command));
return HasReturnvaluesIF::RETURN_OK;
} else {
return CommandMessage::UNKNOWN_COMMAND;
}
}
ReturnValue_t ActionHelper::initialize(MessageQueueIF* queueToUse_) {
ipcStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
if (ipcStore == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED;
}
if(queueToUse_ != nullptr) {
setQueueToUse(queueToUse_);
}
ipcStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
if (ipcStore == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED;
}
if(queueToUse_ != nullptr) {
setQueueToUse(queueToUse_);
}
return HasReturnvaluesIF::RETURN_OK;
return HasReturnvaluesIF::RETURN_OK;
}
void ActionHelper::step(uint8_t step, MessageQueueId_t reportTo,
ActionId_t commandId, ReturnValue_t result) {
CommandMessage reply;
ActionMessage::setStepReply(&reply, commandId, step + STEP_OFFSET, result);
queueToUse->sendMessage(reportTo, &reply);
CommandMessage reply;
ActionMessage::setStepReply(&reply, commandId, step + STEP_OFFSET, result);
queueToUse->sendMessage(reportTo, &reply);
}
void ActionHelper::finish(MessageQueueId_t reportTo, ActionId_t commandId,
ReturnValue_t result) {
CommandMessage reply;
ActionMessage::setCompletionReply(&reply, commandId, result);
queueToUse->sendMessage(reportTo, &reply);
CommandMessage reply;
ActionMessage::setCompletionReply(&reply, commandId, result);
queueToUse->sendMessage(reportTo, &reply);
}
void ActionHelper::setQueueToUse(MessageQueueIF* queue) {
queueToUse = queue;
queueToUse = queue;
}
void ActionHelper::prepareExecution(MessageQueueId_t commandedBy,
ActionId_t actionId, store_address_t dataAddress) {
const uint8_t* dataPtr = NULL;
size_t size = 0;
ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size);
if (result != HasReturnvaluesIF::RETURN_OK) {
CommandMessage reply;
ActionMessage::setStepReply(&reply, actionId, 0, result);
queueToUse->sendMessage(commandedBy, &reply);
return;
}
result = owner->executeAction(actionId, commandedBy, dataPtr, size);
ipcStore->deleteData(dataAddress);
if(result == HasActionsIF::EXECUTION_FINISHED) {
CommandMessage reply;
ActionMessage::setCompletionReply(&reply, actionId, result);
queueToUse->sendMessage(commandedBy, &reply);
}
if (result != HasReturnvaluesIF::RETURN_OK) {
CommandMessage reply;
ActionMessage::setStepReply(&reply, actionId, 0, result);
queueToUse->sendMessage(commandedBy, &reply);
return;
}
const uint8_t* dataPtr = NULL;
size_t size = 0;
ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size);
if (result != HasReturnvaluesIF::RETURN_OK) {
CommandMessage reply;
ActionMessage::setStepReply(&reply, actionId, 0, result);
queueToUse->sendMessage(commandedBy, &reply);
return;
}
result = owner->executeAction(actionId, commandedBy, dataPtr, size);
ipcStore->deleteData(dataAddress);
if(result == HasActionsIF::EXECUTION_FINISHED) {
CommandMessage reply;
ActionMessage::setCompletionReply(&reply, actionId, result);
queueToUse->sendMessage(commandedBy, &reply);
}
if (result != HasReturnvaluesIF::RETURN_OK) {
CommandMessage reply;
ActionMessage::setStepReply(&reply, actionId, 0, result);
queueToUse->sendMessage(commandedBy, &reply);
return;
}
}
ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo,
ActionId_t replyId, SerializeIF* data, bool hideSender) {
CommandMessage reply;
store_address_t storeAddress;
uint8_t *dataPtr;
size_t maxSize = data->getSerializedSize();
if (maxSize == 0) {
//No error, there's simply nothing to report.
return HasReturnvaluesIF::RETURN_OK;
}
size_t size = 0;
ReturnValue_t result = ipcStore->getFreeElement(&storeAddress, maxSize,
&dataPtr);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = data->serialize(&dataPtr, &size, maxSize,
SerializeIF::Endianness::BIG);
if (result != HasReturnvaluesIF::RETURN_OK) {
ipcStore->deleteData(storeAddress);
return result;
}
// We don't need to report the objectId, as we receive REQUESTED data
// before the completion success message.
// True aperiodic replies need to be reported with
// another dedicated message.
ActionMessage::setDataReply(&reply, replyId, storeAddress);
// If the sender needs to be hidden, for example to handle packet
// as unrequested reply, this will be done here.
if (hideSender) {
result = MessageQueueSenderIF::sendMessage(reportTo, &reply);
}
else {
result = queueToUse->sendMessage(reportTo, &reply);
}
if (result != HasReturnvaluesIF::RETURN_OK){
ipcStore->deleteData(storeAddress);
}
return result;
}
void ActionHelper::resetHelper() {
}
ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo,
ActionId_t replyId, const uint8_t *data, size_t dataSize,
bool hideSender) {
ActionId_t replyId, SerializeIF* data, bool hideSender) {
CommandMessage reply;
store_address_t storeAddress;
ReturnValue_t result = ipcStore->addData(&storeAddress, data, dataSize);
uint8_t *dataPtr;
size_t maxSize = data->getSerializedSize();
if (maxSize == 0) {
/* No error, there's simply nothing to report. */
return HasReturnvaluesIF::RETURN_OK;
}
size_t size = 0;
ReturnValue_t result = ipcStore->getFreeElement(&storeAddress, maxSize,
&dataPtr);
if (result != HasReturnvaluesIF::RETURN_OK) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "ActionHelper::reportData: Getting free element from IPC store failed!" <<
std::endl;
#else
sif::printWarning("ActionHelper::reportData: Getting free element from IPC "
"store failed!\n");
#endif
return result;
}
result = data->serialize(&dataPtr, &size, maxSize,
SerializeIF::Endianness::BIG);
if (result != HasReturnvaluesIF::RETURN_OK) {
ipcStore->deleteData(storeAddress);
return result;
}
// We don't need to report the objectId, as we receive REQUESTED data
// before the completion success message.
// True aperiodic replies need to be reported with
// another dedicated message.
/* We don't need to report the objectId, as we receive REQUESTED data before the completion
success message. True aperiodic replies need to be reported with another dedicated message. */
ActionMessage::setDataReply(&reply, replyId, storeAddress);
// If the sender needs to be hidden, for example to handle packet
// as unrequested reply, this will be done here.
/* If the sender needs to be hidden, for example to handle packet
as unrequested reply, this will be done here. */
if (hideSender) {
result = MessageQueueSenderIF::sendMessage(reportTo, &reply);
}
@ -160,3 +128,45 @@ ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo,
}
return result;
}
void ActionHelper::resetHelper() {
}
ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo,
ActionId_t replyId, const uint8_t *data, size_t dataSize,
bool hideSender) {
CommandMessage reply;
store_address_t storeAddress;
ReturnValue_t result = ipcStore->addData(&storeAddress, data, dataSize);
if (result != HasReturnvaluesIF::RETURN_OK) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "ActionHelper::reportData: Adding data to IPC store failed!" << std::endl;
#else
sif::printWarning("ActionHelper::reportData: Adding data to IPC store failed!\n");
#endif
return result;
}
if (result != HasReturnvaluesIF::RETURN_OK) {
ipcStore->deleteData(storeAddress);
return result;
}
/* We don't need to report the objectId, as we receive REQUESTED data before the completion
success message. True aperiodic replies need to be reported with another dedicated message. */
ActionMessage::setDataReply(&reply, replyId, storeAddress);
/* If the sender needs to be hidden, for example to handle packet
as unrequested reply, this will be done here. */
if (hideSender) {
result = MessageQueueSenderIF::sendMessage(reportTo, &reply);
}
else {
result = queueToUse->sendMessage(reportTo, &reply);
}
if (result != HasReturnvaluesIF::RETURN_OK) {
ipcStore->deleteData(storeAddress);
}
return result;
}

View File

@ -18,68 +18,68 @@ class HasActionsIF;
class ActionHelper {
public:
/**
* Constructor of the action helper
* @param setOwner Pointer to the owner of the interface
* @param useThisQueue messageQueue to be used, can be set during
* initialize function as well.
*/
ActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue);
/**
* Constructor of the action helper
* @param setOwner Pointer to the owner of the interface
* @param useThisQueue messageQueue to be used, can be set during
* initialize function as well.
*/
ActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue);
virtual ~ActionHelper();
/**
* Function to be called from the owner with a new command message
*
* If the message is a valid action message the helper will use the
* executeAction function from HasActionsIF.
* If the message is invalid or the callback fails a message reply will be
* send to the sender of the message automatically.
*
* @param command Pointer to a command message received by the owner
* @return HasReturnvaluesIF::RETURN_OK if the message is a action message,
* CommandMessage::UNKNOW_COMMAND if this message ID is unkown
*/
ReturnValue_t handleActionMessage(CommandMessage* command);
/**
* Helper initialize function. Must be called before use of any other
* helper function
* @param queueToUse_ Pointer to the messageQueue to be used, optional
* if queue was set in constructor
* @return Returns RETURN_OK if successful
*/
ReturnValue_t initialize(MessageQueueIF* queueToUse_ = nullptr);
/**
* Function to be called from the owner to send a step message.
* Success or failure will be determined by the result value.
*
* @param step Number of steps already done
* @param reportTo The messageQueueId to report the step message to
* @param commandId ID of the executed command
* @param result Result of the execution
*/
void step(uint8_t step, MessageQueueId_t reportTo,
ActionId_t commandId,
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
/**
* Function to be called by the owner to send a action completion message
*
* @param reportTo MessageQueueId_t to report the action completion message to
* @param commandId ID of the executed command
* @param result Result of the execution
*/
void finish(MessageQueueId_t reportTo, ActionId_t commandId,
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
/**
* Function to be called by the owner if an action does report data.
* Takes a SerializeIF* pointer and serializes it into the IPC store.
* @param reportTo MessageQueueId_t to report the action completion
* message to
* @param replyId ID of the executed command
* @param data Pointer to the data
* @return Returns RETURN_OK if successful, otherwise failure code
*/
ReturnValue_t reportData(MessageQueueId_t reportTo, ActionId_t replyId,
SerializeIF* data, bool hideSender = false);
virtual ~ActionHelper();
/**
* Function to be called from the owner with a new command message
*
* If the message is a valid action message the helper will use the
* executeAction function from HasActionsIF.
* If the message is invalid or the callback fails a message reply will be
* send to the sender of the message automatically.
*
* @param command Pointer to a command message received by the owner
* @return HasReturnvaluesIF::RETURN_OK if the message is a action message,
* CommandMessage::UNKNOW_COMMAND if this message ID is unkown
*/
ReturnValue_t handleActionMessage(CommandMessage* command);
/**
* Helper initialize function. Must be called before use of any other
* helper function
* @param queueToUse_ Pointer to the messageQueue to be used, optional
* if queue was set in constructor
* @return Returns RETURN_OK if successful
*/
ReturnValue_t initialize(MessageQueueIF* queueToUse_ = nullptr);
/**
* Function to be called from the owner to send a step message.
* Success or failure will be determined by the result value.
*
* @param step Number of steps already done
* @param reportTo The messageQueueId to report the step message to
* @param commandId ID of the executed command
* @param result Result of the execution
*/
void step(uint8_t step, MessageQueueId_t reportTo,
ActionId_t commandId,
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
/**
* Function to be called by the owner to send a action completion message
*
* @param reportTo MessageQueueId_t to report the action completion message to
* @param commandId ID of the executed command
* @param result Result of the execution
*/
void finish(MessageQueueId_t reportTo, ActionId_t commandId,
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
/**
* Function to be called by the owner if an action does report data.
* Takes a SerializeIF* pointer and serializes it into the IPC store.
* @param reportTo MessageQueueId_t to report the action completion
* message to
* @param replyId ID of the executed command
* @param data Pointer to the data
* @return Returns RETURN_OK if successful, otherwise failure code
*/
ReturnValue_t reportData(MessageQueueId_t reportTo, ActionId_t replyId,
SerializeIF* data, bool hideSender = false);
/**
* Function to be called by the owner if an action does report data.
* Takes the raw data and writes it into the IPC store.
@ -91,35 +91,36 @@ public:
*/
ReturnValue_t reportData(MessageQueueId_t reportTo, ActionId_t replyId,
const uint8_t* data, size_t dataSize, bool hideSender = false);
/**
* Function to setup the MessageQueueIF* of the helper. Can be used to
* set the MessageQueueIF* if message queue is unavailable at construction
* and initialize but must be setup before first call of other functions.
* @param queue Queue to be used by the helper
*/
void setQueueToUse(MessageQueueIF *queue);
/**
* Function to setup the MessageQueueIF* of the helper. Can be used to
* set the MessageQueueIF* if message queue is unavailable at construction
* and initialize but must be setup before first call of other functions.
* @param queue Queue to be used by the helper
*/
void setQueueToUse(MessageQueueIF *queue);
protected:
//!< Increase of value of this per step
static const uint8_t STEP_OFFSET = 1;
HasActionsIF* owner;//!< Pointer to the owner
//! Queue to be used as response sender, has to be set in ctor or with
//! setQueueToUse
MessageQueueIF* queueToUse;
//! Pointer to an IPC Store, initialized during construction or
StorageManagerIF* ipcStore = nullptr;
//! Increase of value of this per step
static const uint8_t STEP_OFFSET = 1;
//! Pointer to the owner
HasActionsIF* owner;
//! Queue to be used as response sender, has to be set in ctor or with
//! setQueueToUse
MessageQueueIF* queueToUse;
//! Pointer to an IPC Store, initialized during construction or
StorageManagerIF* ipcStore = nullptr;
/**
* Internal function called by handleActionMessage
* @param commandedBy MessageQueueID of Commander
* @param actionId ID of action to be done
* @param dataAddress Address of additional data in IPC Store
*/
virtual void prepareExecution(MessageQueueId_t commandedBy,
ActionId_t actionId, store_address_t dataAddress);
/**
* @brief Default implementation is empty.
*/
virtual void resetHelper();
/**
* Internal function called by handleActionMessage
* @param commandedBy MessageQueueID of Commander
* @param actionId ID of action to be done
* @param dataAddress Address of additional data in IPC Store
*/
virtual void prepareExecution(MessageQueueId_t commandedBy,
ActionId_t actionId, store_address_t dataAddress);
/**
* @brief Default implementation is empty.
*/
virtual void resetHelper();
};
#endif /* FSFW_ACTION_ACTIONHELPER_H_ */

View File

@ -11,71 +11,71 @@ ActionMessage::~ActionMessage() {
}
void ActionMessage::setCommand(CommandMessage* message, ActionId_t fid,
store_address_t parameters) {
message->setCommand(EXECUTE_ACTION);
message->setParameter(fid);
message->setParameter2(parameters.raw);
store_address_t parameters) {
message->setCommand(EXECUTE_ACTION);
message->setParameter(fid);
message->setParameter2(parameters.raw);
}
ActionId_t ActionMessage::getActionId(const CommandMessage* message) {
return ActionId_t(message->getParameter());
return ActionId_t(message->getParameter());
}
store_address_t ActionMessage::getStoreId(const CommandMessage* message) {
store_address_t temp;
temp.raw = message->getParameter2();
return temp;
store_address_t temp;
temp.raw = message->getParameter2();
return temp;
}
void ActionMessage::setStepReply(CommandMessage* message, ActionId_t fid, uint8_t step,
ReturnValue_t result) {
if (result == HasReturnvaluesIF::RETURN_OK) {
message->setCommand(STEP_SUCCESS);
} else {
message->setCommand(STEP_FAILED);
}
message->setParameter(fid);
message->setParameter2((step << 16) + result);
ReturnValue_t result) {
if (result == HasReturnvaluesIF::RETURN_OK) {
message->setCommand(STEP_SUCCESS);
} else {
message->setCommand(STEP_FAILED);
}
message->setParameter(fid);
message->setParameter2((step << 16) + result);
}
uint8_t ActionMessage::getStep(const CommandMessage* message) {
return uint8_t((message->getParameter2() >> 16) & 0xFF);
return uint8_t((message->getParameter2() >> 16) & 0xFF);
}
ReturnValue_t ActionMessage::getReturnCode(const CommandMessage* message) {
return message->getParameter2() & 0xFFFF;
return message->getParameter2() & 0xFFFF;
}
void ActionMessage::setDataReply(CommandMessage* message, ActionId_t actionId,
store_address_t data) {
message->setCommand(DATA_REPLY);
message->setParameter(actionId);
message->setParameter2(data.raw);
store_address_t data) {
message->setCommand(DATA_REPLY);
message->setParameter(actionId);
message->setParameter2(data.raw);
}
void ActionMessage::setCompletionReply(CommandMessage* message,
ActionId_t fid, ReturnValue_t result) {
if (result == HasReturnvaluesIF::RETURN_OK or result == HasActionsIF::EXECUTION_FINISHED) {
message->setCommand(COMPLETION_SUCCESS);
} else {
message->setCommand(COMPLETION_FAILED);
}
message->setParameter(fid);
message->setParameter2(result);
ActionId_t fid, ReturnValue_t result) {
if (result == HasReturnvaluesIF::RETURN_OK or result == HasActionsIF::EXECUTION_FINISHED) {
message->setCommand(COMPLETION_SUCCESS);
} else {
message->setCommand(COMPLETION_FAILED);
}
message->setParameter(fid);
message->setParameter2(result);
}
void ActionMessage::clear(CommandMessage* message) {
switch(message->getCommand()) {
case EXECUTE_ACTION:
case DATA_REPLY: {
StorageManagerIF *ipcStore = objectManager->get<StorageManagerIF>(
objects::IPC_STORE);
if (ipcStore != NULL) {
ipcStore->deleteData(getStoreId(message));
}
break;
}
default:
break;
}
switch(message->getCommand()) {
case EXECUTE_ACTION:
case DATA_REPLY: {
StorageManagerIF *ipcStore = objectManager->get<StorageManagerIF>(
objects::IPC_STORE);
if (ipcStore != NULL) {
ipcStore->deleteData(getStoreId(message));
}
break;
}
default:
break;
}
}

View File

@ -15,29 +15,29 @@ using ActionId_t = uint32_t;
*/
class ActionMessage {
private:
ActionMessage();
ActionMessage();
public:
static const uint8_t MESSAGE_ID = messagetypes::ACTION;
static const Command_t EXECUTE_ACTION = MAKE_COMMAND_ID(1);
static const Command_t STEP_SUCCESS = MAKE_COMMAND_ID(2);
static const Command_t STEP_FAILED = MAKE_COMMAND_ID(3);
static const Command_t DATA_REPLY = MAKE_COMMAND_ID(4);
static const Command_t COMPLETION_SUCCESS = MAKE_COMMAND_ID(5);
static const Command_t COMPLETION_FAILED = MAKE_COMMAND_ID(6);
virtual ~ActionMessage();
static void setCommand(CommandMessage* message, ActionId_t fid,
store_address_t parameters);
static ActionId_t getActionId(const CommandMessage* message );
static store_address_t getStoreId(const CommandMessage* message );
static void setStepReply(CommandMessage* message, ActionId_t fid,
uint8_t step, ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
static uint8_t getStep(const CommandMessage* message );
static ReturnValue_t getReturnCode(const CommandMessage* message );
static void setDataReply(CommandMessage* message, ActionId_t actionId,
store_address_t data);
static void setCompletionReply(CommandMessage* message, ActionId_t fid,
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
static void clear(CommandMessage* message);
static const uint8_t MESSAGE_ID = messagetypes::ACTION;
static const Command_t EXECUTE_ACTION = MAKE_COMMAND_ID(1);
static const Command_t STEP_SUCCESS = MAKE_COMMAND_ID(2);
static const Command_t STEP_FAILED = MAKE_COMMAND_ID(3);
static const Command_t DATA_REPLY = MAKE_COMMAND_ID(4);
static const Command_t COMPLETION_SUCCESS = MAKE_COMMAND_ID(5);
static const Command_t COMPLETION_FAILED = MAKE_COMMAND_ID(6);
virtual ~ActionMessage();
static void setCommand(CommandMessage* message, ActionId_t fid,
store_address_t parameters);
static ActionId_t getActionId(const CommandMessage* message );
static store_address_t getStoreId(const CommandMessage* message );
static void setStepReply(CommandMessage* message, ActionId_t fid,
uint8_t step, ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
static uint8_t getStep(const CommandMessage* message );
static ReturnValue_t getReturnCode(const CommandMessage* message );
static void setDataReply(CommandMessage* message, ActionId_t actionId,
store_address_t data);
static void setCompletionReply(CommandMessage* message, ActionId_t fid,
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
static void clear(CommandMessage* message);
};
#endif /* FSFW_ACTION_ACTIONMESSAGE_H_ */

View File

@ -1,7 +1,7 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
ActionHelper.cpp
ActionMessage.cpp
CommandActionHelper.cpp
SimpleActionHelper.cpp
PRIVATE
ActionHelper.cpp
ActionMessage.cpp
CommandActionHelper.cpp
SimpleActionHelper.cpp
)

View File

@ -5,123 +5,123 @@
#include "../objectmanager/ObjectManagerIF.h"
CommandActionHelper::CommandActionHelper(CommandsActionsIF *setOwner) :
owner(setOwner), queueToUse(NULL), ipcStore(
NULL), commandCount(0), lastTarget(0) {
owner(setOwner), queueToUse(NULL), ipcStore(
NULL), commandCount(0), lastTarget(0) {
}
CommandActionHelper::~CommandActionHelper() {
}
ReturnValue_t CommandActionHelper::commandAction(object_id_t commandTo,
ActionId_t actionId, SerializeIF *data) {
HasActionsIF *receiver = objectManager->get<HasActionsIF>(commandTo);
if (receiver == NULL) {
return CommandsActionsIF::OBJECT_HAS_NO_FUNCTIONS;
}
store_address_t storeId;
uint8_t *storePointer;
size_t maxSize = data->getSerializedSize();
ReturnValue_t result = ipcStore->getFreeElement(&storeId, maxSize,
&storePointer);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
size_t size = 0;
result = data->serialize(&storePointer, &size, maxSize,
SerializeIF::Endianness::BIG);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
return sendCommand(receiver->getCommandQueue(), actionId, storeId);
ActionId_t actionId, SerializeIF *data) {
HasActionsIF *receiver = objectManager->get<HasActionsIF>(commandTo);
if (receiver == NULL) {
return CommandsActionsIF::OBJECT_HAS_NO_FUNCTIONS;
}
store_address_t storeId;
uint8_t *storePointer;
size_t maxSize = data->getSerializedSize();
ReturnValue_t result = ipcStore->getFreeElement(&storeId, maxSize,
&storePointer);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
size_t size = 0;
result = data->serialize(&storePointer, &size, maxSize,
SerializeIF::Endianness::BIG);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
return sendCommand(receiver->getCommandQueue(), actionId, storeId);
}
ReturnValue_t CommandActionHelper::commandAction(object_id_t commandTo,
ActionId_t actionId, const uint8_t *data, uint32_t size) {
// if (commandCount != 0) {
// return CommandsFunctionsIF::ALREADY_COMMANDING;
// }
HasActionsIF *receiver = objectManager->get<HasActionsIF>(commandTo);
if (receiver == NULL) {
return CommandsActionsIF::OBJECT_HAS_NO_FUNCTIONS;
}
store_address_t storeId;
ReturnValue_t result = ipcStore->addData(&storeId, data, size);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
return sendCommand(receiver->getCommandQueue(), actionId, storeId);
ActionId_t actionId, const uint8_t *data, uint32_t size) {
// if (commandCount != 0) {
// return CommandsFunctionsIF::ALREADY_COMMANDING;
// }
HasActionsIF *receiver = objectManager->get<HasActionsIF>(commandTo);
if (receiver == NULL) {
return CommandsActionsIF::OBJECT_HAS_NO_FUNCTIONS;
}
store_address_t storeId;
ReturnValue_t result = ipcStore->addData(&storeId, data, size);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
return sendCommand(receiver->getCommandQueue(), actionId, storeId);
}
ReturnValue_t CommandActionHelper::sendCommand(MessageQueueId_t queueId,
ActionId_t actionId, store_address_t storeId) {
CommandMessage command;
ActionMessage::setCommand(&command, actionId, storeId);
ReturnValue_t result = queueToUse->sendMessage(queueId, &command);
if (result != HasReturnvaluesIF::RETURN_OK) {
ipcStore->deleteData(storeId);
}
lastTarget = queueId;
commandCount++;
return result;
ActionId_t actionId, store_address_t storeId) {
CommandMessage command;
ActionMessage::setCommand(&command, actionId, storeId);
ReturnValue_t result = queueToUse->sendMessage(queueId, &command);
if (result != HasReturnvaluesIF::RETURN_OK) {
ipcStore->deleteData(storeId);
}
lastTarget = queueId;
commandCount++;
return result;
}
ReturnValue_t CommandActionHelper::initialize() {
ipcStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
if (ipcStore == NULL) {
return HasReturnvaluesIF::RETURN_FAILED;
}
ipcStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
if (ipcStore == NULL) {
return HasReturnvaluesIF::RETURN_FAILED;
}
queueToUse = owner->getCommandQueuePtr();
if (queueToUse == NULL) {
return HasReturnvaluesIF::RETURN_FAILED;
}
return HasReturnvaluesIF::RETURN_OK;
queueToUse = owner->getCommandQueuePtr();
if (queueToUse == NULL) {
return HasReturnvaluesIF::RETURN_FAILED;
}
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t CommandActionHelper::handleReply(CommandMessage *reply) {
if (reply->getSender() != lastTarget) {
return HasReturnvaluesIF::RETURN_FAILED;
}
switch (reply->getCommand()) {
case ActionMessage::COMPLETION_SUCCESS:
commandCount--;
owner->completionSuccessfulReceived(ActionMessage::getActionId(reply));
return HasReturnvaluesIF::RETURN_OK;
case ActionMessage::COMPLETION_FAILED:
commandCount--;
owner->completionFailedReceived(ActionMessage::getActionId(reply),
ActionMessage::getReturnCode(reply));
return HasReturnvaluesIF::RETURN_OK;
case ActionMessage::STEP_SUCCESS:
owner->stepSuccessfulReceived(ActionMessage::getActionId(reply),
ActionMessage::getStep(reply));
return HasReturnvaluesIF::RETURN_OK;
case ActionMessage::STEP_FAILED:
commandCount--;
owner->stepFailedReceived(ActionMessage::getActionId(reply),
ActionMessage::getStep(reply),
ActionMessage::getReturnCode(reply));
return HasReturnvaluesIF::RETURN_OK;
case ActionMessage::DATA_REPLY:
extractDataForOwner(ActionMessage::getActionId(reply),
ActionMessage::getStoreId(reply));
return HasReturnvaluesIF::RETURN_OK;
default:
return HasReturnvaluesIF::RETURN_FAILED;
}
if (reply->getSender() != lastTarget) {
return HasReturnvaluesIF::RETURN_FAILED;
}
switch (reply->getCommand()) {
case ActionMessage::COMPLETION_SUCCESS:
commandCount--;
owner->completionSuccessfulReceived(ActionMessage::getActionId(reply));
return HasReturnvaluesIF::RETURN_OK;
case ActionMessage::COMPLETION_FAILED:
commandCount--;
owner->completionFailedReceived(ActionMessage::getActionId(reply),
ActionMessage::getReturnCode(reply));
return HasReturnvaluesIF::RETURN_OK;
case ActionMessage::STEP_SUCCESS:
owner->stepSuccessfulReceived(ActionMessage::getActionId(reply),
ActionMessage::getStep(reply));
return HasReturnvaluesIF::RETURN_OK;
case ActionMessage::STEP_FAILED:
commandCount--;
owner->stepFailedReceived(ActionMessage::getActionId(reply),
ActionMessage::getStep(reply),
ActionMessage::getReturnCode(reply));
return HasReturnvaluesIF::RETURN_OK;
case ActionMessage::DATA_REPLY:
extractDataForOwner(ActionMessage::getActionId(reply),
ActionMessage::getStoreId(reply));
return HasReturnvaluesIF::RETURN_OK;
default:
return HasReturnvaluesIF::RETURN_FAILED;
}
}
uint8_t CommandActionHelper::getCommandCount() const {
return commandCount;
return commandCount;
}
void CommandActionHelper::extractDataForOwner(ActionId_t actionId, store_address_t storeId) {
const uint8_t * data = NULL;
size_t size = 0;
ReturnValue_t result = ipcStore->getData(storeId, &data, &size);
if (result != HasReturnvaluesIF::RETURN_OK) {
return;
}
owner->dataReceived(actionId, data, size);
ipcStore->deleteData(storeId);
const uint8_t * data = NULL;
size_t size = 0;
ReturnValue_t result = ipcStore->getData(storeId, &data, &size);
if (result != HasReturnvaluesIF::RETURN_OK) {
return;
}
owner->dataReceived(actionId, data, size);
ipcStore->deleteData(storeId);
}

View File

@ -11,26 +11,26 @@
class CommandsActionsIF;
class CommandActionHelper {
friend class CommandsActionsIF;
friend class CommandsActionsIF;
public:
CommandActionHelper(CommandsActionsIF* owner);
virtual ~CommandActionHelper();
ReturnValue_t commandAction(object_id_t commandTo,
ActionId_t actionId, const uint8_t* data, uint32_t size);
ReturnValue_t commandAction(object_id_t commandTo,
ActionId_t actionId, SerializeIF* data);
ReturnValue_t initialize();
ReturnValue_t handleReply(CommandMessage* reply);
uint8_t getCommandCount() const;
CommandActionHelper(CommandsActionsIF* owner);
virtual ~CommandActionHelper();
ReturnValue_t commandAction(object_id_t commandTo,
ActionId_t actionId, const uint8_t* data, uint32_t size);
ReturnValue_t commandAction(object_id_t commandTo,
ActionId_t actionId, SerializeIF* data);
ReturnValue_t initialize();
ReturnValue_t handleReply(CommandMessage* reply);
uint8_t getCommandCount() const;
private:
CommandsActionsIF* owner;
MessageQueueIF* queueToUse;
StorageManagerIF* ipcStore;
uint8_t commandCount;
MessageQueueId_t lastTarget;
void extractDataForOwner(ActionId_t actionId, store_address_t storeId);
ReturnValue_t sendCommand(MessageQueueId_t queueId, ActionId_t actionId,
store_address_t storeId);
CommandsActionsIF* owner;
MessageQueueIF* queueToUse;
StorageManagerIF* ipcStore;
uint8_t commandCount;
MessageQueueId_t lastTarget;
void extractDataForOwner(ActionId_t actionId, store_address_t storeId);
ReturnValue_t sendCommand(MessageQueueId_t queueId, ActionId_t actionId,
store_address_t storeId);
};
#endif /* COMMANDACTIONHELPER_H_ */

View File

@ -15,22 +15,22 @@
* - replyReceived(id, step, cause) (if cause == OK, it's a success).
*/
class CommandsActionsIF {
friend class CommandActionHelper;
friend class CommandActionHelper;
public:
static const uint8_t INTERFACE_ID = CLASS_ID::COMMANDS_ACTIONS_IF;
static const ReturnValue_t OBJECT_HAS_NO_FUNCTIONS = MAKE_RETURN_CODE(1);
static const ReturnValue_t ALREADY_COMMANDING = MAKE_RETURN_CODE(2);
virtual ~CommandsActionsIF() {}
virtual MessageQueueIF* getCommandQueuePtr() = 0;
static const uint8_t INTERFACE_ID = CLASS_ID::COMMANDS_ACTIONS_IF;
static const ReturnValue_t OBJECT_HAS_NO_FUNCTIONS = MAKE_RETURN_CODE(1);
static const ReturnValue_t ALREADY_COMMANDING = MAKE_RETURN_CODE(2);
virtual ~CommandsActionsIF() {}
virtual MessageQueueIF* getCommandQueuePtr() = 0;
protected:
virtual void stepSuccessfulReceived(ActionId_t actionId, uint8_t step) = 0;
virtual void stepFailedReceived(ActionId_t actionId, uint8_t step,
ReturnValue_t returnCode) = 0;
virtual void dataReceived(ActionId_t actionId, const uint8_t* data,
uint32_t size) = 0;
virtual void completionSuccessfulReceived(ActionId_t actionId) = 0;
virtual void completionFailedReceived(ActionId_t actionId,
ReturnValue_t returnCode) = 0;
virtual void stepSuccessfulReceived(ActionId_t actionId, uint8_t step) = 0;
virtual void stepFailedReceived(ActionId_t actionId, uint8_t step,
ReturnValue_t returnCode) = 0;
virtual void dataReceived(ActionId_t actionId, const uint8_t* data,
uint32_t size) = 0;
virtual void completionSuccessfulReceived(ActionId_t actionId) = 0;
virtual void completionFailedReceived(ActionId_t actionId,
ReturnValue_t returnCode) = 0;
};

View File

@ -35,28 +35,28 @@
*/
class HasActionsIF {
public:
static const uint8_t INTERFACE_ID = CLASS_ID::HAS_ACTIONS_IF;
static const ReturnValue_t IS_BUSY = MAKE_RETURN_CODE(1);
static const ReturnValue_t INVALID_PARAMETERS = MAKE_RETURN_CODE(2);
static const ReturnValue_t EXECUTION_FINISHED = MAKE_RETURN_CODE(3);
static const ReturnValue_t INVALID_ACTION_ID = MAKE_RETURN_CODE(4);
virtual ~HasActionsIF() { }
/**
* Function to get the MessageQueueId_t of the implementing object
* @return MessageQueueId_t of the object
*/
virtual MessageQueueId_t getCommandQueue() const = 0;
/**
* Execute or initialize the execution of a certain function.
* The ActionHelpers will execute this function and behave differently
* depending on the returnvalue.
*
* @return
* -@c EXECUTION_FINISHED Finish reply will be generated
* -@c Not RETURN_OK Step failure reply will be generated
*/
virtual ReturnValue_t executeAction(ActionId_t actionId,
MessageQueueId_t commandedBy, const uint8_t* data, size_t size) = 0;
static const uint8_t INTERFACE_ID = CLASS_ID::HAS_ACTIONS_IF;
static const ReturnValue_t IS_BUSY = MAKE_RETURN_CODE(1);
static const ReturnValue_t INVALID_PARAMETERS = MAKE_RETURN_CODE(2);
static const ReturnValue_t EXECUTION_FINISHED = MAKE_RETURN_CODE(3);
static const ReturnValue_t INVALID_ACTION_ID = MAKE_RETURN_CODE(4);
virtual ~HasActionsIF() { }
/**
* Function to get the MessageQueueId_t of the implementing object
* @return MessageQueueId_t of the object
*/
virtual MessageQueueId_t getCommandQueue() const = 0;
/**
* Execute or initialize the execution of a certain function.
* The ActionHelpers will execute this function and behave differently
* depending on the returnvalue.
*
* @return
* -@c EXECUTION_FINISHED Finish reply will be generated
* -@c Not RETURN_OK Step failure reply will be generated
*/
virtual ReturnValue_t executeAction(ActionId_t actionId,
MessageQueueId_t commandedBy, const uint8_t* data, size_t size) = 0;
};

View File

@ -2,74 +2,74 @@
#include "SimpleActionHelper.h"
SimpleActionHelper::SimpleActionHelper(HasActionsIF* setOwner,
MessageQueueIF* useThisQueue) :
ActionHelper(setOwner, useThisQueue), isExecuting(false) {
MessageQueueIF* useThisQueue) :
ActionHelper(setOwner, useThisQueue), isExecuting(false) {
}
SimpleActionHelper::~SimpleActionHelper() {
}
void SimpleActionHelper::step(ReturnValue_t result) {
// STEP_OFFESET is subtracted to compensate for adding offset in base
// method, which is not necessary here.
ActionHelper::step(stepCount - STEP_OFFSET, lastCommander, lastAction,
result);
if (result != HasReturnvaluesIF::RETURN_OK) {
resetHelper();
}
// STEP_OFFESET is subtracted to compensate for adding offset in base
// method, which is not necessary here.
ActionHelper::step(stepCount - STEP_OFFSET, lastCommander, lastAction,
result);
if (result != HasReturnvaluesIF::RETURN_OK) {
resetHelper();
}
}
void SimpleActionHelper::finish(ReturnValue_t result) {
ActionHelper::finish(lastCommander, lastAction, result);
resetHelper();
ActionHelper::finish(lastCommander, lastAction, result);
resetHelper();
}
ReturnValue_t SimpleActionHelper::reportData(SerializeIF* data) {
return ActionHelper::reportData(lastCommander, lastAction, data);
return ActionHelper::reportData(lastCommander, lastAction, data);
}
void SimpleActionHelper::resetHelper() {
stepCount = 0;
isExecuting = false;
lastAction = 0;
lastCommander = 0;
stepCount = 0;
isExecuting = false;
lastAction = 0;
lastCommander = 0;
}
void SimpleActionHelper::prepareExecution(MessageQueueId_t commandedBy,
ActionId_t actionId, store_address_t dataAddress) {
CommandMessage reply;
if (isExecuting) {
ipcStore->deleteData(dataAddress);
ActionMessage::setStepReply(&reply, actionId, 0,
HasActionsIF::IS_BUSY);
queueToUse->sendMessage(commandedBy, &reply);
}
const uint8_t* dataPtr = NULL;
size_t size = 0;
ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size);
if (result != HasReturnvaluesIF::RETURN_OK) {
ActionMessage::setStepReply(&reply, actionId, 0, result);
queueToUse->sendMessage(commandedBy, &reply);
return;
}
lastCommander = commandedBy;
lastAction = actionId;
result = owner->executeAction(actionId, commandedBy, dataPtr, size);
ipcStore->deleteData(dataAddress);
switch (result) {
case HasReturnvaluesIF::RETURN_OK:
isExecuting = true;
stepCount++;
break;
case HasActionsIF::EXECUTION_FINISHED:
ActionMessage::setCompletionReply(&reply, actionId,
HasReturnvaluesIF::RETURN_OK);
queueToUse->sendMessage(commandedBy, &reply);
break;
default:
ActionMessage::setStepReply(&reply, actionId, 0, result);
queueToUse->sendMessage(commandedBy, &reply);
break;
}
ActionId_t actionId, store_address_t dataAddress) {
CommandMessage reply;
if (isExecuting) {
ipcStore->deleteData(dataAddress);
ActionMessage::setStepReply(&reply, actionId, 0,
HasActionsIF::IS_BUSY);
queueToUse->sendMessage(commandedBy, &reply);
}
const uint8_t* dataPtr = NULL;
size_t size = 0;
ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size);
if (result != HasReturnvaluesIF::RETURN_OK) {
ActionMessage::setStepReply(&reply, actionId, 0, result);
queueToUse->sendMessage(commandedBy, &reply);
return;
}
lastCommander = commandedBy;
lastAction = actionId;
result = owner->executeAction(actionId, commandedBy, dataPtr, size);
ipcStore->deleteData(dataAddress);
switch (result) {
case HasReturnvaluesIF::RETURN_OK:
isExecuting = true;
stepCount++;
break;
case HasActionsIF::EXECUTION_FINISHED:
ActionMessage::setCompletionReply(&reply, actionId,
HasReturnvaluesIF::RETURN_OK);
queueToUse->sendMessage(commandedBy, &reply);
break;
default:
ActionMessage::setStepReply(&reply, actionId, 0, result);
queueToUse->sendMessage(commandedBy, &reply);
break;
}
}

View File

@ -4,27 +4,27 @@
#include "ActionHelper.h"
/**
* @brief This is an action helper which is only able to service one action
* at a time but remembers last commander and last action which
* simplifies usage
* @brief This is an action helper which is only able to service one action
* at a time but remembers last commander and last action which
* simplifies usage
*/
class SimpleActionHelper: public ActionHelper {
public:
SimpleActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue);
virtual ~SimpleActionHelper();
void step(ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
void finish(ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
ReturnValue_t reportData(SerializeIF* data);
SimpleActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue);
virtual ~SimpleActionHelper();
void step(ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
void finish(ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
ReturnValue_t reportData(SerializeIF* data);
protected:
void prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId,
store_address_t dataAddress);
virtual void resetHelper();
void prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId,
store_address_t dataAddress);
virtual void resetHelper();
private:
bool isExecuting;
MessageQueueId_t lastCommander = MessageQueueIF::NO_QUEUE;
ActionId_t lastAction = 0;
uint8_t stepCount = 0;
bool isExecuting;
MessageQueueId_t lastCommander = MessageQueueIF::NO_QUEUE;
ActionId_t lastAction = 0;
uint8_t stepCount = 0;
};
#endif /* SIMPLEACTIONHELPER_H_ */

View File

@ -6,7 +6,7 @@
#include "../serialize/SerializeIF.h"
/**
* @brief A List that stores its values in an array.
* @brief A List that stores its values in an array.
* @details
* The underlying storage is an array that can be allocated by the class
* itself or supplied via ctor.
@ -15,237 +15,237 @@
*/
template<typename T, typename count_t = uint8_t>
class ArrayList {
template<typename U, typename count> friend class SerialArrayListAdapter;
template<typename U, typename count> friend class SerialArrayListAdapter;
public:
static const uint8_t INTERFACE_ID = CLASS_ID::ARRAY_LIST;
static const ReturnValue_t FULL = MAKE_RETURN_CODE(0x01);
static const uint8_t INTERFACE_ID = CLASS_ID::ARRAY_LIST;
static const ReturnValue_t FULL = MAKE_RETURN_CODE(0x01);
/**
* This is the allocating constructor.
* It allocates an array of the specified size.
* @param maxSize
*/
ArrayList(count_t maxSize) :
size(0), maxSize_(maxSize), allocated(true) {
entries = new T[maxSize];
}
/**
* This is the allocating constructor.
* It allocates an array of the specified size.
* @param maxSize
*/
ArrayList(count_t maxSize) :
size(0), maxSize_(maxSize), allocated(true) {
entries = new T[maxSize];
}
/**
* This is the non-allocating constructor
*
* It expects a pointer to an array of a certain size and initializes
* itself to it.
*
* @param storage the array to use as backend
* @param maxSize size of storage
* @param size size of data already present in storage
*/
ArrayList(T *storage, count_t maxSize, count_t size = 0) :
size(size), entries(storage), maxSize_(maxSize), allocated(false) {
}
/**
* This is the non-allocating constructor
*
* It expects a pointer to an array of a certain size and initializes
* itself to it.
*
* @param storage the array to use as backend
* @param maxSize size of storage
* @param size size of data already present in storage
*/
ArrayList(T *storage, count_t maxSize, count_t size = 0) :
size(size), entries(storage), maxSize_(maxSize), allocated(false) {
}
/**
* Copying is forbiden by declaring copy ctor and copy assignment deleted
* It is too ambigous in this case.
* (Allocate a new backend? Use the same? What to do in an modifying call?)
*/
ArrayList(const ArrayList& other) = delete;
const ArrayList& operator=(const ArrayList& other) = delete;
/**
* Copying is forbiden by declaring copy ctor and copy assignment deleted
* It is too ambigous in this case.
* (Allocate a new backend? Use the same? What to do in an modifying call?)
*/
ArrayList(const ArrayList& other) = delete;
const ArrayList& operator=(const ArrayList& other) = delete;
/**
* Number of Elements stored in this List
*/
count_t size;
/**
* Number of Elements stored in this List
*/
count_t size;
/**
* Destructor, if the allocating constructor was used, it deletes the array.
*/
virtual ~ArrayList() {
if (allocated) {
delete[] entries;
}
}
/**
* Destructor, if the allocating constructor was used, it deletes the array.
*/
virtual ~ArrayList() {
if (allocated) {
delete[] entries;
}
}
/**
* An Iterator to go trough an ArrayList
*
* It stores a pointer to an element and increments the
* pointer when incremented itself.
*/
class Iterator {
public:
/**
* Empty ctor, points to NULL
*/
Iterator(): value(0) {}
/**
* An Iterator to go trough an ArrayList
*
* It stores a pointer to an element and increments the
* pointer when incremented itself.
*/
class Iterator {
public:
/**
* Empty ctor, points to NULL
*/
Iterator(): value(0) {}
/**
* Initializes the Iterator to point to an element
*
* @param initialize
*/
Iterator(T *initialize) {
value = initialize;
}
/**
* Initializes the Iterator to point to an element
*
* @param initialize
*/
Iterator(T *initialize) {
value = initialize;
}
/**
* The current element the iterator points to
*/
T *value;
/**