Merge branch 'mueller/master' of https://egit.irs.uni-stuttgart.de/KSat/fsfw into mueller/master

This commit is contained in:
Robin Müller 2020-08-23 20:27:00 +02:00
commit 2f53a3fb1b
471 changed files with 39160 additions and 39069 deletions

View File

@ -1,110 +1,110 @@
#include <framework/action/ActionHelper.h> #include "../action/ActionHelper.h"
#include <framework/action/HasActionsIF.h> #include "../action/HasActionsIF.h"
#include <framework/objectmanager/ObjectManagerIF.h> #include "../objectmanager/ObjectManagerIF.h"
ActionHelper::ActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue) : ActionHelper::ActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue) :
owner(setOwner), queueToUse(useThisQueue), ipcStore(nullptr) { owner(setOwner), queueToUse(useThisQueue), ipcStore(nullptr) {
} }
ActionHelper::~ActionHelper() { ActionHelper::~ActionHelper() {
} }
ReturnValue_t ActionHelper::handleActionMessage(CommandMessage* command) { ReturnValue_t ActionHelper::handleActionMessage(CommandMessage* command) {
if (command->getCommand() == ActionMessage::EXECUTE_ACTION) { if (command->getCommand() == ActionMessage::EXECUTE_ACTION) {
ActionId_t currentAction = ActionMessage::getActionId(command); ActionId_t currentAction = ActionMessage::getActionId(command);
prepareExecution(command->getSender(), currentAction, prepareExecution(command->getSender(), currentAction,
ActionMessage::getStoreId(command)); ActionMessage::getStoreId(command));
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} else { } else {
return CommandMessage::UNKNOWN_COMMAND; return CommandMessage::UNKNOWN_COMMAND;
} }
} }
ReturnValue_t ActionHelper::initialize(MessageQueueIF* queueToUse_) { ReturnValue_t ActionHelper::initialize(MessageQueueIF* queueToUse_) {
ipcStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE); ipcStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
if (ipcStore == nullptr) { if (ipcStore == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
if(queueToUse_ != nullptr) { if(queueToUse_ != nullptr) {
setQueueToUse(queueToUse_); 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) { void ActionHelper::step(uint8_t step, MessageQueueId_t reportTo, ActionId_t commandId, ReturnValue_t result) {
CommandMessage reply; CommandMessage reply;
ActionMessage::setStepReply(&reply, commandId, step + STEP_OFFSET, result); ActionMessage::setStepReply(&reply, commandId, step + STEP_OFFSET, result);
queueToUse->sendMessage(reportTo, &reply); queueToUse->sendMessage(reportTo, &reply);
} }
void ActionHelper::finish(MessageQueueId_t reportTo, ActionId_t commandId, ReturnValue_t result) { void ActionHelper::finish(MessageQueueId_t reportTo, ActionId_t commandId, ReturnValue_t result) {
CommandMessage reply; CommandMessage reply;
ActionMessage::setCompletionReply(&reply, commandId, result); ActionMessage::setCompletionReply(&reply, commandId, result);
queueToUse->sendMessage(reportTo, &reply); queueToUse->sendMessage(reportTo, &reply);
} }
void ActionHelper::setQueueToUse(MessageQueueIF* queue) { void ActionHelper::setQueueToUse(MessageQueueIF* queue) {
queueToUse = queue; queueToUse = queue;
} }
void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId, void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId,
store_address_t dataAddress) { store_address_t dataAddress) {
const uint8_t* dataPtr = NULL; const uint8_t* dataPtr = NULL;
size_t size = 0; size_t size = 0;
ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size); ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
CommandMessage reply; CommandMessage reply;
ActionMessage::setStepReply(&reply, actionId, 0, result); ActionMessage::setStepReply(&reply, actionId, 0, result);
queueToUse->sendMessage(commandedBy, &reply); queueToUse->sendMessage(commandedBy, &reply);
return; return;
} }
result = owner->executeAction(actionId, commandedBy, dataPtr, size); result = owner->executeAction(actionId, commandedBy, dataPtr, size);
ipcStore->deleteData(dataAddress); ipcStore->deleteData(dataAddress);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
CommandMessage reply; CommandMessage reply;
ActionMessage::setStepReply(&reply, actionId, 0, result); ActionMessage::setStepReply(&reply, actionId, 0, result);
queueToUse->sendMessage(commandedBy, &reply); queueToUse->sendMessage(commandedBy, &reply);
return; return;
} }
} }
ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo, ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo,
ActionId_t replyId, SerializeIF* data, bool hideSender) { ActionId_t replyId, SerializeIF* data, bool hideSender) {
CommandMessage reply; CommandMessage reply;
store_address_t storeAddress; store_address_t storeAddress;
uint8_t *dataPtr; uint8_t *dataPtr;
size_t maxSize = data->getSerializedSize(); size_t maxSize = data->getSerializedSize();
if (maxSize == 0) { if (maxSize == 0) {
//No error, there's simply nothing to report. //No error, there's simply nothing to report.
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
size_t size = 0; size_t size = 0;
ReturnValue_t result = ipcStore->getFreeElement(&storeAddress, maxSize, ReturnValue_t result = ipcStore->getFreeElement(&storeAddress, maxSize,
&dataPtr); &dataPtr);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
result = data->serialize(&dataPtr, &size, maxSize, SerializeIF::Endianness::BIG); result = data->serialize(&dataPtr, &size, maxSize, SerializeIF::Endianness::BIG);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
ipcStore->deleteData(storeAddress); ipcStore->deleteData(storeAddress);
return result; return result;
} }
//We don't need to report the objectId, as we receive REQUESTED data before the completion success 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. //True aperiodic replies need to be reported with another dedicated message.
ActionMessage::setDataReply(&reply, replyId, storeAddress); ActionMessage::setDataReply(&reply, replyId, storeAddress);
//TODO Service Implementation sucks at the moment //TODO Service Implementation sucks at the moment
if (hideSender){ if (hideSender){
result = MessageQueueSenderIF::sendMessage(reportTo, &reply); result = MessageQueueSenderIF::sendMessage(reportTo, &reply);
} else { } else {
result = queueToUse->sendMessage(reportTo, &reply); result = queueToUse->sendMessage(reportTo, &reply);
} }
if ( result != HasReturnvaluesIF::RETURN_OK){ if ( result != HasReturnvaluesIF::RETURN_OK){
ipcStore->deleteData(storeAddress); ipcStore->deleteData(storeAddress);
} }
return result; return result;
} }
void ActionHelper::resetHelper() { void ActionHelper::resetHelper() {
} }

View File

@ -1,93 +1,93 @@
#ifndef ACTIONHELPER_H_ #ifndef ACTIONHELPER_H_
#define ACTIONHELPER_H_ #define ACTIONHELPER_H_
#include <framework/action/ActionMessage.h> #include "../action/ActionMessage.h"
#include <framework/serialize/SerializeIF.h> #include "../serialize/SerializeIF.h"
#include <framework/ipc/MessageQueueIF.h> #include "../ipc/MessageQueueIF.h"
/** /**
* \brief Action Helper is a helper class which handles action messages * \brief Action Helper is a helper class which handles action messages
* *
* Components which use the HasActionIF this helper can be used to handle the action messages. * Components which use the HasActionIF this helper can be used to handle the action messages.
* It does handle step messages as well as other answers to action calls. It uses the executeAction function * It does handle step messages as well as other answers to action calls. It uses the executeAction function
* of its owner as callback. The call of the initialize function is mandatory and it needs a valid messageQueueIF pointer! * of its owner as callback. The call of the initialize function is mandatory and it needs a valid messageQueueIF pointer!
*/ */
class HasActionsIF; class HasActionsIF;
class ActionHelper { class ActionHelper {
public: public:
/** /**
* Constructor of the action helper * Constructor of the action helper
* @param setOwner Pointer to the owner of the interface * @param setOwner Pointer to the owner of the interface
* @param useThisQueue messageQueue to be used, can be set during initialize function as well. * @param useThisQueue messageQueue to be used, can be set during initialize function as well.
*/ */
ActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue); ActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue);
virtual ~ActionHelper(); virtual ~ActionHelper();
/** /**
* Function to be called from the owner with a new command message * 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 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. * 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 * @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 * @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); ReturnValue_t handleActionMessage(CommandMessage* command);
/** /**
* Helper initialize function. Must be called before use of any other helper function * Helper initialize function. Must be called before use of any other helper function
* @param queueToUse_ Pointer to the messageQueue to be used * @param queueToUse_ Pointer to the messageQueue to be used
* @return Returns RETURN_OK if successful * @return Returns RETURN_OK if successful
*/ */
ReturnValue_t initialize(MessageQueueIF* queueToUse_ = nullptr); 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. * 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 step Number of steps already done
* @param reportTo The messageQueueId to report the step message to * @param reportTo The messageQueueId to report the step message to
* @param commandId ID of the executed command * @param commandId ID of the executed command
* @param result Result of the execution * @param result Result of the execution
*/ */
void step(uint8_t step, MessageQueueId_t reportTo, ActionId_t commandId, ReturnValue_t result = HasReturnvaluesIF::RETURN_OK); 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 * 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 reportTo MessageQueueId_t to report the action completion message to
* @param commandId ID of the executed command * @param commandId ID of the executed command
* @param result Result of the execution * @param result Result of the execution
*/ */
void finish(MessageQueueId_t reportTo, ActionId_t commandId, ReturnValue_t result = HasReturnvaluesIF::RETURN_OK); 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 * Function to be called by the owner if an action does report data
* *
* @param reportTo MessageQueueId_t to report the action completion message to * @param reportTo MessageQueueId_t to report the action completion message to
* @param replyId ID of the executed command * @param replyId ID of the executed command
* @param data Pointer to the data * @param data Pointer to the data
* @return Returns RETURN_OK if successful, otherwise failure code * @return Returns RETURN_OK if successful, otherwise failure code
*/ */
ReturnValue_t reportData(MessageQueueId_t reportTo, ActionId_t replyId, SerializeIF* data, bool hideSender = false); ReturnValue_t reportData(MessageQueueId_t reportTo, ActionId_t replyId, SerializeIF* data, bool hideSender = false);
/** /**
* Function to setup the MessageQueueIF* of the helper. Can be used to set the messageQueueIF* if * 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. * 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 * @param queue Queue to be used by the helper
*/ */
void setQueueToUse(MessageQueueIF *queue); void setQueueToUse(MessageQueueIF *queue);
protected: protected:
static const uint8_t STEP_OFFSET = 1;//!< Increase of value of this per step static const uint8_t STEP_OFFSET = 1;//!< Increase of value of this per step
HasActionsIF* owner;//!< Pointer to the owner HasActionsIF* owner;//!< Pointer to the owner
MessageQueueIF* queueToUse;//!< Queue to be used as response sender, has to be set with MessageQueueIF* queueToUse;//!< Queue to be used as response sender, has to be set with
StorageManagerIF* ipcStore;//!< Pointer to an IPC Store, initialized during construction or initialize(MessageQueueIF* queueToUse_) or with setQueueToUse(MessageQueueIF *queue) StorageManagerIF* ipcStore;//!< Pointer to an IPC Store, initialized during construction or initialize(MessageQueueIF* queueToUse_) or with setQueueToUse(MessageQueueIF *queue)
/** /**
*Internal function called by handleActionMessage(CommandMessage* command) *Internal function called by handleActionMessage(CommandMessage* command)
* *
* @param commandedBy MessageQueueID of Commander * @param commandedBy MessageQueueID of Commander
* @param actionId ID of action to be done * @param actionId ID of action to be done
* @param dataAddress Address of additional data in IPC Store * @param dataAddress Address of additional data in IPC Store
*/ */
virtual void prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId, store_address_t dataAddress); virtual void prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId, store_address_t dataAddress);
/** /**
* *
*/ */
virtual void resetHelper(); virtual void resetHelper();
}; };
#endif /* ACTIONHELPER_H_ */ #endif /* ACTIONHELPER_H_ */

View File

@ -1,79 +1,79 @@
#include <framework/action/ActionMessage.h> #include "../action/ActionMessage.h"
#include <framework/objectmanager/ObjectManagerIF.h> #include "../objectmanager/ObjectManagerIF.h"
#include <framework/storagemanager/StorageManagerIF.h> #include "../storagemanager/StorageManagerIF.h"
ActionMessage::ActionMessage() { ActionMessage::ActionMessage() {
} }
ActionMessage::~ActionMessage() { ActionMessage::~ActionMessage() {
} }
void ActionMessage::setCommand(CommandMessage* message, ActionId_t fid, void ActionMessage::setCommand(CommandMessage* message, ActionId_t fid,
store_address_t parameters) { store_address_t parameters) {
message->setCommand(EXECUTE_ACTION); message->setCommand(EXECUTE_ACTION);
message->setParameter(fid); message->setParameter(fid);
message->setParameter2(parameters.raw); message->setParameter2(parameters.raw);
} }
ActionId_t ActionMessage::getActionId(const CommandMessage* message) { 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 ActionMessage::getStoreId(const CommandMessage* message) {
store_address_t temp; store_address_t temp;
temp.raw = message->getParameter2(); temp.raw = message->getParameter2();
return temp; return temp;
} }
void ActionMessage::setStepReply(CommandMessage* message, ActionId_t fid, uint8_t step, void ActionMessage::setStepReply(CommandMessage* message, ActionId_t fid, uint8_t step,
ReturnValue_t result) { ReturnValue_t result) {
if (result == HasReturnvaluesIF::RETURN_OK) { if (result == HasReturnvaluesIF::RETURN_OK) {
message->setCommand(STEP_SUCCESS); message->setCommand(STEP_SUCCESS);
} else { } else {
message->setCommand(STEP_FAILED); message->setCommand(STEP_FAILED);
} }
message->setParameter(fid); message->setParameter(fid);
message->setParameter2((step << 16) + result); message->setParameter2((step << 16) + result);
} }
uint8_t ActionMessage::getStep(const CommandMessage* message) { 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) { ReturnValue_t ActionMessage::getReturnCode(const CommandMessage* message) {
return message->getParameter2() & 0xFFFF; return message->getParameter2() & 0xFFFF;
} }
void ActionMessage::setDataReply(CommandMessage* message, ActionId_t actionId, void ActionMessage::setDataReply(CommandMessage* message, ActionId_t actionId,
store_address_t data) { store_address_t data) {
message->setCommand(DATA_REPLY); message->setCommand(DATA_REPLY);
message->setParameter(actionId); message->setParameter(actionId);
message->setParameter2(data.raw); message->setParameter2(data.raw);
} }
void ActionMessage::setCompletionReply(CommandMessage* message, void ActionMessage::setCompletionReply(CommandMessage* message,
ActionId_t fid, ReturnValue_t result) { ActionId_t fid, ReturnValue_t result) {
if (result == HasReturnvaluesIF::RETURN_OK) { if (result == HasReturnvaluesIF::RETURN_OK) {
message->setCommand(COMPLETION_SUCCESS); message->setCommand(COMPLETION_SUCCESS);
} else { } else {
message->setCommand(COMPLETION_FAILED); message->setCommand(COMPLETION_FAILED);
} }
message->setParameter(fid); message->setParameter(fid);
message->setParameter2(result); message->setParameter2(result);
} }
void ActionMessage::clear(CommandMessage* message) { void ActionMessage::clear(CommandMessage* message) {
switch(message->getCommand()) { switch(message->getCommand()) {
case EXECUTE_ACTION: case EXECUTE_ACTION:
case DATA_REPLY: { case DATA_REPLY: {
StorageManagerIF *ipcStore = objectManager->get<StorageManagerIF>( StorageManagerIF *ipcStore = objectManager->get<StorageManagerIF>(
objects::IPC_STORE); objects::IPC_STORE);
if (ipcStore != NULL) { if (ipcStore != NULL) {
ipcStore->deleteData(getStoreId(message)); ipcStore->deleteData(getStoreId(message));
} }
break; break;
} }
default: default:
break; break;
} }
} }

View File

@ -1,32 +1,32 @@
#ifndef ACTIONMESSAGE_H_ #ifndef ACTIONMESSAGE_H_
#define ACTIONMESSAGE_H_ #define ACTIONMESSAGE_H_
#include <framework/ipc/CommandMessage.h> #include "../ipc/CommandMessage.h"
#include <framework/objectmanager/ObjectManagerIF.h> #include "../objectmanager/ObjectManagerIF.h"
#include <framework/storagemanager/StorageManagerIF.h> #include "../storagemanager/StorageManagerIF.h"
typedef uint32_t ActionId_t; typedef uint32_t ActionId_t;
class ActionMessage { class ActionMessage {
private: private:
ActionMessage(); ActionMessage();
public: public:
static const uint8_t MESSAGE_ID = messagetypes::ACTION; static const uint8_t MESSAGE_ID = messagetypes::ACTION;
static const Command_t EXECUTE_ACTION = MAKE_COMMAND_ID(1); 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_SUCCESS = MAKE_COMMAND_ID(2);
static const Command_t STEP_FAILED = MAKE_COMMAND_ID(3); static const Command_t STEP_FAILED = MAKE_COMMAND_ID(3);
static const Command_t DATA_REPLY = MAKE_COMMAND_ID(4); 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_SUCCESS = MAKE_COMMAND_ID(5);
static const Command_t COMPLETION_FAILED = MAKE_COMMAND_ID(6); static const Command_t COMPLETION_FAILED = MAKE_COMMAND_ID(6);
virtual ~ActionMessage(); virtual ~ActionMessage();
static void setCommand(CommandMessage* message, ActionId_t fid, store_address_t parameters); static void setCommand(CommandMessage* message, ActionId_t fid, store_address_t parameters);
static ActionId_t getActionId(const CommandMessage* message ); static ActionId_t getActionId(const CommandMessage* message );
static store_address_t getStoreId(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 void setStepReply(CommandMessage* message, ActionId_t fid, uint8_t step, ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
static uint8_t getStep(const CommandMessage* message ); static uint8_t getStep(const CommandMessage* message );
static ReturnValue_t getReturnCode(const CommandMessage* message ); static ReturnValue_t getReturnCode(const CommandMessage* message );
static void setDataReply(CommandMessage* message, ActionId_t actionId, store_address_t data); 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 setCompletionReply(CommandMessage* message, ActionId_t fid, ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
static void clear(CommandMessage* message); static void clear(CommandMessage* message);
}; };
#endif /* ACTIONMESSAGE_H_ */ #endif /* ACTIONMESSAGE_H_ */

View File

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

View File

@ -1,36 +1,36 @@
#ifndef COMMANDACTIONHELPER_H_ #ifndef COMMANDACTIONHELPER_H_
#define COMMANDACTIONHELPER_H_ #define COMMANDACTIONHELPER_H_
#include <framework/action/ActionMessage.h> #include "../action/ActionMessage.h"
#include <framework/objectmanager/ObjectManagerIF.h> #include "../objectmanager/ObjectManagerIF.h"
#include <framework/returnvalues/HasReturnvaluesIF.h> #include "../returnvalues/HasReturnvaluesIF.h"
#include <framework/serialize/SerializeIF.h> #include "../serialize/SerializeIF.h"
#include <framework/storagemanager/StorageManagerIF.h> #include "../storagemanager/StorageManagerIF.h"
#include <framework/ipc/MessageQueueIF.h> #include "../ipc/MessageQueueIF.h"
class CommandsActionsIF; class CommandsActionsIF;
class CommandActionHelper { class CommandActionHelper {
friend class CommandsActionsIF; friend class CommandsActionsIF;
public: public:
CommandActionHelper(CommandsActionsIF* owner); CommandActionHelper(CommandsActionsIF* owner);
virtual ~CommandActionHelper(); virtual ~CommandActionHelper();
ReturnValue_t commandAction(object_id_t commandTo, ReturnValue_t commandAction(object_id_t commandTo,
ActionId_t actionId, const uint8_t* data, uint32_t size); ActionId_t actionId, const uint8_t* data, uint32_t size);
ReturnValue_t commandAction(object_id_t commandTo, ReturnValue_t commandAction(object_id_t commandTo,
ActionId_t actionId, SerializeIF* data); ActionId_t actionId, SerializeIF* data);
ReturnValue_t initialize(); ReturnValue_t initialize();
ReturnValue_t handleReply(CommandMessage* reply); ReturnValue_t handleReply(CommandMessage* reply);
uint8_t getCommandCount() const; uint8_t getCommandCount() const;
private: private:
CommandsActionsIF* owner; CommandsActionsIF* owner;
MessageQueueIF* queueToUse; MessageQueueIF* queueToUse;
StorageManagerIF* ipcStore; StorageManagerIF* ipcStore;
uint8_t commandCount; uint8_t commandCount;
MessageQueueId_t lastTarget; MessageQueueId_t lastTarget;
void extractDataForOwner(ActionId_t actionId, store_address_t storeId); void extractDataForOwner(ActionId_t actionId, store_address_t storeId);
ReturnValue_t sendCommand(MessageQueueId_t queueId, ActionId_t actionId, ReturnValue_t sendCommand(MessageQueueId_t queueId, ActionId_t actionId,
store_address_t storeId); store_address_t storeId);
}; };
#endif /* COMMANDACTIONHELPER_H_ */ #endif /* COMMANDACTIONHELPER_H_ */

View File

@ -1,34 +1,34 @@
#ifndef COMMANDSACTIONSIF_H_ #ifndef COMMANDSACTIONSIF_H_
#define COMMANDSACTIONSIF_H_ #define COMMANDSACTIONSIF_H_
#include <framework/action/CommandActionHelper.h> #include "../action/CommandActionHelper.h"
#include <framework/returnvalues/HasReturnvaluesIF.h> #include "../returnvalues/HasReturnvaluesIF.h"
#include <framework/ipc/MessageQueueIF.h> #include "../ipc/MessageQueueIF.h"
/** /**
* Interface to separate commanding actions of other objects. * Interface to separate commanding actions of other objects.
* In next iteration, IF should be shortened to three calls: * In next iteration, IF should be shortened to three calls:
* - dataReceived(data) * - dataReceived(data)
* - successReceived(id, step) * - successReceived(id, step)
* - failureReceived(id, step, cause) * - failureReceived(id, step, cause)
* or even * or even
* - replyReceived(id, step, cause) (if cause == OK, it's a success). * - replyReceived(id, step, cause) (if cause == OK, it's a success).
*/ */
class CommandsActionsIF { class CommandsActionsIF {
friend class CommandActionHelper; friend class CommandActionHelper;
public: public:
static const uint8_t INTERFACE_ID = CLASS_ID::COMMANDS_ACTIONS_IF; 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 OBJECT_HAS_NO_FUNCTIONS = MAKE_RETURN_CODE(1);
static const ReturnValue_t ALREADY_COMMANDING = MAKE_RETURN_CODE(2); static const ReturnValue_t ALREADY_COMMANDING = MAKE_RETURN_CODE(2);
virtual ~CommandsActionsIF() {} virtual ~CommandsActionsIF() {}
virtual MessageQueueIF* getCommandQueuePtr() = 0; virtual MessageQueueIF* getCommandQueuePtr() = 0;
protected: protected:
virtual void stepSuccessfulReceived(ActionId_t actionId, uint8_t step) = 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 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 dataReceived(ActionId_t actionId, const uint8_t* data, uint32_t size) = 0;
virtual void completionSuccessfulReceived(ActionId_t actionId) = 0; virtual void completionSuccessfulReceived(ActionId_t actionId) = 0;
virtual void completionFailedReceived(ActionId_t actionId, ReturnValue_t returnCode) = 0; virtual void completionFailedReceived(ActionId_t actionId, ReturnValue_t returnCode) = 0;
}; };
#endif /* COMMANDSACTIONSIF_H_ */ #endif /* COMMANDSACTIONSIF_H_ */

View File

@ -1,60 +1,60 @@
#ifndef FRAMEWORK_ACTION_HASACTIONSIF_H_ #ifndef FRAMEWORK_ACTION_HASACTIONSIF_H_
#define FRAMEWORK_ACTION_HASACTIONSIF_H_ #define FRAMEWORK_ACTION_HASACTIONSIF_H_
#include <framework/action/ActionHelper.h> #include "../action/ActionHelper.h"
#include <framework/action/ActionMessage.h> #include "../action/ActionMessage.h"
#include <framework/action/SimpleActionHelper.h> #include "../action/SimpleActionHelper.h"
#include <framework/returnvalues/HasReturnvaluesIF.h> #include "../returnvalues/HasReturnvaluesIF.h"
#include <framework/ipc/MessageQueueIF.h> #include "../ipc/MessageQueueIF.h"
/** /**
* @brief * @brief
* Interface for component which uses actions * Interface for component which uses actions
* *
* @details * @details
* This interface is used to execute actions in the component. Actions, in the * This interface is used to execute actions in the component. Actions, in the
* sense of this interface, are activities with a well-defined beginning and * sense of this interface, are activities with a well-defined beginning and
* end in time. They may adjust sub-states of components, but are not supposed * end in time. They may adjust sub-states of components, but are not supposed
* to change the main mode of operation, which is handled with the HasModesIF * to change the main mode of operation, which is handled with the HasModesIF
* described below. * described below.
* *
* The HasActionsIF allows components to define such actions and make them * The HasActionsIF allows components to define such actions and make them
* available for other components to use. Implementing the interface is * available for other components to use. Implementing the interface is
* straightforward: Theres a single executeAction call, which provides an * straightforward: Theres a single executeAction call, which provides an
* identifier for the action to execute, as well as arbitrary parameters for * identifier for the action to execute, as well as arbitrary parameters for
* input. * input.
* Aside from direct, software-based actions, it is used in device handler * Aside from direct, software-based actions, it is used in device handler
* components as an interface to forward commands to devices. * components as an interface to forward commands to devices.
* Implementing components of the interface are supposed to check identifier * Implementing components of the interface are supposed to check identifier
* (ID) and parameters and immediately start execution of the action. * (ID) and parameters and immediately start execution of the action.
* It is, however, not required to immediately finish execution. * It is, however, not required to immediately finish execution.
* Instead, this may be deferred to a later point in time, at which the * Instead, this may be deferred to a later point in time, at which the
* component needs to inform the caller about finished or failed execution. * component needs to inform the caller about finished or failed execution.
* *
* @ingroup interfaces * @ingroup interfaces
*/ */
class HasActionsIF { class HasActionsIF {
public: public:
static const uint8_t INTERFACE_ID = CLASS_ID::HAS_ACTIONS_IF; 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 IS_BUSY = MAKE_RETURN_CODE(1);
static const ReturnValue_t INVALID_PARAMETERS = MAKE_RETURN_CODE(2); static const ReturnValue_t INVALID_PARAMETERS = MAKE_RETURN_CODE(2);
static const ReturnValue_t EXECUTION_FINISHED = MAKE_RETURN_CODE(3); static const ReturnValue_t EXECUTION_FINISHED = MAKE_RETURN_CODE(3);
static const ReturnValue_t INVALID_ACTION_ID = MAKE_RETURN_CODE(4); static const ReturnValue_t INVALID_ACTION_ID = MAKE_RETURN_CODE(4);
virtual ~HasActionsIF() { } virtual ~HasActionsIF() { }
/** /**
* Function to get the MessageQueueId_t of the implementing object * Function to get the MessageQueueId_t of the implementing object
* @return MessageQueueId_t of the object * @return MessageQueueId_t of the object
*/ */
virtual MessageQueueId_t getCommandQueue() const = 0; virtual MessageQueueId_t getCommandQueue() const = 0;
/** /**
* Execute or initialize the execution of a certain function. * Execute or initialize the execution of a certain function.
* Returning #EXECUTION_FINISHED or a failure code, nothing else needs to * Returning #EXECUTION_FINISHED or a failure code, nothing else needs to
* be done. When needing more steps, return RETURN_OK and issue steps and * be done. When needing more steps, return RETURN_OK and issue steps and
* completion manually. * completion manually.
* One "step failed" or completion report must be issued! * One "step failed" or completion report must be issued!
*/ */
virtual ReturnValue_t executeAction(ActionId_t actionId, virtual ReturnValue_t executeAction(ActionId_t actionId,
MessageQueueId_t commandedBy, const uint8_t* data, size_t size) = 0; MessageQueueId_t commandedBy, const uint8_t* data, size_t size) = 0;
}; };
#endif /* FRAMEWORK_ACTION_HASACTIONSIF_H_ */ #endif /* FRAMEWORK_ACTION_HASACTIONSIF_H_ */

View File

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

View File

@ -1,24 +1,24 @@
#ifndef SIMPLEACTIONHELPER_H_ #ifndef SIMPLEACTIONHELPER_H_
#define SIMPLEACTIONHELPER_H_ #define SIMPLEACTIONHELPER_H_
#include <framework/action/ActionHelper.h> #include "../action/ActionHelper.h"
class SimpleActionHelper: public ActionHelper { class SimpleActionHelper: public ActionHelper {
public: public:
SimpleActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue); SimpleActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue);
virtual ~SimpleActionHelper(); virtual ~SimpleActionHelper();
void step(ReturnValue_t result = HasReturnvaluesIF::RETURN_OK); void step(ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
void finish(ReturnValue_t result = HasReturnvaluesIF::RETURN_OK); void finish(ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
ReturnValue_t reportData(SerializeIF* data); ReturnValue_t reportData(SerializeIF* data);
protected: protected:
void prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId, store_address_t dataAddress); void prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId, store_address_t dataAddress);
virtual void resetHelper(); virtual void resetHelper();
private: private:
bool isExecuting; bool isExecuting;
MessageQueueId_t lastCommander; MessageQueueId_t lastCommander;
ActionId_t lastAction; ActionId_t lastAction;
uint8_t stepCount; uint8_t stepCount;
}; };
#endif /* SIMPLEACTIONHELPER_H_ */ #endif /* SIMPLEACTIONHELPER_H_ */

View File

@ -1,247 +1,247 @@
#ifndef FRAMEWORK_CONTAINER_ARRAYLIST_H_ #ifndef FRAMEWORK_CONTAINER_ARRAYLIST_H_
#define FRAMEWORK_CONTAINER_ARRAYLIST_H_ #define FRAMEWORK_CONTAINER_ARRAYLIST_H_
#include <framework/returnvalues/HasReturnvaluesIF.h> #include "../returnvalues/HasReturnvaluesIF.h"
#include <framework/serialize/SerializeAdapter.h> #include "../serialize/SerializeAdapter.h"
#include <framework/serialize/SerializeIF.h> #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 * @details
* The underlying storage is an array that can be allocated by the class * The underlying storage is an array that can be allocated by the class
* itself or supplied via ctor. * itself or supplied via ctor.
* *
* @ingroup container * @ingroup container
*/ */
template<typename T, typename count_t = uint8_t> template<typename T, typename count_t = uint8_t>
class ArrayList { class ArrayList {
template<typename U, typename count> friend class SerialArrayListAdapter; template<typename U, typename count> friend class SerialArrayListAdapter;
public: public:
static const uint8_t INTERFACE_ID = CLASS_ID::ARRAY_LIST; static const uint8_t INTERFACE_ID = CLASS_ID::ARRAY_LIST;
static const ReturnValue_t FULL = MAKE_RETURN_CODE(0x01); static const ReturnValue_t FULL = MAKE_RETURN_CODE(0x01);
/** /**
* Copying is forbiden by declaring copy ctor and copy assignment deleted * Copying is forbiden by declaring copy ctor and copy assignment deleted
* It is too ambigous in this case. * It is too ambigous in this case.
* (Allocate a new backend? Use the same? What to do in an modifying call?) * (Allocate a new backend? Use the same? What to do in an modifying call?)
*/ */
ArrayList(const ArrayList& other) = delete; ArrayList(const ArrayList& other) = delete;
const ArrayList& operator=(const ArrayList& other) = delete; const ArrayList& operator=(const ArrayList& other) = delete;
/** /**
* Number of Elements stored in this List * Number of Elements stored in this List
*/ */
count_t size; count_t size;
/** /**
* This is the allocating constructor; * This is the allocating constructor;
* *
* It allocates an array of the specified size. * It allocates an array of the specified size.
* *
* @param maxSize * @param maxSize
*/ */
ArrayList(count_t maxSize) : ArrayList(count_t maxSize) :
size(0), maxSize_(maxSize), allocated(true) { size(0), maxSize_(maxSize), allocated(true) {
entries = new T[maxSize]; entries = new T[maxSize];
} }
/** /**
* This is the non-allocating constructor * This is the non-allocating constructor
* *
* It expects a pointer to an array of a certain size and initializes itself to it. * 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 storage the array to use as backend
* @param maxSize size of storage * @param maxSize size of storage
* @param size size of data already present in storage * @param size size of data already present in storage
*/ */
ArrayList(T *storage, count_t maxSize, count_t size = 0) : ArrayList(T *storage, count_t maxSize, count_t size = 0) :
size(size), entries(storage), maxSize_(maxSize), allocated(false) { size(size), entries(storage), maxSize_(maxSize), allocated(false) {
} }
/** /**
* Destructor, if the allocating constructor was used, it deletes the array. * Destructor, if the allocating constructor was used, it deletes the array.
*/ */
virtual ~ArrayList() { virtual ~ArrayList() {
if (allocated) { if (allocated) {
delete[] entries; delete[] entries;
} }
} }
/** /**
* An Iterator to go trough an ArrayList * An Iterator to go trough an ArrayList
* *
* It stores a pointer to an element and increments the * It stores a pointer to an element and increments the
* pointer when incremented itself. * pointer when incremented itself.
*/ */
class Iterator { class Iterator {
public: public:
/** /**
* Empty ctor, points to NULL * Empty ctor, points to NULL
*/ */
Iterator(): value(0) {} Iterator(): value(0) {}
/** /**
* Initializes the Iterator to point to an element * Initializes the Iterator to point to an element
* *
* @param initialize * @param initialize
*/ */
Iterator(T *initialize) { Iterator(T *initialize) {
value = initialize; value = initialize;
} }
/** /**
* The current element the iterator points to * The current element the iterator points to
*/ */
T *value; T *value;
Iterator& operator++() { Iterator& operator++() {
value++; value++;
return *this; return *this;
} }
Iterator operator++(int) { Iterator operator++(int) {
Iterator tmp(*this); Iterator tmp(*this);
operator++(); operator++();
return tmp; return tmp;
} }
Iterator& operator--() { Iterator& operator--() {
value--; value--;
return *this; return *this;
} }
Iterator operator--(int) { Iterator operator--(int) {
Iterator tmp(*this); Iterator tmp(*this);
operator--(); operator--();
return tmp; return tmp;
} }
T operator*() { T operator*() {
return *value; return *value;
} }
T *operator->() { T *operator->() {
return value; return value;
} }
const T *operator->() const{ const T *operator->() const{
return value; return value;
} }
//SHOULDDO this should be implemented as non-member //SHOULDDO this should be implemented as non-member
bool operator==(const typename ArrayList<T, count_t>::Iterator& other) const{ bool operator==(const typename ArrayList<T, count_t>::Iterator& other) const{
return (value == other.value); return (value == other.value);
} }
//SHOULDDO this should be implemented as non-member //SHOULDDO this should be implemented as non-member
bool operator!=(const typename ArrayList<T, count_t>::Iterator& other) const { bool operator!=(const typename ArrayList<T, count_t>::Iterator& other) const {
return !(*this == other); return !(*this == other);
} }
}; };
/** /**
* Iterator pointing to the first stored elmement * Iterator pointing to the first stored elmement
* *
* @return Iterator to the first element * @return Iterator to the first element
*/ */
Iterator begin() const { Iterator begin() const {
return Iterator(&entries[0]); return Iterator(&entries[0]);
} }
/** /**
* returns an Iterator pointing to the element after the last stored entry * returns an Iterator pointing to the element after the last stored entry
* *
* @return Iterator to the element after the last entry * @return Iterator to the element after the last entry
*/ */
Iterator end() const { Iterator end() const {
return Iterator(&entries[size]); return Iterator(&entries[size]);
} }
T & operator[](count_t i) const { T & operator[](count_t i) const {
return entries[i]; return entries[i];
} }
/** /**
* The first element * The first element
* *
* @return pointer to the first stored element * @return pointer to the first stored element
*/ */
T *front() { T *front() {
return entries; return entries;
} }
/** /**
* The last element * The last element
* *
* does not return a valid pointer if called on an empty list. * does not return a valid pointer if called on an empty list.
* *
* @return pointer to the last stored element * @return pointer to the last stored element
*/ */
T *back() { T *back() {
return &entries[size - 1]; return &entries[size - 1];
//Alternative solution //Alternative solution
//return const_cast<T*>(static_cast<const T*>(*this).back()); //return const_cast<T*>(static_cast<const T*>(*this).back());
} }
const T* back() const{ const T* back() const{
return &entries[size-1]; return &entries[size-1];
} }
/** /**
* The maximum number of elements this List can contain * The maximum number of elements this List can contain
* *
* @return maximum number of elements * @return maximum number of elements
*/ */
uint32_t maxSize() const { uint32_t maxSize() const {
return this->maxSize_; return this->maxSize_;
} }
/** /**
* Insert a new element into the list. * Insert a new element into the list.
* *
* The new element is inserted after the last stored element. * The new element is inserted after the last stored element.
* *
* @param entry * @param entry
* @return * @return
* -@c FULL if the List is full * -@c FULL if the List is full
* -@c RETURN_OK else * -@c RETURN_OK else
*/ */
ReturnValue_t insert(T entry) { ReturnValue_t insert(T entry) {
if (size >= maxSize_) { if (size >= maxSize_) {
return FULL; return FULL;
} }
entries[size] = entry; entries[size] = entry;
++size; ++size;
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
/** /**
* clear the List * clear the List
* *
* This does not actually clear all entries, it only sets the size to 0. * This does not actually clear all entries, it only sets the size to 0.
*/ */
void clear() { void clear() {
size = 0; size = 0;
} }
count_t remaining() { count_t remaining() {
return (maxSize_ - size); return (maxSize_ - size);
} }
protected: protected:
/** /**
* pointer to the array in which the entries are stored * pointer to the array in which the entries are stored
*/ */
T *entries; T *entries;
/** /**
* remembering the maximum size * remembering the maximum size
*/ */
uint32_t maxSize_; uint32_t maxSize_;
/** /**
* true if the array was allocated and needs to be deleted in the destructor. * true if the array was allocated and needs to be deleted in the destructor.
*/ */
bool allocated; bool allocated;
}; };
#endif /* ARRAYLIST_H_ */ #endif /* ARRAYLIST_H_ */

View File

@ -1,42 +1,42 @@
#ifndef FRAMEWORK_CONTAINER_DYNAMICFIFO_H_ #ifndef FRAMEWORK_CONTAINER_DYNAMICFIFO_H_
#define FRAMEWORK_CONTAINER_DYNAMICFIFO_H_ #define FRAMEWORK_CONTAINER_DYNAMICFIFO_H_
#include <framework/container/FIFOBase.h> #include "../container/FIFOBase.h"
#include <vector> #include <vector>
/** /**
* @brief Simple First-In-First-Out data structure. The maximum size * @brief Simple First-In-First-Out data structure. The maximum size
* can be set in the constructor. * can be set in the constructor.
* @details * @details
* The maximum capacity can be determined at run-time, so this container * The maximum capacity can be determined at run-time, so this container
* performs dynamic memory allocation! * performs dynamic memory allocation!
* The public interface of FIFOBase exposes the user interface for the FIFO. * The public interface of FIFOBase exposes the user interface for the FIFO.
* @tparam T Entry Type * @tparam T Entry Type
* @tparam capacity Maximum capacity * @tparam capacity Maximum capacity
*/ */
template<typename T> template<typename T>
class DynamicFIFO: public FIFOBase<T> { class DynamicFIFO: public FIFOBase<T> {
public: public:
DynamicFIFO(size_t maxCapacity): FIFOBase<T>(nullptr, maxCapacity), DynamicFIFO(size_t maxCapacity): FIFOBase<T>(nullptr, maxCapacity),
fifoVector(maxCapacity) { fifoVector(maxCapacity) {
// trying to pass the pointer of the uninitialized vector // trying to pass the pointer of the uninitialized vector
// to the FIFOBase constructor directly lead to a super evil bug. // to the FIFOBase constructor directly lead to a super evil bug.
// So we do it like this now. // So we do it like this now.
this->setData(fifoVector.data()); this->setData(fifoVector.data());
}; };
/** /**
* @brief Custom copy constructor which prevents setting the * @brief Custom copy constructor which prevents setting the
* underlying pointer wrong. * underlying pointer wrong.
*/ */
DynamicFIFO(const DynamicFIFO& other): FIFOBase<T>(other), DynamicFIFO(const DynamicFIFO& other): FIFOBase<T>(other),
fifoVector(other.maxCapacity) { fifoVector(other.maxCapacity) {
this->setData(fifoVector.data()); this->setData(fifoVector.data());
} }
private: private:
std::vector<T> fifoVector; std::vector<T> fifoVector;
}; };
#endif /* FRAMEWORK_CONTAINER_DYNAMICFIFO_H_ */ #endif /* FRAMEWORK_CONTAINER_DYNAMICFIFO_H_ */

View File

@ -1,34 +1,34 @@
#ifndef FRAMEWORK_CONTAINER_FIFO_H_ #ifndef FRAMEWORK_CONTAINER_FIFO_H_
#define FRAMEWORK_CONTAINER_FIFO_H_ #define FRAMEWORK_CONTAINER_FIFO_H_
#include <framework/returnvalues/HasReturnvaluesIF.h> #include "../returnvalues/HasReturnvaluesIF.h"
#include <framework/container/FIFOBase.h> #include "../container/FIFOBase.h"
#include <array> #include <array>
/** /**
* @brief Simple First-In-First-Out data structure with size fixed at * @brief Simple First-In-First-Out data structure with size fixed at
* compile time * compile time
* @details * @details
* Performs no dynamic memory allocation. * Performs no dynamic memory allocation.
* The public interface of FIFOBase exposes the user interface for the FIFO. * The public interface of FIFOBase exposes the user interface for the FIFO.
* @tparam T Entry Type * @tparam T Entry Type
* @tparam capacity Maximum capacity * @tparam capacity Maximum capacity
*/ */
template<typename T, size_t capacity> template<typename T, size_t capacity>
class FIFO: public FIFOBase<T> { class FIFO: public FIFOBase<T> {
public: public:
FIFO(): FIFOBase<T>(fifoArray.data(), capacity) {}; FIFO(): FIFOBase<T>(fifoArray.data(), capacity) {};
/** /**
* @brief Custom copy constructor to set pointer correctly. * @brief Custom copy constructor to set pointer correctly.
* @param other * @param other
*/ */
FIFO(const FIFO& other): FIFOBase<T>(other) { FIFO(const FIFO& other): FIFOBase<T>(other) {
this->setData(fifoArray.data()); this->setData(fifoArray.data());
} }
private: private:
std::array<T, capacity> fifoArray; std::array<T, capacity> fifoArray;
}; };
#endif /* FRAMEWORK_CONTAINERS_STATICFIFO_H_ */ #endif /* FRAMEWORK_CONTAINERS_STATICFIFO_H_ */

View File

@ -1,65 +1,65 @@
#ifndef FRAMEWORK_CONTAINER_FIFOBASE_H_ #ifndef FRAMEWORK_CONTAINER_FIFOBASE_H_
#define FRAMEWORK_CONTAINER_FIFOBASE_H_ #define FRAMEWORK_CONTAINER_FIFOBASE_H_
#include <framework/returnvalues/HasReturnvaluesIF.h> #include "../returnvalues/HasReturnvaluesIF.h"
#include <cstddef> #include <cstddef>
#include <cstring> #include <cstring>
template <typename T> template <typename T>
class FIFOBase { class FIFOBase {
public: public:
static const uint8_t INTERFACE_ID = CLASS_ID::FIFO_CLASS; static const uint8_t INTERFACE_ID = CLASS_ID::FIFO_CLASS;
static const ReturnValue_t FULL = MAKE_RETURN_CODE(1); static const ReturnValue_t FULL = MAKE_RETURN_CODE(1);
static const ReturnValue_t EMPTY = MAKE_RETURN_CODE(2); static const ReturnValue_t EMPTY = MAKE_RETURN_CODE(2);
/** Default ctor, takes pointer to first entry of underlying container /** Default ctor, takes pointer to first entry of underlying container
* and maximum capacity */ * and maximum capacity */
FIFOBase(T* values, const size_t maxCapacity); FIFOBase(T* values, const size_t maxCapacity);
/** /**
* Insert value into FIFO * Insert value into FIFO
* @param value * @param value
* @return * @return
*/ */
ReturnValue_t insert(T value); ReturnValue_t insert(T value);
/** /**
* Retrieve item from FIFO. This removes the item from the FIFO. * Retrieve item from FIFO. This removes the item from the FIFO.
* @param value * @param value
* @return * @return
*/ */
ReturnValue_t retrieve(T *value); ReturnValue_t retrieve(T *value);
/** /**
* Retrieve item from FIFO without removing it from FIFO. * Retrieve item from FIFO without removing it from FIFO.
* @param value * @param value
* @return * @return
*/ */
ReturnValue_t peek(T * value); ReturnValue_t peek(T * value);
/** /**
* Remove item from FIFO. * Remove item from FIFO.
* @return * @return
*/ */
ReturnValue_t pop(); ReturnValue_t pop();
bool empty(); bool empty();
bool full(); bool full();
size_t size(); size_t size();
size_t getMaxCapacity() const; size_t getMaxCapacity() const;
protected: protected:
void setData(T* data); void setData(T* data);
size_t maxCapacity = 0; size_t maxCapacity = 0;
T* values; T* values;
size_t readIndex = 0; size_t readIndex = 0;
size_t writeIndex = 0; size_t writeIndex = 0;
size_t currentSize = 0; size_t currentSize = 0;
size_t next(size_t current); size_t next(size_t current);
}; };
#include <framework/container/FIFOBase.tpp> #include "../container/FIFOBase.tpp"
#endif /* FRAMEWORK_CONTAINER_FIFOBASE_H_ */ #endif /* FRAMEWORK_CONTAINER_FIFOBASE_H_ */

View File

@ -1,57 +1,57 @@
#ifndef FIXEDARRAYLIST_H_ #ifndef FIXEDARRAYLIST_H_
#define FIXEDARRAYLIST_H_ #define FIXEDARRAYLIST_H_
#include <framework/container/ArrayList.h> #include "../container/ArrayList.h"
/** /**
* @brief Array List with a fixed maximum size * @brief Array List with a fixed maximum size
* @ingroup container * @ingroup container
*/ */
template<typename T, uint32_t MAX_SIZE, typename count_t = uint8_t> template<typename T, uint32_t MAX_SIZE, typename count_t = uint8_t>
class FixedArrayList: public ArrayList<T, count_t> { class FixedArrayList: public ArrayList<T, count_t> {
private: private:
T data[MAX_SIZE]; T data[MAX_SIZE];
public: public:
/** /**
* (Robin) Maybe we should also implement move assignment and move ctor. * (Robin) Maybe we should also implement move assignment and move ctor.
* Or at least delete them. * Or at least delete them.
*/ */
FixedArrayList() : FixedArrayList() :
ArrayList<T, count_t>(data, MAX_SIZE) { ArrayList<T, count_t>(data, MAX_SIZE) {
} }
// (Robin): We could create a constructor to initialize the fixed array list // (Robin): We could create a constructor to initialize the fixed array list
// with data and the known size field // with data and the known size field
// so it can be used for serialization too (with SerialFixedArrrayListAdapter) // so it can be used for serialization too (with SerialFixedArrrayListAdapter)
// is this feasible? // is this feasible?
/** /**
* Initialize a fixed array list with data and number of data fields. * Initialize a fixed array list with data and number of data fields.
* Endianness of entries can be swapped optionally. * Endianness of entries can be swapped optionally.
* @param data_ * @param data_
* @param count * @param count
* @param swapArrayListEndianess * @param swapArrayListEndianess
*/ */
FixedArrayList(T * data_, count_t count): FixedArrayList(T * data_, count_t count):
ArrayList<T, count_t>(data, MAX_SIZE) { ArrayList<T, count_t>(data, MAX_SIZE) {
memcpy(this->data, data_, count * sizeof(T)); memcpy(this->data, data_, count * sizeof(T));
this->size = count; this->size = count;
} }
FixedArrayList(const FixedArrayList& other) : FixedArrayList(const FixedArrayList& other) :
ArrayList<T, count_t>(data, MAX_SIZE) { ArrayList<T, count_t>(data, MAX_SIZE) {
memcpy(this->data, other.data, sizeof(this->data)); memcpy(this->data, other.data, sizeof(this->data));
this->entries = data; this->entries = data;
} }
FixedArrayList& operator=(FixedArrayList other) { FixedArrayList& operator=(FixedArrayList other) {
memcpy(this->data, other.data, sizeof(this->data)); memcpy(this->data, other.data, sizeof(this->data));
this->entries = data; this->entries = data;
return *this; return *this;
} }
virtual ~FixedArrayList() { virtual ~FixedArrayList() {
} }
}; };
#endif /* FIXEDARRAYLIST_H_ */ #endif /* FIXEDARRAYLIST_H_ */

View File

@ -1,225 +1,225 @@
#ifndef FIXEDMAP_H_ #ifndef FIXEDMAP_H_
#define FIXEDMAP_H_ #define FIXEDMAP_H_
#include <framework/container/ArrayList.h> #include "../container/ArrayList.h"
#include <framework/returnvalues/HasReturnvaluesIF.h> #include "../returnvalues/HasReturnvaluesIF.h"
#include <utility> #include <utility>
/** /**
* @brief Map implementation for maps with a pre-defined size. * @brief Map implementation for maps with a pre-defined size.
* @details Can be initialized with desired maximum size. * @details Can be initialized with desired maximum size.
* Iterator is used to access <key,value> pair and * Iterator is used to access <key,value> pair and
* iterate through map entries. Complexity O(n). * iterate through map entries. Complexity O(n).
* @ingroup container * @ingroup container
*/ */
template<typename key_t, typename T> template<typename key_t, typename T>
class FixedMap: public SerializeIF { class FixedMap: public SerializeIF {
public: public:
static const uint8_t INTERFACE_ID = CLASS_ID::FIXED_MAP; static const uint8_t INTERFACE_ID = CLASS_ID::FIXED_MAP;
static const ReturnValue_t KEY_ALREADY_EXISTS = MAKE_RETURN_CODE(0x01); static const ReturnValue_t KEY_ALREADY_EXISTS = MAKE_RETURN_CODE(0x01);
static const ReturnValue_t MAP_FULL = MAKE_RETURN_CODE(0x02); static const ReturnValue_t MAP_FULL = MAKE_RETURN_CODE(0x02);
static const ReturnValue_t KEY_DOES_NOT_EXIST = MAKE_RETURN_CODE(0x03); static const ReturnValue_t KEY_DOES_NOT_EXIST = MAKE_RETURN_CODE(0x03);
private: private:
static const key_t EMPTY_SLOT = -1; static const key_t EMPTY_SLOT = -1;
ArrayList<std::pair<key_t, T>, uint32_t> theMap; ArrayList<std::pair<key_t, T>, uint32_t> theMap;
uint32_t _size; uint32_t _size;
uint32_t findIndex(key_t key) const { uint32_t findIndex(key_t key) const {
if (_size == 0) { if (_size == 0) {
return 1; return 1;
} }
uint32_t i = 0; uint32_t i = 0;
for (i = 0; i < _size; ++i) { for (i = 0; i < _size; ++i) {
if (theMap[i].first == key) { if (theMap[i].first == key) {
return i; return i;
} }
} }
return i; return i;
} }
public: public:
FixedMap(uint32_t maxSize) : FixedMap(uint32_t maxSize) :
theMap(maxSize), _size(0) { theMap(maxSize), _size(0) {
} }
class Iterator: public ArrayList<std::pair<key_t, T>, uint32_t>::Iterator { class Iterator: public ArrayList<std::pair<key_t, T>, uint32_t>::Iterator {
public: public:
Iterator() : Iterator() :
ArrayList<std::pair<key_t, T>, uint32_t>::Iterator() { ArrayList<std::pair<key_t, T>, uint32_t>::Iterator() {
} }
Iterator(std::pair<key_t, T> *pair) : Iterator(std::pair<key_t, T> *pair) :
ArrayList<std::pair<key_t, T>, uint32_t>::Iterator(pair) { ArrayList<std::pair<key_t, T>, uint32_t>::Iterator(pair) {
} }
T operator*() { T operator*() {
return ArrayList<std::pair<key_t, T>, uint32_t>::Iterator::value->second; return ArrayList<std::pair<key_t, T>, uint32_t>::Iterator::value->second;
} }
// -> operator overloaded, can be used to access value // -> operator overloaded, can be used to access value
T *operator->() { T *operator->() {
return &ArrayList<std::pair<key_t, T>, uint32_t>::Iterator::value->second; return &ArrayList<std::pair<key_t, T>, uint32_t>::Iterator::value->second;
} }
// Can be used to access the key of the iterator // Can be used to access the key of the iterator
key_t first() { key_t first() {
return ArrayList<std::pair<key_t, T>, uint32_t>::Iterator::value->first; return ArrayList<std::pair<key_t, T>, uint32_t>::Iterator::value->first;
} }
// Alternative to access value, similar to std::map implementation // Alternative to access value, similar to std::map implementation
T second() { T second() {
return ArrayList<std::pair<key_t, T>, uint32_t>::Iterator::value->second; return ArrayList<std::pair<key_t, T>, uint32_t>::Iterator::value->second;
} }
}; };
Iterator begin() const { Iterator begin() const {
return Iterator(&theMap[0]); return Iterator(&theMap[0]);
} }
Iterator end() const { Iterator end() const {
return Iterator(&theMap[_size]); return Iterator(&theMap[_size]);
} }
uint32_t size() const { uint32_t size() const {
return _size; return _size;
} }
ReturnValue_t insert(key_t key, T value, Iterator *storedValue = NULL) { ReturnValue_t insert(key_t key, T value, Iterator *storedValue = NULL) {
if (exists(key) == HasReturnvaluesIF::RETURN_OK) { if (exists(key) == HasReturnvaluesIF::RETURN_OK) {
return FixedMap::KEY_ALREADY_EXISTS; return FixedMap::KEY_ALREADY_EXISTS;
} }
if (_size == theMap.maxSize()) { if (_size == theMap.maxSize()) {
return FixedMap::MAP_FULL; return FixedMap::MAP_FULL;
} }
theMap[_size].first = key; theMap[_size].first = key;
theMap[_size].second = value; theMap[_size].second = value;
if (storedValue != NULL) { if (storedValue != NULL) {
*storedValue = Iterator(&theMap[_size]); *storedValue = Iterator(&theMap[_size]);
} }
++_size; ++_size;
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
ReturnValue_t insert(std::pair<key_t, T> pair) { ReturnValue_t insert(std::pair<key_t, T> pair) {
return insert(pair.first, pair.second); return insert(pair.first, pair.second);
} }
ReturnValue_t exists(key_t key) const { ReturnValue_t exists(key_t key) const {
ReturnValue_t result = KEY_DOES_NOT_EXIST; ReturnValue_t result = KEY_DOES_NOT_EXIST;
if (findIndex(key) < _size) { if (findIndex(key) < _size) {
result = HasReturnvaluesIF::RETURN_OK; result = HasReturnvaluesIF::RETURN_OK;
} }
return result; return result;
} }
ReturnValue_t erase(Iterator *iter) { ReturnValue_t erase(Iterator *iter) {
uint32_t i; uint32_t i;
if ((i = findIndex((*iter).value->first)) >= _size) { if ((i = findIndex((*iter).value->first)) >= _size) {
return KEY_DOES_NOT_EXIST; return KEY_DOES_NOT_EXIST;
} }
theMap[i] = theMap[_size - 1]; theMap[i] = theMap[_size - 1];
--_size; --_size;
--((*iter).value); --((*iter).value);
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
ReturnValue_t erase(key_t key) { ReturnValue_t erase(key_t key) {
uint32_t i; uint32_t i;
if ((i = findIndex(key)) >= _size) { if ((i = findIndex(key)) >= _size) {
return KEY_DOES_NOT_EXIST; return KEY_DOES_NOT_EXIST;
} }
theMap[i] = theMap[_size - 1]; theMap[i] = theMap[_size - 1];
--_size; --_size;
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
T *findValue(key_t key) const { T *findValue(key_t key) const {
return &theMap[findIndex(key)].second; return &theMap[findIndex(key)].second;
} }
Iterator find(key_t key) const { Iterator find(key_t key) const {
ReturnValue_t result = exists(key); ReturnValue_t result = exists(key);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return end(); return end();
} }
return Iterator(&theMap[findIndex(key)]); return Iterator(&theMap[findIndex(key)]);
} }
ReturnValue_t find(key_t key, T **value) const { ReturnValue_t find(key_t key, T **value) const {
ReturnValue_t result = exists(key); ReturnValue_t result = exists(key);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
*value = &theMap[findIndex(key)].second; *value = &theMap[findIndex(key)].second;
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
void clear() { void clear() {
_size = 0; _size = 0;
} }
uint32_t maxSize() const { uint32_t maxSize() const {
return theMap.maxSize(); return theMap.maxSize();
} }
bool full() { bool full() {
if(_size == theMap.maxSize()) { if(_size == theMap.maxSize()) {
return true; return true;
} }
else { else {
return false; return false;
} }
} }
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
size_t maxSize, Endianness streamEndianness) const { size_t maxSize, Endianness streamEndianness) const {
ReturnValue_t result = SerializeAdapter::serialize(&this->_size, ReturnValue_t result = SerializeAdapter::serialize(&this->_size,
buffer, size, maxSize, streamEndianness); buffer, size, maxSize, streamEndianness);
uint32_t i = 0; uint32_t i = 0;
while ((result == HasReturnvaluesIF::RETURN_OK) && (i < this->_size)) { while ((result == HasReturnvaluesIF::RETURN_OK) && (i < this->_size)) {
result = SerializeAdapter::serialize(&theMap[i].first, buffer, result = SerializeAdapter::serialize(&theMap[i].first, buffer,
size, maxSize, streamEndianness); size, maxSize, streamEndianness);
result = SerializeAdapter::serialize(&theMap[i].second, buffer, size, result = SerializeAdapter::serialize(&theMap[i].second, buffer, size,
maxSize, streamEndianness); maxSize, streamEndianness);
++i; ++i;
} }
return result; return result;
} }
virtual size_t getSerializedSize() const { virtual size_t getSerializedSize() const {
uint32_t printSize = sizeof(_size); uint32_t printSize = sizeof(_size);
uint32_t i = 0; uint32_t i = 0;
for (i = 0; i < _size; ++i) { for (i = 0; i < _size; ++i) {
printSize += SerializeAdapter::getSerializedSize( printSize += SerializeAdapter::getSerializedSize(
&theMap[i].first); &theMap[i].first);
printSize += SerializeAdapter::getSerializedSize(&theMap[i].second); printSize += SerializeAdapter::getSerializedSize(&theMap[i].second);
} }
return printSize; return printSize;
} }
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
Endianness streamEndianness) { Endianness streamEndianness) {
ReturnValue_t result = SerializeAdapter::deSerialize(&this->_size, ReturnValue_t result = SerializeAdapter::deSerialize(&this->_size,
buffer, size, streamEndianness); buffer, size, streamEndianness);
if (this->_size > theMap.maxSize()) { if (this->_size > theMap.maxSize()) {
return SerializeIF::TOO_MANY_ELEMENTS; return SerializeIF::TOO_MANY_ELEMENTS;
} }
uint32_t i = 0; uint32_t i = 0;
while ((result == HasReturnvaluesIF::RETURN_OK) && (i < this->_size)) { while ((result == HasReturnvaluesIF::RETURN_OK) && (i < this->_size)) {
result = SerializeAdapter::deSerialize(&theMap[i].first, buffer, result = SerializeAdapter::deSerialize(&theMap[i].first, buffer,
size, streamEndianness); size, streamEndianness);
result = SerializeAdapter::deSerialize(&theMap[i].second, buffer, size, result = SerializeAdapter::deSerialize(&theMap[i].second, buffer, size,
streamEndianness); streamEndianness);
++i; ++i;
} }
return result; return result;
} }
}; };
#endif /* FIXEDMAP_H_ */ #endif /* FIXEDMAP_H_ */

View File

@ -1,7 +1,7 @@
#ifndef FRAMEWORK_CONTAINER_FIXEDORDEREDMULTIMAP_H_ #ifndef FRAMEWORK_CONTAINER_FIXEDORDEREDMULTIMAP_H_
#define FRAMEWORK_CONTAINER_FIXEDORDEREDMULTIMAP_H_ #define FRAMEWORK_CONTAINER_FIXEDORDEREDMULTIMAP_H_
#include <framework/container/ArrayList.h> #include "../container/ArrayList.h"
#include <cstring> #include <cstring>
#include <set> #include <set>
@ -166,6 +166,6 @@ private:
} }
}; };
#include <framework/container/FixedOrderedMultimap.tpp> #include "FixedOrderedMultimap.tpp"
#endif /* FRAMEWORK_CONTAINER_FIXEDORDEREDMULTIMAP_H_ */ #endif /* FRAMEWORK_CONTAINER_FIXEDORDEREDMULTIMAP_H_ */

View File

@ -1,90 +1,90 @@
#ifndef FRAMEWORK_CONTAINER_HYBRIDITERATOR_H_ #ifndef FRAMEWORK_CONTAINER_HYBRIDITERATOR_H_
#define FRAMEWORK_CONTAINER_HYBRIDITERATOR_H_ #define FRAMEWORK_CONTAINER_HYBRIDITERATOR_H_
#include <framework/container/ArrayList.h> #include "../container/ArrayList.h"
#include <framework/container/SinglyLinkedList.h> #include "../container/SinglyLinkedList.h"
template<typename T, typename count_t = uint8_t> template<typename T, typename count_t = uint8_t>
class HybridIterator: public LinkedElement<T>::Iterator, class HybridIterator: public LinkedElement<T>::Iterator,
public ArrayList<T, count_t>::Iterator { public ArrayList<T, count_t>::Iterator {
public: public:
HybridIterator() {} HybridIterator() {}
HybridIterator(typename LinkedElement<T>::Iterator *iter) : HybridIterator(typename LinkedElement<T>::Iterator *iter) :
LinkedElement<T>::Iterator(*iter), value(iter->value), LinkedElement<T>::Iterator(*iter), value(iter->value),
linked(true) { linked(true) {
} }
HybridIterator(LinkedElement<T> *start) : HybridIterator(LinkedElement<T> *start) :
LinkedElement<T>::Iterator(start), value(start->value), LinkedElement<T>::Iterator(start), value(start->value),
linked(true) { linked(true) {
} }
HybridIterator(typename ArrayList<T, count_t>::Iterator start, HybridIterator(typename ArrayList<T, count_t>::Iterator start,
typename ArrayList<T, count_t>::Iterator end) : typename ArrayList<T, count_t>::Iterator end) :
ArrayList<T, count_t>::Iterator(start), value(start.value), ArrayList<T, count_t>::Iterator(start), value(start.value),
linked(false), end(end.value) { linked(false), end(end.value) {
if (value == this->end) { if (value == this->end) {
value = NULL; value = NULL;
} }
} }
HybridIterator(T *firstElement, T *lastElement) : HybridIterator(T *firstElement, T *lastElement) :
ArrayList<T, count_t>::Iterator(firstElement), value(firstElement), ArrayList<T, count_t>::Iterator(firstElement), value(firstElement),
linked(false), end(++lastElement) { linked(false), end(++lastElement) {
if (value == end) { if (value == end) {
value = NULL; value = NULL;
} }
} }
HybridIterator& operator++() { HybridIterator& operator++() {
if (linked) { if (linked) {
LinkedElement<T>::Iterator::operator++(); LinkedElement<T>::Iterator::operator++();
if (LinkedElement<T>::Iterator::value != nullptr) { if (LinkedElement<T>::Iterator::value != nullptr) {
value = LinkedElement<T>::Iterator::value->value; value = LinkedElement<T>::Iterator::value->value;
} else { } else {
value = nullptr; value = nullptr;
} }
} else { } else {
ArrayList<T, count_t>::Iterator::operator++(); ArrayList<T, count_t>::Iterator::operator++();
value = ArrayList<T, count_t>::Iterator::value; value = ArrayList<T, count_t>::Iterator::value;
if (value == end) { if (value == end) {
value = nullptr; value = nullptr;
} }
} }
return *this; return *this;
} }
HybridIterator operator++(int) { HybridIterator operator++(int) {
HybridIterator tmp(*this); HybridIterator tmp(*this);
operator++(); operator++();
return tmp; return tmp;
} }
bool operator==(const HybridIterator& other) const { bool operator==(const HybridIterator& other) const {
return value == other.value; return value == other.value;
} }
bool operator!=(const HybridIterator& other) const { bool operator!=(const HybridIterator& other) const {
return !(*this == other); return !(*this == other);
} }
T operator*() { T operator*() {
return *value; return *value;
} }
T *operator->() { T *operator->() {
return value; return value;
} }
T* value = nullptr; T* value = nullptr;
private: private:
bool linked = false; bool linked = false;
T *end = nullptr; T *end = nullptr;
}; };
#endif /* FRAMEWORK_CONTAINER_HYBRIDITERATOR_H_ */ #endif /* FRAMEWORK_CONTAINER_HYBRIDITERATOR_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -1,35 +1,35 @@
#ifndef FRAMEWORK_CONTAINER_PLACEMENTFACTORY_H_ #ifndef FRAMEWORK_CONTAINER_PLACEMENTFACTORY_H_
#define FRAMEWORK_CONTAINER_PLACEMENTFACTORY_H_ #define FRAMEWORK_CONTAINER_PLACEMENTFACTORY_H_
#include <framework/storagemanager/StorageManagerIF.h> #include "../storagemanager/StorageManagerIF.h"
#include <utility> #include <utility>
class PlacementFactory { class PlacementFactory {
public: public:
PlacementFactory(StorageManagerIF* backend) : PlacementFactory(StorageManagerIF* backend) :
dataBackend(backend) { dataBackend(backend) {
} }
template<typename T, typename ... Args> template<typename T, typename ... Args>
T* generate(Args&&... args) { T* generate(Args&&... args) {
store_address_t tempId; store_address_t tempId;
uint8_t* pData = NULL; uint8_t* pData = NULL;
ReturnValue_t result = dataBackend->getFreeElement(&tempId, sizeof(T), ReturnValue_t result = dataBackend->getFreeElement(&tempId, sizeof(T),
&pData); &pData);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return NULL; return NULL;
} }
T* temp = new (pData) T(std::forward<Args>(args)...); T* temp = new (pData) T(std::forward<Args>(args)...);
return temp; return temp;
} }
template<typename T> template<typename T>
ReturnValue_t destroy(T* thisElement) { ReturnValue_t destroy(T* thisElement) {
//Need to call destructor first, in case something was allocated by the object (shouldn't do that, however). //Need to call destructor first, in case something was allocated by the object (shouldn't do that, however).
thisElement->~T(); thisElement->~T();
uint8_t* pointer = (uint8_t*) (thisElement); uint8_t* pointer = (uint8_t*) (thisElement);
return dataBackend->deleteData(pointer, sizeof(T)); return dataBackend->deleteData(pointer, sizeof(T));
} }
private: private:
StorageManagerIF* dataBackend; StorageManagerIF* dataBackend;
}; };
#endif /* FRAMEWORK_CONTAINER_PLACEMENTFACTORY_H_ */ #endif /* FRAMEWORK_CONTAINER_PLACEMENTFACTORY_H_ */

View File

@ -1,113 +1,113 @@
#ifndef FRAMEWORK_CONTAINER_RINGBUFFERBASE_H_ #ifndef FRAMEWORK_CONTAINER_RINGBUFFERBASE_H_
#define FRAMEWORK_CONTAINER_RINGBUFFERBASE_H_ #define FRAMEWORK_CONTAINER_RINGBUFFERBASE_H_
#include <framework/returnvalues/HasReturnvaluesIF.h> #include "../returnvalues/HasReturnvaluesIF.h"
#include <cstddef> #include <cstddef>
template<uint8_t N_READ_PTRS = 1> template<uint8_t N_READ_PTRS = 1>
class RingBufferBase { class RingBufferBase {
public: public:
RingBufferBase(size_t startAddress, const size_t size, bool overwriteOld) : RingBufferBase(size_t startAddress, const size_t size, bool overwriteOld) :
start(startAddress), write(startAddress), size(size), start(startAddress), write(startAddress), size(size),
overwriteOld(overwriteOld) { overwriteOld(overwriteOld) {
for (uint8_t count = 0; count < N_READ_PTRS; count++) { for (uint8_t count = 0; count < N_READ_PTRS; count++) {
read[count] = startAddress; read[count] = startAddress;
} }
} }
virtual ~RingBufferBase() {} virtual ~RingBufferBase() {}
bool isFull(uint8_t n = 0) { bool isFull(uint8_t n = 0) {
return (availableWriteSpace(n) == 0); return (availableWriteSpace(n) == 0);
} }
bool isEmpty(uint8_t n = 0) { bool isEmpty(uint8_t n = 0) {
return (availableReadData(n) == 0); return (getAvailableReadData(n) == 0);
} }
size_t availableReadData(uint8_t n = 0) const { size_t getAvailableReadData(uint8_t n = 0) const {
return ((write + size) - read[n]) % size; return ((write + size) - read[n]) % size;
} }
size_t availableWriteSpace(uint8_t n = 0) const { size_t availableWriteSpace(uint8_t n = 0) const {
//One less to avoid ambiguous full/empty problem. //One less to avoid ambiguous full/empty problem.
return (((read[n] + size) - write - 1) % size); return (((read[n] + size) - write - 1) % size);
} }
bool overwritesOld() const { bool overwritesOld() const {
return overwriteOld; return overwriteOld;
} }
size_t maxSize() const { size_t getMaxSize() const {
return size - 1; return size - 1;
} }
void clear() { void clear() {
write = start; write = start;
for (uint8_t count = 0; count < N_READ_PTRS; count++) { for (uint8_t count = 0; count < N_READ_PTRS; count++) {
read[count] = start; read[count] = start;
} }
} }
size_t writeTillWrap() { size_t writeTillWrap() {
return (start + size) - write; return (start + size) - write;
} }
size_t readTillWrap(uint8_t n = 0) { size_t readTillWrap(uint8_t n = 0) {
return (start + size) - read[n]; return (start + size) - read[n];
} }
size_t getStart() const { size_t getStart() const {
return start; return start;
} }
protected: protected:
const size_t start; const size_t start;
size_t write; size_t write;
size_t read[N_READ_PTRS]; size_t read[N_READ_PTRS];
const size_t size; const size_t size;
const bool overwriteOld; const bool overwriteOld;
void incrementWrite(uint32_t amount) { void incrementWrite(uint32_t amount) {
write = ((write + amount - start) % size) + start; write = ((write + amount - start) % size) + start;
} }
void incrementRead(uint32_t amount, uint8_t n = 0) { void incrementRead(uint32_t amount, uint8_t n = 0) {
read[n] = ((read[n] + amount - start) % size) + start; read[n] = ((read[n] + amount - start) % size) + start;
} }
ReturnValue_t readData(uint32_t amount, uint8_t n = 0) { ReturnValue_t readData(uint32_t amount, uint8_t n = 0) {
if (availableReadData(n) >= amount) { if (getAvailableReadData(n) >= amount) {
incrementRead(amount, n); incrementRead(amount, n);
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} else { } else {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
} }
ReturnValue_t writeData(uint32_t amount) { ReturnValue_t writeData(uint32_t amount) {
if (availableWriteSpace() >= amount or overwriteOld) { if (availableWriteSpace() >= amount or overwriteOld) {
incrementWrite(amount); incrementWrite(amount);
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} else { } else {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
} }
size_t getRead(uint8_t n = 0) const { size_t getRead(uint8_t n = 0) const {
return read[n]; return read[n];
} }
void setRead(uint32_t read, uint8_t n = 0) { void setRead(uint32_t read, uint8_t n = 0) {
if (read >= start && read < (start+size)) { if (read >= start && read < (start+size)) {
this->read[n] = read; this->read[n] = read;
} }
} }
uint32_t getWrite() const { uint32_t getWrite() const {
return write; return write;
} }
void setWrite(uint32_t write) { void setWrite(uint32_t write) {
this->write = write; this->write = write;
} }
}; };
#endif /* FRAMEWORK_CONTAINER_RINGBUFFERBASE_H_ */ #endif /* FRAMEWORK_CONTAINER_RINGBUFFERBASE_H_ */

View File

@ -1,30 +1,30 @@
#include <framework/container/SharedRingBuffer.h> #include "../container/SharedRingBuffer.h"
#include <framework/ipc/MutexFactory.h> #include "../ipc/MutexFactory.h"
#include <framework/ipc/MutexHelper.h> #include "../ipc/MutexHelper.h"
SharedRingBuffer::SharedRingBuffer(object_id_t objectId, const size_t size, SharedRingBuffer::SharedRingBuffer(object_id_t objectId, const size_t size,
bool overwriteOld, size_t maxExcessBytes): bool overwriteOld, size_t maxExcessBytes):
SystemObject(objectId), SimpleRingBuffer(size, overwriteOld, SystemObject(objectId), SimpleRingBuffer(size, overwriteOld,
maxExcessBytes) { maxExcessBytes) {
mutex = MutexFactory::instance()->createMutex(); mutex = MutexFactory::instance()->createMutex();
} }
SharedRingBuffer::SharedRingBuffer(object_id_t objectId, uint8_t *buffer, SharedRingBuffer::SharedRingBuffer(object_id_t objectId, uint8_t *buffer,
const size_t size, bool overwriteOld, size_t maxExcessBytes): const size_t size, bool overwriteOld, size_t maxExcessBytes):
SystemObject(objectId), SimpleRingBuffer(buffer, size, overwriteOld, SystemObject(objectId), SimpleRingBuffer(buffer, size, overwriteOld,
maxExcessBytes) { maxExcessBytes) {
mutex = MutexFactory::instance()->createMutex(); mutex = MutexFactory::instance()->createMutex();
} }
ReturnValue_t SharedRingBuffer::lockRingBufferMutex( ReturnValue_t SharedRingBuffer::lockRingBufferMutex(
MutexIF::TimeoutType timeoutType, dur_millis_t timeout) { MutexIF::TimeoutType timeoutType, dur_millis_t timeout) {
return mutex->lockMutex(timeoutType, timeout); return mutex->lockMutex(timeoutType, timeout);
} }
ReturnValue_t SharedRingBuffer::unlockRingBufferMutex() { ReturnValue_t SharedRingBuffer::unlockRingBufferMutex() {
return mutex->unlockMutex(); return mutex->unlockMutex();
} }
MutexIF* SharedRingBuffer::getMutexHandle() const { MutexIF* SharedRingBuffer::getMutexHandle() const {
return mutex; return mutex;
} }

View File

@ -1,68 +1,68 @@
#ifndef FRAMEWORK_CONTAINER_SHAREDRINGBUFFER_H_ #ifndef FRAMEWORK_CONTAINER_SHAREDRINGBUFFER_H_
#define FRAMEWORK_CONTAINER_SHAREDRINGBUFFER_H_ #define FRAMEWORK_CONTAINER_SHAREDRINGBUFFER_H_
#include <framework/container/SimpleRingBuffer.h> #include "../container/SimpleRingBuffer.h"
#include <framework/ipc/MutexIF.h> #include "../ipc/MutexIF.h"
#include <framework/objectmanager/SystemObject.h> #include "../objectmanager/SystemObject.h"
#include <framework/timemanager/Clock.h> #include "../timemanager/Clock.h"
/** /**
* @brief Ring buffer which can be shared among multiple objects * @brief Ring buffer which can be shared among multiple objects
* @details * @details
* This class offers a mutex to perform thread-safe operation on the ring * This class offers a mutex to perform thread-safe operation on the ring
* buffer. It is still up to the developer to actually perform the lock * buffer. It is still up to the developer to actually perform the lock
* and unlock operations. * and unlock operations.
*/ */
class SharedRingBuffer: public SystemObject, class SharedRingBuffer: public SystemObject,
public SimpleRingBuffer { public SimpleRingBuffer {
public: public:
/** /**
* This constructor allocates a new internal buffer with the supplied size. * This constructor allocates a new internal buffer with the supplied size.
* @param size * @param size
* @param overwriteOld * @param overwriteOld
* If the ring buffer is overflowing at a write operartion, the oldest data * If the ring buffer is overflowing at a write operartion, the oldest data
* will be overwritten. * will be overwritten.
*/ */
SharedRingBuffer(object_id_t objectId, const size_t size, SharedRingBuffer(object_id_t objectId, const size_t size,
bool overwriteOld, size_t maxExcessBytes); bool overwriteOld, size_t maxExcessBytes);
/** /**
* This constructor takes an external buffer with the specified size. * This constructor takes an external buffer with the specified size.
* @param buffer * @param buffer
* @param size * @param size
* @param overwriteOld * @param overwriteOld
* If the ring buffer is overflowing at a write operartion, the oldest data * If the ring buffer is overflowing at a write operartion, the oldest data
* will be overwritten. * will be overwritten.
*/ */
SharedRingBuffer(object_id_t objectId, uint8_t* buffer, const size_t size, SharedRingBuffer(object_id_t objectId, uint8_t* buffer, const size_t size,
bool overwriteOld, size_t maxExcessBytes); bool overwriteOld, size_t maxExcessBytes);
/** /**
* Unless a read-only constant value is read, all operations on the * Unless a read-only constant value is read, all operations on the
* shared ring buffer should be protected by calling this function. * shared ring buffer should be protected by calling this function.
* @param timeoutType * @param timeoutType
* @param timeout * @param timeout
* @return * @return
*/ */
virtual ReturnValue_t lockRingBufferMutex(MutexIF::TimeoutType timeoutType, virtual ReturnValue_t lockRingBufferMutex(MutexIF::TimeoutType timeoutType,
dur_millis_t timeout); dur_millis_t timeout);
/** /**
* Any locked mutex also has to be unlocked, otherwise, access to the * Any locked mutex also has to be unlocked, otherwise, access to the
* shared ring buffer will be blocked. * shared ring buffer will be blocked.
* @return * @return
*/ */
virtual ReturnValue_t unlockRingBufferMutex(); virtual ReturnValue_t unlockRingBufferMutex();
/** /**
* The mutex handle can be accessed directly, for example to perform * The mutex handle can be accessed directly, for example to perform
* the lock with the #MutexHelper for a RAII compliant lock operation. * the lock with the #MutexHelper for a RAII compliant lock operation.
* @return * @return
*/ */
MutexIF* getMutexHandle() const; MutexIF* getMutexHandle() const;
private: private:
MutexIF* mutex = nullptr; MutexIF* mutex = nullptr;
}; };
#endif /* FRAMEWORK_CONTAINER_SHAREDRINGBUFFER_H_ */ #endif /* FRAMEWORK_CONTAINER_SHAREDRINGBUFFER_H_ */

View File

@ -1,127 +1,135 @@
#include <framework/container/SimpleRingBuffer.h> #include "../container/SimpleRingBuffer.h"
#include <cstring> #include <cstring>
SimpleRingBuffer::SimpleRingBuffer(const size_t size, bool overwriteOld, SimpleRingBuffer::SimpleRingBuffer(const size_t size, bool overwriteOld,
size_t maxExcessBytes) : size_t maxExcessBytes) :
RingBufferBase<>(0, size, overwriteOld), RingBufferBase<>(0, size, overwriteOld),
maxExcessBytes(maxExcessBytes) { maxExcessBytes(maxExcessBytes) {
if(maxExcessBytes > size) { if(maxExcessBytes > size) {
this->maxExcessBytes = size; this->maxExcessBytes = size;
} }
else { else {
this->maxExcessBytes = maxExcessBytes; this->maxExcessBytes = maxExcessBytes;
} }
buffer = new uint8_t[size + maxExcessBytes]; buffer = new uint8_t[size + maxExcessBytes];
} }
SimpleRingBuffer::SimpleRingBuffer(uint8_t *buffer, const size_t size, SimpleRingBuffer::SimpleRingBuffer(uint8_t *buffer, const size_t size,
bool overwriteOld, size_t maxExcessBytes): bool overwriteOld, size_t maxExcessBytes):
RingBufferBase<>(0, size, overwriteOld), buffer(buffer) { RingBufferBase<>(0, size, overwriteOld), buffer(buffer) {
if(maxExcessBytes > size) { if(maxExcessBytes > size) {
this->maxExcessBytes = size; this->maxExcessBytes = size;
} }
else { else {
this->maxExcessBytes = maxExcessBytes; this->maxExcessBytes = maxExcessBytes;
} }
} }
SimpleRingBuffer::~SimpleRingBuffer() { SimpleRingBuffer::~SimpleRingBuffer() {
delete[] buffer; delete[] buffer;
} }
ReturnValue_t SimpleRingBuffer::getFreeElement(uint8_t **writePointer, ReturnValue_t SimpleRingBuffer::getFreeElement(uint8_t **writePointer,
size_t amount) { size_t amount) {
if (availableWriteSpace() >= amount or overwriteOld) { if (availableWriteSpace() >= amount or overwriteOld) {
size_t amountTillWrap = writeTillWrap(); size_t amountTillWrap = writeTillWrap();
if (amountTillWrap < amount) { if (amountTillWrap < amount) {
if((amount - amountTillWrap + excessBytes) > maxExcessBytes) { if((amount - amountTillWrap + excessBytes) > maxExcessBytes) {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
excessBytes = amount - amountTillWrap; excessBytes = amount - amountTillWrap;
} }
*writePointer = &buffer[write]; *writePointer = &buffer[write];
incrementWrite(amount); return HasReturnvaluesIF::RETURN_OK;
return HasReturnvaluesIF::RETURN_OK; }
} else {
else { return HasReturnvaluesIF::RETURN_FAILED;
return HasReturnvaluesIF::RETURN_FAILED; }
} }
}
void SimpleRingBuffer::confirmBytesWritten(size_t amount) {
ReturnValue_t SimpleRingBuffer::writeData(const uint8_t* data, if(getExcessBytes() > 0) {
size_t amount) { moveExcessBytesToStart();
if (availableWriteSpace() >= amount or overwriteOld) { }
size_t amountTillWrap = writeTillWrap(); incrementWrite(amount);
if (amountTillWrap >= amount) {
// remaining size in buffer is sufficient to fit full amount. }
memcpy(&buffer[write], data, amount);
} ReturnValue_t SimpleRingBuffer::writeData(const uint8_t* data,
else { size_t amount) {
memcpy(&buffer[write], data, amountTillWrap); if (availableWriteSpace() >= amount or overwriteOld) {
memcpy(buffer, data + amountTillWrap, amount - amountTillWrap); size_t amountTillWrap = writeTillWrap();
} if (amountTillWrap >= amount) {
incrementWrite(amount); // remaining size in buffer is sufficient to fit full amount.
return HasReturnvaluesIF::RETURN_OK; memcpy(&buffer[write], data, amount);
} else { }
return HasReturnvaluesIF::RETURN_FAILED; else {
} memcpy(&buffer[write], data, amountTillWrap);
} memcpy(buffer, data + amountTillWrap, amount - amountTillWrap);
}
ReturnValue_t SimpleRingBuffer::readData(uint8_t* data, size_t amount, incrementWrite(amount);
bool incrementReadPtr, bool readRemaining, size_t* trueAmount) { return HasReturnvaluesIF::RETURN_OK;
size_t availableData = availableReadData(READ_PTR); } else {
size_t amountTillWrap = readTillWrap(READ_PTR); return HasReturnvaluesIF::RETURN_FAILED;
if (availableData < amount) { }
if (readRemaining) { }
// more data available than amount specified.
amount = availableData; ReturnValue_t SimpleRingBuffer::readData(uint8_t* data, size_t amount,
} else { bool incrementReadPtr, bool readRemaining, size_t* trueAmount) {
return HasReturnvaluesIF::RETURN_FAILED; size_t availableData = getAvailableReadData(READ_PTR);
} size_t amountTillWrap = readTillWrap(READ_PTR);
} if (availableData < amount) {
if (trueAmount != nullptr) { if (readRemaining) {
*trueAmount = amount; // more data available than amount specified.
} amount = availableData;
if (amountTillWrap >= amount) { } else {
memcpy(data, &buffer[read[READ_PTR]], amount); return HasReturnvaluesIF::RETURN_FAILED;
} else { }
memcpy(data, &buffer[read[READ_PTR]], amountTillWrap); }
memcpy(data + amountTillWrap, buffer, amount - amountTillWrap); if (trueAmount != nullptr) {
} *trueAmount = amount;
}
if(incrementReadPtr) { if (amountTillWrap >= amount) {
deleteData(amount, readRemaining); memcpy(data, &buffer[read[READ_PTR]], amount);
} } else {
return HasReturnvaluesIF::RETURN_OK; memcpy(data, &buffer[read[READ_PTR]], amountTillWrap);
} memcpy(data + amountTillWrap, buffer, amount - amountTillWrap);
}
size_t SimpleRingBuffer::getExcessBytes() const {
return excessBytes; if(incrementReadPtr) {
} deleteData(amount, readRemaining);
}
void SimpleRingBuffer::moveExcessBytesToStart() { return HasReturnvaluesIF::RETURN_OK;
if(excessBytes > 0) { }
std::memcpy(buffer, &buffer[size], excessBytes);
excessBytes = 0; size_t SimpleRingBuffer::getExcessBytes() const {
} return excessBytes;
} }
ReturnValue_t SimpleRingBuffer::deleteData(size_t amount, void SimpleRingBuffer::moveExcessBytesToStart() {
bool deleteRemaining, size_t* trueAmount) { if(excessBytes > 0) {
size_t availableData = availableReadData(READ_PTR); std::memcpy(buffer, &buffer[size], excessBytes);
if (availableData < amount) { excessBytes = 0;
if (deleteRemaining) { }
amount = availableData; }
} else {
return HasReturnvaluesIF::RETURN_FAILED; ReturnValue_t SimpleRingBuffer::deleteData(size_t amount,
} bool deleteRemaining, size_t* trueAmount) {
} size_t availableData = getAvailableReadData(READ_PTR);
if (trueAmount != nullptr) { if (availableData < amount) {
*trueAmount = amount; if (deleteRemaining) {
} amount = availableData;
incrementRead(amount, READ_PTR); } else {
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_FAILED;
} }
}
if (trueAmount != nullptr) {
*trueAmount = amount;
}
incrementRead(amount, READ_PTR);
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -1,119 +1,128 @@
#ifndef FRAMEWORK_CONTAINER_SIMPLERINGBUFFER_H_ #ifndef FRAMEWORK_CONTAINER_SIMPLERINGBUFFER_H_
#define FRAMEWORK_CONTAINER_SIMPLERINGBUFFER_H_ #define FRAMEWORK_CONTAINER_SIMPLERINGBUFFER_H_
#include <framework/container/RingBufferBase.h> #include "../container/RingBufferBase.h"
#include <cstddef> #include <cstddef>
/** /**
* @brief Circular buffer implementation, useful for buffering * @brief Circular buffer implementation, useful for buffering
* into data streams. * into data streams.
* @details * @details
* Note that the deleteData() has to be called to increment the read pointer. * Note that the deleteData() has to be called to increment the read pointer.
* This class allocated dynamically, so * This class allocated dynamically, so
* @ingroup containers * @ingroup containers
*/ */
class SimpleRingBuffer: public RingBufferBase<> { class SimpleRingBuffer: public RingBufferBase<> {
public: public:
/** /**
* This constructor allocates a new internal buffer with the supplied size. * This constructor allocates a new internal buffer with the supplied size.
* *
* @param size * @param size
* @param overwriteOld If the ring buffer is overflowing at a write * @param overwriteOld If the ring buffer is overflowing at a write
* operation, the oldest data will be overwritten. * operation, the oldest data will be overwritten.
* @param maxExcessBytes These additional bytes will be allocated in addtion * @param maxExcessBytes These additional bytes will be allocated in addtion
* to the specified size to accomodate contiguous write operations * to the specified size to accomodate contiguous write operations
* with getFreeElement. * with getFreeElement.
* *
*/ */
SimpleRingBuffer(const size_t size, bool overwriteOld, SimpleRingBuffer(const size_t size, bool overwriteOld,
size_t maxExcessBytes = 0); size_t maxExcessBytes = 0);
/** /**
* This constructor takes an external buffer with the specified size. * This constructor takes an external buffer with the specified size.
* @param buffer * @param buffer
* @param size * @param size
* @param overwriteOld * @param overwriteOld
* If the ring buffer is overflowing at a write operartion, the oldest data * If the ring buffer is overflowing at a write operartion, the oldest data
* will be overwritten. * will be overwritten.
* @param maxExcessBytes * @param maxExcessBytes
* If the buffer can accomodate additional bytes for contigous write * If the buffer can accomodate additional bytes for contigous write
* operations with getFreeElement, this is the maximum allowed additional * operations with getFreeElement, this is the maximum allowed additional
* size * size
*/ */
SimpleRingBuffer(uint8_t* buffer, const size_t size, bool overwriteOld, SimpleRingBuffer(uint8_t* buffer, const size_t size, bool overwriteOld,
size_t maxExcessBytes = 0); size_t maxExcessBytes = 0);
virtual ~SimpleRingBuffer(); virtual ~SimpleRingBuffer();
/** /**
* Write to circular buffer and increment write pointer by amount. * Write to circular buffer and increment write pointer by amount.
* @param data * @param data
* @param amount * @param amount
* @return -@c RETURN_OK if write operation was successfull * @return -@c RETURN_OK if write operation was successfull
* -@c RETURN_FAILED if * -@c RETURN_FAILED if
*/ */
ReturnValue_t writeData(const uint8_t* data, size_t amount); ReturnValue_t writeData(const uint8_t* data, size_t amount);
/** /**
* Returns a pointer to a free element. If the remaining buffer is * Returns a pointer to a free element. If the remaining buffer is
* not large enough, the data will be written past the actual size * not large enough, the data will be written past the actual size
* and the amount of excess bytes will be cached. * and the amount of excess bytes will be cached. This function
* @param writePointer Pointer to a pointer which can be used to write * does not increment the write pointer!
* contiguous blocks into the ring buffer * @param writePointer Pointer to a pointer which can be used to write
* @param amount * contiguous blocks into the ring buffer
* @return * @param amount
*/ * @return
ReturnValue_t getFreeElement(uint8_t** writePointer, size_t amount); */
ReturnValue_t getFreeElement(uint8_t** writePointer, size_t amount);
virtual size_t getExcessBytes() const;
/** /**
* Helper functions which moves any excess bytes to the start * This increments the write pointer and also copies the excess bytes
* of the ring buffer. * to the beginning. It should be called if the write operation
* @return * conducted after calling getFreeElement() was performed.
*/ * @return
virtual void moveExcessBytesToStart(); */
void confirmBytesWritten(size_t amount);
/**
* Read from circular buffer at read pointer. virtual size_t getExcessBytes() const;
* @param data /**
* @param amount * Helper functions which moves any excess bytes to the start
* @param incrementReadPtr * of the ring buffer.
* If this is set to true, the read pointer will be incremented. * @return
* If readRemaining is set to true, the read pointer will be incremented */
* accordingly. virtual void moveExcessBytesToStart();
* @param readRemaining
* If this is set to true, the data will be read even if the amount /**
* specified exceeds the read data available. * Read from circular buffer at read pointer.
* @param trueAmount [out] * @param data
* If readRemaining was set to true, the true amount read will be assigned * @param amount
* to the passed value. * @param incrementReadPtr
* @return * If this is set to true, the read pointer will be incremented.
* - @c RETURN_OK if data was read successfully * If readRemaining is set to true, the read pointer will be incremented
* - @c RETURN_FAILED if not enough data was available and readRemaining * accordingly.
* was set to false. * @param readRemaining
*/ * If this is set to true, the data will be read even if the amount
ReturnValue_t readData(uint8_t* data, size_t amount, * specified exceeds the read data available.
bool incrementReadPtr = false, bool readRemaining = false, * @param trueAmount [out]
size_t* trueAmount = nullptr); * If readRemaining was set to true, the true amount read will be assigned
* to the passed value.
/** * @return
* Delete data by incrementing read pointer. * - @c RETURN_OK if data was read successfully
* @param amount * - @c RETURN_FAILED if not enough data was available and readRemaining
* @param deleteRemaining * was set to false.
* If the amount specified is larger than the remaing size to read and this */
* is set to true, the remaining amount will be deleted as well ReturnValue_t readData(uint8_t* data, size_t amount,
* @param trueAmount [out] bool incrementReadPtr = false, bool readRemaining = false,
* If deleteRemaining was set to true, the amount deleted will be assigned size_t* trueAmount = nullptr);
* to the passed value.
* @return /**
*/ * Delete data by incrementing read pointer.
ReturnValue_t deleteData(size_t amount, bool deleteRemaining = false, * @param amount
size_t* trueAmount = nullptr); * @param deleteRemaining
private: * If the amount specified is larger than the remaing size to read and this
static const uint8_t READ_PTR = 0; * is set to true, the remaining amount will be deleted as well
uint8_t* buffer = nullptr; * @param trueAmount [out]
size_t maxExcessBytes; * If deleteRemaining was set to true, the amount deleted will be assigned
size_t excessBytes = 0; * to the passed value.
}; * @return
*/
#endif /* FRAMEWORK_CONTAINER_SIMPLERINGBUFFER_H_ */ ReturnValue_t deleteData(size_t amount, bool deleteRemaining = false,
size_t* trueAmount = nullptr);
private:
static const uint8_t READ_PTR = 0;
uint8_t* buffer = nullptr;
size_t maxExcessBytes;
size_t excessBytes = 0;
};
#endif /* FRAMEWORK_CONTAINER_SIMPLERINGBUFFER_H_ */

View File

@ -1,137 +1,137 @@
#include <framework/subsystem/SubsystemBase.h> #include "../subsystem/SubsystemBase.h"
#include <framework/controller/ControllerBase.h> #include "../controller/ControllerBase.h"
#include <framework/subsystem/SubsystemBase.h> #include "../subsystem/SubsystemBase.h"
#include <framework/ipc/QueueFactory.h> #include "../ipc/QueueFactory.h"
#include <framework/action/HasActionsIF.h> #include "../action/HasActionsIF.h"
ControllerBase::ControllerBase(uint32_t setObjectId, uint32_t parentId, ControllerBase::ControllerBase(uint32_t setObjectId, uint32_t parentId,
size_t commandQueueDepth) : size_t commandQueueDepth) :
SystemObject(setObjectId), parentId(parentId), mode(MODE_OFF), submode( SystemObject(setObjectId), parentId(parentId), mode(MODE_OFF), submode(
SUBMODE_NONE), commandQueue(NULL), modeHelper( SUBMODE_NONE), commandQueue(NULL), modeHelper(
this), healthHelper(this, setObjectId),hkSwitcher(this),executingTask(NULL) { this), healthHelper(this, setObjectId),hkSwitcher(this),executingTask(NULL) {
commandQueue = QueueFactory::instance()->createMessageQueue(commandQueueDepth); commandQueue = QueueFactory::instance()->createMessageQueue(commandQueueDepth);
} }
ControllerBase::~ControllerBase() { ControllerBase::~ControllerBase() {
QueueFactory::instance()->deleteMessageQueue(commandQueue); QueueFactory::instance()->deleteMessageQueue(commandQueue);
} }
ReturnValue_t ControllerBase::initialize() { ReturnValue_t ControllerBase::initialize() {
ReturnValue_t result = SystemObject::initialize(); ReturnValue_t result = SystemObject::initialize();
if (result != RETURN_OK) { if (result != RETURN_OK) {
return result; return result;
} }
MessageQueueId_t parentQueue = 0; MessageQueueId_t parentQueue = 0;
if (parentId != 0) { if (parentId != 0) {
SubsystemBase *parent = objectManager->get<SubsystemBase>(parentId); SubsystemBase *parent = objectManager->get<SubsystemBase>(parentId);
if (parent == NULL) { if (parent == NULL) {
return RETURN_FAILED; return RETURN_FAILED;
} }
parentQueue = parent->getCommandQueue(); parentQueue = parent->getCommandQueue();
parent->registerChild(getObjectId()); parent->registerChild(getObjectId());
} }
result = healthHelper.initialize(parentQueue); result = healthHelper.initialize(parentQueue);
if (result != RETURN_OK) { if (result != RETURN_OK) {
return result; return result;
} }
result = modeHelper.initialize(parentQueue); result = modeHelper.initialize(parentQueue);
if (result != RETURN_OK) { if (result != RETURN_OK) {
return result; return result;
} }
result = hkSwitcher.initialize(); result = hkSwitcher.initialize();
if (result != RETURN_OK) { if (result != RETURN_OK) {
return result; return result;
} }
return RETURN_OK; return RETURN_OK;
} }
MessageQueueId_t ControllerBase::getCommandQueue() const { MessageQueueId_t ControllerBase::getCommandQueue() const {
return commandQueue->getId(); return commandQueue->getId();
} }
void ControllerBase::handleQueue() { void ControllerBase::handleQueue() {
CommandMessage command; CommandMessage command;
ReturnValue_t result; ReturnValue_t result;
for (result = commandQueue->receiveMessage(&command); result == RETURN_OK; for (result = commandQueue->receiveMessage(&command); result == RETURN_OK;
result = commandQueue->receiveMessage(&command)) { result = commandQueue->receiveMessage(&command)) {
result = modeHelper.handleModeCommand(&command); result = modeHelper.handleModeCommand(&command);
if (result == RETURN_OK) { if (result == RETURN_OK) {
continue; continue;
} }
result = healthHelper.handleHealthCommand(&command); result = healthHelper.handleHealthCommand(&command);
if (result == RETURN_OK) { if (result == RETURN_OK) {
continue; continue;
} }
result = handleCommandMessage(&command); result = handleCommandMessage(&command);
if (result == RETURN_OK) { if (result == RETURN_OK) {
continue; continue;
} }
command.setToUnknownCommand(); command.setToUnknownCommand();
commandQueue->reply(&command); commandQueue->reply(&command);
} }
} }
void ControllerBase::startTransition(Mode_t mode, Submode_t submode) { void ControllerBase::startTransition(Mode_t mode, Submode_t submode) {
changeHK(this->mode, this->submode, false); changeHK(this->mode, this->submode, false);
triggerEvent(CHANGING_MODE, mode, submode); triggerEvent(CHANGING_MODE, mode, submode);
this->mode = mode; this->mode = mode;
this->submode = submode; this->submode = submode;
modeHelper.modeChanged(mode, submode); modeHelper.modeChanged(mode, submode);
modeChanged(mode, submode); modeChanged(mode, submode);
announceMode(false); announceMode(false);
changeHK(this->mode, this->submode, true); changeHK(this->mode, this->submode, true);
} }
void ControllerBase::getMode(Mode_t* mode, Submode_t* submode) { void ControllerBase::getMode(Mode_t* mode, Submode_t* submode) {
*mode = this->mode; *mode = this->mode;
*submode = this->submode; *submode = this->submode;
} }
void ControllerBase::setToExternalControl() { void ControllerBase::setToExternalControl() {
healthHelper.setHealth(EXTERNAL_CONTROL); healthHelper.setHealth(EXTERNAL_CONTROL);
} }
void ControllerBase::announceMode(bool recursive) { void ControllerBase::announceMode(bool recursive) {
triggerEvent(MODE_INFO, mode, submode); triggerEvent(MODE_INFO, mode, submode);
} }
ReturnValue_t ControllerBase::performOperation(uint8_t opCode) { ReturnValue_t ControllerBase::performOperation(uint8_t opCode) {
handleQueue(); handleQueue();
hkSwitcher.performOperation(); hkSwitcher.performOperation();
performControlOperation(); performControlOperation();
return RETURN_OK; return RETURN_OK;
} }
void ControllerBase::modeChanged(Mode_t mode, Submode_t submode) { void ControllerBase::modeChanged(Mode_t mode, Submode_t submode) {
return; return;
} }
ReturnValue_t ControllerBase::setHealth(HealthState health) { ReturnValue_t ControllerBase::setHealth(HealthState health) {
switch (health) { switch (health) {
case HEALTHY: case HEALTHY:
case EXTERNAL_CONTROL: case EXTERNAL_CONTROL:
healthHelper.setHealth(health); healthHelper.setHealth(health);
return RETURN_OK; return RETURN_OK;
default: default:
return INVALID_HEALTH_STATE; return INVALID_HEALTH_STATE;
} }
} }
HasHealthIF::HealthState ControllerBase::getHealth() { HasHealthIF::HealthState ControllerBase::getHealth() {
return healthHelper.getHealth(); return healthHelper.getHealth();
} }
void ControllerBase::setTaskIF(PeriodicTaskIF* task_){ void ControllerBase::setTaskIF(PeriodicTaskIF* task_){
executingTask = task_; executingTask = task_;
} }
void ControllerBase::changeHK(Mode_t mode, Submode_t submode, bool enable) { void ControllerBase::changeHK(Mode_t mode, Submode_t submode, bool enable) {
} }

View File

@ -1,79 +1,79 @@
#ifndef CONTROLLERBASE_H_ #ifndef CONTROLLERBASE_H_
#define CONTROLLERBASE_H_ #define CONTROLLERBASE_H_
#include <framework/health/HasHealthIF.h> #include "../health/HasHealthIF.h"
#include <framework/health/HealthHelper.h> #include "../health/HealthHelper.h"
#include <framework/modes/HasModesIF.h> #include "../modes/HasModesIF.h"
#include <framework/modes/ModeHelper.h> #include "../modes/ModeHelper.h"
#include <framework/objectmanager/SystemObject.h> #include "../objectmanager/SystemObject.h"
#include <framework/tasks/ExecutableObjectIF.h> #include "../tasks/ExecutableObjectIF.h"
#include <framework/datapool/HkSwitchHelper.h> #include "../datapool/HkSwitchHelper.h"
class ControllerBase: public HasModesIF, class ControllerBase: public HasModesIF,
public HasHealthIF, public HasHealthIF,
public ExecutableObjectIF, public ExecutableObjectIF,
public SystemObject, public SystemObject,
public HasReturnvaluesIF { public HasReturnvaluesIF {
public: public:
static const Mode_t MODE_NORMAL = 2; static const Mode_t MODE_NORMAL = 2;
ControllerBase(uint32_t setObjectId, uint32_t parentId, ControllerBase(uint32_t setObjectId, uint32_t parentId,
size_t commandQueueDepth = 3); size_t commandQueueDepth = 3);
virtual ~ControllerBase(); virtual ~ControllerBase();
ReturnValue_t initialize(); ReturnValue_t initialize();
virtual MessageQueueId_t getCommandQueue() const; virtual MessageQueueId_t getCommandQueue() const;
virtual ReturnValue_t performOperation(uint8_t opCode); virtual ReturnValue_t performOperation(uint8_t opCode);
virtual ReturnValue_t setHealth(HealthState health); virtual ReturnValue_t setHealth(HealthState health);
virtual HasHealthIF::HealthState getHealth(); virtual HasHealthIF::HealthState getHealth();
/** /**
* Implementation of ExecutableObjectIF function * Implementation of ExecutableObjectIF function
* *
* Used to setup the reference of the task, that executes this component * Used to setup the reference of the task, that executes this component
* @param task_ Pointer to the taskIF of this task * @param task_ Pointer to the taskIF of this task
*/ */
virtual void setTaskIF(PeriodicTaskIF* task_); virtual void setTaskIF(PeriodicTaskIF* task_);
protected: protected:
const uint32_t parentId; const uint32_t parentId;
Mode_t mode; Mode_t mode;
Submode_t submode; Submode_t submode;
MessageQueueIF* commandQueue; MessageQueueIF* commandQueue;
ModeHelper modeHelper; ModeHelper modeHelper;
HealthHelper healthHelper; HealthHelper healthHelper;
HkSwitchHelper hkSwitcher; HkSwitchHelper hkSwitcher;
/** /**
* Pointer to the task which executes this component, is invalid before setTaskIF was called. * Pointer to the task which executes this component, is invalid before setTaskIF was called.
*/ */
PeriodicTaskIF* executingTask; PeriodicTaskIF* executingTask;
void handleQueue(); void handleQueue();
virtual ReturnValue_t handleCommandMessage(CommandMessage *message) = 0; virtual ReturnValue_t handleCommandMessage(CommandMessage *message) = 0;
virtual void performControlOperation() = 0; virtual void performControlOperation() = 0;
virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t *msToReachTheMode) = 0; uint32_t *msToReachTheMode) = 0;
virtual void modeChanged(Mode_t mode, Submode_t submode); virtual void modeChanged(Mode_t mode, Submode_t submode);
virtual void startTransition(Mode_t mode, Submode_t submode); virtual void startTransition(Mode_t mode, Submode_t submode);
virtual void getMode(Mode_t *mode, Submode_t *submode); virtual void getMode(Mode_t *mode, Submode_t *submode);
virtual void setToExternalControl(); virtual void setToExternalControl();
virtual void announceMode(bool recursive); virtual void announceMode(bool recursive);
virtual void changeHK(Mode_t mode, Submode_t submode, bool enable); virtual void changeHK(Mode_t mode, Submode_t submode, bool enable);
}; };
#endif /* CONTROLLERBASE_H_ */ #endif /* CONTROLLERBASE_H_ */

View File

@ -1,227 +1,227 @@
#include <framework/coordinates/CoordinateTransformations.h> #include "../coordinates/CoordinateTransformations.h"
#include <framework/globalfunctions/constants.h> #include "../globalfunctions/constants.h"
#include <framework/globalfunctions/math/MatrixOperations.h> #include "../globalfunctions/math/MatrixOperations.h"
#include <framework/globalfunctions/math/VectorOperations.h> #include "../globalfunctions/math/VectorOperations.h"
#include <stddef.h> #include <stddef.h>
#include <cmath> #include <cmath>
void CoordinateTransformations::positionEcfToEci(const double* ecfPosition, void CoordinateTransformations::positionEcfToEci(const double* ecfPosition,
double* eciPosition, timeval *timeUTC) { double* eciPosition, timeval *timeUTC) {
ecfToEci(ecfPosition, eciPosition, NULL, timeUTC); ecfToEci(ecfPosition, eciPosition, NULL, timeUTC);
} }
void CoordinateTransformations::velocityEcfToEci(const double* ecfVelocity, void CoordinateTransformations::velocityEcfToEci(const double* ecfVelocity,
const double* ecfPosition, double* eciVelocity, timeval *timeUTC) { const double* ecfPosition, double* eciVelocity, timeval *timeUTC) {
ecfToEci(ecfVelocity, eciVelocity, ecfPosition, timeUTC); ecfToEci(ecfVelocity, eciVelocity, ecfPosition, timeUTC);
} }
void CoordinateTransformations::positionEciToEcf(const double* eciCoordinates, double* ecfCoordinates,timeval *timeUTC){ void CoordinateTransformations::positionEciToEcf(const double* eciCoordinates, double* ecfCoordinates,timeval *timeUTC){
eciToEcf(eciCoordinates,ecfCoordinates,NULL,timeUTC); eciToEcf(eciCoordinates,ecfCoordinates,NULL,timeUTC);
}; };
void CoordinateTransformations::velocityEciToEcf(const double* eciVelocity,const double* eciPosition, double* ecfVelocity,timeval* timeUTC){ void CoordinateTransformations::velocityEciToEcf(const double* eciVelocity,const double* eciPosition, double* ecfVelocity,timeval* timeUTC){
eciToEcf(eciVelocity,ecfVelocity,eciPosition,timeUTC); eciToEcf(eciVelocity,ecfVelocity,eciPosition,timeUTC);
} }
double CoordinateTransformations::getEarthRotationAngle(timeval timeUTC) { double CoordinateTransformations::getEarthRotationAngle(timeval timeUTC) {
double jD2000UTC; double jD2000UTC;
Clock::convertTimevalToJD2000(timeUTC, &jD2000UTC); Clock::convertTimevalToJD2000(timeUTC, &jD2000UTC);
double TTt2000 = getJuleanCenturiesTT(timeUTC); double TTt2000 = getJuleanCenturiesTT(timeUTC);
double theta = 2 * Math::PI double theta = 2 * Math::PI
* (0.779057273264 + 1.00273781191135448 * jD2000UTC); * (0.779057273264 + 1.00273781191135448 * jD2000UTC);
//Correct theta according to IAU 2000 precession-nutation model //Correct theta according to IAU 2000 precession-nutation model
theta = theta + 7.03270725817493E-008 + 0.0223603701 * TTt2000 theta = theta + 7.03270725817493E-008 + 0.0223603701 * TTt2000
+ 6.77128219501896E-006 * TTt2000 * TTt2000 + 6.77128219501896E-006 * TTt2000 * TTt2000
+ 4.5300990362875E-010 * TTt2000 * TTt2000 * TTt2000 + 4.5300990362875E-010 * TTt2000 * TTt2000 * TTt2000
+ 9.12419347848147E-011 * TTt2000 * TTt2000 * TTt2000 * TTt2000; + 9.12419347848147E-011 * TTt2000 * TTt2000 * TTt2000 * TTt2000;
return theta; return theta;
} }
void CoordinateTransformations::getEarthRotationMatrix(timeval timeUTC, void CoordinateTransformations::getEarthRotationMatrix(timeval timeUTC,
double matrix[][3]) { double matrix[][3]) {
double theta = getEarthRotationAngle(timeUTC); double theta = getEarthRotationAngle(timeUTC);
matrix[0][0] = cos(theta); matrix[0][0] = cos(theta);
matrix[0][1] = sin(theta); matrix[0][1] = sin(theta);
matrix[0][2] = 0; matrix[0][2] = 0;
matrix[1][0] = -sin(theta); matrix[1][0] = -sin(theta);
matrix[1][1] = cos(theta); matrix[1][1] = cos(theta);
matrix[1][2] = 0; matrix[1][2] = 0;
matrix[2][0] = 0; matrix[2][0] = 0;
matrix[2][1] = 0; matrix[2][1] = 0;
matrix[2][2] = 1; matrix[2][2] = 1;
} }
void CoordinateTransformations::ecfToEci(const double* ecfCoordinates, void CoordinateTransformations::ecfToEci(const double* ecfCoordinates,
double* eciCoordinates, double* eciCoordinates,
const double* ecfPositionIfCoordinatesAreVelocity, timeval *timeUTCin) { const double* ecfPositionIfCoordinatesAreVelocity, timeval *timeUTCin) {
timeval timeUTC; timeval timeUTC;
if (timeUTCin != NULL) { if (timeUTCin != NULL) {
timeUTC = *timeUTCin; timeUTC = *timeUTCin;
} else { } else {
Clock::getClock_timeval(&timeUTC); Clock::getClock_timeval(&timeUTC);
} }
double Tfi[3][3]; double Tfi[3][3];
double Tif[3][3]; double Tif[3][3];
getTransMatrixECITOECF(timeUTC,Tfi); getTransMatrixECITOECF(timeUTC,Tfi);
MatrixOperations<double>::transpose(Tfi[0], Tif[0], 3); MatrixOperations<double>::transpose(Tfi[0], Tif[0], 3);
MatrixOperations<double>::multiply(Tif[0], ecfCoordinates, eciCoordinates, MatrixOperations<double>::multiply(Tif[0], ecfCoordinates, eciCoordinates,
3, 3, 1); 3, 3, 1);
if (ecfPositionIfCoordinatesAreVelocity != NULL) { if (ecfPositionIfCoordinatesAreVelocity != NULL) {
double Tdotfi[3][3]; double Tdotfi[3][3];
double Tdotif[3][3]; double Tdotif[3][3];
double Trot[3][3] = { { 0, Earth::OMEGA, 0 }, double Trot[3][3] = { { 0, Earth::OMEGA, 0 },
{ 0 - Earth::OMEGA, 0, 0 }, { 0, 0, 0 } }; { 0 - Earth::OMEGA, 0, 0 }, { 0, 0, 0 } };
MatrixOperations<double>::multiply(Trot[0], Tfi[0], Tdotfi[0], 3, 3, MatrixOperations<double>::multiply(Trot[0], Tfi[0], Tdotfi[0], 3, 3,
3); 3);
MatrixOperations<double>::transpose(Tdotfi[0], Tdotif[0], 3); MatrixOperations<double>::transpose(Tdotfi[0], Tdotif[0], 3);
double velocityCorrection[3]; double velocityCorrection[3];
MatrixOperations<double>::multiply(Tdotif[0], MatrixOperations<double>::multiply(Tdotif[0],
ecfPositionIfCoordinatesAreVelocity, velocityCorrection, 3, 3, ecfPositionIfCoordinatesAreVelocity, velocityCorrection, 3, 3,
1); 1);
VectorOperations<double>::add(velocityCorrection, eciCoordinates, VectorOperations<double>::add(velocityCorrection, eciCoordinates,
eciCoordinates, 3); eciCoordinates, 3);
} }
} }
double CoordinateTransformations::getJuleanCenturiesTT(timeval timeUTC) { double CoordinateTransformations::getJuleanCenturiesTT(timeval timeUTC) {
timeval timeTT; timeval timeTT;
Clock::convertUTCToTT(timeUTC, &timeTT); Clock::convertUTCToTT(timeUTC, &timeTT);
double jD2000TT; double jD2000TT;
Clock::convertTimevalToJD2000(timeTT, &jD2000TT); Clock::convertTimevalToJD2000(timeTT, &jD2000TT);
return jD2000TT / 36525.; return jD2000TT / 36525.;
} }
void CoordinateTransformations::eciToEcf(const double* eciCoordinates, void CoordinateTransformations::eciToEcf(const double* eciCoordinates,
double* ecfCoordinates, double* ecfCoordinates,
const double* eciPositionIfCoordinatesAreVelocity,timeval *timeUTCin){ const double* eciPositionIfCoordinatesAreVelocity,timeval *timeUTCin){
timeval timeUTC; timeval timeUTC;
if (timeUTCin != NULL) { if (timeUTCin != NULL) {
timeUTC = *timeUTCin; timeUTC = *timeUTCin;
}else{ }else{
Clock::getClock_timeval(&timeUTC); Clock::getClock_timeval(&timeUTC);
} }
double Tfi[3][3]; double Tfi[3][3];
getTransMatrixECITOECF(timeUTC,Tfi); getTransMatrixECITOECF(timeUTC,Tfi);
MatrixOperations<double>::multiply(Tfi[0],eciCoordinates,ecfCoordinates,3,3,1); MatrixOperations<double>::multiply(Tfi[0],eciCoordinates,ecfCoordinates,3,3,1);
if (eciPositionIfCoordinatesAreVelocity != NULL) { if (eciPositionIfCoordinatesAreVelocity != NULL) {
double Tdotfi[3][3]; double Tdotfi[3][3];
double Trot[3][3] = { { 0, Earth::OMEGA, 0 }, double Trot[3][3] = { { 0, Earth::OMEGA, 0 },
{ 0 - Earth::OMEGA, 0, 0 }, { 0, 0, 0 } }; { 0 - Earth::OMEGA, 0, 0 }, { 0, 0, 0 } };
MatrixOperations<double>::multiply(Trot[0], Tfi[0], Tdotfi[0], 3, 3, MatrixOperations<double>::multiply(Trot[0], Tfi[0], Tdotfi[0], 3, 3,
3); 3);
double velocityCorrection[3]; double velocityCorrection[3];
MatrixOperations<double>::multiply(Tdotfi[0], MatrixOperations<double>::multiply(Tdotfi[0],
eciPositionIfCoordinatesAreVelocity, velocityCorrection, 3, 3, eciPositionIfCoordinatesAreVelocity, velocityCorrection, 3, 3,
1); 1);
VectorOperations<double>::add(ecfCoordinates, velocityCorrection, VectorOperations<double>::add(ecfCoordinates, velocityCorrection,
ecfCoordinates, 3); ecfCoordinates, 3);
} }
}; };
void CoordinateTransformations::getTransMatrixECITOECF(timeval timeUTC,double Tfi[3][3]){ void CoordinateTransformations::getTransMatrixECITOECF(timeval timeUTC,double Tfi[3][3]){
double TTt2000 = getJuleanCenturiesTT(timeUTC); double TTt2000 = getJuleanCenturiesTT(timeUTC);
////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////
// Calculate Precession Matrix // Calculate Precession Matrix
double zeta = 0.0111808609 * TTt2000 double zeta = 0.0111808609 * TTt2000
+ 1.46355554053347E-006 * TTt2000 * TTt2000 + 1.46355554053347E-006 * TTt2000 * TTt2000
+ 8.72567663260943E-008 * TTt2000 * TTt2000 * TTt2000; + 8.72567663260943E-008 * TTt2000 * TTt2000 * TTt2000;
double theta_p = 0.0097171735 * TTt2000 double theta_p = 0.0097171735 * TTt2000
- 2.06845757045384E-006 * TTt2000 * TTt2000 - 2.06845757045384E-006 * TTt2000 * TTt2000
- 2.02812107218552E-007 * TTt2000 * TTt2000 * TTt2000; - 2.02812107218552E-007 * TTt2000 * TTt2000 * TTt2000;
double z = zeta + 3.8436028638364E-006 * TTt2000 * TTt2000 double z = zeta + 3.8436028638364E-006 * TTt2000 * TTt2000
+ 0.000000001 * TTt2000 * TTt2000 * TTt2000; + 0.000000001 * TTt2000 * TTt2000 * TTt2000;
double mPrecession[3][3]; double mPrecession[3][3];
mPrecession[0][0] = -sin(z) * sin(zeta) + cos(z) * cos(theta_p) * cos(zeta); mPrecession[0][0] = -sin(z) * sin(zeta) + cos(z) * cos(theta_p) * cos(zeta);
mPrecession[1][0] = cos(z) * sin(zeta) + sin(z) * cos(theta_p) * cos(zeta); mPrecession[1][0] = cos(z) * sin(zeta) + sin(z) * cos(theta_p) * cos(zeta);
mPrecession[2][0] = sin(theta_p) * cos(zeta); mPrecession[2][0] = sin(theta_p) * cos(zeta);
mPrecession[0][1] = -sin(z) * cos(zeta) - cos(z) * cos(theta_p) * sin(zeta); mPrecession[0][1] = -sin(z) * cos(zeta) - cos(z) * cos(theta_p) * sin(zeta);
mPrecession[1][1] = cos(z) * cos(zeta) - sin(z) * cos(theta_p) * sin(zeta); mPrecession[1][1] = cos(z) * cos(zeta) - sin(z) * cos(theta_p) * sin(zeta);
mPrecession[2][1] = -sin(theta_p) * sin(zeta); mPrecession[2][1] = -sin(theta_p) * sin(zeta);
mPrecession[0][2] = -cos(z) * sin(theta_p); mPrecession[0][2] = -cos(z) * sin(theta_p);
mPrecession[1][2] = -sin(z) * sin(theta_p); mPrecession[1][2] = -sin(z) * sin(theta_p);
mPrecession[2][2] = cos(theta_p); mPrecession[2][2] = cos(theta_p);
////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////
// Calculate Nutation Matrix // Calculate Nutation Matrix
double omega_moon = 2.1824386244 - 33.7570459338 * TTt2000 double omega_moon = 2.1824386244 - 33.7570459338 * TTt2000
+ 3.61428599267159E-005 * TTt2000 * TTt2000 + 3.61428599267159E-005 * TTt2000 * TTt2000
+ 3.87850944887629E-008 * TTt2000 * TTt2000 * TTt2000; + 3.87850944887629E-008 * TTt2000 * TTt2000 * TTt2000;
double deltaPsi = -0.000083388 * sin(omega_moon); double deltaPsi = -0.000083388 * sin(omega_moon);
double deltaEpsilon = 4.46174030725106E-005 * cos(omega_moon); double deltaEpsilon = 4.46174030725106E-005 * cos(omega_moon);
double epsilon = 0.4090928042 - 0.0002269655 * TTt2000 double epsilon = 0.4090928042 - 0.0002269655 * TTt2000
- 2.86040071854626E-009 * TTt2000 * TTt2000 - 2.86040071854626E-009 * TTt2000 * TTt2000
+ 8.78967203851589E-009 * TTt2000 * TTt2000 * TTt2000; + 8.78967203851589E-009 * TTt2000 * TTt2000 * TTt2000;
double mNutation[3][3]; double mNutation[3][3];
mNutation[0][0] = cos(deltaPsi); mNutation[0][0] = cos(deltaPsi);
mNutation[1][0] = cos(epsilon + deltaEpsilon) * sin(deltaPsi); mNutation[1][0] = cos(epsilon + deltaEpsilon) * sin(deltaPsi);
mNutation[2][0] = sin(epsilon + deltaEpsilon) * sin(deltaPsi); mNutation[2][0] = sin(epsilon + deltaEpsilon) * sin(deltaPsi);
mNutation[0][1] = -cos(epsilon) * sin(deltaPsi); mNutation[0][1] = -cos(epsilon) * sin(deltaPsi);
mNutation[1][1] = cos(epsilon) * cos(epsilon + deltaEpsilon) * cos(deltaPsi) mNutation[1][1] = cos(epsilon) * cos(epsilon + deltaEpsilon) * cos(deltaPsi)
+ sin(epsilon) * sin(epsilon + deltaEpsilon); + sin(epsilon) * sin(epsilon + deltaEpsilon);
mNutation[2][1] = cos(epsilon) * sin(epsilon + deltaEpsilon) * cos(deltaPsi) mNutation[2][1] = cos(epsilon) * sin(epsilon + deltaEpsilon) * cos(deltaPsi)
- sin(epsilon) * cos(epsilon + deltaEpsilon); - sin(epsilon) * cos(epsilon + deltaEpsilon);
mNutation[0][2] = -sin(epsilon) * sin(deltaPsi); mNutation[0][2] = -sin(epsilon) * sin(deltaPsi);
mNutation[1][2] = sin(epsilon) * cos(epsilon + deltaEpsilon) * cos(deltaPsi) mNutation[1][2] = sin(epsilon) * cos(epsilon + deltaEpsilon) * cos(deltaPsi)
- cos(epsilon) * sin(epsilon + deltaEpsilon); - cos(epsilon) * sin(epsilon + deltaEpsilon);
mNutation[2][2] = sin(epsilon) * sin(epsilon + deltaEpsilon) * cos(deltaPsi) mNutation[2][2] = sin(epsilon) * sin(epsilon + deltaEpsilon) * cos(deltaPsi)
+ cos(epsilon) * cos(epsilon + deltaEpsilon); + cos(epsilon) * cos(epsilon + deltaEpsilon);
////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////
// Calculate Earth rotation matrix // Calculate Earth rotation matrix
//calculate theta //calculate theta
double mTheta[3][3]; double mTheta[3][3];
double Ttemp[3][3]; double Ttemp[3][3];
getEarthRotationMatrix(timeUTC, mTheta); getEarthRotationMatrix(timeUTC, mTheta);
//polar motion is neglected //polar motion is neglected
MatrixOperations<double>::multiply(mNutation[0], mPrecession[0], Ttemp[0], MatrixOperations<double>::multiply(mNutation[0], mPrecession[0], Ttemp[0],
3, 3, 3); 3, 3, 3);
MatrixOperations<double>::multiply(mTheta[0], Ttemp[0], Tfi[0], 3, 3, 3); MatrixOperations<double>::multiply(mTheta[0], Ttemp[0], Tfi[0], 3, 3, 3);
}; };

View File

@ -1,34 +1,34 @@
#ifndef COORDINATETRANSFORMATIONS_H_ #ifndef COORDINATETRANSFORMATIONS_H_
#define COORDINATETRANSFORMATIONS_H_ #define COORDINATETRANSFORMATIONS_H_
#include <framework/timemanager/Clock.h> #include "../timemanager/Clock.h"
#include <cstring> #include <cstring>
class CoordinateTransformations { class CoordinateTransformations {
public: public:
static void positionEcfToEci(const double* ecfCoordinates, double* eciCoordinates, timeval *timeUTC = NULL); static void positionEcfToEci(const double* ecfCoordinates, double* eciCoordinates, timeval *timeUTC = NULL);
static void velocityEcfToEci(const double* ecfVelocity, static void velocityEcfToEci(const double* ecfVelocity,
const double* ecfPosition, const double* ecfPosition,
double* eciVelocity, timeval *timeUTC = NULL); double* eciVelocity, timeval *timeUTC = NULL);
static void positionEciToEcf(const double* eciCoordinates, double* ecfCoordinates,timeval *timeUTC = NULL); static void positionEciToEcf(const double* eciCoordinates, double* ecfCoordinates,timeval *timeUTC = NULL);
static void velocityEciToEcf(const double* eciVelocity,const double* eciPosition, double* ecfVelocity,timeval* timeUTC = NULL); static void velocityEciToEcf(const double* eciVelocity,const double* eciPosition, double* ecfVelocity,timeval* timeUTC = NULL);
static double getEarthRotationAngle(timeval timeUTC); static double getEarthRotationAngle(timeval timeUTC);
static void getEarthRotationMatrix(timeval timeUTC, double matrix[][3]); static void getEarthRotationMatrix(timeval timeUTC, double matrix[][3]);
private: private:
CoordinateTransformations(); CoordinateTransformations();
static void ecfToEci(const double* ecfCoordinates, double* eciCoordinates, static void ecfToEci(const double* ecfCoordinates, double* eciCoordinates,
const double* ecfPositionIfCoordinatesAreVelocity, timeval *timeUTCin); const double* ecfPositionIfCoordinatesAreVelocity, timeval *timeUTCin);
static void eciToEcf(const double* eciCoordinates, static void eciToEcf(const double* eciCoordinates,
double* ecfCoordinates, double* ecfCoordinates,
const double* eciPositionIfCoordinatesAreVelocity,timeval *timeUTCin); const double* eciPositionIfCoordinatesAreVelocity,timeval *timeUTCin);
static double getJuleanCenturiesTT(timeval timeUTC); static double getJuleanCenturiesTT(timeval timeUTC);
static void getTransMatrixECITOECF(timeval time,double Tfi[3][3]); static void getTransMatrixECITOECF(timeval time,double Tfi[3][3]);
}; };
#endif /* COORDINATETRANSFORMATIONS_H_ */ #endif /* COORDINATETRANSFORMATIONS_H_ */

View File

@ -1,180 +1,180 @@
#ifndef FRAMEWORK_COORDINATES_JGM3MODEL_H_ #ifndef FRAMEWORK_COORDINATES_JGM3MODEL_H_
#define FRAMEWORK_COORDINATES_JGM3MODEL_H_ #define FRAMEWORK_COORDINATES_JGM3MODEL_H_
#include <stdint.h> #include <stdint.h>
#include <framework/coordinates/CoordinateTransformations.h> #include "../coordinates/CoordinateTransformations.h"
#include <framework/globalfunctions/math/VectorOperations.h> #include "../globalfunctions/math/VectorOperations.h"
#include <framework/globalfunctions/timevalOperations.h> #include "../globalfunctions/timevalOperations.h"
#include <framework/globalfunctions/constants.h> #include "../globalfunctions/constants.h"
#include <memory.h> #include <memory.h>
template<uint8_t DEGREE,uint8_t ORDER> template<uint8_t DEGREE,uint8_t ORDER>
class Jgm3Model { class Jgm3Model {
public: public:
static const uint32_t factorialLookupTable[DEGREE+3]; //This table is used instead of factorial calculation, must be increased if order or degree is higher static const uint32_t factorialLookupTable[DEGREE+3]; //This table is used instead of factorial calculation, must be increased if order or degree is higher
Jgm3Model() { Jgm3Model() {
y0[0] = 0; y0[0] = 0;
y0[1] = 0; y0[1] = 0;
y0[2] = 0; y0[2] = 0;
y0[3] = 0; y0[3] = 0;
y0[4] = 0; y0[4] = 0;
y0[5] = 0; y0[5] = 0;
lastExecutionTime.tv_sec = 0; lastExecutionTime.tv_sec = 0;
lastExecutionTime.tv_usec = 0; lastExecutionTime.tv_usec = 0;
} }
virtual ~Jgm3Model(){}; virtual ~Jgm3Model(){};
//double acsNavOrbit(double posECF[3],double velECF[3],timeval gpsTime); //double acsNavOrbit(double posECF[3],double velECF[3],timeval gpsTime);
double y0[6]; //position and velocity at beginning of RK step in EC double y0[6]; //position and velocity at beginning of RK step in EC
timeval lastExecutionTime; //Time of last execution timeval lastExecutionTime; //Time of last execution
void accelDegOrd(const double pos[3],const double S[ORDER+1][DEGREE+1],const double C[ORDER+1][DEGREE+1],double* accel){ void accelDegOrd(const double pos[3],const double S[ORDER+1][DEGREE+1],const double C[ORDER+1][DEGREE+1],double* accel){
//Get radius of this position //Get radius of this position
double r = VectorOperations<double>::norm(pos,3); double r = VectorOperations<double>::norm(pos,3);
//Initialize the V and W matrix //Initialize the V and W matrix
double V[DEGREE+2][ORDER+2] = {{0}}; double V[DEGREE+2][ORDER+2] = {{0}};
double W[DEGREE+2][ORDER+2] = {{0}}; double W[DEGREE+2][ORDER+2] = {{0}};
for(uint8_t m=0;m<(ORDER+2);m++){ for(uint8_t m=0;m<(ORDER+2);m++){
for(uint8_t n=m;n<(DEGREE+2);n++){ for(uint8_t n=m;n<(DEGREE+2);n++){
if((n==0) && (m==0)){ if((n==0) && (m==0)){
//Montenbruck "Satellite Orbits Eq.3.31" //Montenbruck "Satellite Orbits Eq.3.31"
V[0][0] = Earth::MEAN_RADIUS / r; V[0][0] = Earth::MEAN_RADIUS / r;
W[0][0] = 0; W[0][0] = 0;
}else{ }else{
if(n==m){ if(n==m){
//Montenbruck "Satellite Orbits Eq.3.29" //Montenbruck "Satellite Orbits Eq.3.29"
V[m][m] = (2*m-1)* (pos[0]*Earth::MEAN_RADIUS/pow(r,2)*V[m-1][m-1] - pos[1]*Earth::MEAN_RADIUS/pow(r,2)*W[m-1][m-1]); V[m][m] = (2*m-1)* (pos[0]*Earth::MEAN_RADIUS/pow(r,2)*V[m-1][m-1] - pos[1]*Earth::MEAN_RADIUS/pow(r,2)*W[m-1][m-1]);
W[m][m] = (2*m-1)* (pos[0]*Earth::MEAN_RADIUS/pow(r,2)*W[m-1][m-1] + pos[1]*Earth::MEAN_RADIUS/pow(r,2)*V[m-1][m-1]); W[m][m] = (2*m-1)* (pos[0]*Earth::MEAN_RADIUS/pow(r,2)*W[m-1][m-1] + pos[1]*Earth::MEAN_RADIUS/pow(r,2)*V[m-1][m-1]);
}else{ }else{
//Montenbruck "Satellite Orbits Eq.3.30" //Montenbruck "Satellite Orbits Eq.3.30"
V[n][m] = ((2*n-1)/(double)(n-m))*pos[2]*Earth::MEAN_RADIUS / pow(r,2)*V[n-1][m]; V[n][m] = ((2*n-1)/(double)(n-m))*pos[2]*Earth::MEAN_RADIUS / pow(r,2)*V[n-1][m];
W[n][m] = ((2*n-1)/(double)(n-m))*pos[2]*Earth::MEAN_RADIUS / pow(r,2)*W[n-1][m]; W[n][m] = ((2*n-1)/(double)(n-m))*pos[2]*Earth::MEAN_RADIUS / pow(r,2)*W[n-1][m];
if(n!=(m+1)){ if(n!=(m+1)){
V[n][m] = V[n][m] - (((n+m-1)/(double)(n-m)) * (pow(Earth::MEAN_RADIUS,2) / pow(r,2)) * V[n-2][m]); V[n][m] = V[n][m] - (((n+m-1)/(double)(n-m)) * (pow(Earth::MEAN_RADIUS,2) / pow(r,2)) * V[n-2][m]);
W[n][m] = W[n][m] - (((n+m-1)/(double)(n-m)) * (pow(Earth::MEAN_RADIUS,2) / pow(r,2)) * W[n-2][m]); W[n][m] = W[n][m] - (((n+m-1)/(double)(n-m)) * (pow(Earth::MEAN_RADIUS,2) / pow(r,2)) * W[n-2][m]);
}//End of if(n!=(m+1)) }//End of if(n!=(m+1))
}//End of if(n==m){ }//End of if(n==m){
}//End of if(n==0 and m==0) }//End of if(n==0 and m==0)
}//End of for(uint8_t n=0;n<(DEGREE+1);n++) }//End of for(uint8_t n=0;n<(DEGREE+1);n++)
}//End of for(uint8_t m=0;m<(ORDER+1);m++) }//End of for(uint8_t m=0;m<(ORDER+1);m++)
//overwrite accel if not properly initialized //overwrite accel if not properly initialized
accel[0] = 0; accel[0] = 0;
accel[1] = 0; accel[1] = 0;
accel[2] = 0; accel[2] = 0;
for(uint8_t m=0;m<(ORDER+1);m++){ for(uint8_t m=0;m<(ORDER+1);m++){
for(uint8_t n=m;n<(DEGREE+1);n++){ for(uint8_t n=m;n<(DEGREE+1);n++){
//Use table lookup to get factorial //Use table lookup to get factorial
double partAccel[3] = {0}; double partAccel[3] = {0};
double factor = Earth::STANDARD_GRAVITATIONAL_PARAMETER/pow(Earth::MEAN_RADIUS,2); double factor = Earth::STANDARD_GRAVITATIONAL_PARAMETER/pow(Earth::MEAN_RADIUS,2);
if(m==0){ if(m==0){
//Montenbruck "Satellite Orbits Eq.3.33" //Montenbruck "Satellite Orbits Eq.3.33"
partAccel[0] = factor * (-C[n][0]*V[n+1][1]); partAccel[0] = factor * (-C[n][0]*V[n+1][1]);
partAccel[1] = factor * (-C[n][0]*W[n+1][1]); partAccel[1] = factor * (-C[n][0]*W[n+1][1]);
}else{ }else{
double factMN = static_cast<double>(factorialLookupTable[n-m+2]) / static_cast<double>(factorialLookupTable[n-m]); double factMN = static_cast<double>(factorialLookupTable[n-m+2]) / static_cast<double>(factorialLookupTable[n-m]);
partAccel[0] = factor * 0.5 * ((-C[n][m]*V[n+1][m+1]-S[n][m]*W[n+1][m+1])+factMN*(C[n][m]*V[n+1][m-1]+S[n][m]*W[n+1][m-1])); partAccel[0] = factor * 0.5 * ((-C[n][m]*V[n+1][m+1]-S[n][m]*W[n+1][m+1])+factMN*(C[n][m]*V[n+1][m-1]+S[n][m]*W[n+1][m-1]));
partAccel[1] = factor * 0.5 * ((-C[n][m]*W[n+1][m+1]+S[n][m]*V[n+1][m+1])+factMN*(-C[n][m]*W[n+1][m-1]+S[n][m]*V[n+1][m-1])); partAccel[1] = factor * 0.5 * ((-C[n][m]*W[n+1][m+1]+S[n][m]*V[n+1][m+1])+factMN*(-C[n][m]*W[n+1][m-1]+S[n][m]*V[n+1][m-1]));
} }
partAccel[2] = factor * ((n-m+1)*(-C[n][m]*V[n+1][m]-S[n][m]*W[n+1][m])); partAccel[2] = factor * ((n-m+1)*(-C[n][m]*V[n+1][m]-S[n][m]*W[n+1][m]));
accel[0] += partAccel[0]; accel[0] += partAccel[0];
accel[1] += partAccel[1]; accel[1] += partAccel[1];
accel[2] += partAccel[2]; accel[2] += partAccel[2];
}//End of for(uint8_t n=0;n<DEGREE;n++) }//End of for(uint8_t n=0;n<DEGREE;n++)
}//End of uint8_t m=0;m<ORDER;m++ }//End of uint8_t m=0;m<ORDER;m++
} }
void initializeNavOrbit(const double position[3],const double velocity[3], timeval timeUTC){ void initializeNavOrbit(const double position[3],const double velocity[3], timeval timeUTC){
CoordinateTransformations::positionEcfToEci(position,&y0[0],&timeUTC); CoordinateTransformations::positionEcfToEci(position,&y0[0],&timeUTC);
CoordinateTransformations::velocityEcfToEci(velocity,position,&y0[3],&timeUTC); CoordinateTransformations::velocityEcfToEci(velocity,position,&y0[3],&timeUTC);
lastExecutionTime = timeUTC; lastExecutionTime = timeUTC;
} }
void acsNavOrbit(timeval timeUTC, const double S[ORDER+1][DEGREE+1],const double C[ORDER+1][DEGREE+1], double outputPos[3],double outputVel[3]){ void acsNavOrbit(timeval timeUTC, const double S[ORDER+1][DEGREE+1],const double C[ORDER+1][DEGREE+1], double outputPos[3],double outputVel[3]){
//RK4 Integration for this timestamp //RK4 Integration for this timestamp
double deltaT = timevalOperations::toDouble(timeUTC-lastExecutionTime); double deltaT = timevalOperations::toDouble(timeUTC-lastExecutionTime);
double y0dot[6] = {0,0,0,0,0,0}; double y0dot[6] = {0,0,0,0,0,0};
double yA[6] = {0,0,0,0,0,0}; double yA[6] = {0,0,0,0,0,0};
double yAdot[6] = {0,0,0,0,0,0}; double yAdot[6] = {0,0,0,0,0,0};
double yB[6] = {0,0,0,0,0,0}; double yB[6] = {0,0,0,0,0,0};
double yBdot[6] = {0,0,0,0,0,0}; double yBdot[6] = {0,0,0,0,0,0};
double yC[6] = {0,0,0,0,0,0}; double yC[6] = {0,0,0,0,0,0};
double yCdot[6] = {0,0,0,0,0,0}; double yCdot[6] = {0,0,0,0,0,0};
//Step One //Step One
rungeKuttaStep(y0,y0dot,lastExecutionTime,S,C); rungeKuttaStep(y0,y0dot,lastExecutionTime,S,C);
//Step Two //Step Two
VectorOperations<double>::mulScalar(y0dot,deltaT/2,yA,6); VectorOperations<double>::mulScalar(y0dot,deltaT/2,yA,6);
VectorOperations<double>::add(y0,yA,yA,6); VectorOperations<double>::add(y0,yA,yA,6);
rungeKuttaStep(yA,yAdot,lastExecutionTime,S,C); rungeKuttaStep(yA,yAdot,lastExecutionTime,S,C);
//Step Three //Step Three
VectorOperations<double>::mulScalar(yAdot,deltaT/2,yB,6); VectorOperations<double>::mulScalar(yAdot,deltaT/2,yB,6);
VectorOperations<double>::add(y0,yB,yB,6); VectorOperations<double>::add(y0,yB,yB,6);
rungeKuttaStep(yB,yBdot,lastExecutionTime,S,C); rungeKuttaStep(yB,yBdot,lastExecutionTime,S,C);
//Step Four //Step Four
VectorOperations<double>::mulScalar(yBdot,deltaT,yC,6); VectorOperations<double>::mulScalar(yBdot,deltaT,yC,6);
VectorOperations<double>::add(y0,yC,yC,6); VectorOperations<double>::add(y0,yC,yC,6);
rungeKuttaStep(yC,yCdot,lastExecutionTime,S,C); rungeKuttaStep(yC,yCdot,lastExecutionTime,S,C);
//Calc new State //Calc new State
VectorOperations<double>::mulScalar(yAdot,2,yAdot,6); VectorOperations<double>::mulScalar(yAdot,2,yAdot,6);
VectorOperations<double>::mulScalar(yBdot,2,yBdot,6); VectorOperations<double>::mulScalar(yBdot,2,yBdot,6);
VectorOperations<double>::add(y0dot,yAdot,y0dot,6); VectorOperations<double>::add(y0dot,yAdot,y0dot,6);
VectorOperations<double>::add(y0dot,yBdot,y0dot,6); VectorOperations<double>::add(y0dot,yBdot,y0dot,6);
VectorOperations<double>::add(y0dot,yCdot,y0dot,6); VectorOperations<double>::add(y0dot,yCdot,y0dot,6);
VectorOperations<double>::mulScalar(y0dot,1./6.*deltaT,y0dot,6); VectorOperations<double>::mulScalar(y0dot,1./6.*deltaT,y0dot,6);
VectorOperations<double>::add(y0,y0dot,y0,6); VectorOperations<double>::add(y0,y0dot,y0,6);
CoordinateTransformations::positionEciToEcf(&y0[0],outputPos,&timeUTC); CoordinateTransformations::positionEciToEcf(&y0[0],outputPos,&timeUTC);
CoordinateTransformations::velocityEciToEcf(&y0[3],&y0[0],outputVel,&timeUTC); CoordinateTransformations::velocityEciToEcf(&y0[3],&y0[0],outputVel,&timeUTC);
lastExecutionTime = timeUTC; lastExecutionTime = timeUTC;
} }
void rungeKuttaStep(const double* yIn,double* yOut,timeval time, const double S[ORDER+1][DEGREE+1],const double C[ORDER+1][DEGREE+1]){ void rungeKuttaStep(const double* yIn,double* yOut,timeval time, const double S[ORDER+1][DEGREE+1],const double C[ORDER+1][DEGREE+1]){
double rECF[3] = {0,0,0}; double rECF[3] = {0,0,0};
double rDotECF[3] = {0,0,0}; double rDotECF[3] = {0,0,0};
double accelECF[3] = {0,0,0}; double accelECF[3] = {0,0,0};
double accelECI[3] = {0,0,0}; double accelECI[3] = {0,0,0};
CoordinateTransformations::positionEciToEcf(&yIn[0],rECF,&time); CoordinateTransformations::positionEciToEcf(&yIn[0],rECF,&time);
CoordinateTransformations::velocityEciToEcf(&yIn[3],&yIn[0],rDotECF,&time); CoordinateTransformations::velocityEciToEcf(&yIn[3],&yIn[0],rDotECF,&time);
accelDegOrd(rECF,S,C,accelECF); accelDegOrd(rECF,S,C,accelECF);
//This is not correct, as the acceleration would have derived terms but we don't know the velocity and position at that time //This is not correct, as the acceleration would have derived terms but we don't know the velocity and position at that time
//Tests showed that a wrong velocity does make the equation worse than neglecting it //Tests showed that a wrong velocity does make the equation worse than neglecting it
CoordinateTransformations::positionEcfToEci(accelECF,accelECI,&time); CoordinateTransformations::positionEcfToEci(accelECF,accelECI,&time);
memcpy(&yOut[0],&yIn[3],sizeof(yOut[0])*3); memcpy(&yOut[0],&yIn[3],sizeof(yOut[0])*3);
memcpy(&yOut[3],accelECI,sizeof(yOut[0])*3); memcpy(&yOut[3],accelECI,sizeof(yOut[0])*3);
} }
}; };
#endif /* FRAMEWORK_COORDINATES_JGM3MODEL_H_ */ #endif /* FRAMEWORK_COORDINATES_JGM3MODEL_H_ */

View File

@ -1,228 +1,228 @@
#include <framework/coordinates/CoordinateTransformations.h> #include "../coordinates/CoordinateTransformations.h"
#include <framework/coordinates/Sgp4Propagator.h> #include "../coordinates/Sgp4Propagator.h"
#include <framework/globalfunctions/constants.h> #include "../globalfunctions/constants.h"
#include <framework/globalfunctions/math/MatrixOperations.h> #include "../globalfunctions/math/MatrixOperations.h"
#include <framework/globalfunctions/math/VectorOperations.h> #include "../globalfunctions/math/VectorOperations.h"
#include <framework/globalfunctions/timevalOperations.h> #include "../globalfunctions/timevalOperations.h"
#include <cstring> #include <cstring>
Sgp4Propagator::Sgp4Propagator() : Sgp4Propagator::Sgp4Propagator() :
initialized(false), epoch({0, 0}), whichconst(wgs84) { initialized(false), epoch({0, 0}), whichconst(wgs84) {
} }
Sgp4Propagator::~Sgp4Propagator() { Sgp4Propagator::~Sgp4Propagator() {
} }
void jday(int year, int mon, int day, int hr, int minute, double sec, void jday(int year, int mon, int day, int hr, int minute, double sec,
double& jd) { double& jd) {
jd = 367.0 * year - floor((7 * (year + floor((mon + 9) / 12.0))) * 0.25) jd = 367.0 * year - floor((7 * (year + floor((mon + 9) / 12.0))) * 0.25)
+ floor(275 * mon / 9.0) + day + 1721013.5 + floor(275 * mon / 9.0) + day + 1721013.5
+ ((sec / 60.0 + minute) / 60.0 + hr) / 24.0; // ut in days + ((sec / 60.0 + minute) / 60.0 + hr) / 24.0; // ut in days
// - 0.5*sgn(100.0*year + mon - 190002.5) + 0.5; // - 0.5*sgn(100.0*year + mon - 190002.5) + 0.5;
} }
void days2mdhms(int year, double days, int& mon, int& day, int& hr, int& minute, void days2mdhms(int year, double days, int& mon, int& day, int& hr, int& minute,
double& sec) { double& sec) {
int i, inttemp, dayofyr; int i, inttemp, dayofyr;
double temp; double temp;
int lmonth[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; int lmonth[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
dayofyr = (int) floor(days); dayofyr = (int) floor(days);
/* ----------------- find month and day of month ---------------- */ /* ----------------- find month and day of month ---------------- */
if ((year % 4) == 0) if ((year % 4) == 0)
lmonth[1] = 29; lmonth[1] = 29;
i = 1; i = 1;
inttemp = 0; inttemp = 0;
while ((dayofyr > inttemp + lmonth[i - 1]) && (i < 12)) { while ((dayofyr > inttemp + lmonth[i - 1]) && (i < 12)) {
inttemp = inttemp + lmonth[i - 1]; inttemp = inttemp + lmonth[i - 1];
i++; i++;
} }
mon = i; mon = i;
day = dayofyr - inttemp; day = dayofyr - inttemp;
/* ----------------- find hours minutes and seconds ------------- */ /* ----------------- find hours minutes and seconds ------------- */
temp = (days - dayofyr) * 24.0; temp = (days - dayofyr) * 24.0;
hr = (int) floor(temp); hr = (int) floor(temp);
temp = (temp - hr) * 60.0; temp = (temp - hr) * 60.0;
minute = (int) floor(temp); minute = (int) floor(temp);
sec = (temp - minute) * 60.0; sec = (temp - minute) * 60.0;
} }
ReturnValue_t Sgp4Propagator::initialize(const uint8_t* line1, ReturnValue_t Sgp4Propagator::initialize(const uint8_t* line1,
const uint8_t* line2) { const uint8_t* line2) {
char longstr1[130]; char longstr1[130];
char longstr2[130]; char longstr2[130];
//need some space for decimal points //need some space for decimal points
memcpy(longstr1, line1, 69); memcpy(longstr1, line1, 69);
memcpy(longstr2, line2, 69); memcpy(longstr2, line2, 69);
const double deg2rad = Math::PI / 180.0; // 0.0174532925199433 const double deg2rad = Math::PI / 180.0; // 0.0174532925199433
const double xpdotp = 1440.0 / (2.0 * Math::PI); // 229.1831180523293 const double xpdotp = 1440.0 / (2.0 * Math::PI); // 229.1831180523293
double sec, mu, radiusearthkm, tumin, xke, j2, j3, j4, j3oj2; double sec, mu, radiusearthkm, tumin, xke, j2, j3, j4, j3oj2;
int cardnumb, numb, j; int cardnumb, numb, j;
long revnum = 0, elnum = 0; long revnum = 0, elnum = 0;
char classification, intldesg[11]; char classification, intldesg[11];
int year = 0; int year = 0;
int mon, day, hr, minute, nexp, ibexp; int mon, day, hr, minute, nexp, ibexp;
getgravconst(whichconst, tumin, mu, radiusearthkm, xke, j2, j3, j4, j3oj2); getgravconst(whichconst, tumin, mu, radiusearthkm, xke, j2, j3, j4, j3oj2);
satrec.error = 0; satrec.error = 0;
// set the implied decimal points since doing a formated read // set the implied decimal points since doing a formated read
// fixes for bad input data values (missing, ...) // fixes for bad input data values (missing, ...)
for (j = 10; j <= 15; j++) for (j = 10; j <= 15; j++)
if (longstr1[j] == ' ') if (longstr1[j] == ' ')
longstr1[j] = '_'; longstr1[j] = '_';
if (longstr1[44] != ' ') if (longstr1[44] != ' ')
longstr1[43] = longstr1[44]; longstr1[43] = longstr1[44];
longstr1[44] = '.'; longstr1[44] = '.';
if (longstr1[7] == ' ') if (longstr1[7] == ' ')
longstr1[7] = 'U'; longstr1[7] = 'U';
if (longstr1[9] == ' ') if (longstr1[9] == ' ')
longstr1[9] = '.'; longstr1[9] = '.';
for (j = 45; j <= 49; j++) for (j = 45; j <= 49; j++)
if (longstr1[j] == ' ') if (longstr1[j] == ' ')
longstr1[j] = '0'; longstr1[j] = '0';
if (longstr1[51] == ' ') if (longstr1[51] == ' ')
longstr1[51] = '0'; longstr1[51] = '0';
if (longstr1[53] != ' ') if (longstr1[53] != ' ')
longstr1[52] = longstr1[53]; longstr1[52] = longstr1[53];
longstr1[53] = '.'; longstr1[53] = '.';
longstr2[25] = '.'; longstr2[25] = '.';
for (j = 26; j <= 32; j++) for (j = 26; j <= 32; j++)
if (longstr2[j] == ' ') if (longstr2[j] == ' ')
longstr2[j] = '0'; longstr2[j] = '0';
if (longstr1[62] == ' ') if (longstr1[62] == ' ')
longstr1[62] = '0'; longstr1[62] = '0';
if (longstr1[68] == ' ') if (longstr1[68] == ' ')
longstr1[68] = '0'; longstr1[68] = '0';
sscanf(longstr1, sscanf(longstr1,
"%2d %5ld %1c %10s %2d %12lf %11lf %7lf %2d %7lf %2d %2d %6ld ", "%2d %5ld %1c %10s %2d %12lf %11lf %7lf %2d %7lf %2d %2d %6ld ",
&cardnumb, &satrec.satnum, &classification, intldesg, &cardnumb, &satrec.satnum, &classification, intldesg,
&satrec.epochyr, &satrec.epochdays, &satrec.ndot, &satrec.nddot, &satrec.epochyr, &satrec.epochdays, &satrec.ndot, &satrec.nddot,
&nexp, &satrec.bstar, &ibexp, &numb, &elnum); &nexp, &satrec.bstar, &ibexp, &numb, &elnum);
if (longstr2[52] == ' ') { if (longstr2[52] == ' ') {
sscanf(longstr2, "%2d %5ld %9lf %9lf %8lf %9lf %9lf %10lf %6ld \n", sscanf(longstr2, "%2d %5ld %9lf %9lf %8lf %9lf %9lf %10lf %6ld \n",
&cardnumb, &satrec.satnum, &satrec.inclo, &satrec.nodeo, &cardnumb, &satrec.satnum, &satrec.inclo, &satrec.nodeo,
&satrec.ecco, &satrec.argpo, &satrec.mo, &satrec.no, &revnum); &satrec.ecco, &satrec.argpo, &satrec.mo, &satrec.no, &revnum);
} else { } else {
sscanf(longstr2, "%2d %5ld %9lf %9lf %8lf %9lf %9lf %11lf %6ld \n", sscanf(longstr2, "%2d %5ld %9lf %9lf %8lf %9lf %9lf %11lf %6ld \n",
&cardnumb, &satrec.satnum, &satrec.inclo, &satrec.nodeo, &cardnumb, &satrec.satnum, &satrec.inclo, &satrec.nodeo,
&satrec.ecco, &satrec.argpo, &satrec.mo, &satrec.no, &revnum); &satrec.ecco, &satrec.argpo, &satrec.mo, &satrec.no, &revnum);
} }
// ---- find no, ndot, nddot ---- // ---- find no, ndot, nddot ----
satrec.no = satrec.no / xpdotp; //* rad/min satrec.no = satrec.no / xpdotp; //* rad/min
satrec.nddot = satrec.nddot * pow(10.0, nexp); satrec.nddot = satrec.nddot * pow(10.0, nexp);
satrec.bstar = satrec.bstar * pow(10.0, ibexp); satrec.bstar = satrec.bstar * pow(10.0, ibexp);
// ---- convert to sgp4 units ---- // ---- convert to sgp4 units ----
satrec.a = pow(satrec.no * tumin, (-2.0 / 3.0)); satrec.a = pow(satrec.no * tumin, (-2.0 / 3.0));
satrec.ndot = satrec.ndot / (xpdotp * 1440.0); //* ? * minperday satrec.ndot = satrec.ndot / (xpdotp * 1440.0); //* ? * minperday
satrec.nddot = satrec.nddot / (xpdotp * 1440.0 * 1440); satrec.nddot = satrec.nddot / (xpdotp * 1440.0 * 1440);
// ---- find standard orbital elements ---- // ---- find standard orbital elements ----
satrec.inclo = satrec.inclo * deg2rad; satrec.inclo = satrec.inclo * deg2rad;
satrec.nodeo = satrec.nodeo * deg2rad; satrec.nodeo = satrec.nodeo * deg2rad;
satrec.argpo = satrec.argpo * deg2rad; satrec.argpo = satrec.argpo * deg2rad;
satrec.mo = satrec.mo * deg2rad; satrec.mo = satrec.mo * deg2rad;
satrec.alta = satrec.a * (1.0 + satrec.ecco) - 1.0; satrec.alta = satrec.a * (1.0 + satrec.ecco) - 1.0;
satrec.altp = satrec.a * (1.0 - satrec.ecco) - 1.0; satrec.altp = satrec.a * (1.0 - satrec.ecco) - 1.0;
// ---------------------------------------------------------------- // ----------------------------------------------------------------
// find sgp4epoch time of element set // find sgp4epoch time of element set
// remember that sgp4 uses units of days from 0 jan 1950 (sgp4epoch) // remember that sgp4 uses units of days from 0 jan 1950 (sgp4epoch)
// and minutes from the epoch (time) // and minutes from the epoch (time)
// ---------------------------------------------------------------- // ----------------------------------------------------------------
// ---------------- temp fix for years from 1957-2056 ------------------- // ---------------- temp fix for years from 1957-2056 -------------------
// --------- correct fix will occur when year is 4-digit in tle --------- // --------- correct fix will occur when year is 4-digit in tle ---------
if (satrec.epochyr < 57) { if (satrec.epochyr < 57) {
year = satrec.epochyr + 2000; year = satrec.epochyr + 2000;
} else { } else {
year = satrec.epochyr + 1900; year = satrec.epochyr + 1900;
} }
days2mdhms(year, satrec.epochdays, mon, day, hr, minute, sec); days2mdhms(year, satrec.epochdays, mon, day, hr, minute, sec);
jday(year, mon, day, hr, minute, sec, satrec.jdsatepoch); jday(year, mon, day, hr, minute, sec, satrec.jdsatepoch);
double unixSeconds = (satrec.jdsatepoch - 2451544.5) * 24 * 3600 double unixSeconds = (satrec.jdsatepoch - 2451544.5) * 24 * 3600
+ 946684800; + 946684800;
epoch.tv_sec = unixSeconds; epoch.tv_sec = unixSeconds;
double subseconds = unixSeconds - epoch.tv_sec; double subseconds = unixSeconds - epoch.tv_sec;
epoch.tv_usec = subseconds * 1000000; epoch.tv_usec = subseconds * 1000000;
// ---------------- initialize the orbit at sgp4epoch ------------------- // ---------------- initialize the orbit at sgp4epoch -------------------
uint8_t result = sgp4init(whichconst, satrec.satnum, uint8_t result = sgp4init(whichconst, satrec.satnum,
satrec.jdsatepoch - 2433281.5, satrec.bstar, satrec.ecco, satrec.jdsatepoch - 2433281.5, satrec.bstar, satrec.ecco,
satrec.argpo, satrec.inclo, satrec.mo, satrec.no, satrec.nodeo, satrec.argpo, satrec.inclo, satrec.mo, satrec.no, satrec.nodeo,
satrec); satrec);
if (result != 00) { if (result != 00) {
return MAKE_RETURN_CODE(result); return MAKE_RETURN_CODE(result);
} else { } else {
initialized = true; initialized = true;
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
} }
ReturnValue_t Sgp4Propagator::propagate(double* position, double* velocity, ReturnValue_t Sgp4Propagator::propagate(double* position, double* velocity,
timeval time, uint8_t gpsUtcOffset) { timeval time, uint8_t gpsUtcOffset) {
if (!initialized) { if (!initialized) {
return TLE_NOT_INITIALIZED; return TLE_NOT_INITIALIZED;
} }
//Time since epoch in minutes //Time since epoch in minutes
timeval timeSinceEpoch = time - epoch; timeval timeSinceEpoch = time - epoch;
double minutesSinceEpoch = timeSinceEpoch.tv_sec / 60. double minutesSinceEpoch = timeSinceEpoch.tv_sec / 60.
+ timeSinceEpoch.tv_usec / 60000000.; + timeSinceEpoch.tv_usec / 60000000.;
double yearsSinceEpoch = minutesSinceEpoch / 60 / 24 / 365; double yearsSinceEpoch = minutesSinceEpoch / 60 / 24 / 365;
if ((yearsSinceEpoch > 1) || (yearsSinceEpoch < -1)) { if ((yearsSinceEpoch > 1) || (yearsSinceEpoch < -1)) {
return TLE_TOO_OLD; return TLE_TOO_OLD;
} }
double positionTEME[3]; double positionTEME[3];
double velocityTEME[3]; double velocityTEME[3];
uint8_t result = sgp4(whichconst, satrec, minutesSinceEpoch, positionTEME, uint8_t result = sgp4(whichconst, satrec, minutesSinceEpoch, positionTEME,
velocityTEME); velocityTEME);
VectorOperations<double>::mulScalar(positionTEME, 1000, positionTEME, 3); VectorOperations<double>::mulScalar(positionTEME, 1000, positionTEME, 3);
VectorOperations<double>::mulScalar(velocityTEME, 1000, velocityTEME, 3); VectorOperations<double>::mulScalar(velocityTEME, 1000, velocityTEME, 3);
//Transform to ECF //Transform to ECF
double earthRotationMatrix[3][3]; double earthRotationMatrix[3][3];
CoordinateTransformations::getEarthRotationMatrix(time, CoordinateTransformations::getEarthRotationMatrix(time,
earthRotationMatrix); earthRotationMatrix);
MatrixOperations<double>::multiply(earthRotationMatrix[0], positionTEME, MatrixOperations<double>::multiply(earthRotationMatrix[0], positionTEME,
position, 3, 3, 1); position, 3, 3, 1);
MatrixOperations<double>::multiply(earthRotationMatrix[0], velocityTEME, MatrixOperations<double>::multiply(earthRotationMatrix[0], velocityTEME,
velocity, 3, 3, 1); velocity, 3, 3, 1);
double omegaEarth[3] = { 0, 0, Earth::OMEGA }; double omegaEarth[3] = { 0, 0, Earth::OMEGA };
double velocityCorrection[3]; double velocityCorrection[3];
VectorOperations<double>::cross(omegaEarth, position, velocityCorrection); VectorOperations<double>::cross(omegaEarth, position, velocityCorrection);
VectorOperations<double>::subtract(velocity, velocityCorrection, velocity); VectorOperations<double>::subtract(velocity, velocityCorrection, velocity);
if (result != 0) { if (result != 0) {
return MAKE_RETURN_CODE(result || 0xB0); return MAKE_RETURN_CODE(result || 0xB0);
} else { } else {
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
} }

View File

@ -1,44 +1,44 @@
#ifndef SGP4PROPAGATOR_H_ #ifndef SGP4PROPAGATOR_H_
#define SGP4PROPAGATOR_H_ #define SGP4PROPAGATOR_H_
#include <sys/time.h> #include <sys/time.h>
#include "../contrib/sgp4/sgp4unit.h" #include "../contrib/sgp4/sgp4unit.h"
#include <framework/returnvalues/HasReturnvaluesIF.h> #include "../returnvalues/HasReturnvaluesIF.h"
class Sgp4Propagator { class Sgp4Propagator {
public: public:
static const uint8_t INTERFACE_ID = CLASS_ID::SGP4PROPAGATOR_CLASS; static const uint8_t INTERFACE_ID = CLASS_ID::SGP4PROPAGATOR_CLASS;
static const ReturnValue_t INVALID_ECCENTRICITY = MAKE_RETURN_CODE(0xA1); static const ReturnValue_t INVALID_ECCENTRICITY = MAKE_RETURN_CODE(0xA1);
static const ReturnValue_t INVALID_MEAN_MOTION = MAKE_RETURN_CODE(0xA2); static const ReturnValue_t INVALID_MEAN_MOTION = MAKE_RETURN_CODE(0xA2);
static const ReturnValue_t INVALID_PERTURBATION_ELEMENTS = MAKE_RETURN_CODE(0xA3); static const ReturnValue_t INVALID_PERTURBATION_ELEMENTS = MAKE_RETURN_CODE(0xA3);
static const ReturnValue_t INVALID_SEMI_LATUS_RECTUM = MAKE_RETURN_CODE(0xA4); static const ReturnValue_t INVALID_SEMI_LATUS_RECTUM = MAKE_RETURN_CODE(0xA4);
static const ReturnValue_t INVALID_EPOCH_ELEMENTS = MAKE_RETURN_CODE(0xA5); static const ReturnValue_t INVALID_EPOCH_ELEMENTS = MAKE_RETURN_CODE(0xA5);
static const ReturnValue_t SATELLITE_HAS_DECAYED = MAKE_RETURN_CODE(0xA6); static const ReturnValue_t SATELLITE_HAS_DECAYED = MAKE_RETURN_CODE(0xA6);
static const ReturnValue_t TLE_TOO_OLD = MAKE_RETURN_CODE(0xB1); static const ReturnValue_t TLE_TOO_OLD = MAKE_RETURN_CODE(0xB1);
static const ReturnValue_t TLE_NOT_INITIALIZED = MAKE_RETURN_CODE(0xB2); static const ReturnValue_t TLE_NOT_INITIALIZED = MAKE_RETURN_CODE(0xB2);
Sgp4Propagator(); Sgp4Propagator();
virtual ~Sgp4Propagator(); virtual ~Sgp4Propagator();
ReturnValue_t initialize(const uint8_t *line1, const uint8_t *line2); ReturnValue_t initialize(const uint8_t *line1, const uint8_t *line2);
/** /**
* *
* @param[out] position in ECF * @param[out] position in ECF
* @param[out] velocity in ECF * @param[out] velocity in ECF
* @param time to which to propagate * @param time to which to propagate
* @return * @return
*/ */
ReturnValue_t propagate(double *position, double *velocity, timeval time, uint8_t gpsUtcOffset); ReturnValue_t propagate(double *position, double *velocity, timeval time, uint8_t gpsUtcOffset);
private: private:
bool initialized; bool initialized;
timeval epoch; timeval epoch;
elsetrec satrec; elsetrec satrec;
gravconsttype whichconst; gravconsttype whichconst;
}; };
#endif /* SGP4PROPAGATOR_H_ */ #endif /* SGP4PROPAGATOR_H_ */

View File

@ -1,62 +1,62 @@
/** /**
* @file BCFrame.h * @file BCFrame.h
* @brief This file defines the BCFrame class. * @brief This file defines the BCFrame class.
* @date 24.04.2013 * @date 24.04.2013
* @author baetz * @author baetz
*/ */
#ifndef BCFRAME_H_ #ifndef BCFRAME_H_
#define BCFRAME_H_ #define BCFRAME_H_
#include <framework/datalinklayer/CCSDSReturnValuesIF.h> #include "../datalinklayer/CCSDSReturnValuesIF.h"
/** /**
* Small helper class to identify a BcFrame. * Small helper class to identify a BcFrame.
* @ingroup ccsds_handling * @ingroup ccsds_handling
*/ */
class BcFrame: public CCSDSReturnValuesIF { class BcFrame: public CCSDSReturnValuesIF {
private: private:
static const uint8_t UNLOCK_COMMAND = 0b00000000;//! Identifier for a certain BC Command. static const uint8_t UNLOCK_COMMAND = 0b00000000;//! Identifier for a certain BC Command.
static const uint8_t SET_V_R_1 = 0b10000010;//! Identifier for a certain BC Command. static const uint8_t SET_V_R_1 = 0b10000010;//! Identifier for a certain BC Command.
static const uint8_t SET_V_R_2 = 0b00000000;//! Identifier for a certain BC Command. static const uint8_t SET_V_R_2 = 0b00000000;//! Identifier for a certain BC Command.
public: public:
uint8_t byte1; //!< First content byte uint8_t byte1; //!< First content byte
uint8_t byte2; //!< Second content byte uint8_t byte2; //!< Second content byte
uint8_t vR; //!< vR byte uint8_t vR; //!< vR byte
/** /**
* Simple default constructor. * Simple default constructor.
*/ */
BcFrame() : BcFrame() :
byte1(0), byte2(0), vR(0) { byte1(0), byte2(0), vR(0) {
} }
/** /**
* Main and only useful method of the class. * Main and only useful method of the class.
* With the buffer and size information passed, the class passes the content * With the buffer and size information passed, the class passes the content
* and checks if it is one of the two valid BC Command Frames. * and checks if it is one of the two valid BC Command Frames.
* @param inBuffer Content of the frame to check, * @param inBuffer Content of the frame to check,
* @param inSize Size of the data to check. * @param inSize Size of the data to check.
* @return - #BC_ILLEGAL_COMMAND if it is no command. * @return - #BC_ILLEGAL_COMMAND if it is no command.
* - #BC_IS_UNLOCK_COMMAND if it is an unlock command. * - #BC_IS_UNLOCK_COMMAND if it is an unlock command.
* - #BC_IS_SET_VR_COMMAND if it is such. * - #BC_IS_SET_VR_COMMAND if it is such.
*/ */
ReturnValue_t initialize(const uint8_t* inBuffer, uint16_t inSize) { ReturnValue_t initialize(const uint8_t* inBuffer, uint16_t inSize) {
ReturnValue_t returnValue = BC_ILLEGAL_COMMAND; ReturnValue_t returnValue = BC_ILLEGAL_COMMAND;
if (inSize == 1) { if (inSize == 1) {
byte1 = inBuffer[0]; byte1 = inBuffer[0];
if (byte1 == UNLOCK_COMMAND) { if (byte1 == UNLOCK_COMMAND) {
returnValue = BC_IS_UNLOCK_COMMAND; returnValue = BC_IS_UNLOCK_COMMAND;
} }
} else if (inSize == 3) { } else if (inSize == 3) {
byte1 = inBuffer[0]; byte1 = inBuffer[0];
byte2 = inBuffer[1]; byte2 = inBuffer[1];
vR = inBuffer[2]; vR = inBuffer[2];
if (byte1 == SET_V_R_1 && byte2 == SET_V_R_2) { if (byte1 == SET_V_R_1 && byte2 == SET_V_R_2) {
returnValue = BC_IS_SET_VR_COMMAND; returnValue = BC_IS_SET_VR_COMMAND;
} }
} }
return returnValue; return returnValue;
} }
}; };
#endif /* BCFRAME_H_ */ #endif /* BCFRAME_H_ */

View File

@ -1,56 +1,56 @@
/** /**
* @file CCSDSReturnValuesIF.h * @file CCSDSReturnValuesIF.h
* @brief This file defines the CCSDSReturnValuesIF class. * @brief This file defines the CCSDSReturnValuesIF class.
* @date 24.04.2013 * @date 24.04.2013
* @author baetz * @author baetz
*/ */
#ifndef CCSDSRETURNVALUESIF_H_ #ifndef CCSDSRETURNVALUESIF_H_
#define CCSDSRETURNVALUESIF_H_ #define CCSDSRETURNVALUESIF_H_
#include <framework/returnvalues/HasReturnvaluesIF.h> #include "../returnvalues/HasReturnvaluesIF.h"
/** /**
* This is a helper class to collect special return values that come up during CCSDS Handling. * This is a helper class to collect special return values that come up during CCSDS Handling.
* @ingroup ccsds_handling * @ingroup ccsds_handling
*/ */
class CCSDSReturnValuesIF: public HasReturnvaluesIF { class CCSDSReturnValuesIF: public HasReturnvaluesIF {
public: public:
static const uint8_t INTERFACE_ID = CLASS_ID::CCSDS_HANDLER_IF; //!< Basic ID of the interface. static const uint8_t INTERFACE_ID = CLASS_ID::CCSDS_HANDLER_IF; //!< Basic ID of the interface.
static const ReturnValue_t BC_IS_SET_VR_COMMAND = MAKE_RETURN_CODE( 0x01 ); //!< A value to describe a BC frame. static const ReturnValue_t BC_IS_SET_VR_COMMAND = MAKE_RETURN_CODE( 0x01 ); //!< A value to describe a BC frame.
static const ReturnValue_t BC_IS_UNLOCK_COMMAND = MAKE_RETURN_CODE( 0x02 ); //!< A value to describe a BC frame. static const ReturnValue_t BC_IS_UNLOCK_COMMAND = MAKE_RETURN_CODE( 0x02 ); //!< A value to describe a BC frame.
static const ReturnValue_t BC_ILLEGAL_COMMAND = MAKE_RETURN_CODE( 0xB0 );//!< A value to describe an illegal BC frame. static const ReturnValue_t BC_ILLEGAL_COMMAND = MAKE_RETURN_CODE( 0xB0 );//!< A value to describe an illegal BC frame.
static const ReturnValue_t BOARD_READING_NOT_FINISHED = MAKE_RETURN_CODE( 0xB1 ); //! The CCSDS Board is not yet finished reading, it requires another cycle. static const ReturnValue_t BOARD_READING_NOT_FINISHED = MAKE_RETURN_CODE( 0xB1 ); //! The CCSDS Board is not yet finished reading, it requires another cycle.
static const ReturnValue_t NS_POSITIVE_W = MAKE_RETURN_CODE( 0xF0 );//!< NS is in the positive window static const ReturnValue_t NS_POSITIVE_W = MAKE_RETURN_CODE( 0xF0 );//!< NS is in the positive window
static const ReturnValue_t NS_NEGATIVE_W = MAKE_RETURN_CODE( 0xF1 );//!< NS is in the negative window static const ReturnValue_t NS_NEGATIVE_W = MAKE_RETURN_CODE( 0xF1 );//!< NS is in the negative window
static const ReturnValue_t NS_LOCKOUT = MAKE_RETURN_CODE( 0xF2 ); //!< NS is in lockout state static const ReturnValue_t NS_LOCKOUT = MAKE_RETURN_CODE( 0xF2 ); //!< NS is in lockout state
static const ReturnValue_t FARM_IN_LOCKOUT = MAKE_RETURN_CODE( 0xF3 );//!< FARM-1 is currently in lockout state static const ReturnValue_t FARM_IN_LOCKOUT = MAKE_RETURN_CODE( 0xF3 );//!< FARM-1 is currently in lockout state
static const ReturnValue_t FARM_IN_WAIT = MAKE_RETURN_CODE( 0xF4 ); //!< FARM-1 is currently in wait state static const ReturnValue_t FARM_IN_WAIT = MAKE_RETURN_CODE( 0xF4 ); //!< FARM-1 is currently in wait state
static const ReturnValue_t WRONG_SYMBOL = MAKE_RETURN_CODE( 0xE0 ); //!< An error code in the FrameFinder. static const ReturnValue_t WRONG_SYMBOL = MAKE_RETURN_CODE( 0xE0 ); //!< An error code in the FrameFinder.
static const ReturnValue_t DOUBLE_START = MAKE_RETURN_CODE( 0xE1 ); //!< An error code in the FrameFinder. static const ReturnValue_t DOUBLE_START = MAKE_RETURN_CODE( 0xE1 ); //!< An error code in the FrameFinder.
static const ReturnValue_t START_SYMBOL_MISSED = MAKE_RETURN_CODE( 0xE2 );//!< An error code in the FrameFinder. static const ReturnValue_t START_SYMBOL_MISSED = MAKE_RETURN_CODE( 0xE2 );//!< An error code in the FrameFinder.
static const ReturnValue_t END_WITHOUT_START = MAKE_RETURN_CODE( 0xE3 );//!< An error code in the FrameFinder. static const ReturnValue_t END_WITHOUT_START = MAKE_RETURN_CODE( 0xE3 );//!< An error code in the FrameFinder.
static const ReturnValue_t TOO_LARGE = MAKE_RETURN_CODE( 0xE4 );//!< An error code for a frame. static const ReturnValue_t TOO_LARGE = MAKE_RETURN_CODE( 0xE4 );//!< An error code for a frame.
static const ReturnValue_t TOO_SHORT = MAKE_RETURN_CODE( 0xE5 );//!< An error code for a frame. static const ReturnValue_t TOO_SHORT = MAKE_RETURN_CODE( 0xE5 );//!< An error code for a frame.
static const ReturnValue_t WRONG_TF_VERSION = MAKE_RETURN_CODE( 0xE6 ); //!< An error code for a frame. static const ReturnValue_t WRONG_TF_VERSION = MAKE_RETURN_CODE( 0xE6 ); //!< An error code for a frame.
static const ReturnValue_t WRONG_SPACECRAFT_ID = MAKE_RETURN_CODE( 0xE7 );//!< An error code for a frame. static const ReturnValue_t WRONG_SPACECRAFT_ID = MAKE_RETURN_CODE( 0xE7 );//!< An error code for a frame.
static const ReturnValue_t NO_VALID_FRAME_TYPE = MAKE_RETURN_CODE( 0xE8 );//!< An error code for a frame. static const ReturnValue_t NO_VALID_FRAME_TYPE = MAKE_RETURN_CODE( 0xE8 );//!< An error code for a frame.
static const ReturnValue_t CRC_FAILED = MAKE_RETURN_CODE( 0xE9 );//!< An error code for a frame. static const ReturnValue_t CRC_FAILED = MAKE_RETURN_CODE( 0xE9 );//!< An error code for a frame.
static const ReturnValue_t VC_NOT_FOUND = MAKE_RETURN_CODE( 0xEA ); //!< An error code for a frame. static const ReturnValue_t VC_NOT_FOUND = MAKE_RETURN_CODE( 0xEA ); //!< An error code for a frame.
static const ReturnValue_t FORWARDING_FAILED = MAKE_RETURN_CODE( 0xEB );//!< An error code for a frame. static const ReturnValue_t FORWARDING_FAILED = MAKE_RETURN_CODE( 0xEB );//!< An error code for a frame.
static const ReturnValue_t CONTENT_TOO_LARGE = MAKE_RETURN_CODE( 0xEC );//!< An error code for a frame. static const ReturnValue_t CONTENT_TOO_LARGE = MAKE_RETURN_CODE( 0xEC );//!< An error code for a frame.
static const ReturnValue_t RESIDUAL_DATA = MAKE_RETURN_CODE( 0xED );//!< An error code for a frame. static const ReturnValue_t RESIDUAL_DATA = MAKE_RETURN_CODE( 0xED );//!< An error code for a frame.
static const ReturnValue_t DATA_CORRUPTED = MAKE_RETURN_CODE( 0xEE );//!< An error code for a frame. static const ReturnValue_t DATA_CORRUPTED = MAKE_RETURN_CODE( 0xEE );//!< An error code for a frame.
static const ReturnValue_t ILLEGAL_SEGMENTATION_FLAG = MAKE_RETURN_CODE( 0xEF );//!< An error code for a frame. static const ReturnValue_t ILLEGAL_SEGMENTATION_FLAG = MAKE_RETURN_CODE( 0xEF );//!< An error code for a frame.
static const ReturnValue_t ILLEGAL_FLAG_COMBINATION = MAKE_RETURN_CODE( 0xD0 ); //!< An error code for a frame. static const ReturnValue_t ILLEGAL_FLAG_COMBINATION = MAKE_RETURN_CODE( 0xD0 ); //!< An error code for a frame.
static const ReturnValue_t SHORTER_THAN_HEADER = MAKE_RETURN_CODE( 0xD1 ); //!< An error code for a frame. static const ReturnValue_t SHORTER_THAN_HEADER = MAKE_RETURN_CODE( 0xD1 ); //!< An error code for a frame.
static const ReturnValue_t TOO_SHORT_BLOCKED_PACKET = MAKE_RETURN_CODE( 0xD2 ); //!< An error code for a frame. static const ReturnValue_t TOO_SHORT_BLOCKED_PACKET = MAKE_RETURN_CODE( 0xD2 ); //!< An error code for a frame.
static const ReturnValue_t TOO_SHORT_MAP_EXTRACTION = MAKE_RETURN_CODE( 0xD3 ); //!< An error code for a frame. static const ReturnValue_t TOO_SHORT_MAP_EXTRACTION = MAKE_RETURN_CODE( 0xD3 ); //!< An error code for a frame.
virtual ~CCSDSReturnValuesIF() { virtual ~CCSDSReturnValuesIF() {
} //!< Empty virtual destructor } //!< Empty virtual destructor
}; };
#endif /* CCSDSRETURNVALUESIF_H_ */ #endif /* CCSDSRETURNVALUESIF_H_ */

View File

@ -1,63 +1,63 @@
/** /**
* @file Clcw.cpp * @file Clcw.cpp
* @brief This file defines the Clcw class. * @brief This file defines the Clcw class.
* @date 17.04.2013 * @date 17.04.2013
* @author baetz * @author baetz
*/ */
#include <framework/datalinklayer/Clcw.h> #include "../datalinklayer/Clcw.h"
#include <framework/serviceinterface/ServiceInterfaceStream.h> #include "../serviceinterface/ServiceInterfaceStream.h"
Clcw::Clcw() { Clcw::Clcw() {
content.raw = 0; content.raw = 0;
content.status = STATUS_FIELD_DEFAULT; content.status = STATUS_FIELD_DEFAULT;
} }
Clcw::~Clcw() { Clcw::~Clcw() {
} }
void Clcw::setVirtualChannel(uint8_t setChannel) { void Clcw::setVirtualChannel(uint8_t setChannel) {
content.virtualChannelIdSpare = ((setChannel & 0x3F) << 2); content.virtualChannelIdSpare = ((setChannel & 0x3F) << 2);
} }
void Clcw::setLockoutFlag(bool lockout) { void Clcw::setLockoutFlag(bool lockout) {
content.flags = (content.flags & LOCKOUT_FLAG_MASK) | (lockout << LOCKOUT_FLAG_POSITION); content.flags = (content.flags & LOCKOUT_FLAG_MASK) | (lockout << LOCKOUT_FLAG_POSITION);
} }
void Clcw::setWaitFlag(bool waitFlag) { void Clcw::setWaitFlag(bool waitFlag) {
content.flags = (content.flags & WAIT_FLAG_MASK) | (waitFlag << WAIT_FLAG_POSITION); content.flags = (content.flags & WAIT_FLAG_MASK) | (waitFlag << WAIT_FLAG_POSITION);
} }
void Clcw::setRetransmitFlag(bool retransmitFlag) { void Clcw::setRetransmitFlag(bool retransmitFlag) {
content.flags = (content.flags & RETRANSMIT_FLAG_MASK) | (retransmitFlag << RETRANSMIT_FLAG_POSITION); content.flags = (content.flags & RETRANSMIT_FLAG_MASK) | (retransmitFlag << RETRANSMIT_FLAG_POSITION);
} }
void Clcw::setFarmBCount(uint8_t count) { void Clcw::setFarmBCount(uint8_t count) {
content.flags = (content.flags & FARM_B_COUNT_MASK) | ((count & 0x03) << 1); content.flags = (content.flags & FARM_B_COUNT_MASK) | ((count & 0x03) << 1);
} }
void Clcw::setReceiverFrameSequenceNumber(uint8_t vR) { void Clcw::setReceiverFrameSequenceNumber(uint8_t vR) {
content.vRValue = vR; content.vRValue = vR;
} }
uint32_t Clcw::getAsWhole() { uint32_t Clcw::getAsWhole() {
return content.raw; return content.raw;
} }
void Clcw::setRFAvailable(bool rfAvailable) { void Clcw::setRFAvailable(bool rfAvailable) {
content.flags = (content.flags & NO_RF_AVIALABLE_MASK) | (!rfAvailable << NO_RF_AVIALABLE_POSITION); content.flags = (content.flags & NO_RF_AVIALABLE_MASK) | (!rfAvailable << NO_RF_AVIALABLE_POSITION);
} }
void Clcw::setBitLock(bool bitLock) { void Clcw::setBitLock(bool bitLock) {
content.flags = (content.flags & NO_BIT_LOCK_MASK) | (!bitLock << NO_BIT_LOCK_POSITION); content.flags = (content.flags & NO_BIT_LOCK_MASK) | (!bitLock << NO_BIT_LOCK_POSITION);
} }
void Clcw::print() { void Clcw::print() {
sif::debug << "Clcw::print: Clcw is: " << std::hex << getAsWhole() << std::dec << std::endl; sif::debug << "Clcw::print: Clcw is: " << std::hex << getAsWhole() << std::dec << std::endl;
} }
void Clcw::setWhole(uint32_t rawClcw) { void Clcw::setWhole(uint32_t rawClcw) {
content.raw = rawClcw; content.raw = rawClcw;
} }

View File

@ -1,66 +1,66 @@
/** /**
* @file Clcw.h * @file Clcw.h
* @brief This file defines the Clcw class. * @brief This file defines the Clcw class.
* @date 17.04.2013 * @date 17.04.2013
* @author baetz * @author baetz
*/ */
#ifndef CLCW_H_ #ifndef CLCW_H_
#define CLCW_H_ #define CLCW_H_
#include <framework/datalinklayer/ClcwIF.h> #include "../datalinklayer/ClcwIF.h"
/** /**
* Small helper method to handle the Clcw values. * Small helper method to handle the Clcw values.
* It has a content struct that manages the register and can be set externally. * It has a content struct that manages the register and can be set externally.
* @ingroup ccsds_handling * @ingroup ccsds_handling
*/ */
class Clcw : public ClcwIF { class Clcw : public ClcwIF {
private: private:
static const uint8_t STATUS_FIELD_DEFAULT = 0b00000001; //!< Default for the status field. static const uint8_t STATUS_FIELD_DEFAULT = 0b00000001; //!< Default for the status field.
static const uint8_t NO_RF_AVIALABLE_POSITION = 7; //!< Position of a flag in the register (starting with 0). static const uint8_t NO_RF_AVIALABLE_POSITION = 7; //!< Position of a flag in the register (starting with 0).
static const uint8_t NO_BIT_LOCK_POSITION = 6; //!< Position of a flag in the register (starting with 0). static const uint8_t NO_BIT_LOCK_POSITION = 6; //!< Position of a flag in the register (starting with 0).
static const uint8_t LOCKOUT_FLAG_POSITION = 5; //!< Position of a flag in the register (starting with 0). static const uint8_t LOCKOUT_FLAG_POSITION = 5; //!< Position of a flag in the register (starting with 0).
static const uint8_t WAIT_FLAG_POSITION = 4; //!< Position of a flag in the register (starting with 0). static const uint8_t WAIT_FLAG_POSITION = 4; //!< Position of a flag in the register (starting with 0).
static const uint8_t RETRANSMIT_FLAG_POSITION = 3; //!< Position of a flag in the register (starting with 0). static const uint8_t RETRANSMIT_FLAG_POSITION = 3; //!< Position of a flag in the register (starting with 0).
static const uint8_t NO_RF_AVIALABLE_MASK = 0xFF xor (1 << NO_RF_AVIALABLE_POSITION); //!< Mask for a flag in the register. static const uint8_t NO_RF_AVIALABLE_MASK = 0xFF xor (1 << NO_RF_AVIALABLE_POSITION); //!< Mask for a flag in the register.
static const uint8_t NO_BIT_LOCK_MASK = 0xFF xor (1 << NO_BIT_LOCK_POSITION); //!< Mask for a flag in the register. static const uint8_t NO_BIT_LOCK_MASK = 0xFF xor (1 << NO_BIT_LOCK_POSITION); //!< Mask for a flag in the register.
static const uint8_t LOCKOUT_FLAG_MASK = 0xFF xor (1 << LOCKOUT_FLAG_POSITION); //!< Mask for a flag in the register. static const uint8_t LOCKOUT_FLAG_MASK = 0xFF xor (1 << LOCKOUT_FLAG_POSITION); //!< Mask for a flag in the register.
static const uint8_t WAIT_FLAG_MASK = 0xFF xor (1 << WAIT_FLAG_POSITION); //!< Mask for a flag in the register. static const uint8_t WAIT_FLAG_MASK = 0xFF xor (1 << WAIT_FLAG_POSITION); //!< Mask for a flag in the register.
static const uint8_t RETRANSMIT_FLAG_MASK = 0xFF xor (1 << RETRANSMIT_FLAG_POSITION); //!< Mask for a flag in the register. static const uint8_t RETRANSMIT_FLAG_MASK = 0xFF xor (1 << RETRANSMIT_FLAG_POSITION); //!< Mask for a flag in the register.
static const uint8_t FARM_B_COUNT_MASK = 0b11111001; //!< Mask for a counter in the register. static const uint8_t FARM_B_COUNT_MASK = 0b11111001; //!< Mask for a counter in the register.
/** /**
* This is the data structure of the CLCW register. * This is the data structure of the CLCW register.
*/ */
union clcwContent { union clcwContent {
uint32_t raw; uint32_t raw;
struct { struct {
uint8_t status; uint8_t status;
uint8_t virtualChannelIdSpare; uint8_t virtualChannelIdSpare;
uint8_t flags; uint8_t flags;
uint8_t vRValue; uint8_t vRValue;
}; };
}; };
clcwContent content; //!< Represents the content of the register. clcwContent content; //!< Represents the content of the register.
public: public:
/** /**
* The constructor sets everything to default values. * The constructor sets everything to default values.
*/ */
Clcw(); Clcw();
/** /**
* Nothing happens in the destructor. * Nothing happens in the destructor.
*/ */
~Clcw(); ~Clcw();
void setVirtualChannel( uint8_t setChannel ); void setVirtualChannel( uint8_t setChannel );
void setLockoutFlag( bool lockout ); void setLockoutFlag( bool lockout );
void setWaitFlag( bool waitFlag ); void setWaitFlag( bool waitFlag );
void setRetransmitFlag( bool retransmitFlag ); void setRetransmitFlag( bool retransmitFlag );
void setFarmBCount( uint8_t count ); void setFarmBCount( uint8_t count );
void setReceiverFrameSequenceNumber( uint8_t vR ); void setReceiverFrameSequenceNumber( uint8_t vR );
void setRFAvailable( bool rfAvailable ); void setRFAvailable( bool rfAvailable );
void setBitLock( bool bitLock ); void setBitLock( bool bitLock );
uint32_t getAsWhole(); uint32_t getAsWhole();
void setWhole( uint32_t rawClcw ); void setWhole( uint32_t rawClcw );
void print(); void print();
}; };
#endif /* CLCW_H_ */ #endif /* CLCW_H_ */

View File

@ -1,139 +1,139 @@
#include <framework/datalinklayer/DataLinkLayer.h> #include "../datalinklayer/DataLinkLayer.h"
#include <framework/globalfunctions/CRC.h> #include "../globalfunctions/CRC.h"
#include <framework/serviceinterface/ServiceInterfaceStream.h> #include "../serviceinterface/ServiceInterfaceStream.h"
DataLinkLayer::DataLinkLayer(uint8_t* set_frame_buffer, ClcwIF* setClcw, DataLinkLayer::DataLinkLayer(uint8_t* set_frame_buffer, ClcwIF* setClcw,
uint8_t set_start_sequence_length, uint16_t set_scid) : uint8_t set_start_sequence_length, uint16_t set_scid) :
spacecraftId(set_scid), frameBuffer(set_frame_buffer), clcw(setClcw), receivedDataLength(0), currentFrame( spacecraftId(set_scid), frameBuffer(set_frame_buffer), clcw(setClcw), receivedDataLength(0), currentFrame(
NULL), startSequenceLength(set_start_sequence_length) { NULL), startSequenceLength(set_start_sequence_length) {
//Nothing to do except from setting the values above. //Nothing to do except from setting the values above.
} }
DataLinkLayer::~DataLinkLayer() { DataLinkLayer::~DataLinkLayer() {
} }
ReturnValue_t DataLinkLayer::frameDelimitingAndFillRemoval() { ReturnValue_t DataLinkLayer::frameDelimitingAndFillRemoval() {
if ((receivedDataLength - startSequenceLength) < FRAME_PRIMARY_HEADER_LENGTH) { if ((receivedDataLength - startSequenceLength) < FRAME_PRIMARY_HEADER_LENGTH) {
return SHORTER_THAN_HEADER; return SHORTER_THAN_HEADER;
} }
//Removing start sequence. //Removing start sequence.
//SHOULDDO: Not implemented here. //SHOULDDO: Not implemented here.
while ( *frameBuffer == START_SEQUENCE_PATTERN ) { while ( *frameBuffer == START_SEQUENCE_PATTERN ) {
frameBuffer++; frameBuffer++;
} }
TcTransferFrame frame_candidate(frameBuffer); TcTransferFrame frame_candidate(frameBuffer);
this->currentFrame = frame_candidate; //should work with shallow copy. this->currentFrame = frame_candidate; //should work with shallow copy.
return RETURN_OK; return RETURN_OK;
} }
ReturnValue_t DataLinkLayer::frameValidationCheck() { ReturnValue_t DataLinkLayer::frameValidationCheck() {
//Check TF_version number //Check TF_version number
if (this->currentFrame.getVersionNumber() != FRAME_VERSION_NUMBER_DEFAULT) { if (this->currentFrame.getVersionNumber() != FRAME_VERSION_NUMBER_DEFAULT) {
return WRONG_TF_VERSION; return WRONG_TF_VERSION;
} }
//Check SpaceCraft ID //Check SpaceCraft ID
if (this->currentFrame.getSpacecraftId() != this->spacecraftId) { if (this->currentFrame.getSpacecraftId() != this->spacecraftId) {
return WRONG_SPACECRAFT_ID; return WRONG_SPACECRAFT_ID;
} }
//Check other header limitations: //Check other header limitations:
if (!this->currentFrame.bypassFlagSet() && this->currentFrame.controlCommandFlagSet()) { if (!this->currentFrame.bypassFlagSet() && this->currentFrame.controlCommandFlagSet()) {
return NO_VALID_FRAME_TYPE; return NO_VALID_FRAME_TYPE;
} }
//- Spares are zero //- Spares are zero
if (!this->currentFrame.spareIsZero()) { if (!this->currentFrame.spareIsZero()) {
return NO_VALID_FRAME_TYPE; return NO_VALID_FRAME_TYPE;
} }
//Compare detected frame length with the one in the header //Compare detected frame length with the one in the header
uint16_t length = currentFrame.getFullSize(); uint16_t length = currentFrame.getFullSize();
if (length > receivedDataLength) { if (length > receivedDataLength) {
//Frame is too long or just right //Frame is too long or just right
// error << "frameValidationCheck: Too short."; // error << "frameValidationCheck: Too short.";
// currentFrame.print(); // currentFrame.print();
return TOO_SHORT; return TOO_SHORT;
} }
if (USE_CRC) { if (USE_CRC) {
return this->frameCheckCRC(); return this->frameCheckCRC();
} }
return RETURN_OK; return RETURN_OK;
} }
ReturnValue_t DataLinkLayer::frameCheckCRC() { ReturnValue_t DataLinkLayer::frameCheckCRC() {
uint16_t checkValue = CRC::crc16ccitt(this->currentFrame.getFullFrame(), uint16_t checkValue = CRC::crc16ccitt(this->currentFrame.getFullFrame(),
this->currentFrame.getFullSize()); this->currentFrame.getFullSize());
if (checkValue == 0) { if (checkValue == 0) {
return RETURN_OK; return RETURN_OK;
} else { } else {
return CRC_FAILED; return CRC_FAILED;
} }
} }
ReturnValue_t DataLinkLayer::allFramesReception() { ReturnValue_t DataLinkLayer::allFramesReception() {
ReturnValue_t status = this->frameDelimitingAndFillRemoval(); ReturnValue_t status = this->frameDelimitingAndFillRemoval();
if (status != RETURN_OK) { if (status != RETURN_OK) {
return status; return status;
} }
return this->frameValidationCheck(); return this->frameValidationCheck();
} }
ReturnValue_t DataLinkLayer::masterChannelDemultiplexing() { ReturnValue_t DataLinkLayer::masterChannelDemultiplexing() {
//Nothing to do at present. Ideally, there would be a map of MCID's identifying which MC to use. //Nothing to do at present. Ideally, there would be a map of MCID's identifying which MC to use.
return virtualChannelDemultiplexing(); return virtualChannelDemultiplexing();
} }
ReturnValue_t DataLinkLayer::virtualChannelDemultiplexing() { ReturnValue_t DataLinkLayer::virtualChannelDemultiplexing() {
uint8_t vcId = currentFrame.getVirtualChannelId(); uint8_t vcId = currentFrame.getVirtualChannelId();
virtualChannelIterator iter = virtualChannels.find(vcId); virtualChannelIterator iter = virtualChannels.find(vcId);
if (iter == virtualChannels.end()) { if (iter == virtualChannels.end()) {
//Do not report because passive board will get this error all the time. //Do not report because passive board will get this error all the time.
return RETURN_OK; return RETURN_OK;
} else { } else {
return (iter->second)->frameAcceptanceAndReportingMechanism(&currentFrame, clcw); return (iter->second)->frameAcceptanceAndReportingMechanism(&currentFrame, clcw);
} }
} }
ReturnValue_t DataLinkLayer::processFrame(uint16_t length) { ReturnValue_t DataLinkLayer::processFrame(uint16_t length) {
receivedDataLength = length; receivedDataLength = length;
ReturnValue_t status = allFramesReception(); ReturnValue_t status = allFramesReception();
if (status != RETURN_OK) { if (status != RETURN_OK) {
sif::error << "DataLinkLayer::processFrame: frame reception failed. " sif::error << "DataLinkLayer::processFrame: frame reception failed. "
"Error code: " << std::hex << status << std::dec << std::endl; "Error code: " << std::hex << status << std::dec << std::endl;
// currentFrame.print(); // currentFrame.print();
return status; return status;
} else { } else {
return masterChannelDemultiplexing(); return masterChannelDemultiplexing();
} }
} }
ReturnValue_t DataLinkLayer::addVirtualChannel(uint8_t virtualChannelId, ReturnValue_t DataLinkLayer::addVirtualChannel(uint8_t virtualChannelId,
VirtualChannelReceptionIF* object) { VirtualChannelReceptionIF* object) {
std::pair<virtualChannelIterator, bool> returnValue = virtualChannels.insert( std::pair<virtualChannelIterator, bool> returnValue = virtualChannels.insert(
std::pair<uint8_t, VirtualChannelReceptionIF*>(virtualChannelId, object)); std::pair<uint8_t, VirtualChannelReceptionIF*>(virtualChannelId, object));
if (returnValue.second == true) { if (returnValue.second == true) {
return RETURN_OK; return RETURN_OK;
} else { } else {
return RETURN_FAILED; return RETURN_FAILED;
} }
} }
ReturnValue_t DataLinkLayer::initialize() { ReturnValue_t DataLinkLayer::initialize() {
ReturnValue_t returnValue = RETURN_FAILED; ReturnValue_t returnValue = RETURN_FAILED;
//Set Virtual Channel ID to first virtual channel instance in this DataLinkLayer instance to avoid faulty information (e.g. 0) in the VCID. //Set Virtual Channel ID to first virtual channel instance in this DataLinkLayer instance to avoid faulty information (e.g. 0) in the VCID.
if ( virtualChannels.begin() != virtualChannels.end() ) { if ( virtualChannels.begin() != virtualChannels.end() ) {
clcw->setVirtualChannel( virtualChannels.begin()->second->getChannelId() ); clcw->setVirtualChannel( virtualChannels.begin()->second->getChannelId() );
} else { } else {
sif::error << "DataLinkLayer::initialize: No VC assigned to this DLL instance! " << std::endl; sif::error << "DataLinkLayer::initialize: No VC assigned to this DLL instance! " << std::endl;
return RETURN_FAILED; return RETURN_FAILED;
} }
for (virtualChannelIterator iterator = virtualChannels.begin(); for (virtualChannelIterator iterator = virtualChannels.begin();
iterator != virtualChannels.end(); iterator++) { iterator != virtualChannels.end(); iterator++) {
returnValue = iterator->second->initialize(); returnValue = iterator->second->initialize();
if (returnValue != RETURN_OK) if (returnValue != RETURN_OK)
break; break;
} }
return returnValue; return returnValue;
} }

View File

@ -1,112 +1,112 @@
#ifndef DATALINKLAYER_H_ #ifndef DATALINKLAYER_H_
#define DATALINKLAYER_H_ #define DATALINKLAYER_H_
#include <framework/datalinklayer/CCSDSReturnValuesIF.h> #include "../datalinklayer/CCSDSReturnValuesIF.h"
#include <framework/datalinklayer/ClcwIF.h> #include "../datalinklayer/ClcwIF.h"
#include <framework/datalinklayer/TcTransferFrame.h> #include "../datalinklayer/TcTransferFrame.h"
#include <framework/datalinklayer/VirtualChannelReceptionIF.h> #include "../datalinklayer/VirtualChannelReceptionIF.h"
#include <framework/events/Event.h> #include "../events/Event.h"
#include <map> #include <map>
class VirtualChannelReception; class VirtualChannelReception;
/** /**
* A complete representation of the CCSDS Data Link Layer. * A complete representation of the CCSDS Data Link Layer.
* The operations of this layer are defined in the CCSDS TC Space Data Link Protocol * The operations of this layer are defined in the CCSDS TC Space Data Link Protocol
* document. It is configured to handle a VC Demultiplexing function. All reception * document. It is configured to handle a VC Demultiplexing function. All reception
* steps are performed. * steps are performed.
*/ */
class DataLinkLayer : public CCSDSReturnValuesIF { class DataLinkLayer : public CCSDSReturnValuesIF {
public: public:
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SYSTEM_1; static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SYSTEM_1;
static const Event RF_AVAILABLE = MAKE_EVENT(0, SEVERITY::INFO); //!< A RF available signal was detected. P1: raw RFA state, P2: 0 static const Event RF_AVAILABLE = MAKE_EVENT(0, SEVERITY::INFO); //!< A RF available signal was detected. P1: raw RFA state, P2: 0
static const Event RF_LOST = MAKE_EVENT(1, SEVERITY::INFO); //!< A previously found RF available signal was lost. P1: raw RFA state, P2: 0 static const Event RF_LOST = MAKE_EVENT(1, SEVERITY::INFO); //!< A previously found RF available signal was lost. P1: raw RFA state, P2: 0
static const Event BIT_LOCK = MAKE_EVENT(2, SEVERITY::INFO); //!< A Bit Lock signal. Was detected. P1: raw BLO state, P2: 0 static const Event BIT_LOCK = MAKE_EVENT(2, SEVERITY::INFO); //!< A Bit Lock signal. Was detected. P1: raw BLO state, P2: 0
static const Event BIT_LOCK_LOST = MAKE_EVENT(3, SEVERITY::INFO); //!< A previously found Bit Lock signal was lost. P1: raw BLO state, P2: 0 static const Event BIT_LOCK_LOST = MAKE_EVENT(3, SEVERITY::INFO); //!< A previously found Bit Lock signal was lost. P1: raw BLO state, P2: 0
// static const Event RF_CHAIN_LOST = MAKE_EVENT(4, SEVERITY::INFO); //!< The CCSDS Board detected that either bit lock or RF available or both are lost. No parameters. // static const Event RF_CHAIN_LOST = MAKE_EVENT(4, SEVERITY::INFO); //!< The CCSDS Board detected that either bit lock or RF available or both are lost. No parameters.
static const Event FRAME_PROCESSING_FAILED = MAKE_EVENT(5, SEVERITY::LOW); //!< The CCSDS Board could not interpret a TC static const Event FRAME_PROCESSING_FAILED = MAKE_EVENT(5, SEVERITY::LOW); //!< The CCSDS Board could not interpret a TC
/** /**
* The Constructor sets the passed parameters and nothing else. * The Constructor sets the passed parameters and nothing else.
* @param set_frame_buffer The buffer in which incoming frame candidates are stored. * @param set_frame_buffer The buffer in which incoming frame candidates are stored.
* @param setClcw The CLCW class to work on when returning CLCW information. * @param setClcw The CLCW class to work on when returning CLCW information.
* @param set_start_sequence_length Length of the Start sequence in front of every TC Transfer Frame. * @param set_start_sequence_length Length of the Start sequence in front of every TC Transfer Frame.
* @param set_scid The SCID to operate on. * @param set_scid The SCID to operate on.
*/ */
DataLinkLayer( uint8_t* set_frame_buffer, ClcwIF* setClcw, uint8_t set_start_sequence_length, uint16_t set_scid ); DataLinkLayer( uint8_t* set_frame_buffer, ClcwIF* setClcw, uint8_t set_start_sequence_length, uint16_t set_scid );
/** /**
* Empty virtual destructor. * Empty virtual destructor.
*/ */
~DataLinkLayer(); ~DataLinkLayer();
/** /**
* This method tries to process a frame that is placed in #frameBuffer. * This method tries to process a frame that is placed in #frameBuffer.
* The procedures described in the Standard are performed. * The procedures described in the Standard are performed.
* @param length Length of the incoming frame candidate. * @param length Length of the incoming frame candidate.
* @return @c RETURN_OK on successful handling, otherwise the return codes of the higher methods. * @return @c RETURN_OK on successful handling, otherwise the return codes of the higher methods.
*/ */
ReturnValue_t processFrame( uint16_t length ); ReturnValue_t processFrame( uint16_t length );
/** /**
* Configuration method to add a new TC Virtual Channel. * Configuration method to add a new TC Virtual Channel.
* Shall only be called during initialization. As soon as the method was called, the layer can * Shall only be called during initialization. As soon as the method was called, the layer can
* handle Frames directed to this VC. * handle Frames directed to this VC.
* @param virtualChannelId Id of the VC. Shall be smaller than 64. * @param virtualChannelId Id of the VC. Shall be smaller than 64.
* @param object Reference to the object that handles the Frame. * @param object Reference to the object that handles the Frame.
* @return @c RETURN_OK on success, @c RETURN_FAILED otherwise. * @return @c RETURN_OK on success, @c RETURN_FAILED otherwise.
*/ */
ReturnValue_t addVirtualChannel( uint8_t virtualChannelId, VirtualChannelReceptionIF* object ); ReturnValue_t addVirtualChannel( uint8_t virtualChannelId, VirtualChannelReceptionIF* object );
/** /**
* The initialization method calls the @c initialize routine of all virtual channels. * The initialization method calls the @c initialize routine of all virtual channels.
* @return The return code of the first failed VC initialization or @c RETURN_OK. * @return The return code of the first failed VC initialization or @c RETURN_OK.
*/ */
ReturnValue_t initialize(); ReturnValue_t initialize();
private: private:
typedef std::map<uint8_t, VirtualChannelReceptionIF*>::iterator virtualChannelIterator; //!< Typedef to simplify handling the #virtualChannels map. typedef std::map<uint8_t, VirtualChannelReceptionIF*>::iterator virtualChannelIterator; //!< Typedef to simplify handling the #virtualChannels map.
static const uint8_t FRAME_VERSION_NUMBER_DEFAULT = 0x00; //!< Constant for the default value of Frame Version Numbers. static const uint8_t FRAME_VERSION_NUMBER_DEFAULT = 0x00; //!< Constant for the default value of Frame Version Numbers.
static const uint8_t FRAME_PRIMARY_HEADER_LENGTH = 5; //!< Length of the frame's primary header. static const uint8_t FRAME_PRIMARY_HEADER_LENGTH = 5; //!< Length of the frame's primary header.
static const uint8_t START_SEQUENCE_PATTERN = 0x00; //!< The start sequence pattern which might be with the frame. static const uint8_t START_SEQUENCE_PATTERN = 0x00; //!< The start sequence pattern which might be with the frame.
static const bool USE_CRC = true; //!< A global, so called "Managed Parameter" that identifies if incoming frames have CRC's or not. static const bool USE_CRC = true; //!< A global, so called "Managed Parameter" that identifies if incoming frames have CRC's or not.
uint16_t spacecraftId; //!< The Space Craft Identifier (SCID) configured. uint16_t spacecraftId; //!< The Space Craft Identifier (SCID) configured.
uint8_t* frameBuffer; //!< A pointer to point to the current incoming frame. uint8_t* frameBuffer; //!< A pointer to point to the current incoming frame.
ClcwIF* clcw; //!< Pointer to store the CLCW to work on. ClcwIF* clcw; //!< Pointer to store the CLCW to work on.
uint16_t receivedDataLength; //!< Stores the length of the currently processed frame. uint16_t receivedDataLength; //!< Stores the length of the currently processed frame.
TcTransferFrame currentFrame; //!< Stores a more convenient access to the current frame. TcTransferFrame currentFrame; //!< Stores a more convenient access to the current frame.
uint8_t startSequenceLength; //!< Configured length of the start sequence. Maybe this must be done more variable. uint8_t startSequenceLength; //!< Configured length of the start sequence. Maybe this must be done more variable.
std::map<uint8_t, VirtualChannelReceptionIF*> virtualChannels; //!< Map of all virtual channels assigned. std::map<uint8_t, VirtualChannelReceptionIF*> virtualChannels; //!< Map of all virtual channels assigned.
/** /**
* Method that performs all possible frame validity checks (as specified). * Method that performs all possible frame validity checks (as specified).
* @return Various error codes or @c RETURN_OK on success. * @return Various error codes or @c RETURN_OK on success.
*/ */
ReturnValue_t frameValidationCheck(); ReturnValue_t frameValidationCheck();
/** /**
* First method to call. * First method to call.
* Removes start sequence bytes and checks if the complete frame was received. * Removes start sequence bytes and checks if the complete frame was received.
* SHOULDDO: Maybe handling the start sequence must be done more variable. * SHOULDDO: Maybe handling the start sequence must be done more variable.
* @return @c RETURN_OK or @c TOO_SHORT. * @return @c RETURN_OK or @c TOO_SHORT.
*/ */
ReturnValue_t frameDelimitingAndFillRemoval(); ReturnValue_t frameDelimitingAndFillRemoval();
/** /**
* Small helper method to check the CRC of the Frame. * Small helper method to check the CRC of the Frame.
* @return @c RETURN_OK or @c CRC_FAILED. * @return @c RETURN_OK or @c CRC_FAILED.
*/ */
ReturnValue_t frameCheckCRC(); ReturnValue_t frameCheckCRC();
/** /**
* Method that groups the reception process of all Frames. * Method that groups the reception process of all Frames.
* Calls #frameDelimitingAndFillRemoval and #frameValidationCheck. * Calls #frameDelimitingAndFillRemoval and #frameValidationCheck.
* @return The return codes of the sub calls. * @return The return codes of the sub calls.
*/ */
ReturnValue_t allFramesReception(); ReturnValue_t allFramesReception();
/** /**
* Dummy method for master channel demultiplexing. * Dummy method for master channel demultiplexing.
* As there's only one Master Channel here, the method calls #virtualChannelDemultiplexing. * As there's only one Master Channel here, the method calls #virtualChannelDemultiplexing.
* @return The return codes of #virtualChannelDemultiplexing. * @return The return codes of #virtualChannelDemultiplexing.
*/ */
ReturnValue_t masterChannelDemultiplexing(); ReturnValue_t masterChannelDemultiplexing();
/** /**
* Method to demultiplex the Frames to Virtual Channels (VC's). * Method to demultiplex the Frames to Virtual Channels (VC's).
* Looks up the requested VC in #virtualChannels and forwards the Frame to its * Looks up the requested VC in #virtualChannels and forwards the Frame to its
* #frameAcceptanceAndReportingMechanism method, if found. * #frameAcceptanceAndReportingMechanism method, if found.
* @return The higher method codes or @c VC_NOT_FOUND. * @return The higher method codes or @c VC_NOT_FOUND.
*/ */
ReturnValue_t virtualChannelDemultiplexing(); ReturnValue_t virtualChannelDemultiplexing();
}; };
#endif /* DATALINKLAYER_H_ */ #endif /* DATALINKLAYER_H_ */

View File

@ -1,54 +1,54 @@
/** /**
* @file Farm1StateIF.h * @file Farm1StateIF.h
* @brief This file defines the Farm1StateIF class. * @brief This file defines the Farm1StateIF class.
* @date 24.04.2013 * @date 24.04.2013
* @author baetz * @author baetz
*/ */
#ifndef FARM1STATEIF_H_ #ifndef FARM1STATEIF_H_
#define FARM1STATEIF_H_ #define FARM1STATEIF_H_
#include <framework/datalinklayer/CCSDSReturnValuesIF.h> #include "../datalinklayer/CCSDSReturnValuesIF.h"
class VirtualChannelReception; class VirtualChannelReception;
class TcTransferFrame; class TcTransferFrame;
class ClcwIF; class ClcwIF;
/** /**
* This is the interface for states of the FARM-1 state machine. * This is the interface for states of the FARM-1 state machine.
* Classes implementing this interface can be used as FARM-1 states. This is a simple implementation * Classes implementing this interface can be used as FARM-1 states. This is a simple implementation
* of the state pattern. * of the state pattern.
*/ */
class Farm1StateIF : public CCSDSReturnValuesIF { class Farm1StateIF : public CCSDSReturnValuesIF {
public: public:
/** /**
* A method that shall handle an incoming frame as AD Frame. * A method that shall handle an incoming frame as AD Frame.
* @param frame The frame to handle. * @param frame The frame to handle.
* @param clcw Any changes to the CLCW shall be done with the help of this interface. * @param clcw Any changes to the CLCW shall be done with the help of this interface.
* @return If forwarding to a MAP Channel is required, the return value shall be #FRAME_OK. * @return If forwarding to a MAP Channel is required, the return value shall be #FRAME_OK.
* Otherwise, an appropriate return value or error code shall be generated. * Otherwise, an appropriate return value or error code shall be generated.
*/ */
virtual ReturnValue_t handleADFrame( TcTransferFrame* frame, ClcwIF* clcw ) = 0; virtual ReturnValue_t handleADFrame( TcTransferFrame* frame, ClcwIF* clcw ) = 0;
/** /**
* This method shall handle frames that have been successfully identified as BC Unlock frames. * This method shall handle frames that have been successfully identified as BC Unlock frames.
* @param clcw Any changes to the CLCW shall be done with the help of this interface. * @param clcw Any changes to the CLCW shall be done with the help of this interface.
* @return If forwarding to a MAP Channel is required, the return value shall be #FRAME_OK. * @return If forwarding to a MAP Channel is required, the return value shall be #FRAME_OK.
* Otherwise, an appropriate return value or error code shall be generated. * Otherwise, an appropriate return value or error code shall be generated.
*/ */
virtual ReturnValue_t handleBCUnlockCommand( ClcwIF* clcw ) = 0; virtual ReturnValue_t handleBCUnlockCommand( ClcwIF* clcw ) = 0;
/** /**
* This method shall handle frames that have been successfully identified as BC Set VR frames. * This method shall handle frames that have been successfully identified as BC Set VR frames.
* @param clcw Any changes to the CLCW shall be done with the help of this interface. * @param clcw Any changes to the CLCW shall be done with the help of this interface.
* @param vr The V(r) value found in the frame. * @param vr The V(r) value found in the frame.
* @return If forwarding to a MAP Channel is required, the return value shall be #FRAME_OK. * @return If forwarding to a MAP Channel is required, the return value shall be #FRAME_OK.
* Otherwise, an appropriate return value or error code shall be generated. * Otherwise, an appropriate return value or error code shall be generated.
*/ */
virtual ReturnValue_t handleBCSetVrCommand( ClcwIF* clcw, uint8_t vr ) = 0; virtual ReturnValue_t handleBCSetVrCommand( ClcwIF* clcw, uint8_t vr ) = 0;
/** /**
* Empty virtual destructor. * Empty virtual destructor.
*/ */
virtual ~Farm1StateIF() { virtual ~Farm1StateIF() {
} }
}; };
#endif /* FARM1STATEIF_H_ */ #endif /* FARM1STATEIF_H_ */

View File

@ -1,35 +1,35 @@
/** /**
* @file Farm1StateLockout.cpp * @file Farm1StateLockout.cpp
* @brief This file defines the Farm1StateLockout class. * @brief This file defines the Farm1StateLockout class.
* @date 24.04.2013 * @date 24.04.2013
* @author baetz * @author baetz
*/ */
#include <framework/datalinklayer/ClcwIF.h> #include "../datalinklayer/ClcwIF.h"
#include <framework/datalinklayer/Farm1StateLockout.h> #include "../datalinklayer/Farm1StateLockout.h"
#include <framework/datalinklayer/TcTransferFrame.h> #include "../datalinklayer/TcTransferFrame.h"
#include <framework/datalinklayer/VirtualChannelReception.h> #include "../datalinklayer/VirtualChannelReception.h"
Farm1StateLockout::Farm1StateLockout(VirtualChannelReception* setMyVC) : myVC(setMyVC) { Farm1StateLockout::Farm1StateLockout(VirtualChannelReception* setMyVC) : myVC(setMyVC) {
} }
ReturnValue_t Farm1StateLockout::handleADFrame(TcTransferFrame* frame, ReturnValue_t Farm1StateLockout::handleADFrame(TcTransferFrame* frame,
ClcwIF* clcw) { ClcwIF* clcw) {
return FARM_IN_LOCKOUT; return FARM_IN_LOCKOUT;
} }
ReturnValue_t Farm1StateLockout::handleBCUnlockCommand(ClcwIF* clcw) { ReturnValue_t Farm1StateLockout::handleBCUnlockCommand(ClcwIF* clcw) {
myVC->farmBCounter++; myVC->farmBCounter++;
clcw->setRetransmitFlag(false); clcw->setRetransmitFlag(false);
clcw->setLockoutFlag( false ); clcw->setLockoutFlag( false );
clcw->setWaitFlag( false ); clcw->setWaitFlag( false );
myVC->currentState = &(myVC->openState); myVC->currentState = &(myVC->openState);
return BC_IS_UNLOCK_COMMAND; return BC_IS_UNLOCK_COMMAND;
} }
ReturnValue_t Farm1StateLockout::handleBCSetVrCommand(ClcwIF* clcw, ReturnValue_t Farm1StateLockout::handleBCSetVrCommand(ClcwIF* clcw,
uint8_t vr) { uint8_t vr) {
myVC->farmBCounter++; myVC->farmBCounter++;
return BC_IS_SET_VR_COMMAND; return BC_IS_SET_VR_COMMAND;
} }

View File

@ -1,59 +1,59 @@
/** /**
* @file Farm1StateLockout.h * @file Farm1StateLockout.h
* @brief This file defines the Farm1StateLockout class. * @brief This file defines the Farm1StateLockout class.
* @date 24.04.2013 * @date 24.04.2013
* @author baetz * @author baetz
*/ */
#ifndef FARM1STATELOCKOUT_H_ #ifndef FARM1STATELOCKOUT_H_
#define FARM1STATELOCKOUT_H_ #define FARM1STATELOCKOUT_H_
#include <framework/datalinklayer/Farm1StateIF.h> #include "../datalinklayer/Farm1StateIF.h"
/** /**
* This class represents the FARM-1 "Lockout" State. * This class represents the FARM-1 "Lockout" State.
* The Lockout state is reached if the received Transfer Frame Sequence Number is completely wrong * The Lockout state is reached if the received Transfer Frame Sequence Number is completely wrong
* (i.e. within the Lockout Window). No AD Frames are forwarded. To leave the State, a BC Unlock * (i.e. within the Lockout Window). No AD Frames are forwarded. To leave the State, a BC Unlock
* command is required. * command is required.
*/ */
class Farm1StateLockout : public Farm1StateIF { class Farm1StateLockout : public Farm1StateIF {
private: private:
/** /**
* This is a reference to the "owner" class the State works on. * This is a reference to the "owner" class the State works on.
*/ */
VirtualChannelReception* myVC; VirtualChannelReception* myVC;
public: public:
/** /**
* The default constructor if the State. * The default constructor if the State.
* Sets the "owner" of the State. * Sets the "owner" of the State.
* @param setMyVC The "owner" class. * @param setMyVC The "owner" class.
*/ */
Farm1StateLockout( VirtualChannelReception* setMyVC ); Farm1StateLockout( VirtualChannelReception* setMyVC );
/** /**
* All AD Frames are rejected with FARM_IN_LOCKOUT * All AD Frames are rejected with FARM_IN_LOCKOUT
* @param frame The frame to handle. * @param frame The frame to handle.
* @param clcw Any changes to the CLCW shall be done with the help of this interface. * @param clcw Any changes to the CLCW shall be done with the help of this interface.
* @return FARM_IN_LOCKOUT * @return FARM_IN_LOCKOUT
*/ */
ReturnValue_t handleADFrame( TcTransferFrame* frame, ClcwIF* clcw ); ReturnValue_t handleADFrame( TcTransferFrame* frame, ClcwIF* clcw );
/** /**
* These commands are handled as specified. * These commands are handled as specified.
* State changes to Farm1StateOpen. * State changes to Farm1StateOpen.
* @param clcw Any changes to the CLCW shall be done with the help of this interface. * @param clcw Any changes to the CLCW shall be done with the help of this interface.
* @return As the frame needs no forwarding to a MAP Channel, #BC_IS_UNLOCK_COMMAND * @return As the frame needs no forwarding to a MAP Channel, #BC_IS_UNLOCK_COMMAND
* is returned. * is returned.
*/ */
ReturnValue_t handleBCUnlockCommand( ClcwIF* clcw ); ReturnValue_t handleBCUnlockCommand( ClcwIF* clcw );
/** /**
* These commands are handled as specified. * These commands are handled as specified.
* The V(r) value is not set in Lockout State, even though the Command itself is accepted. * The V(r) value is not set in Lockout State, even though the Command itself is accepted.
* @param clcw Any changes to the CLCW shall be done with the help of this interface. * @param clcw Any changes to the CLCW shall be done with the help of this interface.
* @param vr The V(r) value found in the frame. * @param vr The V(r) value found in the frame.
* @return As the frame needs no forwarding to a MAP Channel, #BC_IS_SET_VR_COMMAND * @return As the frame needs no forwarding to a MAP Channel, #BC_IS_SET_VR_COMMAND
* is returned. * is returned.
*/ */
ReturnValue_t handleBCSetVrCommand( ClcwIF* clcw, uint8_t vr ); ReturnValue_t handleBCSetVrCommand( ClcwIF* clcw, uint8_t vr );
}; };
#endif /* FARM1STATELOCKOUT_H_ */ #endif /* FARM1STATELOCKOUT_H_ */

View File

@ -1,49 +1,49 @@
/** /**
* @file Farm1StateOpen.cpp * @file Farm1StateOpen.cpp
* @brief This file defines the Farm1StateOpen class. * @brief This file defines the Farm1StateOpen class.
* @date 24.04.2013 * @date 24.04.2013
* @author baetz * @author baetz
*/ */
#include <framework/datalinklayer/ClcwIF.h> #include "../datalinklayer/ClcwIF.h"
#include <framework/datalinklayer/Farm1StateOpen.h> #include "../datalinklayer/Farm1StateOpen.h"
#include <framework/datalinklayer/TcTransferFrame.h> #include "../datalinklayer/TcTransferFrame.h"
#include <framework/datalinklayer/VirtualChannelReception.h> #include "../datalinklayer/VirtualChannelReception.h"
Farm1StateOpen::Farm1StateOpen(VirtualChannelReception* setMyVC) : myVC(setMyVC) { Farm1StateOpen::Farm1StateOpen(VirtualChannelReception* setMyVC) : myVC(setMyVC) {
} }
ReturnValue_t Farm1StateOpen::handleADFrame(TcTransferFrame* frame, ReturnValue_t Farm1StateOpen::handleADFrame(TcTransferFrame* frame,
ClcwIF* clcw) { ClcwIF* clcw) {
int8_t diff = frame->getSequenceNumber() - myVC->vR; int8_t diff = frame->getSequenceNumber() - myVC->vR;
if (diff == 0 ) { if (diff == 0 ) {
myVC->vR++; myVC->vR++;
clcw->setRetransmitFlag(false); clcw->setRetransmitFlag(false);
return RETURN_OK; return RETURN_OK;
} else if (diff < myVC->positiveWindow && diff > 0 ) { } else if (diff < myVC->positiveWindow && diff > 0 ) {
clcw->setRetransmitFlag(true); clcw->setRetransmitFlag(true);
return NS_POSITIVE_W; return NS_POSITIVE_W;
} else if (diff < 0 && diff >= -myVC->negativeWindow) { } else if (diff < 0 && diff >= -myVC->negativeWindow) {
return NS_NEGATIVE_W; return NS_NEGATIVE_W;
} else { } else {
clcw->setLockoutFlag(true); clcw->setLockoutFlag(true);
myVC->currentState = &(myVC->lockoutState); myVC->currentState = &(myVC->lockoutState);
return NS_LOCKOUT; return NS_LOCKOUT;
} }
} }
ReturnValue_t Farm1StateOpen::handleBCUnlockCommand( ClcwIF* clcw ) { ReturnValue_t Farm1StateOpen::handleBCUnlockCommand( ClcwIF* clcw ) {
myVC->farmBCounter++; myVC->farmBCounter++;
clcw->setRetransmitFlag(false); clcw->setRetransmitFlag(false);
return BC_IS_UNLOCK_COMMAND; return BC_IS_UNLOCK_COMMAND;
} }
ReturnValue_t Farm1StateOpen::handleBCSetVrCommand( ClcwIF* clcw, uint8_t vr ) { ReturnValue_t Farm1StateOpen::handleBCSetVrCommand( ClcwIF* clcw, uint8_t vr ) {
myVC->farmBCounter++; myVC->farmBCounter++;
clcw->setRetransmitFlag(false); clcw->setRetransmitFlag(false);
myVC->vR = vr; myVC->vR = vr;
return BC_IS_SET_VR_COMMAND; return BC_IS_SET_VR_COMMAND;
} }

View File

@ -1,62 +1,62 @@
/** /**
* @file Farm1StateOpen.h * @file Farm1StateOpen.h
* @brief This file defines the Farm1StateOpen class. * @brief This file defines the Farm1StateOpen class.
* @date 24.04.2013 * @date 24.04.2013
* @author baetz * @author baetz
*/ */
#ifndef FARM1STATEOPEN_H_ #ifndef FARM1STATEOPEN_H_
#define FARM1STATEOPEN_H_ #define FARM1STATEOPEN_H_
#include <framework/datalinklayer/Farm1StateIF.h> #include "../datalinklayer/Farm1StateIF.h"
/** /**
* This class represents the FARM-1 "Open" State. * This class represents the FARM-1 "Open" State.
* The Open state is the state of normal operation. It handles all types of frames, * The Open state is the state of normal operation. It handles all types of frames,
* including AD Frames. If a wrong Frame Sequence Number is detected in an AD Frame, the * including AD Frames. If a wrong Frame Sequence Number is detected in an AD Frame, the
* State reacts as specified. * State reacts as specified.
*/ */
class Farm1StateOpen : public Farm1StateIF { class Farm1StateOpen : public Farm1StateIF {
private: private:
/** /**
* This is a reference to the "owner" class the State works on. * This is a reference to the "owner" class the State works on.
*/ */
VirtualChannelReception* myVC; VirtualChannelReception* myVC;
public: public:
/** /**
* The default constructor if the State. * The default constructor if the State.
* Sets the "owner" of the State. * Sets the "owner" of the State.
* @param setMyVC The "owner" class. * @param setMyVC The "owner" class.
*/ */
Farm1StateOpen( VirtualChannelReception* setMyVC ); Farm1StateOpen( VirtualChannelReception* setMyVC );
/** /**
* Method to check the validity of AD Frames. * Method to check the validity of AD Frames.
* It checks the Frame Sequence Number and reacts as specified in the standard. The state may * It checks the Frame Sequence Number and reacts as specified in the standard. The state may
* change to Farm1StateLockout. * change to Farm1StateLockout.
* @param frame The frame to handle. * @param frame The frame to handle.
* @param clcw Any changes to the CLCW shall be done with the help of this interface. * @param clcw Any changes to the CLCW shall be done with the help of this interface.
* @return If the Sequence Number is ok, it returns #RETURN_OK. Otherwise either #NS_POSITIVE_W, * @return If the Sequence Number is ok, it returns #RETURN_OK. Otherwise either #NS_POSITIVE_W,
* #NS_NEGATIVE_W or NS_LOCKOUT is returned. * #NS_NEGATIVE_W or NS_LOCKOUT is returned.
*/ */
ReturnValue_t handleADFrame( TcTransferFrame* frame, ClcwIF* clcw ); ReturnValue_t handleADFrame( TcTransferFrame* frame, ClcwIF* clcw );
/** /**
* These commands are handled as specified. * These commands are handled as specified.
* State does not change. * State does not change.
* @param clcw Any changes to the CLCW shall be done with the help of this interface. * @param clcw Any changes to the CLCW shall be done with the help of this interface.
* @return As the frame needs no forwarding to a MAP Channel, #BC_IS_UNLOCK_COMMAND * @return As the frame needs no forwarding to a MAP Channel, #BC_IS_UNLOCK_COMMAND
* is returned. * is returned.
*/ */
ReturnValue_t handleBCUnlockCommand( ClcwIF* clcw ); ReturnValue_t handleBCUnlockCommand( ClcwIF* clcw );
/** /**
* These commands are handled as specified. * These commands are handled as specified.
* State does not change. * State does not change.
* @param clcw Any changes to the CLCW shall be done with the help of this interface. * @param clcw Any changes to the CLCW shall be done with the help of this interface.
* @param vr The V(r) value found in the frame. * @param vr The V(r) value found in the frame.
* @return As the frame needs no forwarding to a MAP Channel, #BC_IS_SET_VR_COMMAND * @return As the frame needs no forwarding to a MAP Channel, #BC_IS_SET_VR_COMMAND
* is returned. * is returned.
*/ */
ReturnValue_t handleBCSetVrCommand( ClcwIF* clcw, uint8_t vr ); ReturnValue_t handleBCSetVrCommand( ClcwIF* clcw, uint8_t vr );
}; };
#endif /* FARM1STATEOPEN_H_ */ #endif /* FARM1STATEOPEN_H_ */

View File

@ -1,43 +1,43 @@
/** /**
* @file Farm1StateWait.cpp * @file Farm1StateWait.cpp
* @brief This file defines the Farm1StateWait class. * @brief This file defines the Farm1StateWait class.
* @date 24.04.2013 * @date 24.04.2013
* @author baetz * @author baetz
*/ */
#include <framework/datalinklayer/ClcwIF.h> #include "../datalinklayer/ClcwIF.h"
#include <framework/datalinklayer/Farm1StateWait.h> #include "../datalinklayer/Farm1StateWait.h"
#include <framework/datalinklayer/TcTransferFrame.h> #include "../datalinklayer/TcTransferFrame.h"
#include <framework/datalinklayer/VirtualChannelReception.h> #include "../datalinklayer/VirtualChannelReception.h"
Farm1StateWait::Farm1StateWait(VirtualChannelReception* setMyVC) : myVC(setMyVC) { Farm1StateWait::Farm1StateWait(VirtualChannelReception* setMyVC) : myVC(setMyVC) {
} }
ReturnValue_t Farm1StateWait::handleADFrame(TcTransferFrame* frame, ReturnValue_t Farm1StateWait::handleADFrame(TcTransferFrame* frame,
ClcwIF* clcw) { ClcwIF* clcw) {
int8_t diff = frame->getSequenceNumber() - myVC->vR; int8_t diff = frame->getSequenceNumber() - myVC->vR;
if ( diff < -myVC->negativeWindow || diff >= myVC->positiveWindow ) { if ( diff < -myVC->negativeWindow || diff >= myVC->positiveWindow ) {
clcw->setLockoutFlag(true); clcw->setLockoutFlag(true);
myVC->currentState = &(myVC->lockoutState); myVC->currentState = &(myVC->lockoutState);
} }
return FARM_IN_WAIT; return FARM_IN_WAIT;
} }
ReturnValue_t Farm1StateWait::handleBCUnlockCommand(ClcwIF* clcw) { ReturnValue_t Farm1StateWait::handleBCUnlockCommand(ClcwIF* clcw) {
myVC->farmBCounter++; myVC->farmBCounter++;
clcw->setRetransmitFlag(false); clcw->setRetransmitFlag(false);
clcw->setWaitFlag( false ); clcw->setWaitFlag( false );
myVC->currentState = &(myVC->openState); myVC->currentState = &(myVC->openState);
return BC_IS_UNLOCK_COMMAND; return BC_IS_UNLOCK_COMMAND;
} }
ReturnValue_t Farm1StateWait::handleBCSetVrCommand(ClcwIF* clcw, uint8_t vr) { ReturnValue_t Farm1StateWait::handleBCSetVrCommand(ClcwIF* clcw, uint8_t vr) {
myVC->farmBCounter++; myVC->farmBCounter++;
clcw->setWaitFlag( false ); clcw->setWaitFlag( false );
clcw->setRetransmitFlag(false); clcw->setRetransmitFlag(false);
myVC->vR = vr; myVC->vR = vr;
myVC->currentState = &(myVC->openState); myVC->currentState = &(myVC->openState);
return BC_IS_SET_VR_COMMAND; return BC_IS_SET_VR_COMMAND;
} }

View File

@ -1,58 +1,58 @@
/** /**
* @file Farm1StateWait.h * @file Farm1StateWait.h
* @brief This file defines the Farm1StateWait class. * @brief This file defines the Farm1StateWait class.
* @date 24.04.2013 * @date 24.04.2013
* @author baetz * @author baetz
*/ */
#ifndef FARM1STATEWAIT_H_ #ifndef FARM1STATEWAIT_H_
#define FARM1STATEWAIT_H_ #define FARM1STATEWAIT_H_
#include <framework/datalinklayer/Farm1StateIF.h> #include "../datalinklayer/Farm1StateIF.h"
/** /**
* This class represents the FARM-1 "Wait" State. * This class represents the FARM-1 "Wait" State.
* The Wait state is reached if higher level procedures inform the FARM-1 Machine to wait * The Wait state is reached if higher level procedures inform the FARM-1 Machine to wait
* for a certain period. Currently, it is not in use. * for a certain period. Currently, it is not in use.
*/ */
class Farm1StateWait : public Farm1StateIF { class Farm1StateWait : public Farm1StateIF {
private: private:
/** /**
* This is a reference to the "owner" class the State works on. * This is a reference to the "owner" class the State works on.
*/ */
VirtualChannelReception* myVC; VirtualChannelReception* myVC;
public: public:
/** /**
* The default constructor if the State. * The default constructor if the State.
* Sets the "owner" of the State. * Sets the "owner" of the State.
* @param setMyVC The "owner" class. * @param setMyVC The "owner" class.
*/ */
Farm1StateWait( VirtualChannelReception* setMyVC ); Farm1StateWait( VirtualChannelReception* setMyVC );
/** /**
* AD Frames are always discarded. * AD Frames are always discarded.
* If the frame number is in the lockout window, the state changes to Farm1StateLockout. * If the frame number is in the lockout window, the state changes to Farm1StateLockout.
* @param frame The frame to handle. * @param frame The frame to handle.
* @param clcw Any changes to the CLCW shall be done with the help of this interface. * @param clcw Any changes to the CLCW shall be done with the help of this interface.
* @return Always returns FARM_IN_WAIT. * @return Always returns FARM_IN_WAIT.
*/ */
ReturnValue_t handleADFrame( TcTransferFrame* frame, ClcwIF* clcw ); ReturnValue_t handleADFrame( TcTransferFrame* frame, ClcwIF* clcw );
/** /**
* These commands are handled as specified. * These commands are handled as specified.
* State changes to Farm1StateOpen. * State changes to Farm1StateOpen.
* @param clcw Any changes to the CLCW shall be done with the help of this interface. * @param clcw Any changes to the CLCW shall be done with the help of this interface.
* @return As the frame needs no forwarding to a MAP Channel, #BC_IS_UNLOCK_COMMAND * @return As the frame needs no forwarding to a MAP Channel, #BC_IS_UNLOCK_COMMAND
* is returned. * is returned.
*/ */
ReturnValue_t handleBCUnlockCommand( ClcwIF* clcw ); ReturnValue_t handleBCUnlockCommand( ClcwIF* clcw );
/** /**
* These commands are handled as specified. * These commands are handled as specified.
* @param clcw Any changes to the CLCW shall be done with the help of this interface. * @param clcw Any changes to the CLCW shall be done with the help of this interface.
* @param vr The V(r) value found in the frame. * @param vr The V(r) value found in the frame.
* @return As the frame needs no forwarding to a MAP Channel, #BC_IS_SET_VR_COMMAND * @return As the frame needs no forwarding to a MAP Channel, #BC_IS_SET_VR_COMMAND
* is returned. * is returned.
*/ */
ReturnValue_t handleBCSetVrCommand( ClcwIF* clcw, uint8_t vr ); ReturnValue_t handleBCSetVrCommand( ClcwIF* clcw, uint8_t vr );
}; };
#endif /* FARM1STATEWAIT_H_ */ #endif /* FARM1STATEWAIT_H_ */

View File

@ -1,154 +1,154 @@
/** /**
* @file MapPacketExtraction.cpp * @file MapPacketExtraction.cpp
* @brief This file defines the MapPacketExtraction class. * @brief This file defines the MapPacketExtraction class.
* @date 26.03.2013 * @date 26.03.2013
* @author baetz * @author baetz
*/ */
#include <framework/datalinklayer/MapPacketExtraction.h> #include "../datalinklayer/MapPacketExtraction.h"
#include <framework/ipc/QueueFactory.h> #include "../ipc/QueueFactory.h"
#include <framework/serviceinterface/ServiceInterfaceStream.h> #include "../serviceinterface/ServiceInterfaceStream.h"
#include <framework/storagemanager/StorageManagerIF.h> #include "../storagemanager/StorageManagerIF.h"
#include <framework/tmtcpacket/SpacePacketBase.h> #include "../tmtcpacket/SpacePacketBase.h"
#include <framework/tmtcservices/AcceptsTelecommandsIF.h> #include "../tmtcservices/AcceptsTelecommandsIF.h"
#include <framework/tmtcservices/TmTcMessage.h> #include "../tmtcservices/TmTcMessage.h"
#include <string.h> #include <string.h>
MapPacketExtraction::MapPacketExtraction(uint8_t setMapId, MapPacketExtraction::MapPacketExtraction(uint8_t setMapId,
object_id_t setPacketDestination) : object_id_t setPacketDestination) :
lastSegmentationFlag(NO_SEGMENTATION), mapId(setMapId), packetLength(0), lastSegmentationFlag(NO_SEGMENTATION), mapId(setMapId), packetLength(0),
bufferPosition(packetBuffer), packetDestination(setPacketDestination), bufferPosition(packetBuffer), packetDestination(setPacketDestination),
packetStore(nullptr), tcQueueId(MessageQueueMessageIF::NO_QUEUE) { packetStore(nullptr), tcQueueId(MessageQueueMessageIF::NO_QUEUE) {
memset(packetBuffer, 0, sizeof(packetBuffer)); memset(packetBuffer, 0, sizeof(packetBuffer));
} }
ReturnValue_t MapPacketExtraction::extractPackets(TcTransferFrame* frame) { ReturnValue_t MapPacketExtraction::extractPackets(TcTransferFrame* frame) {
uint8_t segmentationFlag = frame->getSequenceFlags(); uint8_t segmentationFlag = frame->getSequenceFlags();
ReturnValue_t status = TOO_SHORT_MAP_EXTRACTION; ReturnValue_t status = TOO_SHORT_MAP_EXTRACTION;
switch (segmentationFlag) { switch (segmentationFlag) {
case NO_SEGMENTATION: case NO_SEGMENTATION:
status = unpackBlockingPackets(frame); status = unpackBlockingPackets(frame);
break; break;
case FIRST_PORTION: case FIRST_PORTION:
packetLength = frame->getDataLength(); packetLength = frame->getDataLength();
if (packetLength <= MAX_PACKET_SIZE) { if (packetLength <= MAX_PACKET_SIZE) {
memcpy(packetBuffer, frame->getDataField(), packetLength); memcpy(packetBuffer, frame->getDataField(), packetLength);
bufferPosition = &packetBuffer[packetLength]; bufferPosition = &packetBuffer[packetLength];
status = RETURN_OK; status = RETURN_OK;
} else { } else {
sif::error sif::error
<< "MapPacketExtraction::extractPackets. Packet too large! Size: " << "MapPacketExtraction::extractPackets. Packet too large! Size: "
<< packetLength << std::endl; << packetLength << std::endl;
clearBuffers(); clearBuffers();
status = CONTENT_TOO_LARGE; status = CONTENT_TOO_LARGE;
} }
break; break;
case CONTINUING_PORTION: case CONTINUING_PORTION:
case LAST_PORTION: case LAST_PORTION:
if (lastSegmentationFlag == FIRST_PORTION if (lastSegmentationFlag == FIRST_PORTION
|| lastSegmentationFlag == CONTINUING_PORTION) { || lastSegmentationFlag == CONTINUING_PORTION) {
packetLength += frame->getDataLength(); packetLength += frame->getDataLength();
if (packetLength <= MAX_PACKET_SIZE) { if (packetLength <= MAX_PACKET_SIZE) {
memcpy(bufferPosition, frame->getDataField(), memcpy(bufferPosition, frame->getDataField(),
frame->getDataLength()); frame->getDataLength());
bufferPosition = &packetBuffer[packetLength]; bufferPosition = &packetBuffer[packetLength];
if (segmentationFlag == LAST_PORTION) { if (segmentationFlag == LAST_PORTION) {
status = sendCompletePacket(packetBuffer, packetLength); status = sendCompletePacket(packetBuffer, packetLength);
clearBuffers(); clearBuffers();
} }
status = RETURN_OK; status = RETURN_OK;
} else { } else {
sif::error sif::error
<< "MapPacketExtraction::extractPackets. Packet too large! Size: " << "MapPacketExtraction::extractPackets. Packet too large! Size: "
<< packetLength << std::endl; << packetLength << std::endl;
clearBuffers(); clearBuffers();
status = CONTENT_TOO_LARGE; status = CONTENT_TOO_LARGE;
} }
} else { } else {
sif::error sif::error
<< "MapPacketExtraction::extractPackets. Illegal segment! Last flag: " << "MapPacketExtraction::extractPackets. Illegal segment! Last flag: "
<< (int) lastSegmentationFlag << std::endl; << (int) lastSegmentationFlag << std::endl;
clearBuffers(); clearBuffers();
status = ILLEGAL_SEGMENTATION_FLAG; status = ILLEGAL_SEGMENTATION_FLAG;
} }
break; break;
default: default:
sif::error sif::error
<< "MapPacketExtraction::extractPackets. Illegal segmentationFlag: " << "MapPacketExtraction::extractPackets. Illegal segmentationFlag: "
<< (int) segmentationFlag << std::endl; << (int) segmentationFlag << std::endl;
clearBuffers(); clearBuffers();
status = DATA_CORRUPTED; status = DATA_CORRUPTED;
break; break;
} }
lastSegmentationFlag = segmentationFlag; lastSegmentationFlag = segmentationFlag;
return status; return status;
} }
ReturnValue_t MapPacketExtraction::unpackBlockingPackets( ReturnValue_t MapPacketExtraction::unpackBlockingPackets(
TcTransferFrame* frame) { TcTransferFrame* frame) {
ReturnValue_t status = TOO_SHORT_BLOCKED_PACKET; ReturnValue_t status = TOO_SHORT_BLOCKED_PACKET;
uint32_t totalLength = frame->getDataLength(); uint32_t totalLength = frame->getDataLength();
if (totalLength > MAX_PACKET_SIZE) if (totalLength > MAX_PACKET_SIZE)
return CONTENT_TOO_LARGE; return CONTENT_TOO_LARGE;
uint8_t* position = frame->getDataField(); uint8_t* position = frame->getDataField();
while ((totalLength > SpacePacketBase::MINIMUM_SIZE)) { while ((totalLength > SpacePacketBase::MINIMUM_SIZE)) {
SpacePacketBase packet(position); SpacePacketBase packet(position);
uint32_t packetSize = packet.getFullSize(); uint32_t packetSize = packet.getFullSize();
if (packetSize <= totalLength) { if (packetSize <= totalLength) {
status = sendCompletePacket(packet.getWholeData(), status = sendCompletePacket(packet.getWholeData(),
packet.getFullSize()); packet.getFullSize());
totalLength -= packet.getFullSize(); totalLength -= packet.getFullSize();
position += packet.getFullSize(); position += packet.getFullSize();
status = RETURN_OK; status = RETURN_OK;
} else { } else {
status = DATA_CORRUPTED; status = DATA_CORRUPTED;
totalLength = 0; totalLength = 0;
} }
} }
if (totalLength > 0) { if (totalLength > 0) {
status = RESIDUAL_DATA; status = RESIDUAL_DATA;
} }
return status; return status;
} }
ReturnValue_t MapPacketExtraction::sendCompletePacket(uint8_t* data, ReturnValue_t MapPacketExtraction::sendCompletePacket(uint8_t* data,
uint32_t size) { uint32_t size) {
store_address_t store_id; store_address_t store_id;
ReturnValue_t status = this->packetStore->addData(&store_id, data, size); ReturnValue_t status = this->packetStore->addData(&store_id, data, size);
if (status == RETURN_OK) { if (status == RETURN_OK) {
TmTcMessage message(store_id); TmTcMessage message(store_id);
status = MessageQueueSenderIF::sendMessage(tcQueueId,&message); status = MessageQueueSenderIF::sendMessage(tcQueueId,&message);
} }
return status; return status;
} }
void MapPacketExtraction::clearBuffers() { void MapPacketExtraction::clearBuffers() {
memset(packetBuffer, 0, sizeof(packetBuffer)); memset(packetBuffer, 0, sizeof(packetBuffer));
bufferPosition = packetBuffer; bufferPosition = packetBuffer;
packetLength = 0; packetLength = 0;
lastSegmentationFlag = NO_SEGMENTATION; lastSegmentationFlag = NO_SEGMENTATION;
} }
ReturnValue_t MapPacketExtraction::initialize() { ReturnValue_t MapPacketExtraction::initialize() {
packetStore = objectManager->get<StorageManagerIF>(objects::TC_STORE); packetStore = objectManager->get<StorageManagerIF>(objects::TC_STORE);
AcceptsTelecommandsIF* distributor = objectManager->get< AcceptsTelecommandsIF* distributor = objectManager->get<
AcceptsTelecommandsIF>(packetDestination); AcceptsTelecommandsIF>(packetDestination);
if ((packetStore != NULL) && (distributor != NULL)) { if ((packetStore != NULL) && (distributor != NULL)) {
tcQueueId = distributor->getRequestQueue(); tcQueueId = distributor->getRequestQueue();
return RETURN_OK; return RETURN_OK;
} else { } else {
return RETURN_FAILED; return RETURN_FAILED;
} }
} }
void MapPacketExtraction::printPacketBuffer(void) { void MapPacketExtraction::printPacketBuffer(void) {
sif::debug << "DLL: packet_buffer contains: " << std::endl; sif::debug << "DLL: packet_buffer contains: " << std::endl;
for (uint32_t i = 0; i < this->packetLength; ++i) { for (uint32_t i = 0; i < this->packetLength; ++i) {
sif::debug << "packet_buffer[" << std::dec << i << "]: 0x" << std::hex sif::debug << "packet_buffer[" << std::dec << i << "]: 0x" << std::hex
<< (uint16_t) this->packetBuffer[i] << std::endl; << (uint16_t) this->packetBuffer[i] << std::endl;
} }
} }
uint8_t MapPacketExtraction::getMapId() const { uint8_t MapPacketExtraction::getMapId() const {
return mapId; return mapId;
} }

View File

@ -1,78 +1,78 @@
/** /**
* @file MapPacketExtraction.h * @file MapPacketExtraction.h
* @brief This file defines the MapPacketExtraction class. * @brief This file defines the MapPacketExtraction class.
* @date 26.03.2013 * @date 26.03.2013
* @author baetz * @author baetz
*/ */
#ifndef MAPPACKETEXTRACTION_H_ #ifndef MAPPACKETEXTRACTION_H_
#define MAPPACKETEXTRACTION_H_ #define MAPPACKETEXTRACTION_H_
#include <framework/datalinklayer/MapPacketExtractionIF.h> #include "../datalinklayer/MapPacketExtractionIF.h"
#include <framework/objectmanager/ObjectManagerIF.h> #include "../objectmanager/ObjectManagerIF.h"
#include <framework/returnvalues/HasReturnvaluesIF.h> #include "../returnvalues/HasReturnvaluesIF.h"
#include <framework/ipc/MessageQueueSenderIF.h> #include "../ipc/MessageQueueSenderIF.h"
class StorageManagerIF; class StorageManagerIF;
/** /**
* Implementation of a MAP Packet Extraction class. * Implementation of a MAP Packet Extraction class.
* The class implements the full MAP Packet Extraction functionality as described in the CCSDS * The class implements the full MAP Packet Extraction functionality as described in the CCSDS
* TC Space Data Link Protocol. It internally stores incomplete segmented packets until they are * TC Space Data Link Protocol. It internally stores incomplete segmented packets until they are
* fully received. All found packets are forwarded to a single distribution entity. * fully received. All found packets are forwarded to a single distribution entity.
*/ */
class MapPacketExtraction: public MapPacketExtractionIF { class MapPacketExtraction: public MapPacketExtractionIF {
private: private:
static const uint32_t MAX_PACKET_SIZE = 4096; static const uint32_t MAX_PACKET_SIZE = 4096;
uint8_t lastSegmentationFlag; //!< The segmentation flag of the last received frame. uint8_t lastSegmentationFlag; //!< The segmentation flag of the last received frame.
uint8_t mapId; //!< MAP ID of this MAP Channel. uint8_t mapId; //!< MAP ID of this MAP Channel.
uint32_t packetLength; //!< Complete length of the current Space Packet. uint32_t packetLength; //!< Complete length of the current Space Packet.
uint8_t* bufferPosition; //!< Position to write to in the internal Packet buffer. uint8_t* bufferPosition; //!< Position to write to in the internal Packet buffer.
uint8_t packetBuffer[MAX_PACKET_SIZE]; //!< The internal Space Packet Buffer. uint8_t packetBuffer[MAX_PACKET_SIZE]; //!< The internal Space Packet Buffer.
object_id_t packetDestination; object_id_t packetDestination;
StorageManagerIF* packetStore; //!< Pointer to the store where full TC packets are stored. StorageManagerIF* packetStore; //!< Pointer to the store where full TC packets are stored.
MessageQueueId_t tcQueueId; //!< QueueId to send found packets to the distributor. MessageQueueId_t tcQueueId; //!< QueueId to send found packets to the distributor.
/** /**
* Debug method to print the packet Buffer's content. * Debug method to print the packet Buffer's content.
*/ */
void printPacketBuffer(); void printPacketBuffer();
/** /**
* Method that is called if the segmentation flag is @c NO_SEGMENTATION. * Method that is called if the segmentation flag is @c NO_SEGMENTATION.
* The method extracts one or more packets within the frame and forwards them to the OBSW. * The method extracts one or more packets within the frame and forwards them to the OBSW.
* @param frame The TC Transfer Frame to work on. * @param frame The TC Transfer Frame to work on.
* @return @c RETURN_OK if all Packets were extracted. If something is entirely wrong, * @return @c RETURN_OK if all Packets were extracted. If something is entirely wrong,
* @c DATA_CORRUPTED is returned, if some bytes are left over @c RESIDUAL_DATA. * @c DATA_CORRUPTED is returned, if some bytes are left over @c RESIDUAL_DATA.
*/ */
ReturnValue_t unpackBlockingPackets(TcTransferFrame* frame); ReturnValue_t unpackBlockingPackets(TcTransferFrame* frame);
/** /**
* Helper method to forward a complete packet to the OBSW. * Helper method to forward a complete packet to the OBSW.
* @param data Pointer to the data, either directly from the frame or from the packetBuffer. * @param data Pointer to the data, either directly from the frame or from the packetBuffer.
* @param size Complete total size of the packet. * @param size Complete total size of the packet.
* @return Return Code of the Packet Store or the Message Queue. * @return Return Code of the Packet Store or the Message Queue.
*/ */
ReturnValue_t sendCompletePacket( uint8_t* data, uint32_t size ); ReturnValue_t sendCompletePacket( uint8_t* data, uint32_t size );
/** /**
* Helper method to reset the internal buffer. * Helper method to reset the internal buffer.
*/ */
void clearBuffers(); void clearBuffers();
public: public:
/** /**
* Default constructor. * Default constructor.
* Members are set to default values. * Members are set to default values.
* @param setMapId The MAP ID of the instance. * @param setMapId The MAP ID of the instance.
*/ */
MapPacketExtraction( uint8_t setMapId, object_id_t setPacketDestination ); MapPacketExtraction( uint8_t setMapId, object_id_t setPacketDestination );
ReturnValue_t extractPackets(TcTransferFrame* frame); ReturnValue_t extractPackets(TcTransferFrame* frame);
/** /**
* The #packetStore and the default destination of #tcQueue are initialized here. * The #packetStore and the default destination of #tcQueue are initialized here.
* @return @c RETURN_OK on success, @c RETURN_FAILED otherwise. * @return @c RETURN_OK on success, @c RETURN_FAILED otherwise.
*/ */
ReturnValue_t initialize(); ReturnValue_t initialize();
/** /**
* Getter. * Getter.
* @return The MAP ID of this instance. * @return The MAP ID of this instance.
*/ */
uint8_t getMapId() const; uint8_t getMapId() const;
}; };
#endif /* MAPPACKETEXTRACTION_H_ */ #endif /* MAPPACKETEXTRACTION_H_ */

View File

@ -1,47 +1,47 @@
/** /**
* @file MapPacketExtractionIF.h * @file MapPacketExtractionIF.h
* @brief This file defines the MapPacketExtractionIF class. * @brief This file defines the MapPacketExtractionIF class.
* @date 25.03.2013 * @date 25.03.2013
* @author baetz * @author baetz
*/ */
#ifndef MAPPACKETEXTRACTIONIF_H_ #ifndef MAPPACKETEXTRACTIONIF_H_
#define MAPPACKETEXTRACTIONIF_H_ #define MAPPACKETEXTRACTIONIF_H_
#include <framework/datalinklayer/CCSDSReturnValuesIF.h> #include "../datalinklayer/CCSDSReturnValuesIF.h"
#include <framework/datalinklayer/TcTransferFrame.h> #include "../datalinklayer/TcTransferFrame.h"
/** /**
* This is the interface for MAP Packet Extraction classes. * This is the interface for MAP Packet Extraction classes.
* All classes implementing this interface shall be able to extract blocked or segmented Space * All classes implementing this interface shall be able to extract blocked or segmented Space
* Packets on a certain MAP channel. This is done in accordance with the CCSDS TC Space Data Link * Packets on a certain MAP channel. This is done in accordance with the CCSDS TC Space Data Link
* Protocol. * Protocol.
*/ */
class MapPacketExtractionIF : public CCSDSReturnValuesIF { class MapPacketExtractionIF : public CCSDSReturnValuesIF {
protected: protected:
static const uint8_t FIRST_PORTION = 0b01; //!< Identification of the first part of a segmented Packet. static const uint8_t FIRST_PORTION = 0b01; //!< Identification of the first part of a segmented Packet.
static const uint8_t CONTINUING_PORTION = 0b00; //!< Identification of a continuing part of segmented Packets. static const uint8_t CONTINUING_PORTION = 0b00; //!< Identification of a continuing part of segmented Packets.
static const uint8_t LAST_PORTION = 0b10; //!< The last portion of a segmented Packet. static const uint8_t LAST_PORTION = 0b10; //!< The last portion of a segmented Packet.
static const uint8_t NO_SEGMENTATION = 0b11; //!< A Frame without segmentation but maybe with blocking. static const uint8_t NO_SEGMENTATION = 0b11; //!< A Frame without segmentation but maybe with blocking.
public: public:
/** /**
* Empty virtual destructor. * Empty virtual destructor.
*/ */
virtual ~MapPacketExtractionIF() { virtual ~MapPacketExtractionIF() {
} }
/** /**
* Method to call to handle a single Transfer Frame. * Method to call to handle a single Transfer Frame.
* The method tries to extract Packets from the frame as stated in the Standard. * The method tries to extract Packets from the frame as stated in the Standard.
* @param frame * @param frame
* @return * @return
*/ */
virtual ReturnValue_t extractPackets( TcTransferFrame* frame ) = 0; virtual ReturnValue_t extractPackets( TcTransferFrame* frame ) = 0;
/** /**
* Any post-instantiation initialization shall be done in this method. * Any post-instantiation initialization shall be done in this method.
* @return * @return
*/ */
virtual ReturnValue_t initialize() = 0; virtual ReturnValue_t initialize() = 0;
}; };
#endif /* MAPPACKETEXTRACTIONIF_H_ */ #endif /* MAPPACKETEXTRACTIONIF_H_ */

View File

@ -1,102 +1,102 @@
/** /**
* @file TcTransferFrame.cpp * @file TcTransferFrame.cpp
* @brief This file defines the TcTransferFrame class. * @brief This file defines the TcTransferFrame class.
* @date 27.04.2013 * @date 27.04.2013
* @author baetz * @author baetz
*/ */
#include <framework/datalinklayer/TcTransferFrame.h> #include "../datalinklayer/TcTransferFrame.h"
#include <framework/serviceinterface/ServiceInterfaceStream.h> #include "../serviceinterface/ServiceInterfaceStream.h"
TcTransferFrame::TcTransferFrame() { TcTransferFrame::TcTransferFrame() {
frame = NULL; frame = NULL;
} }
TcTransferFrame::TcTransferFrame(uint8_t* setData) { TcTransferFrame::TcTransferFrame(uint8_t* setData) {
this->frame = (tc_transfer_frame*)setData; this->frame = (tc_transfer_frame*)setData;
} }
uint8_t TcTransferFrame::getVersionNumber() { uint8_t TcTransferFrame::getVersionNumber() {
return (this->frame->header.flagsAndScid & 0b11000000) >> 6; return (this->frame->header.flagsAndScid & 0b11000000) >> 6;
} }
bool TcTransferFrame::bypassFlagSet() { bool TcTransferFrame::bypassFlagSet() {
return (this->frame->header.flagsAndScid & 0b00100000) != 0; return (this->frame->header.flagsAndScid & 0b00100000) != 0;
} }
bool TcTransferFrame::controlCommandFlagSet() { bool TcTransferFrame::controlCommandFlagSet() {
return (this->frame->header.flagsAndScid & 0b00010000) != 0; return (this->frame->header.flagsAndScid & 0b00010000) != 0;
} }
bool TcTransferFrame::spareIsZero() { bool TcTransferFrame::spareIsZero() {
return ( (this->frame->header.flagsAndScid & 0b00001100) == 0 ); return ( (this->frame->header.flagsAndScid & 0b00001100) == 0 );
} }
uint16_t TcTransferFrame::getSpacecraftId() { uint16_t TcTransferFrame::getSpacecraftId() {
return ( (this->frame->header.flagsAndScid & 0b00000011) << 8 ) + this->frame->header.spacecraftId_l; return ( (this->frame->header.flagsAndScid & 0b00000011) << 8 ) + this->frame->header.spacecraftId_l;
} }
uint8_t TcTransferFrame::getVirtualChannelId() { uint8_t TcTransferFrame::getVirtualChannelId() {
return (this->frame->header.vcidAndLength_h & 0b11111100) >> 2; return (this->frame->header.vcidAndLength_h & 0b11111100) >> 2;
} }
uint16_t TcTransferFrame::getFrameLength() { uint16_t TcTransferFrame::getFrameLength() {
return ( (this->frame->header.vcidAndLength_h & 0b00000011) << 8 ) + this->frame->header.length_l; return ( (this->frame->header.vcidAndLength_h & 0b00000011) << 8 ) + this->frame->header.length_l;
} }
uint16_t TcTransferFrame::getDataLength() { uint16_t TcTransferFrame::getDataLength() {
return this->getFrameLength() - this->getHeaderSize() -1 - FRAME_CRC_SIZE + 1; // -1 for the segment header. return this->getFrameLength() - this->getHeaderSize() -1 - FRAME_CRC_SIZE + 1; // -1 for the segment header.
} }
uint8_t TcTransferFrame::getSequenceNumber() { uint8_t TcTransferFrame::getSequenceNumber() {
return this->frame->header.sequenceNumber; return this->frame->header.sequenceNumber;
} }
uint8_t TcTransferFrame::getSequenceFlags() { uint8_t TcTransferFrame::getSequenceFlags() {
return (this->frame->dataField & 0b11000000)>>6; return (this->frame->dataField & 0b11000000)>>6;
} }
uint8_t TcTransferFrame::getMAPId() { uint8_t TcTransferFrame::getMAPId() {
return this->frame->dataField & 0b00111111; return this->frame->dataField & 0b00111111;
} }
uint8_t* TcTransferFrame::getDataField() { uint8_t* TcTransferFrame::getDataField() {
return &(this->frame->dataField) + 1; return &(this->frame->dataField) + 1;
} }
uint8_t* TcTransferFrame::getFullFrame() { uint8_t* TcTransferFrame::getFullFrame() {
return (uint8_t*)this->frame; return (uint8_t*)this->frame;
} }
uint16_t TcTransferFrame::getFullSize() { uint16_t TcTransferFrame::getFullSize() {
return this->getFrameLength() + 1; return this->getFrameLength() + 1;
} }
uint16_t TcTransferFrame::getHeaderSize() { uint16_t TcTransferFrame::getHeaderSize() {
return sizeof(frame->header); return sizeof(frame->header);
} }
uint16_t TcTransferFrame::getFullDataLength() { uint16_t TcTransferFrame::getFullDataLength() {
return this->getFrameLength() - this->getHeaderSize() - FRAME_CRC_SIZE + 1; return this->getFrameLength() - this->getHeaderSize() - FRAME_CRC_SIZE + 1;
} }
uint8_t* TcTransferFrame::getFullDataField() { uint8_t* TcTransferFrame::getFullDataField() {
return &frame->dataField; return &frame->dataField;
} }
void TcTransferFrame::print() { void TcTransferFrame::print() {
sif::debug << "Raw Frame: " << std::hex << std::endl; sif::debug << "Raw Frame: " << std::hex << std::endl;
for (uint16_t count = 0; count < this->getFullSize(); count++ ) { for (uint16_t count = 0; count < this->getFullSize(); count++ ) {
sif::debug << (uint16_t)this->getFullFrame()[count] << " "; sif::debug << (uint16_t)this->getFullFrame()[count] << " ";
} }
sif::debug << std::dec << std::endl; sif::debug << std::dec << std::endl;
// debug << "Frame Header:" << std::endl; // debug << "Frame Header:" << std::endl;
// debug << "Version Number: " << std::hex << (uint16_t)this->current_frame.getVersionNumber() << std::endl; // debug << "Version Number: " << std::hex << (uint16_t)this->current_frame.getVersionNumber() << std::endl;
// debug << "Bypass Flag set?| Ctrl Cmd Flag set?: " << (uint16_t)this->current_frame.bypassFlagSet() << " | " << (uint16_t)this->current_frame.controlCommandFlagSet() << std::endl; // debug << "Bypass Flag set?| Ctrl Cmd Flag set?: " << (uint16_t)this->current_frame.bypassFlagSet() << " | " << (uint16_t)this->current_frame.controlCommandFlagSet() << std::endl;
// debug << "SCID : " << this->current_frame.getSpacecraftId() << std::endl; // debug << "SCID : " << this->current_frame.getSpacecraftId() << std::endl;
// debug << "VCID : " << (uint16_t)this->current_frame.getVirtualChannelId() << std::endl; // debug << "VCID : " << (uint16_t)this->current_frame.getVirtualChannelId() << std::endl;
// debug << "Frame length: " << std::dec << this->current_frame.getFrameLength() << std::endl; // debug << "Frame length: " << std::dec << this->current_frame.getFrameLength() << std::endl;
// debug << "Sequence Number: " << (uint16_t)this->current_frame.getSequenceNumber() << std::endl; // debug << "Sequence Number: " << (uint16_t)this->current_frame.getSequenceNumber() << std::endl;
} }

View File

@ -1,49 +1,49 @@
/** /**
* @file TcTransferFrameLocal.cpp * @file TcTransferFrameLocal.cpp
* @brief This file defines the TcTransferFrameLocal class. * @brief This file defines the TcTransferFrameLocal class.
* @date 27.04.2013 * @date 27.04.2013
* @author baetz * @author baetz
*/ */
#include <framework/datalinklayer/TcTransferFrameLocal.h> #include "../datalinklayer/TcTransferFrameLocal.h"
#include <framework/globalfunctions/CRC.h> #include "../globalfunctions/CRC.h"
#include <framework/serviceinterface/ServiceInterfaceStream.h> #include "../serviceinterface/ServiceInterfaceStream.h"
#include <string.h> #include <string.h>
TcTransferFrameLocal::TcTransferFrameLocal(bool bypass, bool controlCommand, uint16_t scid, TcTransferFrameLocal::TcTransferFrameLocal(bool bypass, bool controlCommand, uint16_t scid,
uint8_t vcId, uint8_t sequenceNumber, uint8_t setSegmentHeader, uint8_t* data, uint16_t dataSize, uint16_t forceCrc) { uint8_t vcId, uint8_t sequenceNumber, uint8_t setSegmentHeader, uint8_t* data, uint16_t dataSize, uint16_t forceCrc) {
this->frame = (tc_transfer_frame*)&localData; this->frame = (tc_transfer_frame*)&localData;
frame->header.flagsAndScid = (bypass << 5) + (controlCommand << 4) + ((scid & 0x0300) >> 8); frame->header.flagsAndScid = (bypass << 5) + (controlCommand << 4) + ((scid & 0x0300) >> 8);
frame->header.spacecraftId_l = (scid & 0x00FF); frame->header.spacecraftId_l = (scid & 0x00FF);
frame->header.vcidAndLength_h = (vcId & 0b00111111) << 2; frame->header.vcidAndLength_h = (vcId & 0b00111111) << 2;
frame->header.length_l = sizeof(TcTransferFramePrimaryHeader) -1; frame->header.length_l = sizeof(TcTransferFramePrimaryHeader) -1;
frame->header.sequenceNumber = sequenceNumber; frame->header.sequenceNumber = sequenceNumber;
frame->dataField = setSegmentHeader; frame->dataField = setSegmentHeader;
if (data != NULL) { if (data != NULL) {
if (bypass && controlCommand) { if (bypass && controlCommand) {
memcpy(&(frame->dataField), data, dataSize); memcpy(&(frame->dataField), data, dataSize);
uint16_t totalSize = sizeof(TcTransferFramePrimaryHeader) + dataSize + FRAME_CRC_SIZE -1; uint16_t totalSize = sizeof(TcTransferFramePrimaryHeader) + dataSize + FRAME_CRC_SIZE -1;
frame->header.vcidAndLength_h |= (totalSize & 0x0300) >> 8; frame->header.vcidAndLength_h |= (totalSize & 0x0300) >> 8;
frame->header.length_l = (totalSize & 0x00FF); frame->header.length_l = (totalSize & 0x00FF);
uint16_t crc = CRC::crc16ccitt(getFullFrame(), getFullSize() -2); uint16_t crc = CRC::crc16ccitt(getFullFrame(), getFullSize() -2);
this->getFullFrame()[getFullSize()-2] = (crc & 0xFF00) >> 8; this->getFullFrame()[getFullSize()-2] = (crc & 0xFF00) >> 8;
this->getFullFrame()[getFullSize()-1] = (crc & 0x00FF); this->getFullFrame()[getFullSize()-1] = (crc & 0x00FF);
} else if (dataSize <= 1016) { } else if (dataSize <= 1016) {
memcpy(&(frame->dataField) +1, data, dataSize); memcpy(&(frame->dataField) +1, data, dataSize);
uint16_t dataCrcSize = sizeof(TcTransferFramePrimaryHeader) + 1 + dataSize + FRAME_CRC_SIZE -1; uint16_t dataCrcSize = sizeof(TcTransferFramePrimaryHeader) + 1 + dataSize + FRAME_CRC_SIZE -1;
frame->header.vcidAndLength_h |= (dataCrcSize & 0x0300) >> 8; frame->header.vcidAndLength_h |= (dataCrcSize & 0x0300) >> 8;
frame->header.length_l = (dataCrcSize & 0x00FF); frame->header.length_l = (dataCrcSize & 0x00FF);
uint16_t crc = CRC::crc16ccitt(getFullFrame(), getFullSize() -2); uint16_t crc = CRC::crc16ccitt(getFullFrame(), getFullSize() -2);
this->getFullFrame()[getFullSize()-2] = (crc & 0xFF00) >> 8; this->getFullFrame()[getFullSize()-2] = (crc & 0xFF00) >> 8;
this->getFullFrame()[getFullSize()-1] = (crc & 0x00FF); this->getFullFrame()[getFullSize()-1] = (crc & 0x00FF);
} else { } else {
sif::debug << "TcTransferFrameLocal: dataSize too large: " << dataSize << std::endl; sif::debug << "TcTransferFrameLocal: dataSize too large: " << dataSize << std::endl;
} }
} else { } else {
//No data in frame //No data in frame
} }
if (forceCrc != 0 ) { if (forceCrc != 0 ) {
localData.data[getFullSize()-2] = (forceCrc & 0xFF00) >> 8; localData.data[getFullSize()-2] = (forceCrc & 0xFF00) >> 8;
localData.data[getFullSize()-1] = (forceCrc & 0x00FF); localData.data[getFullSize()-1] = (forceCrc & 0x00FF);
} }
} }

View File

@ -1,49 +1,49 @@
/** /**
* @file TcTransferFrameLocal.h * @file TcTransferFrameLocal.h
* @brief This file defines the TcTransferFrameLocal class. * @brief This file defines the TcTransferFrameLocal class.
* @date 27.04.2013 * @date 27.04.2013
* @author baetz * @author baetz
*/ */
#ifndef TCTRANSFERFRAMELOCAL_H_ #ifndef TCTRANSFERFRAMELOCAL_H_
#define TCTRANSFERFRAMELOCAL_H_ #define TCTRANSFERFRAMELOCAL_H_
#include <framework/datalinklayer/TcTransferFrame.h> #include "../datalinklayer/TcTransferFrame.h"
/** /**
* This is a helper class to locally create TC Transfer Frames. * This is a helper class to locally create TC Transfer Frames.
* This is mainly required for testing purposes and therefore not very sophisticated. * This is mainly required for testing purposes and therefore not very sophisticated.
* @ingroup ccsds_handling * @ingroup ccsds_handling
*/ */
class TcTransferFrameLocal : public TcTransferFrame { class TcTransferFrameLocal : public TcTransferFrame {
private: private:
/** /**
* A stuct to locally store the complete data. * A stuct to locally store the complete data.
*/ */
struct frameData { struct frameData {
TcTransferFramePrimaryHeader header; //!< The primary header. TcTransferFramePrimaryHeader header; //!< The primary header.
uint8_t data[1019]; //!< The data field. uint8_t data[1019]; //!< The data field.
}; };
public: public:
frameData localData; //!< The local data in the Frame. frameData localData; //!< The local data in the Frame.
/** /**
* The default Constructor. * The default Constructor.
* All parameters in the Header are passed. * All parameters in the Header are passed.
* If a BC Frame is detected no segment header is created. * If a BC Frame is detected no segment header is created.
* Otherwise (AD and BD), the Segment Header is set. * Otherwise (AD and BD), the Segment Header is set.
* @param bypass The bypass flag. * @param bypass The bypass flag.
* @param controlCommand The Control Command flag. * @param controlCommand The Control Command flag.
* @param scid The SCID. * @param scid The SCID.
* @param vcId The VCID. * @param vcId The VCID.
* @param sequenceNumber The Frame Sequence Number N(s) * @param sequenceNumber The Frame Sequence Number N(s)
* @param setSegmentHeader A value for the Segment Header. * @param setSegmentHeader A value for the Segment Header.
* @param data Data to put into the Frame Data Field. * @param data Data to put into the Frame Data Field.
* @param dataSize Size of the Data. * @param dataSize Size of the Data.
* @param forceCrc if != 0, the value is used as CRC. * @param forceCrc if != 0, the value is used as CRC.
*/ */
TcTransferFrameLocal(bool bypass, bool controlCommand, uint16_t scid, uint8_t vcId, uint8_t sequenceNumber, TcTransferFrameLocal(bool bypass, bool controlCommand, uint16_t scid, uint8_t vcId, uint8_t sequenceNumber,
uint8_t setSegmentHeader = 0xC0, uint8_t* data = NULL, uint16_t dataSize = 0, uint16_t forceCrc = 0); uint8_t setSegmentHeader = 0xC0, uint8_t* data = NULL, uint16_t dataSize = 0, uint16_t forceCrc = 0);
}; };
#endif /* TCTRANSFERFRAMELOCAL_H_ */ #endif /* TCTRANSFERFRAMELOCAL_H_ */

View File

@ -1,121 +1,121 @@
/** /**
* @file VirtualChannelReception.cpp * @file VirtualChannelReception.cpp
* @brief This file defines the VirtualChannelReception class. * @brief This file defines the VirtualChannelReception class.
* @date 26.03.2013 * @date 26.03.2013
* @author baetz * @author baetz
*/ */
#include <framework/datalinklayer/BCFrame.h> #include "../datalinklayer/BCFrame.h"
#include <framework/datalinklayer/VirtualChannelReception.h> #include "../datalinklayer/VirtualChannelReception.h"
#include <framework/serviceinterface/ServiceInterfaceStream.h> #include "../serviceinterface/ServiceInterfaceStream.h"
VirtualChannelReception::VirtualChannelReception(uint8_t setChannelId, VirtualChannelReception::VirtualChannelReception(uint8_t setChannelId,
uint8_t setSlidingWindowWidth) : uint8_t setSlidingWindowWidth) :
channelId(setChannelId), slidingWindowWidth(setSlidingWindowWidth), positiveWindow( channelId(setChannelId), slidingWindowWidth(setSlidingWindowWidth), positiveWindow(
setSlidingWindowWidth / 2), negativeWindow(setSlidingWindowWidth / 2), currentState( setSlidingWindowWidth / 2), negativeWindow(setSlidingWindowWidth / 2), currentState(
&openState), openState(this), waitState(this), lockoutState(this), vR(0), farmBCounter( &openState), openState(this), waitState(this), lockoutState(this), vR(0), farmBCounter(
0) { 0) {
internalClcw.setVirtualChannel(channelId); internalClcw.setVirtualChannel(channelId);
} }
ReturnValue_t VirtualChannelReception::mapDemultiplexing(TcTransferFrame* frame) { ReturnValue_t VirtualChannelReception::mapDemultiplexing(TcTransferFrame* frame) {
uint8_t mapId = frame->getMAPId(); uint8_t mapId = frame->getMAPId();
mapChannelIterator iter = mapChannels.find(mapId); mapChannelIterator iter = mapChannels.find(mapId);
if (iter == mapChannels.end()) { if (iter == mapChannels.end()) {
// error << "VirtualChannelReception::mapDemultiplexing on VC " << std::hex << (int) channelId // error << "VirtualChannelReception::mapDemultiplexing on VC " << std::hex << (int) channelId
// << ": MapChannel " << (int) mapId << std::dec << " not found." << std::endl; // << ": MapChannel " << (int) mapId << std::dec << " not found." << std::endl;
return VC_NOT_FOUND; return VC_NOT_FOUND;
} else { } else {
return (iter->second)->extractPackets(frame); return (iter->second)->extractPackets(frame);
} }
} }
ReturnValue_t VirtualChannelReception::doFARM(TcTransferFrame* frame, ClcwIF* clcw) { ReturnValue_t VirtualChannelReception::doFARM(TcTransferFrame* frame, ClcwIF* clcw) {
uint8_t bypass = frame->bypassFlagSet(); uint8_t bypass = frame->bypassFlagSet();
uint8_t controlCommand = frame->controlCommandFlagSet(); uint8_t controlCommand = frame->controlCommandFlagSet();
uint8_t typeValue = (bypass << 1) + controlCommand; uint8_t typeValue = (bypass << 1) + controlCommand;
switch (typeValue) { switch (typeValue) {
case AD_FRAME: case AD_FRAME:
return currentState->handleADFrame(frame, clcw); return currentState->handleADFrame(frame, clcw);
case BD_FRAME: case BD_FRAME:
return handleBDFrame(frame, clcw); return handleBDFrame(frame, clcw);
case BC_FRAME: case BC_FRAME:
return handleBCFrame(frame, clcw); return handleBCFrame(frame, clcw);
default: default:
return ILLEGAL_FLAG_COMBINATION; return ILLEGAL_FLAG_COMBINATION;
} }
} }
ReturnValue_t VirtualChannelReception::frameAcceptanceAndReportingMechanism(TcTransferFrame* frame, ReturnValue_t VirtualChannelReception::frameAcceptanceAndReportingMechanism(TcTransferFrame* frame,
ClcwIF* clcw) { ClcwIF* clcw) {
ReturnValue_t result = RETURN_OK; ReturnValue_t result = RETURN_OK;
result = doFARM(frame, &internalClcw); result = doFARM(frame, &internalClcw);
internalClcw.setReceiverFrameSequenceNumber(vR); internalClcw.setReceiverFrameSequenceNumber(vR);
internalClcw.setFarmBCount(farmBCounter); internalClcw.setFarmBCount(farmBCounter);
clcw->setWhole(internalClcw.getAsWhole()); clcw->setWhole(internalClcw.getAsWhole());
switch (result) { switch (result) {
case RETURN_OK: case RETURN_OK:
return mapDemultiplexing(frame); return mapDemultiplexing(frame);
case BC_IS_SET_VR_COMMAND: case BC_IS_SET_VR_COMMAND:
case BC_IS_UNLOCK_COMMAND: case BC_IS_UNLOCK_COMMAND:
//Need to catch these codes to avoid error reporting later. //Need to catch these codes to avoid error reporting later.
return RETURN_OK; return RETURN_OK;
default: default:
break; break;
} }
return result; return result;
} }
ReturnValue_t VirtualChannelReception::addMapChannel(uint8_t mapId, MapPacketExtractionIF* object) { ReturnValue_t VirtualChannelReception::addMapChannel(uint8_t mapId, MapPacketExtractionIF* object) {
std::pair<mapChannelIterator, bool> returnValue = mapChannels.insert( std::pair<mapChannelIterator, bool> returnValue = mapChannels.insert(
std::pair<uint8_t, MapPacketExtractionIF*>(mapId, object)); std::pair<uint8_t, MapPacketExtractionIF*>(mapId, object));
if (returnValue.second == true) { if (returnValue.second == true) {
return RETURN_OK; return RETURN_OK;
} else { } else {
return RETURN_FAILED; return RETURN_FAILED;
} }
} }
ReturnValue_t VirtualChannelReception::handleBDFrame(TcTransferFrame* frame, ClcwIF* clcw) { ReturnValue_t VirtualChannelReception::handleBDFrame(TcTransferFrame* frame, ClcwIF* clcw) {
farmBCounter++; farmBCounter++;
return RETURN_OK; return RETURN_OK;
} }
ReturnValue_t VirtualChannelReception::handleBCFrame(TcTransferFrame* frame, ClcwIF* clcw) { ReturnValue_t VirtualChannelReception::handleBCFrame(TcTransferFrame* frame, ClcwIF* clcw) {
BcFrame content; BcFrame content;
ReturnValue_t returnValue = content.initialize(frame->getFullDataField(), ReturnValue_t returnValue = content.initialize(frame->getFullDataField(),
frame->getFullDataLength()); frame->getFullDataLength());
if (returnValue == BC_IS_UNLOCK_COMMAND) { if (returnValue == BC_IS_UNLOCK_COMMAND) {
returnValue = currentState->handleBCUnlockCommand(clcw); returnValue = currentState->handleBCUnlockCommand(clcw);
} else if (returnValue == BC_IS_SET_VR_COMMAND) { } else if (returnValue == BC_IS_SET_VR_COMMAND) {
returnValue = currentState->handleBCSetVrCommand(clcw, content.vR); returnValue = currentState->handleBCSetVrCommand(clcw, content.vR);
} else { } else {
//Do nothing //Do nothing
} }
return returnValue; return returnValue;
} }
uint8_t VirtualChannelReception::getChannelId() const { uint8_t VirtualChannelReception::getChannelId() const {
return channelId; return channelId;
} }
ReturnValue_t VirtualChannelReception::initialize() { ReturnValue_t VirtualChannelReception::initialize() {
ReturnValue_t returnValue = RETURN_FAILED; ReturnValue_t returnValue = RETURN_FAILED;
if ((slidingWindowWidth > 254) || (slidingWindowWidth % 2 != 0)) { if ((slidingWindowWidth > 254) || (slidingWindowWidth % 2 != 0)) {
sif::error << "VirtualChannelReception::initialize: Illegal sliding window width: " sif::error << "VirtualChannelReception::initialize: Illegal sliding window width: "
<< (int) slidingWindowWidth << std::endl; << (int) slidingWindowWidth << std::endl;
return RETURN_FAILED; return RETURN_FAILED;
} }
for (mapChannelIterator iterator = mapChannels.begin(); iterator != mapChannels.end(); for (mapChannelIterator iterator = mapChannels.begin(); iterator != mapChannels.end();
iterator++) { iterator++) {
returnValue = iterator->second->initialize(); returnValue = iterator->second->initialize();
if (returnValue != RETURN_OK) if (returnValue != RETURN_OK)
break; break;
} }
return returnValue; return returnValue;
} }
void VirtualChannelReception::setToWaitState() { void VirtualChannelReception::setToWaitState() {
internalClcw.setWaitFlag(true); internalClcw.setWaitFlag(true);
this->currentState = &waitState; this->currentState = &waitState;
} }

View File

@ -1,114 +1,114 @@
/** /**
* @file VirtualChannelReception.h * @file VirtualChannelReception.h
* @brief This file defines the VirtualChannelReception class. * @brief This file defines the VirtualChannelReception class.
* @date 25.03.2013 * @date 25.03.2013
* @author baetz * @author baetz
*/ */
#ifndef VIRTUALCHANNELRECEPTION_H_ #ifndef VIRTUALCHANNELRECEPTION_H_
#define VIRTUALCHANNELRECEPTION_H_ #define VIRTUALCHANNELRECEPTION_H_
#include <framework/datalinklayer/CCSDSReturnValuesIF.h> #include "../datalinklayer/CCSDSReturnValuesIF.h"
#include <framework/datalinklayer/Clcw.h> #include "../datalinklayer/Clcw.h"
#include <framework/datalinklayer/Farm1StateIF.h> #include "../datalinklayer/Farm1StateIF.h"
#include <framework/datalinklayer/Farm1StateLockout.h> #include "../datalinklayer/Farm1StateLockout.h"
#include <framework/datalinklayer/Farm1StateOpen.h> #include "../datalinklayer/Farm1StateOpen.h"
#include <framework/datalinklayer/Farm1StateWait.h> #include "../datalinklayer/Farm1StateWait.h"
#include <framework/datalinklayer/MapPacketExtractionIF.h> #include "../datalinklayer/MapPacketExtractionIF.h"
#include <framework/datalinklayer/VirtualChannelReceptionIF.h> #include "../datalinklayer/VirtualChannelReceptionIF.h"
#include <map> #include <map>
/** /**
* Implementation of a TC Virtual Channel. * Implementation of a TC Virtual Channel.
* This is a full implementation of a virtual channel as specified in the CCSDS TC Space Data Link * This is a full implementation of a virtual channel as specified in the CCSDS TC Space Data Link
* Protocol. It is designed to operate within an instance of the @c DataLinkLayer class. * Protocol. It is designed to operate within an instance of the @c DataLinkLayer class.
* Features: * Features:
* - any (6bit) Virtual Channel ID is assignable. * - any (6bit) Virtual Channel ID is assignable.
* - Supports an arbitrary number of MAP Channels (with a map). * - Supports an arbitrary number of MAP Channels (with a map).
* - Has a complete FARM-1 Machine built-in. * - Has a complete FARM-1 Machine built-in.
* *
* The FARM-1 state machine uses the State Pattern. * The FARM-1 state machine uses the State Pattern.
*/ */
class VirtualChannelReception : public VirtualChannelReceptionIF, public CCSDSReturnValuesIF { class VirtualChannelReception : public VirtualChannelReceptionIF, public CCSDSReturnValuesIF {
friend class Farm1StateOpen; friend class Farm1StateOpen;
friend class Farm1StateWait; friend class Farm1StateWait;
friend class Farm1StateLockout; friend class Farm1StateLockout;
private: private:
uint8_t channelId; //!< Stores the VCID that was assigned on construction. uint8_t channelId; //!< Stores the VCID that was assigned on construction.
uint8_t slidingWindowWidth; //!< A constant to set the FARM-1 sliding window width. uint8_t slidingWindowWidth; //!< A constant to set the FARM-1 sliding window width.
uint8_t positiveWindow; //!< The positive window for the FARM-1 machine. uint8_t positiveWindow; //!< The positive window for the FARM-1 machine.
uint8_t negativeWindow; //!< The negative window for the FARM-1 machine. uint8_t negativeWindow; //!< The negative window for the FARM-1 machine.
protected: protected:
Farm1StateIF* currentState; //!< The current state. To change, one of the other states must be assigned to this pointer. Farm1StateIF* currentState; //!< The current state. To change, one of the other states must be assigned to this pointer.
Farm1StateOpen openState; //!< Instance of the FARM-1 State "Open". Farm1StateOpen openState; //!< Instance of the FARM-1 State "Open".
Farm1StateWait waitState; //!< Instance of the FARM-1 State "Wait". Farm1StateWait waitState; //!< Instance of the FARM-1 State "Wait".
Farm1StateLockout lockoutState; //!< Instance of the FARM-1 State "Lockout". Farm1StateLockout lockoutState; //!< Instance of the FARM-1 State "Lockout".
Clcw internalClcw; //!< A CLCW class to internally set the values before writing them back to the TTC System. Clcw internalClcw; //!< A CLCW class to internally set the values before writing them back to the TTC System.
uint8_t vR; //!< The Receiver Frame Sequence Number V(R) as it shall be maintained for every Virtual Channel. uint8_t vR; //!< The Receiver Frame Sequence Number V(R) as it shall be maintained for every Virtual Channel.
uint8_t farmBCounter; //!< The FARM-B COunter as it shall be maintained for every Virtual Channel. uint8_t farmBCounter; //!< The FARM-B COunter as it shall be maintained for every Virtual Channel.
typedef std::map<uint8_t, MapPacketExtractionIF*>::iterator mapChannelIterator; //!< Typedef to simplify handling of the mapChannels map. typedef std::map<uint8_t, MapPacketExtractionIF*>::iterator mapChannelIterator; //!< Typedef to simplify handling of the mapChannels map.
std::map<uint8_t, MapPacketExtractionIF*> mapChannels; //!< A map that maintains all map Channels. Channels must be configured on initialization. MAy be omitted in a simplified version. std::map<uint8_t, MapPacketExtractionIF*> mapChannels; //!< A map that maintains all map Channels. Channels must be configured on initialization. MAy be omitted in a simplified version.
/** /**
* This method handles demultiplexing to different map channels. * This method handles demultiplexing to different map channels.
* It parses the entries of #mapChannels and forwards the Frame to a found MAP Channel. * It parses the entries of #mapChannels and forwards the Frame to a found MAP Channel.
* @param frame The frame to forward. * @param frame The frame to forward.
* @return #VC_NOT_FOUND or the return value of the map channel extraction. * @return #VC_NOT_FOUND or the return value of the map channel extraction.
*/ */
ReturnValue_t mapDemultiplexing( TcTransferFrame* frame ); ReturnValue_t mapDemultiplexing( TcTransferFrame* frame );
/** /**
* A sub-method that actually does the FARM-1 handling for different Frame types. * A sub-method that actually does the FARM-1 handling for different Frame types.
* @param frame The Tc Transfer Frame to handle. * @param frame The Tc Transfer Frame to handle.
* @param clcw Any changes on the CLCW shall be done with this method. * @param clcw Any changes on the CLCW shall be done with this method.
* @return The return code of higher methods or @c ILLEGAL_FLAG_COMBINATION. * @return The return code of higher methods or @c ILLEGAL_FLAG_COMBINATION.
*/ */
ReturnValue_t doFARM(TcTransferFrame* frame, ClcwIF* clcw); ReturnValue_t doFARM(TcTransferFrame* frame, ClcwIF* clcw);
/** /**
* Handles incoming BD Frames. * Handles incoming BD Frames.
* Handling these Frames is independent of the State, so no subcall to #currentState is * Handling these Frames is independent of the State, so no subcall to #currentState is
* required. * required.
* @param frame The Tc Transfer Frame to handle. * @param frame The Tc Transfer Frame to handle.
* @param clcw Any changes on the CLCW shall be done with this method. * @param clcw Any changes on the CLCW shall be done with this method.
* @return Always returns @c RETURN_OK. * @return Always returns @c RETURN_OK.
*/ */
ReturnValue_t handleBDFrame( TcTransferFrame* frame, ClcwIF* clcw ); ReturnValue_t handleBDFrame( TcTransferFrame* frame, ClcwIF* clcw );
/** /**
* Handles incoming BC Frames. * Handles incoming BC Frames.
* The type of the BC Frame is detected and checked first, then methods of #currentState are called. * The type of the BC Frame is detected and checked first, then methods of #currentState are called.
* @param frame The Tc Transfer Frame to handle. * @param frame The Tc Transfer Frame to handle.
* @param clcw Any changes on the CLCW shall be done with this method. * @param clcw Any changes on the CLCW shall be done with this method.
* @return The failure code of BC Frame interpretation or the return code of higher methods. * @return The failure code of BC Frame interpretation or the return code of higher methods.
*/ */
ReturnValue_t handleBCFrame( TcTransferFrame* frame, ClcwIF* clcw ); ReturnValue_t handleBCFrame( TcTransferFrame* frame, ClcwIF* clcw );
public: public:
/** /**
* Default constructor. * Default constructor.
* Only sets the channelId of the channel. Setting the Sliding Window width is possible as well. * Only sets the channelId of the channel. Setting the Sliding Window width is possible as well.
* @param setChannelId Virtual Channel Identifier (VCID) of the channel. * @param setChannelId Virtual Channel Identifier (VCID) of the channel.
*/ */
VirtualChannelReception( uint8_t setChannelId, uint8_t setSlidingWindowWidth ); VirtualChannelReception( uint8_t setChannelId, uint8_t setSlidingWindowWidth );
ReturnValue_t frameAcceptanceAndReportingMechanism( TcTransferFrame* frame, ClcwIF* clcw ); ReturnValue_t frameAcceptanceAndReportingMechanism( TcTransferFrame* frame, ClcwIF* clcw );
/** /**
* Helper method to simplify adding a mapChannel during construction. * Helper method to simplify adding a mapChannel during construction.
* @param mapId The mapId of the object to add. * @param mapId The mapId of the object to add.
* @param object Pointer to the MapPacketExtraction object itself. * @param object Pointer to the MapPacketExtraction object itself.
* @return @c RETURN_OK if the channel was successfully inserted, @c RETURN_FAILED otherwise. * @return @c RETURN_OK if the channel was successfully inserted, @c RETURN_FAILED otherwise.
*/ */
ReturnValue_t addMapChannel( uint8_t mapId, MapPacketExtractionIF* object ); ReturnValue_t addMapChannel( uint8_t mapId, MapPacketExtractionIF* object );
/** /**
* The initialization routine checks the set #slidingWindowWidth and initializes all MAP * The initialization routine checks the set #slidingWindowWidth and initializes all MAP
* channels. * channels.
* @return @c RETURN_OK on successful initialization, @c RETURN_FAILED otherwise. * @return @c RETURN_OK on successful initialization, @c RETURN_FAILED otherwise.
*/ */
ReturnValue_t initialize(); ReturnValue_t initialize();
/** /**
* Getter for the VCID. * Getter for the VCID.
* @return The #channelId. * @return The #channelId.
*/ */
uint8_t getChannelId() const; uint8_t getChannelId() const;
/** /**
* Small method to set the state to Farm1StateWait. * Small method to set the state to Farm1StateWait.
*/ */
void setToWaitState(); void setToWaitState();
}; };
#endif /* VIRTUALCHANNELRECEPTION_H_ */ #endif /* VIRTUALCHANNELRECEPTION_H_ */

View File

@ -1,57 +1,57 @@
/** /**
* @file VirtualChannelReceptionIF.h * @file VirtualChannelReceptionIF.h
* @brief This file defines the VirtualChannelReceptionIF class. * @brief This file defines the VirtualChannelReceptionIF class.
* @date 25.03.2013 * @date 25.03.2013
* @author baetz * @author baetz
*/ */
#ifndef VIRTUALCHANNELRECEPTIONIF_H_ #ifndef VIRTUALCHANNELRECEPTIONIF_H_
#define VIRTUALCHANNELRECEPTIONIF_H_ #define VIRTUALCHANNELRECEPTIONIF_H_
#include <framework/datalinklayer/ClcwIF.h> #include "../datalinklayer/ClcwIF.h"
#include <framework/datalinklayer/TcTransferFrame.h> #include "../datalinklayer/TcTransferFrame.h"
#include <framework/returnvalues/HasReturnvaluesIF.h> #include "../returnvalues/HasReturnvaluesIF.h"
/** /**
* This is the interface for Virtual Channel reception classes. * This is the interface for Virtual Channel reception classes.
* It represents a single TC Virtual Channel that operates on one IO * It represents a single TC Virtual Channel that operates on one IO
*/ */
class VirtualChannelReceptionIF { class VirtualChannelReceptionIF {
public: public:
/** /**
* Enum including all valid types of frames. * Enum including all valid types of frames.
* The type is made up by two flags, so 0b1111 is definitely illegal. * The type is made up by two flags, so 0b1111 is definitely illegal.
*/ */
enum frameType { enum frameType {
AD_FRAME = 0b00, AD_FRAME = 0b00,
BC_FRAME = 0b11, BC_FRAME = 0b11,
BD_FRAME = 0b10, BD_FRAME = 0b10,
ILLEGAL_FRAME = 0b1111 ILLEGAL_FRAME = 0b1111
}; };
/** /**
* Empty virtual destructor. * Empty virtual destructor.
*/ */
virtual ~VirtualChannelReceptionIF() { virtual ~VirtualChannelReceptionIF() {
} }
/** /**
* This method shall accept frames and do all FARM-1 stuff. * This method shall accept frames and do all FARM-1 stuff.
* Handling the Frame includes forwarding to higher-level procedures. * Handling the Frame includes forwarding to higher-level procedures.
* @param frame The Tc Transfer Frame that was received and checked. * @param frame The Tc Transfer Frame that was received and checked.
* @param clcw Any changes to the CLCW value are forwarded by using this parameter. * @param clcw Any changes to the CLCW value are forwarded by using this parameter.
* @return The return Value shall indicate successful processing with @c RETURN_OK. * @return The return Value shall indicate successful processing with @c RETURN_OK.
*/ */
virtual ReturnValue_t frameAcceptanceAndReportingMechanism( TcTransferFrame* frame, ClcwIF* clcw ) = 0; virtual ReturnValue_t frameAcceptanceAndReportingMechanism( TcTransferFrame* frame, ClcwIF* clcw ) = 0;
/** /**
* If any other System Objects are required for operation they shall be initialized here. * If any other System Objects are required for operation they shall be initialized here.
* @return @c RETURN_OK for successful initialization. * @return @c RETURN_OK for successful initialization.
*/ */
virtual ReturnValue_t initialize() = 0; virtual ReturnValue_t initialize() = 0;
/** /**
* Getter for the VCID. * Getter for the VCID.
* @return The #channelId. * @return The #channelId.
*/ */
virtual uint8_t getChannelId() const = 0; virtual uint8_t getChannelId() const = 0;
}; };
#endif /* VIRTUALCHANNELRECEPTIONIF_H_ */ #endif /* VIRTUALCHANNELRECEPTIONIF_H_ */

View File

@ -1,14 +1,14 @@
#include <framework/datapool/ControllerSet.h> #include "../datapool/ControllerSet.h"
ControllerSet::ControllerSet() { ControllerSet::ControllerSet() {
} }
ControllerSet::~ControllerSet() { ControllerSet::~ControllerSet() {
} }
void ControllerSet::setInvalid() { void ControllerSet::setInvalid() {
read(); read();
setToDefault(); setToDefault();
commit(PoolVariableIF::INVALID); commit(PoolVariableIF::INVALID);
} }

View File

@ -1,15 +1,15 @@
#ifndef CONTROLLERSET_H_ #ifndef CONTROLLERSET_H_
#define CONTROLLERSET_H_ #define CONTROLLERSET_H_
#include <framework/datapoolglob/GlobalDataSet.h> #include "../datapoolglob/GlobalDataSet.h"
class ControllerSet :public GlobDataSet { class ControllerSet :public GlobDataSet {
public: public:
ControllerSet(); ControllerSet();
virtual ~ControllerSet(); virtual ~ControllerSet();
virtual void setToDefault() = 0; virtual void setToDefault() = 0;
void setInvalid(); void setInvalid();
}; };
#endif /* CONTROLLERSET_H_ */ #endif /* CONTROLLERSET_H_ */

View File

@ -1,8 +1,8 @@
#ifndef FRAMEWORK_DATAPOOL_DATASETIF_H_ #ifndef DATASETIF_H_
#define FRAMEWORK_DATAPOOL_DATASETIF_H_ #define DATASETIF_H_
#include <framework/returnvalues/HasReturnvaluesIF.h> #include "../returnvalues/HasReturnvaluesIF.h"
#include <framework/timemanager/Clock.h> #include "../timemanager/Clock.h"
class PoolVariableIF; class PoolVariableIF;
/** /**

View File

@ -1,75 +1,75 @@
#include <framework/datapool/HkSwitchHelper.h> #include "../datapool/HkSwitchHelper.h"
#include <framework/ipc/QueueFactory.h> #include "../ipc/QueueFactory.h"
HkSwitchHelper::HkSwitchHelper(EventReportingProxyIF* eventProxy) : HkSwitchHelper::HkSwitchHelper(EventReportingProxyIF* eventProxy) :
commandActionHelper(this), eventProxy(eventProxy) { commandActionHelper(this), eventProxy(eventProxy) {
actionQueue = QueueFactory::instance()->createMessageQueue(); actionQueue = QueueFactory::instance()->createMessageQueue();
} }
HkSwitchHelper::~HkSwitchHelper() { HkSwitchHelper::~HkSwitchHelper() {
// TODO Auto-generated destructor stub // TODO Auto-generated destructor stub
} }
ReturnValue_t HkSwitchHelper::initialize() { ReturnValue_t HkSwitchHelper::initialize() {
ReturnValue_t result = commandActionHelper.initialize(); ReturnValue_t result = commandActionHelper.initialize();
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
return result; return result;
} }
ReturnValue_t HkSwitchHelper::performOperation(uint8_t operationCode) { ReturnValue_t HkSwitchHelper::performOperation(uint8_t operationCode) {
CommandMessage command; CommandMessage command;
while (actionQueue->receiveMessage(&command) == HasReturnvaluesIF::RETURN_OK) { while (actionQueue->receiveMessage(&command) == HasReturnvaluesIF::RETURN_OK) {
ReturnValue_t result = commandActionHelper.handleReply(&command); ReturnValue_t result = commandActionHelper.handleReply(&command);
if (result == HasReturnvaluesIF::RETURN_OK) { if (result == HasReturnvaluesIF::RETURN_OK) {
continue; continue;
} }
command.setToUnknownCommand(); command.setToUnknownCommand();
actionQueue->reply(&command); actionQueue->reply(&command);
} }
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
void HkSwitchHelper::stepSuccessfulReceived(ActionId_t actionId, uint8_t step) { void HkSwitchHelper::stepSuccessfulReceived(ActionId_t actionId, uint8_t step) {
} }
void HkSwitchHelper::stepFailedReceived(ActionId_t actionId, uint8_t step, void HkSwitchHelper::stepFailedReceived(ActionId_t actionId, uint8_t step,
ReturnValue_t returnCode) { ReturnValue_t returnCode) {
eventProxy->forwardEvent(SWITCHING_TM_FAILED, returnCode, actionId); eventProxy->forwardEvent(SWITCHING_TM_FAILED, returnCode, actionId);
} }
void HkSwitchHelper::dataReceived(ActionId_t actionId, const uint8_t* data, void HkSwitchHelper::dataReceived(ActionId_t actionId, const uint8_t* data,
uint32_t size) { uint32_t size) {
} }
void HkSwitchHelper::completionSuccessfulReceived(ActionId_t actionId) { void HkSwitchHelper::completionSuccessfulReceived(ActionId_t actionId) {
} }
void HkSwitchHelper::completionFailedReceived(ActionId_t actionId, void HkSwitchHelper::completionFailedReceived(ActionId_t actionId,
ReturnValue_t returnCode) { ReturnValue_t returnCode) {
eventProxy->forwardEvent(SWITCHING_TM_FAILED, returnCode, actionId); eventProxy->forwardEvent(SWITCHING_TM_FAILED, returnCode, actionId);
} }
ReturnValue_t HkSwitchHelper::switchHK(SerializeIF* sids, bool enable) { ReturnValue_t HkSwitchHelper::switchHK(SerializeIF* sids, bool enable) {
// ActionId_t action = HKService::DISABLE_HK; // ActionId_t action = HKService::DISABLE_HK;
// if (enable) { // if (enable) {
// action = HKService::ENABLE_HK; // action = HKService::ENABLE_HK;
// } // }
// //
// ReturnValue_t result = commandActionHelper.commandAction( // ReturnValue_t result = commandActionHelper.commandAction(
// objects::PUS_HK_SERVICE, action, sids); // objects::PUS_HK_SERVICE, action, sids);
// //
// if (result != HasReturnvaluesIF::RETURN_OK) { // if (result != HasReturnvaluesIF::RETURN_OK) {
// eventProxy->forwardEvent(SWITCHING_TM_FAILED, result); // eventProxy->forwardEvent(SWITCHING_TM_FAILED, result);
// } // }
// return result; // return result;
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
MessageQueueIF* HkSwitchHelper::getCommandQueuePtr() { MessageQueueIF* HkSwitchHelper::getCommandQueuePtr() {
return actionQueue; return actionQueue;
} }

View File

@ -1,46 +1,46 @@
#ifndef FRAMEWORK_DATAPOOL_HKSWITCHHELPER_H_ #ifndef FRAMEWORK_DATAPOOL_HKSWITCHHELPER_H_
#define FRAMEWORK_DATAPOOL_HKSWITCHHELPER_H_ #define FRAMEWORK_DATAPOOL_HKSWITCHHELPER_H_
#include <framework/tasks/ExecutableObjectIF.h> #include "../tasks/ExecutableObjectIF.h"
#include <framework/action/CommandsActionsIF.h> #include "../action/CommandsActionsIF.h"
#include <framework/events/EventReportingProxyIF.h> #include "../events/EventReportingProxyIF.h"
//TODO this class violations separation between mission and framework //TODO this class violations separation between mission and framework
//but it is only a transitional solution until the Datapool is //but it is only a transitional solution until the Datapool is
//implemented decentrally //implemented decentrally
class HkSwitchHelper: public ExecutableObjectIF, public CommandsActionsIF { class HkSwitchHelper: public ExecutableObjectIF, public CommandsActionsIF {
public: public:
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::HK; static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::HK;
static const Event SWITCHING_TM_FAILED = MAKE_EVENT(1, SEVERITY::LOW); //!< Commanding the HK Service failed, p1: error code, p2 action: 0 disable / 1 enable static const Event SWITCHING_TM_FAILED = MAKE_EVENT(1, SEVERITY::LOW); //!< Commanding the HK Service failed, p1: error code, p2 action: 0 disable / 1 enable
HkSwitchHelper(EventReportingProxyIF *eventProxy); HkSwitchHelper(EventReportingProxyIF *eventProxy);
virtual ~HkSwitchHelper(); virtual ~HkSwitchHelper();
ReturnValue_t initialize(); ReturnValue_t initialize();
virtual ReturnValue_t performOperation(uint8_t operationCode = 0); virtual ReturnValue_t performOperation(uint8_t operationCode = 0);
ReturnValue_t switchHK(SerializeIF *sids, bool enable); ReturnValue_t switchHK(SerializeIF *sids, bool enable);
virtual void setTaskIF(PeriodicTaskIF* task_){}; virtual void setTaskIF(PeriodicTaskIF* task_){};
protected: protected:
virtual void stepSuccessfulReceived(ActionId_t actionId, uint8_t step); virtual void stepSuccessfulReceived(ActionId_t actionId, uint8_t step);
virtual void stepFailedReceived(ActionId_t actionId, uint8_t step, virtual void stepFailedReceived(ActionId_t actionId, uint8_t step,
ReturnValue_t returnCode); ReturnValue_t returnCode);
virtual void dataReceived(ActionId_t actionId, const uint8_t* data, virtual void dataReceived(ActionId_t actionId, const uint8_t* data,
uint32_t size); uint32_t size);
virtual void completionSuccessfulReceived(ActionId_t actionId); virtual void completionSuccessfulReceived(ActionId_t actionId);
virtual void completionFailedReceived(ActionId_t actionId, virtual void completionFailedReceived(ActionId_t actionId,
ReturnValue_t returnCode); ReturnValue_t returnCode);
virtual MessageQueueIF* getCommandQueuePtr(); virtual MessageQueueIF* getCommandQueuePtr();
private: private:
CommandActionHelper commandActionHelper; CommandActionHelper commandActionHelper;
MessageQueueIF* actionQueue; MessageQueueIF* actionQueue;
EventReportingProxyIF *eventProxy; EventReportingProxyIF *eventProxy;
}; };
#endif /* FRAMEWORK_DATAPOOL_HKSWITCHHELPER_H_ */ #endif /* FRAMEWORK_DATAPOOL_HKSWITCHHELPER_H_ */

View File

@ -1,5 +1,5 @@
#include <framework/datapool/PoolDataSetBase.h> #include "PoolDataSetBase.h"
#include <framework/serviceinterface/ServiceInterfaceStream.h> #include "../serviceinterface/ServiceInterfaceStream.h"
PoolDataSetBase::PoolDataSetBase(PoolVariableIF** registeredVariablesArray, PoolDataSetBase::PoolDataSetBase(PoolVariableIF** registeredVariablesArray,
const size_t maxFillCount): const size_t maxFillCount):

View File

@ -1,9 +1,8 @@
#ifndef FRAMEWORK_DATAPOOL_POOLPOOLDATASETBASE_H_ #ifndef FRAMEWORK_DATAPOOL_DATASETBASE_H_
#define FRAMEWORK_DATAPOOL_POOLPOOLDATASETBASE_H_ #define FRAMEWORK_DATAPOOL_DATASETBASE_H_
#include <framework/datapool/DataSetIF.h> #include "../datapool/PoolDataSetIF.h"
#include <framework/datapool/PoolDataSetIF.h> #include "../datapool/PoolVariableIF.h"
#include <framework/datapool/PoolVariableIF.h> #include "../ipc/MutexIF.h"
#include <framework/ipc/MutexIF.h>
/** /**
* @brief The DataSetBase class manages a set of locally checked out variables. * @brief The DataSetBase class manages a set of locally checked out variables.

View File

@ -1,6 +1,6 @@
#ifndef FRAMEWORK_DATAPOOL_POOLDATASETIF_H_ #ifndef FRAMEWORK_DATAPOOL_POOLDATASETIF_H_
#define FRAMEWORK_DATAPOOL_POOLDATASETIF_H_ #define FRAMEWORK_DATAPOOL_POOLDATASETIF_H_
#include <framework/datapool/DataSetIF.h> #include "DataSetIF.h"
class PoolDataSetIF: public DataSetIF { class PoolDataSetIF: public DataSetIF {
public: public:

View File

@ -1,87 +1,87 @@
#include <framework/datapool/PoolEntry.h> #include "../datapool/PoolEntry.h"
#include <framework/serviceinterface/ServiceInterfaceStream.h> #include "../serviceinterface/ServiceInterfaceStream.h"
#include <framework/globalfunctions/arrayprinter.h> #include "../globalfunctions/arrayprinter.h"
#include <cstring> #include <cstring>
template <typename T> template <typename T>
PoolEntry<T>::PoolEntry(std::initializer_list<T> initValue, uint8_t setLength, PoolEntry<T>::PoolEntry(std::initializer_list<T> initValue, uint8_t setLength,
bool setValid ) : length(setLength), valid(setValid) { bool setValid ) : length(setLength), valid(setValid) {
this->address = new T[this->length]; this->address = new T[this->length];
if(initValue.size() == 0) { if(initValue.size() == 0) {
std::memset(this->address, 0, this->getByteSize()); std::memset(this->address, 0, this->getByteSize());
} }
else if (initValue.size() != setLength){ else if (initValue.size() != setLength){
sif::warning << "PoolEntry: setLength is not equal to initializer list" sif::warning << "PoolEntry: setLength is not equal to initializer list"
"length! Performing zero initialization with given setLength" "length! Performing zero initialization with given setLength"
<< std::endl; << std::endl;
std::memset(this->address, 0, this->getByteSize()); std::memset(this->address, 0, this->getByteSize());
} }
else { else {
std::copy(initValue.begin(), initValue.end(), this->address); std::copy(initValue.begin(), initValue.end(), this->address);
} }
} }
template <typename T> template <typename T>
PoolEntry<T>::PoolEntry( T* initValue, uint8_t setLength, bool setValid ) : PoolEntry<T>::PoolEntry( T* initValue, uint8_t setLength, bool setValid ) :
length(setLength), valid(setValid) { length(setLength), valid(setValid) {
this->address = new T[this->length]; this->address = new T[this->length];
if (initValue != nullptr) { if (initValue != nullptr) {
std::memcpy(this->address, initValue, this->getByteSize() ); std::memcpy(this->address, initValue, this->getByteSize() );
} else { } else {
std::memset(this->address, 0, this->getByteSize() ); std::memset(this->address, 0, this->getByteSize() );
} }
} }
//As the data pool is global, this dtor is only be called on program exit. //As the data pool is global, this dtor is only be called on program exit.
//Warning! Never copy pool entries! //Warning! Never copy pool entries!
template <typename T> template <typename T>
PoolEntry<T>::~PoolEntry() { PoolEntry<T>::~PoolEntry() {
delete[] this->address; delete[] this->address;
} }
template <typename T> template <typename T>
uint16_t PoolEntry<T>::getByteSize() { uint16_t PoolEntry<T>::getByteSize() {
return ( sizeof(T) * this->length ); return ( sizeof(T) * this->length );
} }
template <typename T> template <typename T>
uint8_t PoolEntry<T>::getSize() { uint8_t PoolEntry<T>::getSize() {
return this->length; return this->length;
} }
template <typename T> template <typename T>
void* PoolEntry<T>::getRawData() { void* PoolEntry<T>::getRawData() {
return this->address; return this->address;
} }
template <typename T> template <typename T>
void PoolEntry<T>::setValid(bool isValid) { void PoolEntry<T>::setValid(bool isValid) {
this->valid = isValid; this->valid = isValid;
} }
template <typename T> template <typename T>
bool PoolEntry<T>::getValid() { bool PoolEntry<T>::getValid() {
return valid; return valid;
} }
template <typename T> template <typename T>
void PoolEntry<T>::print() { void PoolEntry<T>::print() {
sif::debug << "Pool Entry Validity: " << sif::debug << "Pool Entry Validity: " <<
(this->valid? " (valid) " : " (invalid) ") << std::endl; (this->valid? " (valid) " : " (invalid) ") << std::endl;
arrayprinter::print(reinterpret_cast<uint8_t*>(address), length); arrayprinter::print(reinterpret_cast<uint8_t*>(address), length);
sif::debug << std::dec << std::endl; sif::debug << std::dec << std::endl;
} }
template<typename T> template<typename T>
Type PoolEntry<T>::getType() { Type PoolEntry<T>::getType() {
return PodTypeConversion<T>::type; return PodTypeConversion<T>::type;
} }
template class PoolEntry<uint8_t>; template class PoolEntry<uint8_t>;
template class PoolEntry<uint16_t>; template class PoolEntry<uint16_t>;
template class PoolEntry<uint32_t>; template class PoolEntry<uint32_t>;
template class PoolEntry<int8_t>; template class PoolEntry<int8_t>;
template class PoolEntry<int16_t>; template class PoolEntry<int16_t>;
template class PoolEntry<int32_t>; template class PoolEntry<int32_t>;
template class PoolEntry<float>; template class PoolEntry<float>;
template class PoolEntry<double>; template class PoolEntry<double>;

View File

@ -1,130 +1,130 @@
#ifndef FRAMEWORK_DATAPOOL_POOLENTRY_H_ #ifndef FRAMEWORK_DATAPOOL_POOLENTRY_H_
#define FRAMEWORK_DATAPOOL_POOLENTRY_H_ #define FRAMEWORK_DATAPOOL_POOLENTRY_H_
#include <framework/datapool/PoolEntryIF.h> #include "../datapool/PoolEntryIF.h"
#include <initializer_list> #include <initializer_list>
#include <type_traits> #include <type_traits>
#include <cstddef> #include <cstddef>
/** /**
* @brief This is a small helper class that defines a single data pool entry. * @brief This is a small helper class that defines a single data pool entry.
* @details * @details
* The helper is used to store all information together with the data as a * The helper is used to store all information together with the data as a
* single data pool entry. The content's type is defined by the template * single data pool entry. The content's type is defined by the template
* argument. * argument.
* *
* It is prepared for use with plain old data types, but may be * It is prepared for use with plain old data types, but may be
* extended to complex types if necessary. It can be initialized with a * extended to complex types if necessary. It can be initialized with a
* certain value, size and validity flag. * certain value, size and validity flag.
* *
* It holds a pointer to the real data and offers methods to access this data * It holds a pointer to the real data and offers methods to access this data
* and to acquire additional information (such as validity and array/byte size). * and to acquire additional information (such as validity and array/byte size).
* It is NOT intended to be used outside DataPool implementations as it performs * It is NOT intended to be used outside DataPool implementations as it performs
* dynamic memory allocation. * dynamic memory allocation.
* *
* @ingroup data_pool * @ingroup data_pool
*/ */
template <typename T> template <typename T>
class PoolEntry : public PoolEntryIF { class PoolEntry : public PoolEntryIF {
public: public:
static_assert(not std::is_same<T, bool>::value, static_assert(not std::is_same<T, bool>::value,
"Do not use boolean for the PoolEntry type, use uint8_t " "Do not use boolean for the PoolEntry type, use uint8_t "
"instead! The ECSS standard defines a boolean as a one bit " "instead! The ECSS standard defines a boolean as a one bit "
"field. Therefore it is preferred to store a boolean as an " "field. Therefore it is preferred to store a boolean as an "
"uint8_t"); "uint8_t");
/** /**
* @brief In the classe's constructor, space is allocated on the heap and * @brief In the classe's constructor, space is allocated on the heap and
* potential init values are copied to that space. * potential init values are copied to that space.
* @details * @details
* Not passing any arguments will initialize an non-array pool entry * Not passing any arguments will initialize an non-array pool entry
* (setLength = 1) with an initial invalid state. * (setLength = 1) with an initial invalid state.
* Please note that if an initializer list is passed, the correct * Please note that if an initializer list is passed, the correct
* corresponding length should be passed too, otherwise a zero * corresponding length should be passed too, otherwise a zero
* initialization will be performed with the given setLength. * initialization will be performed with the given setLength.
* @param initValue * @param initValue
* Initializer list with values to initialize with, for example {0,0} to * Initializer list with values to initialize with, for example {0,0} to
* initialize the two entries to zero. * initialize the two entries to zero.
* @param setLength * @param setLength
* Defines the array length of this entry. Should be equal to the * Defines the array length of this entry. Should be equal to the
* intializer list length. * intializer list length.
* @param setValid * @param setValid
* Sets the initialization flag. It is invalid by default. * Sets the initialization flag. It is invalid by default.
*/ */
PoolEntry(std::initializer_list<T> initValue = {}, uint8_t setLength = 1, PoolEntry(std::initializer_list<T> initValue = {}, uint8_t setLength = 1,
bool setValid = false); bool setValid = false);
/** /**
* @brief In the classe's constructor, space is allocated on the heap and * @brief In the classe's constructor, space is allocated on the heap and
* potential init values are copied to that space. * potential init values are copied to that space.
* @param initValue * @param initValue
* A pointer to the single value or array that holds the init value. * A pointer to the single value or array that holds the init value.
* With the default value (nullptr), the entry is initalized with all 0. * With the default value (nullptr), the entry is initalized with all 0.
* @param setLength * @param setLength
* Defines the array length of this entry. * Defines the array length of this entry.
* @param setValid * @param setValid
* Sets the initialization flag. It is invalid by default. * Sets the initialization flag. It is invalid by default.
*/ */
PoolEntry(T* initValue, uint8_t setLength = 1, bool setValid = false); PoolEntry(T* initValue, uint8_t setLength = 1, bool setValid = false);
//! Explicitely deleted copy ctor, copying is not allowed! //! Explicitely deleted copy ctor, copying is not allowed!
PoolEntry(const PoolEntry&) = delete; PoolEntry(const PoolEntry&) = delete;
//! Explicitely deleted copy assignment, copying is not allowed! //! Explicitely deleted copy assignment, copying is not allowed!
PoolEntry& operator=(const PoolEntry&) = delete; PoolEntry& operator=(const PoolEntry&) = delete;
/** /**
* @brief The allocated memory for the variable is freed * @brief The allocated memory for the variable is freed
* in the destructor. * in the destructor.
* @details * @details
* As the data pool is global, this dtor is only called on program exit. * As the data pool is global, this dtor is only called on program exit.
* PoolEntries shall never be copied, as a copy might delete the variable * PoolEntries shall never be copied, as a copy might delete the variable
* on the heap. * on the heap.
*/ */
~PoolEntry(); ~PoolEntry();
/** /**
* @brief This is the address pointing to the allocated memory. * @brief This is the address pointing to the allocated memory.
*/ */
T* address; T* address;
/** /**
* @brief This attribute stores the length information. * @brief This attribute stores the length information.
*/ */
uint8_t length; uint8_t length;
/** /**
* @brief Here, the validity information for a variable is stored. * @brief Here, the validity information for a variable is stored.
* Every entry (single variable or vector) has one valid flag. * Every entry (single variable or vector) has one valid flag.
*/ */
uint8_t valid; uint8_t valid;
/** /**
* @brief getSize returns the array size of the entry. * @brief getSize returns the array size of the entry.
* @details A single parameter has size 1. * @details A single parameter has size 1.
*/ */
uint8_t getSize(); uint8_t getSize();
/** /**
* @brief This operation returns the size in bytes. * @brief This operation returns the size in bytes.
* @details The size is calculated by sizeof(type) * array_size. * @details The size is calculated by sizeof(type) * array_size.
*/ */
uint16_t getByteSize(); uint16_t getByteSize();
/** /**
* @brief This operation returns a the address pointer casted to void*. * @brief This operation returns a the address pointer casted to void*.
*/ */
void* getRawData(); void* getRawData();
/** /**
* @brief This method allows to set the valid information * @brief This method allows to set the valid information
* of the pool entry. * of the pool entry.
*/ */
void setValid( bool isValid ); void setValid( bool isValid );
/** /**
* @brief This method allows to get the valid information * @brief This method allows to get the valid information
* of the pool entry. * of the pool entry.
*/ */
bool getValid(); bool getValid();
/** /**
* @brief This is a debug method that prints all values and the valid * @brief This is a debug method that prints all values and the valid
* information to the screen. It prints all array entries in a row. * information to the screen. It prints all array entries in a row.
*/ */
void print(); void print();
Type getType(); Type getType();
}; };
#endif /* POOLENTRY_H_ */ #endif /* POOLENTRY_H_ */

View File

@ -1,63 +1,63 @@
#ifndef FRAMEWORK_DATAPOOL_POOLENTRYIF_H_ #ifndef FRAMEWORK_DATAPOOL_POOLENTRYIF_H_
#define FRAMEWORK_DATAPOOL_POOLENTRYIF_H_ #define FRAMEWORK_DATAPOOL_POOLENTRYIF_H_
#include <framework/globalfunctions/Type.h> #include "../globalfunctions/Type.h"
#include <cstdint> #include <cstdint>
/** /**
* @brief This interface defines the access possibilities to a * @brief This interface defines the access possibilities to a
* single data pool entry. * single data pool entry.
* @details * @details
* The interface provides methods to determine the size and the validity * The interface provides methods to determine the size and the validity
* information of a value. It also defines a method to receive a pointer to the * information of a value. It also defines a method to receive a pointer to the
* raw data content. It is mainly used by DataPool itself, but also as a * raw data content. It is mainly used by DataPool itself, but also as a
* return pointer. * return pointer.
* *
* @author Bastian Baetz * @author Bastian Baetz
* @ingroup data_pool * @ingroup data_pool
* *
*/ */
class PoolEntryIF { class PoolEntryIF {
public: public:
/** /**
* @brief This is an empty virtual destructor, * @brief This is an empty virtual destructor,
* as it is required for C++ interfaces. * as it is required for C++ interfaces.
*/ */
virtual ~PoolEntryIF() { virtual ~PoolEntryIF() {
} }
/** /**
* @brief getSize returns the array size of the entry. * @brief getSize returns the array size of the entry.
* A single variable parameter has size 1. * A single variable parameter has size 1.
*/ */
virtual uint8_t getSize() = 0; virtual uint8_t getSize() = 0;
/** /**
* @brief This operation returns the size in bytes, which is calculated by * @brief This operation returns the size in bytes, which is calculated by
* sizeof(type) * array_size. * sizeof(type) * array_size.
*/ */
virtual uint16_t getByteSize() = 0; virtual uint16_t getByteSize() = 0;
/** /**
* @brief This operation returns a the address pointer casted to void*. * @brief This operation returns a the address pointer casted to void*.
*/ */
virtual void* getRawData() = 0; virtual void* getRawData() = 0;
/** /**
* @brief This method allows to set the valid information of the pool entry. * @brief This method allows to set the valid information of the pool entry.
*/ */
virtual void setValid(bool isValid) = 0; virtual void setValid(bool isValid) = 0;
/** /**
* @brief This method allows to set the valid information of the pool entry. * @brief This method allows to set the valid information of the pool entry.
*/ */
virtual bool getValid() = 0; virtual bool getValid() = 0;
/** /**
* @brief This is a debug method that prints all values and the valid * @brief This is a debug method that prints all values and the valid
* information to the screen. It prints all array entries in a row. * information to the screen. It prints all array entries in a row.
* @details * @details
* Also displays whether the pool entry is valid or invalid. * Also displays whether the pool entry is valid or invalid.
*/ */
virtual void print() = 0; virtual void print() = 0;
/** /**
* Returns the type of the entry. * Returns the type of the entry.
*/ */
virtual Type getType() = 0; virtual Type getType() = 0;
}; };
#endif /* POOLENTRYIF_H_ */ #endif /* POOLENTRYIF_H_ */

View File

@ -5,10 +5,10 @@
* @author R. Mueller * @author R. Mueller
*/ */
#include <framework/datapool/PoolRawAccessHelper.h> #include "../datapool/PoolRawAccessHelper.h"
#include <framework/datapoolglob/GlobalDataSet.h> #include "../datapoolglob/GlobalDataSet.h"
#include <framework/serialize/SerializeAdapter.h> #include "../serialize/SerializeAdapter.h"
#include <framework/serviceinterface/ServiceInterfaceStream.h> #include "../serviceinterface/ServiceInterfaceStream.h"
#include <cmath> #include <cmath>
#include <cstring> #include <cstring>

View File

@ -7,9 +7,9 @@
#ifndef FRAMEWORK_DATAPOOL_POOLRAWACCESSHELPER_H_ #ifndef FRAMEWORK_DATAPOOL_POOLRAWACCESSHELPER_H_
#define FRAMEWORK_DATAPOOL_POOLRAWACCESSHELPER_H_ #define FRAMEWORK_DATAPOOL_POOLRAWACCESSHELPER_H_
#include <framework/returnvalues/HasReturnvaluesIF.h> #include "../returnvalues/HasReturnvaluesIF.h"
#include <framework/datapoolglob/GlobalDataSet.h> #include "../datapoolglob/GlobalDataSet.h"
#include <framework/datapoolglob/PoolRawAccess.h> #include "../datapoolglob/PoolRawAccess.h"
/** /**
* @brief This helper function simplifies accessing data pool entries * @brief This helper function simplifies accessing data pool entries

View File

@ -1,28 +1,28 @@
#ifndef POOLVARLIST_H_ #ifndef POOLVARLIST_H_
#define POOLVARLIST_H_ #define POOLVARLIST_H_
#include <framework/datapool/PoolVariableIF.h> #include "../datapool/PoolVariableIF.h"
#include <framework/datapoolglob/GlobalPoolVariable.h> #include "../datapoolglob/GlobalPoolVariable.h"
template <class T, uint8_t n_var> template <class T, uint8_t n_var>
class PoolVarList { class PoolVarList {
private: private:
GlobPoolVar<T> variables[n_var]; GlobPoolVar<T> variables[n_var];
public: public:
PoolVarList( const uint32_t set_id[n_var], DataSetIF* dataSet, PoolVariableIF::ReadWriteMode_t setReadWriteMode ) { PoolVarList( const uint32_t set_id[n_var], DataSetIF* dataSet, PoolVariableIF::ReadWriteMode_t setReadWriteMode ) {
//I really should have a look at the new init list c++ syntax. //I really should have a look at the new init list c++ syntax.
if (dataSet == NULL) { if (dataSet == NULL) {
return; return;
} }
for (uint8_t count = 0; count < n_var; count++) { for (uint8_t count = 0; count < n_var; count++) {
variables[count].dataPoolId = set_id[count]; variables[count].dataPoolId = set_id[count];
variables[count].readWriteMode = setReadWriteMode; variables[count].readWriteMode = setReadWriteMode;
dataSet->registerVariable(&variables[count]); dataSet->registerVariable(&variables[count]);
} }
} }
GlobPoolVar<T> &operator [](int i) { return variables[i]; } GlobPoolVar<T> &operator [](int i) { return variables[i]; }
}; };
#endif /* POOLVARLIST_H_ */ #endif /* POOLVARLIST_H_ */

View File

@ -1,8 +1,8 @@
#ifndef FRAMEWORK_DATAPOOL_POOLVARIABLEIF_H_ #ifndef FRAMEWORK_DATAPOOL_POOLVARIABLEIF_H_
#define FRAMEWORK_DATAPOOL_POOLVARIABLEIF_H_ #define FRAMEWORK_DATAPOOL_POOLVARIABLEIF_H_
#include <framework/returnvalues/HasReturnvaluesIF.h> #include "../returnvalues/HasReturnvaluesIF.h"
#include <framework/serialize/SerializeIF.h> #include "../serialize/SerializeIF.h"
/** /**
* @brief This interface is used to control data pool * @brief This interface is used to control data pool

View File

@ -1,7 +1,6 @@
#ifndef FRAMEWORK_DATAPOOL_SHAREDDATASETIF_H_ #ifndef FRAMEWORK_DATAPOOL_SHAREDDATASETIF_H_
#define FRAMEWORK_DATAPOOL_SHAREDDATASETIF_H_ #define FRAMEWORK_DATAPOOL_SHAREDDATASETIF_H_
#include <framework/datapool/DataSetIF.h> #include "PoolDataSetIF.h"
#include <framework/datapool/PoolDataSetIF.h>
class SharedDataSetIF: public PoolDataSetIF { class SharedDataSetIF: public PoolDataSetIF {
public: public:

View File

@ -1,300 +1,300 @@
#include <framework/datapoolglob/DataPoolAdmin.h> #include "../datapoolglob/DataPoolAdmin.h"
#include <framework/datapoolglob/GlobalDataSet.h> #include "../datapoolglob/GlobalDataSet.h"
#include <framework/datapoolglob/GlobalDataPool.h> #include "../datapoolglob/GlobalDataPool.h"
#include <framework/datapoolglob/PoolRawAccess.h> #include "../datapoolglob/PoolRawAccess.h"
#include <framework/ipc/CommandMessage.h> #include "../ipc/CommandMessage.h"
#include <framework/ipc/QueueFactory.h> #include "../ipc/QueueFactory.h"
#include <framework/parameters/ParameterMessage.h> #include "../parameters/ParameterMessage.h"
DataPoolAdmin::DataPoolAdmin(object_id_t objectId) : DataPoolAdmin::DataPoolAdmin(object_id_t objectId) :
SystemObject(objectId), storage(NULL), commandQueue(NULL), memoryHelper( SystemObject(objectId), storage(NULL), commandQueue(NULL), memoryHelper(
this, NULL), actionHelper(this, NULL) { this, NULL), actionHelper(this, NULL) {
commandQueue = QueueFactory::instance()->createMessageQueue(); commandQueue = QueueFactory::instance()->createMessageQueue();
} }
DataPoolAdmin::~DataPoolAdmin() { DataPoolAdmin::~DataPoolAdmin() {
QueueFactory::instance()->deleteMessageQueue(commandQueue); QueueFactory::instance()->deleteMessageQueue(commandQueue);
} }
ReturnValue_t DataPoolAdmin::performOperation(uint8_t opCode) { ReturnValue_t DataPoolAdmin::performOperation(uint8_t opCode) {
handleCommand(); handleCommand();
return RETURN_OK; return RETURN_OK;
} }
MessageQueueId_t DataPoolAdmin::getCommandQueue() const { MessageQueueId_t DataPoolAdmin::getCommandQueue() const {
return commandQueue->getId(); return commandQueue->getId();
} }
ReturnValue_t DataPoolAdmin::executeAction(ActionId_t actionId, ReturnValue_t DataPoolAdmin::executeAction(ActionId_t actionId,
MessageQueueId_t commandedBy, const uint8_t* data, size_t size) { MessageQueueId_t commandedBy, const uint8_t* data, size_t size) {
if (actionId != SET_VALIDITY) { if (actionId != SET_VALIDITY) {
return INVALID_ACTION_ID; return INVALID_ACTION_ID;
} }
if (size != 5) { if (size != 5) {
return INVALID_PARAMETERS; return INVALID_PARAMETERS;
} }
uint32_t address = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) uint32_t address = (data[0] << 24) | (data[1] << 16) | (data[2] << 8)
| data[3]; | data[3];
uint8_t valid = data[4]; uint8_t valid = data[4];
uint32_t poolId = glob::dataPool.PIDToDataPoolId(address); uint32_t poolId = glob::dataPool.PIDToDataPoolId(address);
GlobDataSet mySet; GlobDataSet mySet;
PoolRawAccess variable(poolId, 0, &mySet, PoolVariableIF::VAR_READ_WRITE); PoolRawAccess variable(poolId, 0, &mySet, PoolVariableIF::VAR_READ_WRITE);
ReturnValue_t status = mySet.read(); ReturnValue_t status = mySet.read();
if (status != RETURN_OK) { if (status != RETURN_OK) {
return INVALID_ADDRESS; return INVALID_ADDRESS;
} }
if (valid != 0) { if (valid != 0) {
variable.setValid(PoolVariableIF::VALID); variable.setValid(PoolVariableIF::VALID);
} else { } else {
variable.setValid(PoolVariableIF::INVALID); variable.setValid(PoolVariableIF::INVALID);
} }
mySet.commit(); mySet.commit();
return EXECUTION_FINISHED; return EXECUTION_FINISHED;
} }
ReturnValue_t DataPoolAdmin::getParameter(uint8_t domainId, ReturnValue_t DataPoolAdmin::getParameter(uint8_t domainId,
uint16_t parameterId, ParameterWrapper* parameterWrapper, uint16_t parameterId, ParameterWrapper* parameterWrapper,
const ParameterWrapper* newValues, uint16_t startAtIndex) { const ParameterWrapper* newValues, uint16_t startAtIndex) {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
void DataPoolAdmin::handleCommand() { void DataPoolAdmin::handleCommand() {
CommandMessage command; CommandMessage command;
ReturnValue_t result = commandQueue->receiveMessage(&command); ReturnValue_t result = commandQueue->receiveMessage(&command);
if (result != RETURN_OK) { if (result != RETURN_OK) {
return; return;
} }
result = actionHelper.handleActionMessage(&command); result = actionHelper.handleActionMessage(&command);
if (result == HasReturnvaluesIF::RETURN_OK) { if (result == HasReturnvaluesIF::RETURN_OK) {
return; return;
} }
result = handleParameterCommand(&command); result = handleParameterCommand(&command);
if (result == HasReturnvaluesIF::RETURN_OK) { if (result == HasReturnvaluesIF::RETURN_OK) {
return; return;
} }
result = memoryHelper.handleMemoryCommand(&command); result = memoryHelper.handleMemoryCommand(&command);
if (result != RETURN_OK) { if (result != RETURN_OK) {
command.setToUnknownCommand(); command.setToUnknownCommand();
commandQueue->reply(&command); commandQueue->reply(&command);
} }
} }
ReturnValue_t DataPoolAdmin::handleMemoryLoad(uint32_t address, ReturnValue_t DataPoolAdmin::handleMemoryLoad(uint32_t address,
const uint8_t* data, size_t size, uint8_t** dataPointer) { const uint8_t* data, size_t size, uint8_t** dataPointer) {
uint32_t poolId = glob::dataPool.PIDToDataPoolId(address); uint32_t poolId = glob::dataPool.PIDToDataPoolId(address);
uint8_t arrayIndex = glob::dataPool.PIDToArrayIndex(address); uint8_t arrayIndex = glob::dataPool.PIDToArrayIndex(address);
GlobDataSet testSet; GlobDataSet testSet;
PoolRawAccess varToGetSize(poolId, arrayIndex, &testSet, PoolRawAccess varToGetSize(poolId, arrayIndex, &testSet,
PoolVariableIF::VAR_READ); PoolVariableIF::VAR_READ);
ReturnValue_t status = testSet.read(); ReturnValue_t status = testSet.read();
if (status != RETURN_OK) { if (status != RETURN_OK) {
return INVALID_ADDRESS; return INVALID_ADDRESS;
} }
uint8_t typeSize = varToGetSize.getSizeOfType(); uint8_t typeSize = varToGetSize.getSizeOfType();
if (size % typeSize != 0) { if (size % typeSize != 0) {
return INVALID_SIZE; return INVALID_SIZE;
} }
if (size > varToGetSize.getSizeTillEnd()) { if (size > varToGetSize.getSizeTillEnd()) {
return INVALID_SIZE; return INVALID_SIZE;
} }
const uint8_t* readPosition = data; const uint8_t* readPosition = data;
for (; size > 0; size -= typeSize) { for (; size > 0; size -= typeSize) {
GlobDataSet rawSet; GlobDataSet rawSet;
PoolRawAccess variable(poolId, arrayIndex, &rawSet, PoolRawAccess variable(poolId, arrayIndex, &rawSet,
PoolVariableIF::VAR_READ_WRITE); PoolVariableIF::VAR_READ_WRITE);
status = rawSet.read(); status = rawSet.read();
if (status == RETURN_OK) { if (status == RETURN_OK) {
status = variable.setEntryFromBigEndian(readPosition, typeSize); status = variable.setEntryFromBigEndian(readPosition, typeSize);
if (status == RETURN_OK) { if (status == RETURN_OK) {
status = rawSet.commit(); status = rawSet.commit();
} }
} }
arrayIndex += 1; arrayIndex += 1;
readPosition += typeSize; readPosition += typeSize;
} }
return ACTIVITY_COMPLETED; return ACTIVITY_COMPLETED;
} }
ReturnValue_t DataPoolAdmin::handleMemoryDump(uint32_t address, size_t size, ReturnValue_t DataPoolAdmin::handleMemoryDump(uint32_t address, size_t size,
uint8_t** dataPointer, uint8_t* copyHere) { uint8_t** dataPointer, uint8_t* copyHere) {
uint32_t poolId = glob::dataPool.PIDToDataPoolId(address); uint32_t poolId = glob::dataPool.PIDToDataPoolId(address);
uint8_t arrayIndex = glob::dataPool.PIDToArrayIndex(address); uint8_t arrayIndex = glob::dataPool.PIDToArrayIndex(address);
GlobDataSet testSet; GlobDataSet testSet;
PoolRawAccess varToGetSize(poolId, arrayIndex, &testSet, PoolRawAccess varToGetSize(poolId, arrayIndex, &testSet,
PoolVariableIF::VAR_READ); PoolVariableIF::VAR_READ);
ReturnValue_t status = testSet.read(); ReturnValue_t status = testSet.read();
if (status != RETURN_OK) { if (status != RETURN_OK) {
return INVALID_ADDRESS; return INVALID_ADDRESS;
} }
uint8_t typeSize = varToGetSize.getSizeOfType(); uint8_t typeSize = varToGetSize.getSizeOfType();
if (size > varToGetSize.getSizeTillEnd()) { if (size > varToGetSize.getSizeTillEnd()) {
return INVALID_SIZE; return INVALID_SIZE;
} }
uint8_t* ptrToCopy = copyHere; uint8_t* ptrToCopy = copyHere;
for (; size > 0; size -= typeSize) { for (; size > 0; size -= typeSize) {
GlobDataSet rawSet; GlobDataSet rawSet;
PoolRawAccess variable(poolId, arrayIndex, &rawSet, PoolRawAccess variable(poolId, arrayIndex, &rawSet,
PoolVariableIF::VAR_READ); PoolVariableIF::VAR_READ);
status = rawSet.read(); status = rawSet.read();
if (status == RETURN_OK) { if (status == RETURN_OK) {
size_t temp = 0; size_t temp = 0;
status = variable.getEntryEndianSafe(ptrToCopy, &temp, size); status = variable.getEntryEndianSafe(ptrToCopy, &temp, size);
if (status != RETURN_OK) { if (status != RETURN_OK) {
return RETURN_FAILED; return RETURN_FAILED;
} }
} else { } else {
//Error reading parameter. //Error reading parameter.
} }
arrayIndex += 1; arrayIndex += 1;
ptrToCopy += typeSize; ptrToCopy += typeSize;
} }
return ACTIVITY_COMPLETED; return ACTIVITY_COMPLETED;
} }
ReturnValue_t DataPoolAdmin::initialize() { ReturnValue_t DataPoolAdmin::initialize() {
ReturnValue_t result = SystemObject::initialize(); ReturnValue_t result = SystemObject::initialize();
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
result = memoryHelper.initialize(commandQueue); result = memoryHelper.initialize(commandQueue);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
storage = objectManager->get<StorageManagerIF>(objects::IPC_STORE); storage = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
if (storage == NULL) { if (storage == NULL) {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
result = actionHelper.initialize(commandQueue); result = actionHelper.initialize(commandQueue);
return result; return result;
} }
//mostly identical to ParameterHelper::handleParameterMessage() //mostly identical to ParameterHelper::handleParameterMessage()
ReturnValue_t DataPoolAdmin::handleParameterCommand(CommandMessage* command) { ReturnValue_t DataPoolAdmin::handleParameterCommand(CommandMessage* command) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED; ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED;
switch (command->getCommand()) { switch (command->getCommand()) {
case ParameterMessage::CMD_PARAMETER_DUMP: { case ParameterMessage::CMD_PARAMETER_DUMP: {
uint8_t domain = HasParametersIF::getDomain( uint8_t domain = HasParametersIF::getDomain(
ParameterMessage::getParameterId(command)); ParameterMessage::getParameterId(command));
uint16_t parameterId = HasParametersIF::getMatrixId( uint16_t parameterId = HasParametersIF::getMatrixId(
ParameterMessage::getParameterId(command)); ParameterMessage::getParameterId(command));
DataPoolParameterWrapper wrapper; DataPoolParameterWrapper wrapper;
result = wrapper.set(domain, parameterId); result = wrapper.set(domain, parameterId);
if (result == HasReturnvaluesIF::RETURN_OK) { if (result == HasReturnvaluesIF::RETURN_OK) {
result = sendParameter(command->getSender(), result = sendParameter(command->getSender(),
ParameterMessage::getParameterId(command), &wrapper); ParameterMessage::getParameterId(command), &wrapper);
} }
} }
break; break;
case ParameterMessage::CMD_PARAMETER_LOAD: { case ParameterMessage::CMD_PARAMETER_LOAD: {
uint8_t domain = HasParametersIF::getDomain( uint8_t domain = HasParametersIF::getDomain(
ParameterMessage::getParameterId(command)); ParameterMessage::getParameterId(command));
uint16_t parameterId = HasParametersIF::getMatrixId( uint16_t parameterId = HasParametersIF::getMatrixId(
ParameterMessage::getParameterId(command)); ParameterMessage::getParameterId(command));
uint8_t index = HasParametersIF::getIndex( uint8_t index = HasParametersIF::getIndex(
ParameterMessage::getParameterId(command)); ParameterMessage::getParameterId(command));
const uint8_t *storedStream; const uint8_t *storedStream;
size_t storedStreamSize; size_t storedStreamSize;
result = storage->getData(ParameterMessage::getStoreId(command), result = storage->getData(ParameterMessage::getStoreId(command),
&storedStream, &storedStreamSize); &storedStream, &storedStreamSize);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
break; break;
} }
ParameterWrapper streamWrapper; ParameterWrapper streamWrapper;
result = streamWrapper.set(storedStream, storedStreamSize); result = streamWrapper.set(storedStream, storedStreamSize);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
storage->deleteData(ParameterMessage::getStoreId(command)); storage->deleteData(ParameterMessage::getStoreId(command));
break; break;
} }
DataPoolParameterWrapper poolWrapper; DataPoolParameterWrapper poolWrapper;
result = poolWrapper.set(domain, parameterId); result = poolWrapper.set(domain, parameterId);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
storage->deleteData(ParameterMessage::getStoreId(command)); storage->deleteData(ParameterMessage::getStoreId(command));
break; break;
} }
result = poolWrapper.copyFrom(&streamWrapper, index); result = poolWrapper.copyFrom(&streamWrapper, index);
storage->deleteData(ParameterMessage::getStoreId(command)); storage->deleteData(ParameterMessage::getStoreId(command));
if (result == HasReturnvaluesIF::RETURN_OK) { if (result == HasReturnvaluesIF::RETURN_OK) {
result = sendParameter(command->getSender(), result = sendParameter(command->getSender(),
ParameterMessage::getParameterId(command), &poolWrapper); ParameterMessage::getParameterId(command), &poolWrapper);
} }
} }
break; break;
default: default:
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
rejectCommand(command->getSender(), result, command->getCommand()); rejectCommand(command->getSender(), result, command->getCommand());
} }
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
//identical to ParameterHelper::sendParameter() //identical to ParameterHelper::sendParameter()
ReturnValue_t DataPoolAdmin::sendParameter(MessageQueueId_t to, uint32_t id, ReturnValue_t DataPoolAdmin::sendParameter(MessageQueueId_t to, uint32_t id,
const DataPoolParameterWrapper* wrapper) { const DataPoolParameterWrapper* wrapper) {
size_t serializedSize = wrapper->getSerializedSize(); size_t serializedSize = wrapper->getSerializedSize();
uint8_t *storeElement; uint8_t *storeElement;
store_address_t address; store_address_t address;
ReturnValue_t result = storage->getFreeElement(&address, serializedSize, ReturnValue_t result = storage->getFreeElement(&address, serializedSize,
&storeElement); &storeElement);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
size_t storeElementSize = 0; size_t storeElementSize = 0;
result = wrapper->serialize(&storeElement, &storeElementSize, result = wrapper->serialize(&storeElement, &storeElementSize,
serializedSize, SerializeIF::Endianness::BIG); serializedSize, SerializeIF::Endianness::BIG);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
storage->deleteData(address); storage->deleteData(address);
return result; return result;
} }
CommandMessage reply; CommandMessage reply;
ParameterMessage::setParameterDumpReply(&reply, id, address); ParameterMessage::setParameterDumpReply(&reply, id, address);
commandQueue->sendMessage(to, &reply); commandQueue->sendMessage(to, &reply);
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
//identical to ParameterHelper::rejectCommand() //identical to ParameterHelper::rejectCommand()
void DataPoolAdmin::rejectCommand(MessageQueueId_t to, ReturnValue_t reason, void DataPoolAdmin::rejectCommand(MessageQueueId_t to, ReturnValue_t reason,
Command_t initialCommand) { Command_t initialCommand) {
CommandMessage reply; CommandMessage reply;
reply.setReplyRejected(reason, initialCommand); reply.setReplyRejected(reason, initialCommand);
commandQueue->sendMessage(to, &reply); commandQueue->sendMessage(to, &reply);
} }

View File

@ -1,59 +1,59 @@
#ifndef DATAPOOLADMIN_H_ #ifndef DATAPOOLADMIN_H_
#define DATAPOOLADMIN_H_ #define DATAPOOLADMIN_H_
#include <framework/objectmanager/SystemObject.h> #include "../objectmanager/SystemObject.h"
#include <framework/returnvalues/HasReturnvaluesIF.h> #include "../returnvalues/HasReturnvaluesIF.h"
#include <framework/tasks/ExecutableObjectIF.h> #include "../tasks/ExecutableObjectIF.h"
#include <framework/action/HasActionsIF.h> #include "../action/HasActionsIF.h"
#include <framework/ipc/MessageQueueIF.h> #include "../ipc/MessageQueueIF.h"
#include <framework/parameters/ReceivesParameterMessagesIF.h> #include "../parameters/ReceivesParameterMessagesIF.h"
#include <framework/memory/MemoryHelper.h> #include "../memory/MemoryHelper.h"
#include <framework/action/SimpleActionHelper.h> #include "../action/SimpleActionHelper.h"
#include <framework/datapoolglob/DataPoolParameterWrapper.h> #include "../datapoolglob/DataPoolParameterWrapper.h"
class DataPoolAdmin: public HasActionsIF, class DataPoolAdmin: public HasActionsIF,
public ExecutableObjectIF, public ExecutableObjectIF,
public AcceptsMemoryMessagesIF, public AcceptsMemoryMessagesIF,
public HasReturnvaluesIF, public HasReturnvaluesIF,
public ReceivesParameterMessagesIF, public ReceivesParameterMessagesIF,
public SystemObject { public SystemObject {
public: public:
static const ActionId_t SET_VALIDITY = 1; static const ActionId_t SET_VALIDITY = 1;
DataPoolAdmin(object_id_t objectId); DataPoolAdmin(object_id_t objectId);
~DataPoolAdmin(); ~DataPoolAdmin();
ReturnValue_t performOperation(uint8_t opCode); ReturnValue_t performOperation(uint8_t opCode);
MessageQueueId_t getCommandQueue() const; MessageQueueId_t getCommandQueue() const;
ReturnValue_t handleMemoryLoad(uint32_t address, const uint8_t* data, ReturnValue_t handleMemoryLoad(uint32_t address, const uint8_t* data,
size_t size, uint8_t** dataPointer); size_t size, uint8_t** dataPointer);
ReturnValue_t handleMemoryDump(uint32_t address, size_t size, ReturnValue_t handleMemoryDump(uint32_t address, size_t size,
uint8_t** dataPointer, uint8_t* copyHere); uint8_t** dataPointer, uint8_t* copyHere);
ReturnValue_t executeAction(ActionId_t actionId, ReturnValue_t executeAction(ActionId_t actionId,
MessageQueueId_t commandedBy, const uint8_t* data, size_t size); MessageQueueId_t commandedBy, const uint8_t* data, size_t size);
//not implemented as ParameterHelper is no used //not implemented as ParameterHelper is no used
ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId, ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId,
ParameterWrapper *parameterWrapper, ParameterWrapper *parameterWrapper,
const ParameterWrapper *newValues, uint16_t startAtIndex); const ParameterWrapper *newValues, uint16_t startAtIndex);
ReturnValue_t initialize(); ReturnValue_t initialize();
private: private:
StorageManagerIF *storage; StorageManagerIF *storage;
MessageQueueIF* commandQueue; MessageQueueIF* commandQueue;
MemoryHelper memoryHelper; MemoryHelper memoryHelper;
SimpleActionHelper actionHelper; SimpleActionHelper actionHelper;
void handleCommand(); void handleCommand();
ReturnValue_t handleParameterCommand(CommandMessage *command); ReturnValue_t handleParameterCommand(CommandMessage *command);
ReturnValue_t sendParameter(MessageQueueId_t to, uint32_t id, ReturnValue_t sendParameter(MessageQueueId_t to, uint32_t id,
const DataPoolParameterWrapper* wrapper); const DataPoolParameterWrapper* wrapper);
void rejectCommand(MessageQueueId_t to, ReturnValue_t reason, void rejectCommand(MessageQueueId_t to, ReturnValue_t reason,
Command_t initialCommand); Command_t initialCommand);
}; };
#endif /* DATAPOOLADMIN_H_ */ #endif /* DATAPOOLADMIN_H_ */

View File

@ -1,179 +1,179 @@
#include <framework/datapoolglob/GlobalDataSet.h> #include "../datapoolglob/GlobalDataSet.h"
#include <framework/datapoolglob/DataPoolParameterWrapper.h> #include "../datapoolglob/DataPoolParameterWrapper.h"
#include <framework/datapoolglob/PoolRawAccess.h> #include "../datapoolglob/PoolRawAccess.h"
#include <framework/parameters/HasParametersIF.h> #include "../parameters/HasParametersIF.h"
DataPoolParameterWrapper::DataPoolParameterWrapper() : DataPoolParameterWrapper::DataPoolParameterWrapper() :
type(Type::UNKNOWN_TYPE), rows(0), columns(0), poolId( type(Type::UNKNOWN_TYPE), rows(0), columns(0), poolId(
PoolVariableIF::NO_PARAMETER) { PoolVariableIF::NO_PARAMETER) {
} }
DataPoolParameterWrapper::~DataPoolParameterWrapper() { DataPoolParameterWrapper::~DataPoolParameterWrapper() {
} }
ReturnValue_t DataPoolParameterWrapper::set(uint8_t domainId, ReturnValue_t DataPoolParameterWrapper::set(uint8_t domainId,
uint16_t parameterId) { uint16_t parameterId) {
poolId = (domainId << 16) + parameterId; poolId = (domainId << 16) + parameterId;
GlobDataSet mySet; GlobDataSet mySet;
PoolRawAccess raw(poolId, 0, &mySet, PoolVariableIF::VAR_READ); PoolRawAccess raw(poolId, 0, &mySet, PoolVariableIF::VAR_READ);
ReturnValue_t status = mySet.read(); ReturnValue_t status = mySet.read();
if (status != HasReturnvaluesIF::RETURN_OK) { if (status != HasReturnvaluesIF::RETURN_OK) {
//should only fail for invalid pool id //should only fail for invalid pool id
return HasParametersIF::INVALID_MATRIX_ID; return HasParametersIF::INVALID_MATRIX_ID;
} }
type = raw.getType(); type = raw.getType();
rows = raw.getArraySize(); rows = raw.getArraySize();
columns = 1; columns = 1;
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
ReturnValue_t DataPoolParameterWrapper::serialize(uint8_t** buffer, ReturnValue_t DataPoolParameterWrapper::serialize(uint8_t** buffer,
size_t* size, size_t maxSize, Endianness streamEndianness) const { size_t* size, size_t maxSize, Endianness streamEndianness) const {
ReturnValue_t result; ReturnValue_t result;
result = SerializeAdapter::serialize(&type, buffer, size, maxSize, result = SerializeAdapter::serialize(&type, buffer, size, maxSize,
streamEndianness); streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
result = SerializeAdapter::serialize(&columns, buffer, size, result = SerializeAdapter::serialize(&columns, buffer, size,
maxSize, streamEndianness); maxSize, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
result = SerializeAdapter::serialize(&rows, buffer, size, maxSize, result = SerializeAdapter::serialize(&rows, buffer, size, maxSize,
streamEndianness); streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
for (uint8_t index = 0; index < rows; index++){ for (uint8_t index = 0; index < rows; index++){
GlobDataSet mySet; GlobDataSet mySet;
PoolRawAccess raw(poolId, index, &mySet,PoolVariableIF::VAR_READ); PoolRawAccess raw(poolId, index, &mySet,PoolVariableIF::VAR_READ);
mySet.read(); mySet.read();
result = raw.serialize(buffer,size,maxSize,streamEndianness); result = raw.serialize(buffer,size,maxSize,streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK){ if (result != HasReturnvaluesIF::RETURN_OK){
return result; return result;
} }
} }
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
//same as ParameterWrapper //same as ParameterWrapper
size_t DataPoolParameterWrapper::getSerializedSize() const { size_t DataPoolParameterWrapper::getSerializedSize() const {
size_t serializedSize = 0; size_t serializedSize = 0;
serializedSize += type.getSerializedSize(); serializedSize += type.getSerializedSize();
serializedSize += sizeof(rows); serializedSize += sizeof(rows);
serializedSize += sizeof(columns); serializedSize += sizeof(columns);
serializedSize += rows * columns * type.getSize(); serializedSize += rows * columns * type.getSize();
return serializedSize; return serializedSize;
} }
ReturnValue_t DataPoolParameterWrapper::deSerialize(const uint8_t** buffer, ReturnValue_t DataPoolParameterWrapper::deSerialize(const uint8_t** buffer,
size_t* size, Endianness streamEndianness) { size_t* size, Endianness streamEndianness) {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
template<typename T> template<typename T>
ReturnValue_t DataPoolParameterWrapper::deSerializeData(uint8_t startingRow, ReturnValue_t DataPoolParameterWrapper::deSerializeData(uint8_t startingRow,
uint8_t startingColumn, const void* from, uint8_t fromRows) { uint8_t startingColumn, const void* from, uint8_t fromRows) {
//treat from as a continuous Stream as we copy all of it //treat from as a continuous Stream as we copy all of it
const uint8_t *fromAsStream = (const uint8_t *) from; const uint8_t *fromAsStream = (const uint8_t *) from;
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
for (uint8_t fromRow = 0; fromRow < fromRows; fromRow++) { for (uint8_t fromRow = 0; fromRow < fromRows; fromRow++) {
GlobDataSet mySet; GlobDataSet mySet;
PoolRawAccess raw(poolId, startingRow + fromRow, &mySet, PoolRawAccess raw(poolId, startingRow + fromRow, &mySet,
PoolVariableIF::VAR_READ_WRITE); PoolVariableIF::VAR_READ_WRITE);
mySet.read(); mySet.read();
result = raw.setEntryFromBigEndian(fromAsStream, sizeof(T)); result = raw.setEntryFromBigEndian(fromAsStream, sizeof(T));
fromAsStream += sizeof(T); fromAsStream += sizeof(T);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
mySet.commit(); mySet.commit();
} }
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
ReturnValue_t DataPoolParameterWrapper::copyFrom(const ParameterWrapper* from, ReturnValue_t DataPoolParameterWrapper::copyFrom(const ParameterWrapper* from,
uint16_t startWritingAtIndex) { uint16_t startWritingAtIndex) {
if (poolId == PoolVariableIF::NO_PARAMETER) { if (poolId == PoolVariableIF::NO_PARAMETER) {
return ParameterWrapper::NOT_SET; return ParameterWrapper::NOT_SET;
} }
if (type != from->type) { if (type != from->type) {
return ParameterWrapper::DATATYPE_MISSMATCH; return ParameterWrapper::DATATYPE_MISSMATCH;
} }
//check if from fits into this //check if from fits into this
uint8_t startingRow = startWritingAtIndex / columns; uint8_t startingRow = startWritingAtIndex / columns;
uint8_t startingColumn = startWritingAtIndex % columns; uint8_t startingColumn = startWritingAtIndex % columns;
if ((from->rows > (rows - startingRow)) if ((from->rows > (rows - startingRow))
|| (from->columns > (columns - startingColumn))) { || (from->columns > (columns - startingColumn))) {
return ParameterWrapper::TOO_BIG; return ParameterWrapper::TOO_BIG;
} }
ReturnValue_t result; ReturnValue_t result;
//copy data //copy data
if (from->pointsToStream) { if (from->pointsToStream) {
switch (type) { switch (type) {
case Type::UINT8_T: case Type::UINT8_T:
result = deSerializeData<uint8_t>(startingRow, startingColumn, result = deSerializeData<uint8_t>(startingRow, startingColumn,
from->readonlyData, from->rows); from->readonlyData, from->rows);
break; break;
case Type::INT8_T: case Type::INT8_T:
result = deSerializeData<int8_t>(startingRow, startingColumn, result = deSerializeData<int8_t>(startingRow, startingColumn,
from->readonlyData, from->rows); from->readonlyData, from->rows);
break; break;
case Type::UINT16_T: case Type::UINT16_T:
result = deSerializeData<uint16_t>(startingRow, startingColumn, result = deSerializeData<uint16_t>(startingRow, startingColumn,
from->readonlyData, from->rows); from->readonlyData, from->rows);
break; break;
case Type::INT16_T: case Type::INT16_T:
result = deSerializeData<int16_t>(startingRow, startingColumn, result = deSerializeData<int16_t>(startingRow, startingColumn,
from->readonlyData, from->rows); from->readonlyData, from->rows);
break; break;
case Type::UINT32_T: case Type::UINT32_T:
result = deSerializeData<uint32_t>(startingRow, startingColumn, result = deSerializeData<uint32_t>(startingRow, startingColumn,
from->readonlyData, from->rows); from->readonlyData, from->rows);
break; break;
case Type::INT32_T: case Type::INT32_T:
result = deSerializeData<int32_t>(startingRow, startingColumn, result = deSerializeData<int32_t>(startingRow, startingColumn,
from->readonlyData, from->rows); from->readonlyData, from->rows);
break; break;
case Type::FLOAT: case Type::FLOAT:
result = deSerializeData<float>(startingRow, startingColumn, result = deSerializeData<float>(startingRow, startingColumn,
from->readonlyData, from->rows); from->readonlyData, from->rows);
break; break;
case Type::DOUBLE: case Type::DOUBLE:
result = deSerializeData<double>(startingRow, startingColumn, result = deSerializeData<double>(startingRow, startingColumn,
from->readonlyData, from->rows); from->readonlyData, from->rows);
break; break;
default: default:
result = ParameterWrapper::UNKNOW_DATATYPE; result = ParameterWrapper::UNKNOW_DATATYPE;
break; break;
} }
} else { } else {
//not supported //not supported
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
return result; return result;
} }

View File

@ -1,38 +1,38 @@
#ifndef DATAPOOLPARAMETERWRAPPER_H_ #ifndef DATAPOOLPARAMETERWRAPPER_H_
#define DATAPOOLPARAMETERWRAPPER_H_ #define DATAPOOLPARAMETERWRAPPER_H_
#include <framework/globalfunctions/Type.h> #include "../globalfunctions/Type.h"
#include <framework/parameters/ParameterWrapper.h> #include "../parameters/ParameterWrapper.h"
class DataPoolParameterWrapper: public SerializeIF { class DataPoolParameterWrapper: public SerializeIF {
public: public:
DataPoolParameterWrapper(); DataPoolParameterWrapper();
virtual ~DataPoolParameterWrapper(); virtual ~DataPoolParameterWrapper();
ReturnValue_t set(uint8_t domainId, uint16_t parameterId); ReturnValue_t set(uint8_t domainId, uint16_t parameterId);
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
size_t maxSize, Endianness streamEndianness) const override; size_t maxSize, Endianness streamEndianness) const override;
virtual size_t getSerializedSize() const override; virtual size_t getSerializedSize() const override;
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
Endianness streamEndianness) override; Endianness streamEndianness) override;
ReturnValue_t copyFrom(const ParameterWrapper *from, ReturnValue_t copyFrom(const ParameterWrapper *from,
uint16_t startWritingAtIndex); uint16_t startWritingAtIndex);
private: private:
Type type; Type type;
uint8_t rows; uint8_t rows;
uint8_t columns; uint8_t columns;
uint32_t poolId; uint32_t poolId;
template<typename T> template<typename T>
ReturnValue_t deSerializeData(uint8_t startingRow, uint8_t startingColumn, ReturnValue_t deSerializeData(uint8_t startingRow, uint8_t startingColumn,
const void *from, uint8_t fromRows); const void *from, uint8_t fromRows);
}; };
#endif /* DATAPOOLPARAMETERWRAPPER_H_ */ #endif /* DATAPOOLPARAMETERWRAPPER_H_ */

View File

@ -1,133 +1,133 @@
#include <framework/datapoolglob/GlobalDataPool.h> #include "../datapoolglob/GlobalDataPool.h"
#include <framework/serviceinterface/ServiceInterfaceStream.h> #include "../serviceinterface/ServiceInterfaceStream.h"
#include <framework/ipc/MutexFactory.h> #include "../ipc/MutexFactory.h"
GlobalDataPool::GlobalDataPool( GlobalDataPool::GlobalDataPool(
void(*initFunction)(GlobPoolMap* pool_map)) { void(*initFunction)(GlobPoolMap* pool_map)) {
mutex = MutexFactory::instance()->createMutex(); mutex = MutexFactory::instance()->createMutex();
if (initFunction != NULL ) { if (initFunction != NULL ) {
initFunction( &this->globDataPool ); initFunction( &this->globDataPool );
} }
} }
GlobalDataPool::~GlobalDataPool() { GlobalDataPool::~GlobalDataPool() {
MutexFactory::instance()->deleteMutex(mutex); MutexFactory::instance()->deleteMutex(mutex);
for(GlobPoolMapIter it = this->globDataPool.begin(); for(GlobPoolMapIter it = this->globDataPool.begin();
it != this->globDataPool.end(); ++it ) it != this->globDataPool.end(); ++it )
{ {
delete it->second; delete it->second;
} }
} }
// The function checks PID, type and array length before returning a copy of // The function checks PID, type and array length before returning a copy of
// the PoolEntry. In failure case, it returns a temp-Entry with size 0 and NULL-ptr. // the PoolEntry. In failure case, it returns a temp-Entry with size 0 and NULL-ptr.
template <typename T> PoolEntry<T>* GlobalDataPool::getData( uint32_t data_pool_id, template <typename T> PoolEntry<T>* GlobalDataPool::getData( uint32_t data_pool_id,
uint8_t sizeOrPosition ) { uint8_t sizeOrPosition ) {
GlobPoolMapIter it = this->globDataPool.find( data_pool_id ); GlobPoolMapIter it = this->globDataPool.find( data_pool_id );
if ( it != this->globDataPool.end() ) { if ( it != this->globDataPool.end() ) {
PoolEntry<T>* entry = dynamic_cast< PoolEntry<T>* >( it->second ); PoolEntry<T>* entry = dynamic_cast< PoolEntry<T>* >( it->second );
if (entry != nullptr ) { if (entry != nullptr ) {
if ( sizeOrPosition <= entry->length ) { if ( sizeOrPosition <= entry->length ) {
return entry; return entry;
} }
} }
} }
return nullptr; return nullptr;
} }
PoolEntryIF* GlobalDataPool::getRawData( uint32_t data_pool_id ) { PoolEntryIF* GlobalDataPool::getRawData( uint32_t data_pool_id ) {
GlobPoolMapIter it = this->globDataPool.find( data_pool_id ); GlobPoolMapIter it = this->globDataPool.find( data_pool_id );
if ( it != this->globDataPool.end() ) { if ( it != this->globDataPool.end() ) {
return it->second; return it->second;
} else { } else {
return nullptr; return nullptr;
} }
} }
ReturnValue_t GlobalDataPool::unlockDataPool() { ReturnValue_t GlobalDataPool::unlockDataPool() {
ReturnValue_t status = mutex->unlockMutex(); ReturnValue_t status = mutex->unlockMutex();
if(status != RETURN_OK) { if(status != RETURN_OK) {
sif::error << "DataPool::DataPool: unlock of mutex failed with" sif::error << "DataPool::DataPool: unlock of mutex failed with"
" error code: " << status << std::endl; " error code: " << status << std::endl;
} }
return status; return status;
} }
ReturnValue_t GlobalDataPool::lockDataPool(uint32_t timeoutMs) { ReturnValue_t GlobalDataPool::lockDataPool(uint32_t timeoutMs) {
ReturnValue_t status = mutex->lockMutex(MutexIF::TimeoutType::WAITING, ReturnValue_t status = mutex->lockMutex(MutexIF::TimeoutType::WAITING,
timeoutMs); timeoutMs);
if(status != RETURN_OK) { if(status != RETURN_OK) {
sif::error << "DataPool::DataPool: lock of mutex failed " sif::error << "DataPool::DataPool: lock of mutex failed "
"with error code: " << status << std::endl; "with error code: " << status << std::endl;
} }
return status; return status;
} }
void GlobalDataPool::print() { void GlobalDataPool::print() {
sif::debug << "DataPool contains: " << std::endl; sif::debug << "DataPool contains: " << std::endl;
std::map<uint32_t, PoolEntryIF*>::iterator dataPoolIt; std::map<uint32_t, PoolEntryIF*>::iterator dataPoolIt;
dataPoolIt = this->globDataPool.begin(); dataPoolIt = this->globDataPool.begin();
while( dataPoolIt != this->globDataPool.end() ) { while( dataPoolIt != this->globDataPool.end() ) {
sif::debug << std::hex << dataPoolIt->first << std::dec << " |"; sif::debug << std::hex << dataPoolIt->first << std::dec << " |";
dataPoolIt->second->print(); dataPoolIt->second->print();
dataPoolIt++; dataPoolIt++;
} }
} }
uint32_t GlobalDataPool::PIDToDataPoolId(uint32_t parameter_id) { uint32_t GlobalDataPool::PIDToDataPoolId(uint32_t parameter_id) {
return (parameter_id >> 8) & 0x00FFFFFF; return (parameter_id >> 8) & 0x00FFFFFF;
} }
uint8_t GlobalDataPool::PIDToArrayIndex(uint32_t parameter_id) { uint8_t GlobalDataPool::PIDToArrayIndex(uint32_t parameter_id) {
return (parameter_id & 0x000000FF); return (parameter_id & 0x000000FF);
} }
uint32_t GlobalDataPool::poolIdAndPositionToPid(uint32_t poolId, uint8_t index) { uint32_t GlobalDataPool::poolIdAndPositionToPid(uint32_t poolId, uint8_t index) {
return (poolId << 8) + index; return (poolId << 8) + index;
} }
//SHOULDDO: Do we need a mutex lock here... I don't think so, //SHOULDDO: Do we need a mutex lock here... I don't think so,
//as we only check static const values of elements in a list that do not change. //as we only check static const values of elements in a list that do not change.
//there is no guarantee in the standard, but it seems to me that the implementation is safe -UM //there is no guarantee in the standard, but it seems to me that the implementation is safe -UM
ReturnValue_t GlobalDataPool::getType(uint32_t parameter_id, Type* type) { ReturnValue_t GlobalDataPool::getType(uint32_t parameter_id, Type* type) {
GlobPoolMapIter it = this->globDataPool.find( PIDToDataPoolId(parameter_id)); GlobPoolMapIter it = this->globDataPool.find( PIDToDataPoolId(parameter_id));
if ( it != this->globDataPool.end() ) { if ( it != this->globDataPool.end() ) {
*type = it->second->getType(); *type = it->second->getType();
return RETURN_OK; return RETURN_OK;
} else { } else {
*type = Type::UNKNOWN_TYPE; *type = Type::UNKNOWN_TYPE;
return RETURN_FAILED; return RETURN_FAILED;
} }
} }
bool GlobalDataPool::exists(uint32_t parameterId) { bool GlobalDataPool::exists(uint32_t parameterId) {
uint32_t poolId = PIDToDataPoolId(parameterId); uint32_t poolId = PIDToDataPoolId(parameterId);
uint32_t index = PIDToArrayIndex(parameterId); uint32_t index = PIDToArrayIndex(parameterId);
GlobPoolMapIter it = this->globDataPool.find( poolId ); GlobPoolMapIter it = this->globDataPool.find( poolId );
if (it != globDataPool.end()) { if (it != globDataPool.end()) {
if (it->second->getSize() >= index) { if (it->second->getSize() >= index) {
return true; return true;
} }
} }
return false; return false;
} }
template PoolEntry<uint8_t>* GlobalDataPool::getData<uint8_t>( template PoolEntry<uint8_t>* GlobalDataPool::getData<uint8_t>(
uint32_t data_pool_id, uint8_t size ); uint32_t data_pool_id, uint8_t size );
template PoolEntry<uint16_t>* GlobalDataPool::getData<uint16_t>( template PoolEntry<uint16_t>* GlobalDataPool::getData<uint16_t>(
uint32_t data_pool_id, uint8_t size ); uint32_t data_pool_id, uint8_t size );
template PoolEntry<uint32_t>* GlobalDataPool::getData<uint32_t>( template PoolEntry<uint32_t>* GlobalDataPool::getData<uint32_t>(
uint32_t data_pool_id, uint8_t size ); uint32_t data_pool_id, uint8_t size );
template PoolEntry<uint64_t>* GlobalDataPool::getData<uint64_t>( template PoolEntry<uint64_t>* GlobalDataPool::getData<uint64_t>(
uint32_t data_pool_id, uint8_t size); uint32_t data_pool_id, uint8_t size);
template PoolEntry<int8_t>* GlobalDataPool::getData<int8_t>( template PoolEntry<int8_t>* GlobalDataPool::getData<int8_t>(
uint32_t data_pool_id, uint8_t size ); uint32_t data_pool_id, uint8_t size );
template PoolEntry<int16_t>* GlobalDataPool::getData<int16_t>( template PoolEntry<int16_t>* GlobalDataPool::getData<int16_t>(
uint32_t data_pool_id, uint8_t size ); uint32_t data_pool_id, uint8_t size );
template PoolEntry<int32_t>* GlobalDataPool::getData<int32_t>( template PoolEntry<int32_t>* GlobalDataPool::getData<int32_t>(
uint32_t data_pool_id, uint8_t size ); uint32_t data_pool_id, uint8_t size );
template PoolEntry<float>* GlobalDataPool::getData<float>( template PoolEntry<float>* GlobalDataPool::getData<float>(
uint32_t data_pool_id, uint8_t size ); uint32_t data_pool_id, uint8_t size );
template PoolEntry<double>* GlobalDataPool::getData<double>( template PoolEntry<double>* GlobalDataPool::getData<double>(
uint32_t data_pool_id, uint8_t size); uint32_t data_pool_id, uint8_t size);

View File

@ -1,149 +1,149 @@
#ifndef GLOBALDATAPOOL_H_ #ifndef GLOBALDATAPOOL_H_
#define GLOBALDATAPOOL_H_ #define GLOBALDATAPOOL_H_
#include <framework/datapool/PoolEntry.h> #include "../datapool/PoolEntry.h"
#include <framework/globalfunctions/Type.h> #include "../globalfunctions/Type.h"
#include <framework/ipc/MutexIF.h> #include "../ipc/MutexIF.h"
#include <map> #include <map>
/** /**
* @defgroup data_pool Global data pool * @defgroup data_pool Global data pool
* This is the group, where all classes associated with global * This is the group, where all classes associated with global
* data pool handling belong to. * data pool handling belong to.
* This includes classes to access Data Pool variables. * This includes classes to access Data Pool variables.
*/ */
/** /**
* Typedefs for the global pool representations * Typedefs for the global pool representations
*/ */
using GlobPoolMap = std::map<uint32_t, PoolEntryIF*>; using GlobPoolMap = std::map<uint32_t, PoolEntryIF*>;
using GlobPoolMapIter = GlobPoolMap::iterator; using GlobPoolMapIter = GlobPoolMap::iterator;
/** /**
* @brief This class represents the OBSW global data-pool. * @brief This class represents the OBSW global data-pool.
* *
* @details * @details
* All variables are registered and space is allocated in an initialization * All variables are registered and space is allocated in an initialization
* function, which is passed do the constructor. Space for the variables is * function, which is passed do the constructor. Space for the variables is
* allocated on the heap (with a new call). * allocated on the heap (with a new call).
* *
* The data is found by a data pool id, which uniquely represents a variable. * The data is found by a data pool id, which uniquely represents a variable.
* Data pool variables should be used with a blackboard logic in mind, * Data pool variables should be used with a blackboard logic in mind,
* which means read data is valid (if flagged so), * which means read data is valid (if flagged so),
* but not necessarily up-to-date. * but not necessarily up-to-date.
* *
* Variables are either single values or arrays. * Variables are either single values or arrays.
* @author Bastian Baetz * @author Bastian Baetz
* @ingroup data_pool * @ingroup data_pool
*/ */
class GlobalDataPool : public HasReturnvaluesIF { class GlobalDataPool : public HasReturnvaluesIF {
private: private:
/** /**
* @brief This is the actual data pool itself. * @brief This is the actual data pool itself.
* @details It is represented by a map with the data pool id as index * @details It is represented by a map with the data pool id as index
* and a pointer to a single PoolEntry as value. * and a pointer to a single PoolEntry as value.
*/ */
GlobPoolMap globDataPool; GlobPoolMap globDataPool;
/** /**
* @brief The mutex is created in the constructor and makes * @brief The mutex is created in the constructor and makes
* access mutual exclusive. * access mutual exclusive.
* @details Locking and unlocking the pool is only done by the DataSet class. * @details Locking and unlocking the pool is only done by the DataSet class.
*/ */
MutexIF* mutex; MutexIF* mutex;
public: public:
/** /**
* @brief In the classes constructor, * @brief In the classes constructor,
* the passed initialization function is called. * the passed initialization function is called.
* @details * @details
* To enable filling the pool, a pointer to the map is passed, * To enable filling the pool, a pointer to the map is passed,
* allowing direct access to the pool's content. * allowing direct access to the pool's content.
* On runtime, adding or removing variables is forbidden. * On runtime, adding or removing variables is forbidden.
*/ */
GlobalDataPool( void ( *initFunction )( GlobPoolMap* pool_map ) ); GlobalDataPool( void ( *initFunction )( GlobPoolMap* pool_map ) );
/** /**
* @brief The destructor iterates through the data_pool map and * @brief The destructor iterates through the data_pool map and
* calls all entries destructors to clean up the heap. * calls all entries destructors to clean up the heap.
*/ */
~GlobalDataPool(); ~GlobalDataPool();
/** /**
* @brief This is the default call to access the pool. * @brief This is the default call to access the pool.
* @details * @details
* A pointer to the PoolEntry object is returned. * A pointer to the PoolEntry object is returned.
* The call checks data pool id, type and array size. * The call checks data pool id, type and array size.
* Returns NULL in case of failure. * Returns NULL in case of failure.
* @param data_pool_id The data pool id to search. * @param data_pool_id The data pool id to search.
* @param sizeOrPosition The array size (not byte size!) of the pool entry, * @param sizeOrPosition The array size (not byte size!) of the pool entry,
* or the position the user wants to read. * or the position the user wants to read.
* If smaller than the entry size, everything's ok. * If smaller than the entry size, everything's ok.
*/ */
template <typename T> PoolEntry<T>* getData( uint32_t data_pool_id, template <typename T> PoolEntry<T>* getData( uint32_t data_pool_id,
uint8_t sizeOrPosition ); uint8_t sizeOrPosition );
/** /**
* @brief An alternative call to get a data pool entry in case the type is not implicitly known * @brief An alternative call to get a data pool entry in case the type is not implicitly known
* (i.e. in Housekeeping Telemetry). * (i.e. in Housekeeping Telemetry).
* @details It returns a basic interface and does NOT perform * @details It returns a basic interface and does NOT perform
* a size check. The caller has to assure he does not copy too much data. * a size check. The caller has to assure he does not copy too much data.
* Returns NULL in case the entry is not found. * Returns NULL in case the entry is not found.
* @param data_pool_id The data pool id to search. * @param data_pool_id The data pool id to search.
*/ */
PoolEntryIF* getRawData( uint32_t data_pool_id ); PoolEntryIF* getRawData( uint32_t data_pool_id );
/** /**
* @brief This is a small helper function to facilitate locking the global data pool. * @brief This is a small helper function to facilitate locking the global data pool.
* @details It fetches the pool's mutex id and tries to acquire the mutex. * @details It fetches the pool's mutex id and tries to acquire the mutex.
*/ */
ReturnValue_t lockDataPool(uint32_t timeoutMs = MutexIF::BLOCKING); ReturnValue_t lockDataPool(uint32_t timeoutMs = MutexIF::BLOCKING);
/** /**
* @brief This is a small helper function to facilitate unlocking the global data pool. * @brief This is a small helper function to facilitate unlocking the global data pool.
* @details It fetches the pool's mutex id and tries to free the mutex. * @details It fetches the pool's mutex id and tries to free the mutex.
*/ */
ReturnValue_t unlockDataPool(); ReturnValue_t unlockDataPool();
/** /**
* @brief The print call is a simple debug method. * @brief The print call is a simple debug method.
* @details It prints the current content of the data pool. * @details It prints the current content of the data pool.
* It iterates through the data_pool map and calls each entry's print() method. * It iterates through the data_pool map and calls each entry's print() method.
*/ */
void print(); void print();
/** /**
* Extracts the data pool id from a SCOS 2000 PID. * Extracts the data pool id from a SCOS 2000 PID.
* @param parameter_id The passed Parameter ID. * @param parameter_id The passed Parameter ID.
* @return The data pool id as used within the OBSW. * @return The data pool id as used within the OBSW.
*/ */
static uint32_t PIDToDataPoolId( uint32_t parameter_id ); static uint32_t PIDToDataPoolId( uint32_t parameter_id );
/** /**
* Extracts an array index out of a SCOS 2000 PID. * Extracts an array index out of a SCOS 2000 PID.
* @param parameter_id The passed Parameter ID. * @param parameter_id The passed Parameter ID.
* @return The index of the corresponding data pool entry. * @return The index of the corresponding data pool entry.
*/ */
static uint8_t PIDToArrayIndex( uint32_t parameter_id ); static uint8_t PIDToArrayIndex( uint32_t parameter_id );
/** /**
* Retransforms a data pool id and an array index to a SCOS 2000 PID. * Retransforms a data pool id and an array index to a SCOS 2000 PID.
*/ */
static uint32_t poolIdAndPositionToPid( uint32_t poolId, uint8_t index ); static uint32_t poolIdAndPositionToPid( uint32_t poolId, uint8_t index );
/** /**
* Method to return the type of a pool variable. * Method to return the type of a pool variable.
* @param parameter_id A parameterID (not pool id) of a DP member. * @param parameter_id A parameterID (not pool id) of a DP member.
* @param type Returns the type or TYPE::UNKNOWN_TYPE * @param type Returns the type or TYPE::UNKNOWN_TYPE
* @return RETURN_OK if parameter exists, RETURN_FAILED else. * @return RETURN_OK if parameter exists, RETURN_FAILED else.
*/ */
ReturnValue_t getType( uint32_t parameter_id, Type* type ); ReturnValue_t getType( uint32_t parameter_id, Type* type );
/** /**
* Method to check if a PID exists. Does not lock, as there's no * Method to check if a PID exists. Does not lock, as there's no
* possibility to alter the list that is checked during run-time. * possibility to alter the list that is checked during run-time.
* @param parameterId The PID (not pool id!) of a parameter. * @param parameterId The PID (not pool id!) of a parameter.
* @return true if exists, false else. * @return true if exists, false else.
*/ */
bool exists(uint32_t parameterId); bool exists(uint32_t parameterId);
}; };
//We assume someone globally instantiates a DataPool. //We assume someone globally instantiates a DataPool.
namespace glob { namespace glob {
extern GlobalDataPool dataPool; extern GlobalDataPool dataPool;
} }
#endif /* DATAPOOL_H_ */ #endif /* DATAPOOL_H_ */

View File

@ -1,6 +1,6 @@
#include <framework/datapoolglob/GlobalDataPool.h> #include "../datapoolglob/GlobalDataPool.h"
#include <framework/datapoolglob/GlobalDataSet.h> #include "../datapoolglob/GlobalDataSet.h"
#include <framework/serviceinterface/ServiceInterfaceStream.h> #include "../serviceinterface/ServiceInterfaceStream.h"
GlobDataSet::GlobDataSet(): PoolDataSetBase( GlobDataSet::GlobDataSet(): PoolDataSetBase(
reinterpret_cast<PoolVariableIF**>(&registeredVariables), reinterpret_cast<PoolVariableIF**>(&registeredVariables),

View File

@ -1,7 +1,7 @@
#ifndef FRAMEWORK_DATAPOOLGLOB_DATASET_H_ #ifndef FRAMEWORK_DATAPOOLGLOB_DATASET_H_
#define FRAMEWORK_DATAPOOLGLOB_DATASET_H_ #define FRAMEWORK_DATAPOOLGLOB_DATASET_H_
#include <framework/datapool/PoolDataSetBase.h> #include "../datapool/PoolDataSetBase.h"
/** /**
* @brief The DataSet class manages a set of locally checked out variables * @brief The DataSet class manages a set of locally checked out variables

View File

@ -1,213 +1,213 @@
#ifndef GLOBALPOOLVARIABLE_H_ #ifndef GLOBALPOOLVARIABLE_H_
#define GLOBALPOOLVARIABLE_H_ #define GLOBALPOOLVARIABLE_H_
#include <framework/datapool/DataSetIF.h> #include "../datapool/DataSetIF.h"
#include <framework/datapoolglob/GlobalDataPool.h> #include "../datapoolglob/GlobalDataPool.h"
#include <framework/datapool/PoolVariableIF.h> #include "../datapool/PoolVariableIF.h"
#include <framework/datapool/PoolEntry.h> #include "../datapool/PoolEntry.h"
#include <framework/serialize/SerializeAdapter.h> #include "../serialize/SerializeAdapter.h"
#include <framework/serviceinterface/ServiceInterfaceStream.h> #include "../serviceinterface/ServiceInterfaceStream.h"
template<typename T, uint8_t n_var> class PoolVarList; template<typename T, uint8_t n_var> class PoolVarList;
/** /**
* @brief This is the access class for non-array data pool entries. * @brief This is the access class for non-array data pool entries.
* *
* @details * @details
* To ensure safe usage of the data pool, operation is not done directly * To ensure safe usage of the data pool, operation is not done directly
* on the data pool entries, but on local copies. This class provides simple * on the data pool entries, but on local copies. This class provides simple
* type-safe access to single data pool entries (i.e. entries with length = 1). * type-safe access to single data pool entries (i.e. entries with length = 1).
* The class can be instantiated as read-write and read only. * The class can be instantiated as read-write and read only.
* It provides a commit-and-roll-back semantic, which means that the * It provides a commit-and-roll-back semantic, which means that the
* variable's value in the data pool is not changed until the * variable's value in the data pool is not changed until the
* commit call is executed. * commit call is executed.
* @tparam T The template parameter sets the type of the variable. * @tparam T The template parameter sets the type of the variable.
* Currently, all plain data types are supported, but in principle * Currently, all plain data types are supported, but in principle
* any type is possible. * any type is possible.
* @ingroup data_pool * @ingroup data_pool
*/ */
template<typename T> template<typename T>
class GlobPoolVar: public PoolVariableIF { class GlobPoolVar: public PoolVariableIF {
template<typename U, uint8_t n_var> friend class PoolVarList; template<typename U, uint8_t n_var> friend class PoolVarList;
static_assert(not std::is_same<T, bool>::value, static_assert(not std::is_same<T, bool>::value,
"Do not use boolean for the PoolEntry type, use uint8_t instead!" "Do not use boolean for the PoolEntry type, use uint8_t instead!"
"There is no boolean type in CCSDS."); "There is no boolean type in CCSDS.");
public: public:
/** /**
* @brief In the constructor, the variable can register itself in a * @brief In the constructor, the variable can register itself in a
* DataSet (if nullptr is not passed). * DataSet (if nullptr is not passed).
* @details * @details
* It DOES NOT fetch the current value from the data pool, but * It DOES NOT fetch the current value from the data pool, but
* sets the value attribute to default (0). * sets the value attribute to default (0).
* The value is fetched within the read() operation. * The value is fetched within the read() operation.
* @param set_id This is the id in the global data pool * @param set_id This is the id in the global data pool
* this instance of the access class corresponds to. * this instance of the access class corresponds to.
* @param dataSet The data set in which the variable shall register * @param dataSet The data set in which the variable shall register
* itself. If NULL, the variable is not registered. * itself. If NULL, the variable is not registered.
* @param setWritable If this flag is set to true, changes in the value * @param setWritable If this flag is set to true, changes in the value
* attribute can be written back to the data pool, otherwise not. * attribute can be written back to the data pool, otherwise not.
*/ */
GlobPoolVar(uint32_t set_id, DataSetIF* dataSet, GlobPoolVar(uint32_t set_id, DataSetIF* dataSet,
ReadWriteMode_t setReadWriteMode); ReadWriteMode_t setReadWriteMode);
/** /**
* @brief This is the local copy of the data pool entry. * @brief This is the local copy of the data pool entry.
* @details The user can work on this attribute * @details The user can work on this attribute
* just like he would on a simple local variable. * just like he would on a simple local variable.
*/ */
T value = 0; T value = 0;
/** /**
* @brief Copy ctor to copy classes containing Pool Variables. * @brief Copy ctor to copy classes containing Pool Variables.
* (Robin): This only copies member variables, which is done * (Robin): This only copies member variables, which is done
* by the default copy ctor. maybe we can ommit this ctor? * by the default copy ctor. maybe we can ommit this ctor?
*/ */
GlobPoolVar(const GlobPoolVar& rhs); GlobPoolVar(const GlobPoolVar& rhs);
/** /**
* @brief The classes destructor is empty. * @brief The classes destructor is empty.
* @details If commit() was not called, the local value is * @details If commit() was not called, the local value is
* discarded and not written back to the data pool. * discarded and not written back to the data pool.
*/ */
~GlobPoolVar() {} ~GlobPoolVar() {}
/** /**
* @brief This is a call to read the value from the global data pool. * @brief This is a call to read the value from the global data pool.
* @details * @details
* When executed, this operation tries to fetch the pool entry with matching * When executed, this operation tries to fetch the pool entry with matching
* data pool id from the global data pool and copies the value and the valid * data pool id from the global data pool and copies the value and the valid
* information to its local attributes. In case of a failure (wrong type or * information to its local attributes. In case of a failure (wrong type or
* pool id not found), the variable is set to zero and invalid. * pool id not found), the variable is set to zero and invalid.
* The read call is protected with a lock. * The read call is protected with a lock.
* It is recommended to use DataSets to read and commit multiple variables * It is recommended to use DataSets to read and commit multiple variables
* at once to avoid the overhead of unnecessary lock und unlock operations. * at once to avoid the overhead of unnecessary lock und unlock operations.
*/ */
ReturnValue_t read(uint32_t lockTimeout) override; ReturnValue_t read(uint32_t lockTimeout) override;
/** /**
* @brief The commit call writes back the variable's value to the data pool. * @brief The commit call writes back the variable's value to the data pool.
* @details * @details
* It checks type and size, as well as if the variable is writable. If so, * It checks type and size, as well as if the variable is writable. If so,
* the value is copied and the valid flag is automatically set to "valid". * the value is copied and the valid flag is automatically set to "valid".
* The operation does NOT provide any mutual exclusive protection by itself. * The operation does NOT provide any mutual exclusive protection by itself.
* The commit call is protected with a lock. * The commit call is protected with a lock.
* It is recommended to use DataSets to read and commit multiple variables * It is recommended to use DataSets to read and commit multiple variables
* at once to avoid the overhead of unnecessary lock und unlock operations. * at once to avoid the overhead of unnecessary lock und unlock operations.
*/ */
ReturnValue_t commit(uint32_t lockTimeout) override; ReturnValue_t commit(uint32_t lockTimeout) override;
protected: protected:
/** /**
* @brief Like #read, but without a lock protection of the global pool. * @brief Like #read, but without a lock protection of the global pool.
* @details * @details
* The operation does NOT provide any mutual exclusive protection by itself. * The operation does NOT provide any mutual exclusive protection by itself.
* This can be used if the lock is handled externally to avoid the overhead * This can be used if the lock is handled externally to avoid the overhead
* of consecutive lock und unlock operations. * of consecutive lock und unlock operations.
* Declared protected to discourage free public usage. * Declared protected to discourage free public usage.
*/ */
ReturnValue_t readWithoutLock() override; ReturnValue_t readWithoutLock() override;
/** /**
* @brief Like #commit, but without a lock protection of the global pool. * @brief Like #commit, but without a lock protection of the global pool.
* @details * @details
* The operation does NOT provide any mutual exclusive protection by itself. * The operation does NOT provide any mutual exclusive protection by itself.
* This can be used if the lock is handled externally to avoid the overhead * This can be used if the lock is handled externally to avoid the overhead
* of consecutive lock und unlock operations. * of consecutive lock und unlock operations.
* Declared protected to discourage free public usage. * Declared protected to discourage free public usage.
*/ */
ReturnValue_t commitWithoutLock() override; ReturnValue_t commitWithoutLock() override;
/** /**
* @brief To access the correct data pool entry on read and commit calls, * @brief To access the correct data pool entry on read and commit calls,
* the data pool is stored. * the data pool is stored.
*/ */
uint32_t dataPoolId; uint32_t dataPoolId;
/** /**
* @brief The valid information as it was stored in the data pool is * @brief The valid information as it was stored in the data pool is
* copied to this attribute. * copied to this attribute.
*/ */
uint8_t valid; uint8_t valid;
/** /**
* @brief The information whether the class is read-write or read-only * @brief The information whether the class is read-write or read-only
* is stored here. * is stored here.
*/ */
pool_rwm_t readWriteMode; pool_rwm_t readWriteMode;
/** /**
* Empty ctor for List initialization * Empty ctor for List initialization
*/ */
GlobPoolVar(); GlobPoolVar();
public: public:
/** /**
* \brief This operation returns the data pool id of the variable. * \brief This operation returns the data pool id of the variable.
*/ */
uint32_t getDataPoolId() const override; uint32_t getDataPoolId() const override;
/** /**
* This method returns if the variable is write-only, read-write or read-only. * This method returns if the variable is write-only, read-write or read-only.
*/ */
ReadWriteMode_t getReadWriteMode() const override; ReadWriteMode_t getReadWriteMode() const override;
/** /**
* This operation sets the data pool id of the variable. * This operation sets the data pool id of the variable.
* The method is necessary to set id's of data pool member variables with bad initialization. * The method is necessary to set id's of data pool member variables with bad initialization.
*/ */
void setDataPoolId(uint32_t poolId); void setDataPoolId(uint32_t poolId);
/** /**
* \brief With this call, the valid information of the variable is returned. * \brief With this call, the valid information of the variable is returned.
*/ */
bool isValid() const override; bool isValid() const override;
uint8_t getValid(); uint8_t getValid();
void setValid(bool valid) override; void setValid(bool valid) override;
operator T() { operator T() {
return value; return value;
} }
operator T() const { operator T() const {
return value; return value;
} }
GlobPoolVar<T> &operator=(T newValue) { GlobPoolVar<T> &operator=(T newValue) {
value = newValue; value = newValue;
return *this; return *this;
} }
GlobPoolVar<T> &operator=(GlobPoolVar<T> newPoolVariable) { GlobPoolVar<T> &operator=(GlobPoolVar<T> newPoolVariable) {
value = newPoolVariable.value; value = newPoolVariable.value;
return *this; return *this;
} }
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
const size_t max_size, const size_t max_size,
SerializeIF::Endianness streamEndianness) const override { SerializeIF::Endianness streamEndianness) const override {
return SerializeAdapter::serialize(&value, buffer, size, max_size, return SerializeAdapter::serialize(&value, buffer, size, max_size,
streamEndianness); streamEndianness);
} }
virtual size_t getSerializedSize() const { virtual size_t getSerializedSize() const {
return SerializeAdapter::getSerializedSize(&value); return SerializeAdapter::getSerializedSize(&value);
} }
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
SerializeIF::Endianness streamEndianness) { SerializeIF::Endianness streamEndianness) {
return SerializeAdapter::deSerialize(&value, buffer, size, return SerializeAdapter::deSerialize(&value, buffer, size,
streamEndianness); streamEndianness);
} }
}; };
#include <framework/datapoolglob/GlobalPoolVariable.tpp> #include "../datapoolglob/GlobalPoolVariable.tpp"
typedef GlobPoolVar<uint8_t> gp_bool_t; typedef GlobPoolVar<uint8_t> gp_bool_t;
typedef GlobPoolVar<uint8_t> gp_uint8_t; typedef GlobPoolVar<uint8_t> gp_uint8_t;
typedef GlobPoolVar<uint16_t> gp_uint16_t; typedef GlobPoolVar<uint16_t> gp_uint16_t;
typedef GlobPoolVar<uint32_t> gp_uint32_t; typedef GlobPoolVar<uint32_t> gp_uint32_t;
typedef GlobPoolVar<int8_t> gp_int8_t; typedef GlobPoolVar<int8_t> gp_int8_t;
typedef GlobPoolVar<int16_t> gp_int16_t; typedef GlobPoolVar<int16_t> gp_int16_t;
typedef GlobPoolVar<int32_t> gp_int32_t; typedef GlobPoolVar<int32_t> gp_int32_t;
typedef GlobPoolVar<float> gp_float_t; typedef GlobPoolVar<float> gp_float_t;
typedef GlobPoolVar<double> gp_double_t; typedef GlobPoolVar<double> gp_double_t;
#endif /* POOLVARIABLE_H_ */ #endif /* POOLVARIABLE_H_ */

View File

@ -1,185 +1,185 @@
#ifndef GLOBALPOOLVECTOR_H_ #ifndef GLOBALPOOLVECTOR_H_
#define GLOBALPOOLVECTOR_H_ #define GLOBALPOOLVECTOR_H_
#include <framework/datapool/DataSetIF.h> #include "../datapool/DataSetIF.h"
#include <framework/datapool/PoolEntry.h> #include "../datapool/PoolEntry.h"
#include <framework/datapool/PoolVariableIF.h> #include "../datapool/PoolVariableIF.h"
#include <framework/serialize/SerializeAdapter.h> #include "../serialize/SerializeAdapter.h"
#include <framework/serviceinterface/ServiceInterfaceStream.h> #include "../serviceinterface/ServiceInterfaceStream.h"
/** /**
* @brief This is the access class for array-type data pool entries. * @brief This is the access class for array-type data pool entries.
* *
* @details * @details
* To ensure safe usage of the data pool, operation is not done directly on the * To ensure safe usage of the data pool, operation is not done directly on the
* data pool entries, but on local copies. This class provides simple type- * data pool entries, but on local copies. This class provides simple type-
* and length-safe access to vector-style data pool entries (i.e. entries with * and length-safe access to vector-style data pool entries (i.e. entries with
* length > 1). The class can be instantiated as read-write and read only. * length > 1). The class can be instantiated as read-write and read only.
* *
* It provides a commit-and-roll-back semantic, which means that no array * It provides a commit-and-roll-back semantic, which means that no array
* entry in the data pool is changed until the commit call is executed. * entry in the data pool is changed until the commit call is executed.
* There are two template parameters: * There are two template parameters:
* @tparam T * @tparam T
* This template parameter specifies the data type of an array entry. Currently, * This template parameter specifies the data type of an array entry. Currently,
* all plain data types are supported, but in principle any type is possible. * all plain data types are supported, but in principle any type is possible.
* @tparam vector_size * @tparam vector_size
* This template parameter specifies the vector size of this entry. Using a * This template parameter specifies the vector size of this entry. Using a
* template parameter for this is not perfect, but avoids * template parameter for this is not perfect, but avoids
* dynamic memory allocation. * dynamic memory allocation.
* @ingroup data_pool * @ingroup data_pool
*/ */
template<typename T, uint16_t vectorSize> template<typename T, uint16_t vectorSize>
class GlobPoolVector: public PoolVariableIF { class GlobPoolVector: public PoolVariableIF {
public: public:
/** /**
* @brief In the constructor, the variable can register itself in a * @brief In the constructor, the variable can register itself in a
* DataSet (if no nullptr is passed). * DataSet (if no nullptr is passed).
* @details * @details
* It DOES NOT fetch the current value from the data pool, but sets the * It DOES NOT fetch the current value from the data pool, but sets the
* value attribute to default (0). The value is fetched within the * value attribute to default (0). The value is fetched within the
* read() operation. * read() operation.
* @param set_id * @param set_id
* This is the id in the global data pool this instance of the access * This is the id in the global data pool this instance of the access
* class corresponds to. * class corresponds to.
* @param dataSet * @param dataSet
* The data set in which the variable shall register itself. If nullptr, * The data set in which the variable shall register itself. If nullptr,
* the variable is not registered. * the variable is not registered.
* @param setWritable * @param setWritable
* If this flag is set to true, changes in the value attribute can be * If this flag is set to true, changes in the value attribute can be
* written back to the data pool, otherwise not. * written back to the data pool, otherwise not.
*/ */
GlobPoolVector(uint32_t set_id, DataSetIF* set, GlobPoolVector(uint32_t set_id, DataSetIF* set,
ReadWriteMode_t setReadWriteMode); ReadWriteMode_t setReadWriteMode);
/** /**
* @brief This is the local copy of the data pool entry. * @brief This is the local copy of the data pool entry.
* @details The user can work on this attribute * @details The user can work on this attribute
* just like he would on a local array of this type. * just like he would on a local array of this type.
*/ */
T value[vectorSize]; T value[vectorSize];
/** /**
* @brief The classes destructor is empty. * @brief The classes destructor is empty.
* @details If commit() was not called, the local value is * @details If commit() was not called, the local value is
* discarded and not written back to the data pool. * discarded and not written back to the data pool.
*/ */
~GlobPoolVector() {}; ~GlobPoolVector() {};
/** /**
* @brief The operation returns the number of array entries * @brief The operation returns the number of array entries
* in this variable. * in this variable.
*/ */
uint8_t getSize() { uint8_t getSize() {
return vectorSize; return vectorSize;
} }
/** /**
* @brief This operation returns the data pool id of the variable. * @brief This operation returns the data pool id of the variable.
*/ */
uint32_t getDataPoolId() const { uint32_t getDataPoolId() const {
return dataPoolId; return dataPoolId;
} }
/** /**
* @brief This operation sets the data pool id of the variable. * @brief This operation sets the data pool id of the variable.
* @details * @details
* The method is necessary to set id's of data pool member variables * The method is necessary to set id's of data pool member variables
* with bad initialization. * with bad initialization.
*/ */
void setDataPoolId(uint32_t poolId) { void setDataPoolId(uint32_t poolId) {
dataPoolId = poolId; dataPoolId = poolId;
} }
/** /**
* This method returns if the variable is write-only, read-write or read-only. * This method returns if the variable is write-only, read-write or read-only.
*/ */
ReadWriteMode_t getReadWriteMode() const { ReadWriteMode_t getReadWriteMode() const {
return readWriteMode; return readWriteMode;
} }
/** /**
* @brief With this call, the valid information of the variable is returned. * @brief With this call, the valid information of the variable is returned.
*/ */
bool isValid() const { bool isValid() const {
if (valid != INVALID) if (valid != INVALID)
return true; return true;
else else
return false; return false;
} }
void setValid(bool valid) {this->valid = valid;} void setValid(bool valid) {this->valid = valid;}
uint8_t getValid() {return valid;} uint8_t getValid() {return valid;}
T &operator [](int i) {return value[i];} T &operator [](int i) {return value[i];}
const T &operator [](int i) const {return value[i];} const T &operator [](int i) const {return value[i];}
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
size_t max_size, Endianness streamEndianness) const override; size_t max_size, Endianness streamEndianness) const override;
virtual size_t getSerializedSize() const override; virtual size_t getSerializedSize() const override;
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
Endianness streamEndianness) override; Endianness streamEndianness) override;
/** /**
* @brief This is a call to read the array's values * @brief This is a call to read the array's values
* from the global data pool. * from the global data pool.
* @details * @details
* When executed, this operation tries to fetch the pool entry with matching * When executed, this operation tries to fetch the pool entry with matching
* data pool id from the global data pool and copies all array values * data pool id from the global data pool and copies all array values
* and the valid information to its local attributes. * and the valid information to its local attributes.
* In case of a failure (wrong type, size or pool id not found), the * In case of a failure (wrong type, size or pool id not found), the
* variable is set to zero and invalid. * variable is set to zero and invalid.
* The read call is protected by a lock of the global data pool. * The read call is protected by a lock of the global data pool.
* It is recommended to use DataSets to read and commit multiple variables * It is recommended to use DataSets to read and commit multiple variables
* at once to avoid the overhead of unnecessary lock und unlock operations. * at once to avoid the overhead of unnecessary lock und unlock operations.
*/ */
ReturnValue_t read(uint32_t lockTimeout = MutexIF::BLOCKING) override; ReturnValue_t read(uint32_t lockTimeout = MutexIF::BLOCKING) override;
/** /**
* @brief The commit call copies the array values back to the data pool. * @brief The commit call copies the array values back to the data pool.
* @details * @details
* It checks type and size, as well as if the variable is writable. If so, * It checks type and size, as well as if the variable is writable. If so,
* the value is copied and the valid flag is automatically set to "valid". * the value is copied and the valid flag is automatically set to "valid".
* The commit call is protected by a lock of the global data pool. * The commit call is protected by a lock of the global data pool.
* It is recommended to use DataSets to read and commit multiple variables * It is recommended to use DataSets to read and commit multiple variables
* at once to avoid the overhead of unnecessary lock und unlock operations. * at once to avoid the overhead of unnecessary lock und unlock operations.
*/ */
ReturnValue_t commit(uint32_t lockTimeout = MutexIF::BLOCKING) override; ReturnValue_t commit(uint32_t lockTimeout = MutexIF::BLOCKING) override;
protected: protected:
/** /**
* @brief Like #read, but without a lock protection of the global pool. * @brief Like #read, but without a lock protection of the global pool.
* @details * @details
* The operation does NOT provide any mutual exclusive protection by itself. * The operation does NOT provide any mutual exclusive protection by itself.
* This can be used if the lock is handled externally to avoid the overhead * This can be used if the lock is handled externally to avoid the overhead
* of consecutive lock und unlock operations. * of consecutive lock und unlock operations.
* Declared protected to discourage free public usage. * Declared protected to discourage free public usage.
*/ */
ReturnValue_t readWithoutLock() override; ReturnValue_t readWithoutLock() override;
/** /**
* @brief Like #commit, but without a lock protection of the global pool. * @brief Like #commit, but without a lock protection of the global pool.
* @details * @details
* The operation does NOT provide any mutual exclusive protection by itself. * The operation does NOT provide any mutual exclusive protection by itself.
* This can be used if the lock is handled externally to avoid the overhead * This can be used if the lock is handled externally to avoid the overhead
* of consecutive lock und unlock operations. * of consecutive lock und unlock operations.
* Declared protected to discourage free public usage. * Declared protected to discourage free public usage.
*/ */
ReturnValue_t commitWithoutLock() override; ReturnValue_t commitWithoutLock() override;
private: private:
/** /**
* @brief To access the correct data pool entry on read and commit calls, * @brief To access the correct data pool entry on read and commit calls,
* the data pool id is stored. * the data pool id is stored.
*/ */
uint32_t dataPoolId; uint32_t dataPoolId;
/** /**
* @brief The valid information as it was stored in the data pool * @brief The valid information as it was stored in the data pool
* is copied to this attribute. * is copied to this attribute.
*/ */
uint8_t valid; uint8_t valid;
/** /**
* @brief The information whether the class is read-write or * @brief The information whether the class is read-write or
* read-only is stored here. * read-only is stored here.
*/ */
ReadWriteMode_t readWriteMode; ReadWriteMode_t readWriteMode;
}; };
#include <framework/datapoolglob/GlobalPoolVector.tpp> #include "../datapoolglob/GlobalPoolVector.tpp"
template<typename T, uint16_t vectorSize> template<typename T, uint16_t vectorSize>
using gp_vec_t = GlobPoolVector<T, vectorSize>; using gp_vec_t = GlobPoolVector<T, vectorSize>;
#endif /* POOLVECTOR_H_ */ #endif /* POOLVECTOR_H_ */

View File

@ -1,164 +1,164 @@
#ifndef PIDREADER_H_ #ifndef PIDREADER_H_
#define PIDREADER_H_ #define PIDREADER_H_
#include <framework/datapool/DataSetIF.h> #include "../datapool/DataSetIF.h"
#include <framework/datapoolglob/GlobalDataPool.h> #include "../datapoolglob/GlobalDataPool.h"
#include <framework/datapool/PoolEntry.h> #include "../datapool/PoolEntry.h"
#include <framework/datapool/PoolVariableIF.h> #include "../datapool/PoolVariableIF.h"
#include <framework/serialize/SerializeAdapter.h> #include "../serialize/SerializeAdapter.h"
#include <framework/serviceinterface/ServiceInterfaceStream.h> #include "../serviceinterface/ServiceInterfaceStream.h"
template<typename U, uint8_t n_var> class PIDReaderList; template<typename U, uint8_t n_var> class PIDReaderList;
template<typename T> template<typename T>
class PIDReader: public PoolVariableIF { class PIDReader: public PoolVariableIF {
template<typename U, uint8_t n_var> friend class PIDReaderList; template<typename U, uint8_t n_var> friend class PIDReaderList;
protected: protected:
uint32_t parameterId; uint32_t parameterId;
uint8_t valid; uint8_t valid;
ReturnValue_t readWithoutLock() { ReturnValue_t readWithoutLock() {
uint8_t arrayIndex = GlobalDataPool::PIDToArrayIndex(parameterId); uint8_t arrayIndex = GlobalDataPool::PIDToArrayIndex(parameterId);
PoolEntry<T> *read_out = glob::dataPool.getData<T>( PoolEntry<T> *read_out = glob::dataPool.getData<T>(
GlobalDataPool::PIDToDataPoolId(parameterId), arrayIndex); GlobalDataPool::PIDToDataPoolId(parameterId), arrayIndex);
if (read_out != NULL) { if (read_out != NULL) {
valid = read_out->valid; valid = read_out->valid;
value = read_out->address[arrayIndex]; value = read_out->address[arrayIndex];
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} else { } else {
value = 0; value = 0;
valid = false; valid = false;
sif::error << "PIDReader: read of PID 0x" << std::hex << parameterId sif::error << "PIDReader: read of PID 0x" << std::hex << parameterId
<< std::dec << " failed." << std::endl; << std::dec << " failed." << std::endl;
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
} }
/** /**
* Never commit, is read-only. * Never commit, is read-only.
* Reason is the possibility to access a single DP vector element, but if we commit, * Reason is the possibility to access a single DP vector element, but if we commit,
* we set validity of the whole vector. * we set validity of the whole vector.
*/ */
ReturnValue_t commit(uint32_t lockTimeout) override { ReturnValue_t commit(uint32_t lockTimeout) override {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
ReturnValue_t commitWithoutLock() override { ReturnValue_t commitWithoutLock() override {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
/** /**
* Empty ctor for List initialization * Empty ctor for List initialization
*/ */
PIDReader() : PIDReader() :
parameterId(PoolVariableIF::NO_PARAMETER), valid( parameterId(PoolVariableIF::NO_PARAMETER), valid(
PoolVariableIF::INVALID), value(0) { PoolVariableIF::INVALID), value(0) {
} }
public: public:
/** /**
* \brief This is the local copy of the data pool entry. * \brief This is the local copy of the data pool entry.
*/ */
T value; T value;
/** /**
* \brief In the constructor, the variable can register itself in a DataSet (if not NULL is * \brief In the constructor, the variable can register itself in a DataSet (if not NULL is
* passed). * passed).
* \details It DOES NOT fetch the current value from the data pool, but sets the value * \details It DOES NOT fetch the current value from the data pool, but sets the value
* attribute to default (0). The value is fetched within the read() operation. * attribute to default (0). The value is fetched within the read() operation.
* \param set_id This is the id in the global data pool this instance of the access class * \param set_id This is the id in the global data pool this instance of the access class
* corresponds to. * corresponds to.
* \param dataSet The data set in which the variable shall register itself. If NULL, * \param dataSet The data set in which the variable shall register itself. If NULL,
* the variable is not registered. * the variable is not registered.
* \param setWritable If this flag is set to true, changes in the value attribute can be * \param setWritable If this flag is set to true, changes in the value attribute can be
* written back to the data pool, otherwise not. * written back to the data pool, otherwise not.
*/ */
PIDReader(uint32_t setParameterId, DataSetIF *dataSet) : PIDReader(uint32_t setParameterId, DataSetIF *dataSet) :
parameterId(setParameterId), valid(PoolVariableIF::INVALID), value( parameterId(setParameterId), valid(PoolVariableIF::INVALID), value(
0) { 0) {
if (dataSet != NULL) { if (dataSet != NULL) {
dataSet->registerVariable(this); dataSet->registerVariable(this);
} }
} }
ReturnValue_t read(uint32_t lockTimeout) override { ReturnValue_t read(uint32_t lockTimeout) override {
ReturnValue_t result = glob::dataPool.lockDataPool(); ReturnValue_t result = glob::dataPool.lockDataPool();
if(result != HasReturnvaluesIF::RETURN_OK) { if(result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
result = readWithoutLock(); result = readWithoutLock();
ReturnValue_t unlockResult = glob::dataPool.unlockDataPool(); ReturnValue_t unlockResult = glob::dataPool.unlockDataPool();
if(unlockResult != HasReturnvaluesIF::RETURN_OK) { if(unlockResult != HasReturnvaluesIF::RETURN_OK) {
sif::error << "PIDReader::read: Could not unlock data pool!" sif::error << "PIDReader::read: Could not unlock data pool!"
<< std::endl; << std::endl;
} }
return result; return result;
} }
/** /**
* Copy ctor to copy classes containing Pool Variables. * Copy ctor to copy classes containing Pool Variables.
*/ */
PIDReader(const PIDReader &rhs) : PIDReader(const PIDReader &rhs) :
parameterId(rhs.parameterId), valid(rhs.valid), value(rhs.value) { parameterId(rhs.parameterId), valid(rhs.valid), value(rhs.value) {
} }
/** /**
* \brief The classes destructor is empty. * \brief The classes destructor is empty.
*/ */
~PIDReader() { ~PIDReader() {
} }
/** /**
* \brief This operation returns the data pool id of the variable. * \brief This operation returns the data pool id of the variable.
*/ */
uint32_t getDataPoolId() const { uint32_t getDataPoolId() const {
return GlobalDataPool::PIDToDataPoolId(parameterId); return GlobalDataPool::PIDToDataPoolId(parameterId);
} }
uint32_t getParameterId() const { uint32_t getParameterId() const {
return parameterId; return parameterId;
} }
/** /**
* This method returns if the variable is write-only, read-write or read-only. * This method returns if the variable is write-only, read-write or read-only.
*/ */
ReadWriteMode_t getReadWriteMode() const { ReadWriteMode_t getReadWriteMode() const {
return VAR_READ; return VAR_READ;
} }
/** /**
* \brief With this call, the valid information of the variable is returned. * \brief With this call, the valid information of the variable is returned.
*/ */
bool isValid() const { bool isValid() const {
if (valid) if (valid)
return true; return true;
else else
return false; return false;
} }
uint8_t getValid() { uint8_t getValid() {
return valid; return valid;
} }
void setValid(bool valid) { void setValid(bool valid) {
this->valid = valid; this->valid = valid;
} }
operator T() { operator T() {
return value; return value;
} }
PIDReader<T>& operator=(T newValue) { PIDReader<T>& operator=(T newValue) {
value = newValue; value = newValue;
return *this; return *this;
} }
virtual ReturnValue_t serialize(uint8_t **buffer, size_t *size, virtual ReturnValue_t serialize(uint8_t **buffer, size_t *size,
size_t maxSize, Endianness streamEndianness) const override { size_t maxSize, Endianness streamEndianness) const override {
return SerializeAdapter::serialize(&value, buffer, size, maxSize, return SerializeAdapter::serialize(&value, buffer, size, maxSize,
streamEndianness); streamEndianness);
} }
virtual size_t getSerializedSize() const override { virtual size_t getSerializedSize() const override {
return SerializeAdapter::getSerializedSize(&value); return SerializeAdapter::getSerializedSize(&value);
} }
virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size, virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
Endianness streamEndianness) override { Endianness streamEndianness) override {
return SerializeAdapter::deSerialize(&value, buffer, size, return SerializeAdapter::deSerialize(&value, buffer, size,
streamEndianness); streamEndianness);
} }
}; };
#endif /* PIDREADER_H_ */ #endif /* PIDREADER_H_ */

View File

@ -1,27 +1,27 @@
#ifndef FRAMEWORK_DATAPOOLGLOB_PIDREADERLIST_H_ #ifndef FRAMEWORK_DATAPOOLGLOB_PIDREADERLIST_H_
#define FRAMEWORK_DATAPOOLGLOB_PIDREADERLIST_H_ #define FRAMEWORK_DATAPOOLGLOB_PIDREADERLIST_H_
#include <framework/datapool/PoolVariableIF.h> #include "../datapool/PoolVariableIF.h"
#include <framework/datapoolglob/PIDReader.h> #include "../datapoolglob/PIDReader.h"
template <class T, uint8_t n_var> template <class T, uint8_t n_var>
class PIDReaderList { class PIDReaderList {
private: private:
PIDReader<T> variables[n_var]; PIDReader<T> variables[n_var];
public: public:
PIDReaderList( const uint32_t setPid[n_var], DataSetIF* dataSet) { PIDReaderList( const uint32_t setPid[n_var], DataSetIF* dataSet) {
//I really should have a look at the new init list c++ syntax. //I really should have a look at the new init list c++ syntax.
if (dataSet == NULL) { if (dataSet == NULL) {
return; return;
} }
for (uint8_t count = 0; count < n_var; count++) { for (uint8_t count = 0; count < n_var; count++) {
variables[count].parameterId = setPid[count]; variables[count].parameterId = setPid[count];
dataSet->registerVariable(&variables[count]); dataSet->registerVariable(&variables[count]);
} }
} }
PIDReader<T> &operator [](int i) { return variables[i]; } PIDReader<T> &operator [](int i) { return variables[i]; }
}; };
#endif /* FRAMEWORK_DATAPOOLGLOB_PIDREADERLIST_H_ */ #endif /* FRAMEWORK_DATAPOOLGLOB_PIDREADERLIST_H_ */

View File

@ -1,239 +1,239 @@
#include <framework/datapoolglob/GlobalDataPool.h> #include "../datapoolglob/GlobalDataPool.h"
#include <framework/datapoolglob/PoolRawAccess.h> #include "../datapoolglob/PoolRawAccess.h"
#include <framework/serviceinterface/ServiceInterfaceStream.h> #include "../serviceinterface/ServiceInterfaceStream.h"
#include <framework/serialize/EndianConverter.h> #include "../serialize/EndianConverter.h"
#include <cstring> #include <cstring>
PoolRawAccess::PoolRawAccess(uint32_t set_id, uint8_t setArrayEntry, PoolRawAccess::PoolRawAccess(uint32_t set_id, uint8_t setArrayEntry,
DataSetIF* dataSet, ReadWriteMode_t setReadWriteMode) : DataSetIF* dataSet, ReadWriteMode_t setReadWriteMode) :
dataPoolId(set_id), arrayEntry(setArrayEntry), valid(false), dataPoolId(set_id), arrayEntry(setArrayEntry), valid(false),
type(Type::UNKNOWN_TYPE), typeSize(0), arraySize(0), sizeTillEnd(0), type(Type::UNKNOWN_TYPE), typeSize(0), arraySize(0), sizeTillEnd(0),
readWriteMode(setReadWriteMode) { readWriteMode(setReadWriteMode) {
memset(value, 0, sizeof(value)); memset(value, 0, sizeof(value));
if (dataSet != nullptr) { if (dataSet != nullptr) {
dataSet->registerVariable(this); dataSet->registerVariable(this);
} }
} }
PoolRawAccess::~PoolRawAccess() {} PoolRawAccess::~PoolRawAccess() {}
ReturnValue_t PoolRawAccess::read(uint32_t lockTimeout) { ReturnValue_t PoolRawAccess::read(uint32_t lockTimeout) {
ReturnValue_t result = glob::dataPool.lockDataPool(lockTimeout); ReturnValue_t result = glob::dataPool.lockDataPool(lockTimeout);
if(result != HasReturnvaluesIF::RETURN_OK) { if(result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
result = readWithoutLock(); result = readWithoutLock();
ReturnValue_t unlockResult = glob::dataPool.unlockDataPool(); ReturnValue_t unlockResult = glob::dataPool.unlockDataPool();
if(unlockResult != HasReturnvaluesIF::RETURN_OK) { if(unlockResult != HasReturnvaluesIF::RETURN_OK) {
sif::error << "GlobPoolVar::read: Could not unlock global data pool" sif::error << "GlobPoolVar::read: Could not unlock global data pool"
<< std::endl; << std::endl;
} }
return result; return result;
} }
ReturnValue_t PoolRawAccess::readWithoutLock() { ReturnValue_t PoolRawAccess::readWithoutLock() {
ReturnValue_t result = RETURN_FAILED; ReturnValue_t result = RETURN_FAILED;
PoolEntryIF* readOut = glob::dataPool.getRawData(dataPoolId); PoolEntryIF* readOut = glob::dataPool.getRawData(dataPoolId);
if (readOut != nullptr) { if (readOut != nullptr) {
result = handleReadOut(readOut); result = handleReadOut(readOut);
if(result == RETURN_OK) { if(result == RETURN_OK) {
return result; return result;
} }
} else { } else {
result = READ_ENTRY_NON_EXISTENT; result = READ_ENTRY_NON_EXISTENT;
} }
handleReadError(result); handleReadError(result);
return result; return result;
} }
ReturnValue_t PoolRawAccess::handleReadOut(PoolEntryIF* readOut) { ReturnValue_t PoolRawAccess::handleReadOut(PoolEntryIF* readOut) {
ReturnValue_t result = RETURN_FAILED; ReturnValue_t result = RETURN_FAILED;
valid = readOut->getValid(); valid = readOut->getValid();
if (readOut->getSize() > arrayEntry) { if (readOut->getSize() > arrayEntry) {
arraySize = readOut->getSize(); arraySize = readOut->getSize();
typeSize = readOut->getByteSize() / readOut->getSize(); typeSize = readOut->getByteSize() / readOut->getSize();
type = readOut->getType(); type = readOut->getType();
if (typeSize <= sizeof(value)) { if (typeSize <= sizeof(value)) {
uint16_t arrayPosition = arrayEntry * typeSize; uint16_t arrayPosition = arrayEntry * typeSize;
sizeTillEnd = readOut->getByteSize() - arrayPosition; sizeTillEnd = readOut->getByteSize() - arrayPosition;
uint8_t* ptr = &((uint8_t*) readOut->getRawData())[arrayPosition]; uint8_t* ptr = &((uint8_t*) readOut->getRawData())[arrayPosition];
memcpy(value, ptr, typeSize); memcpy(value, ptr, typeSize);
return RETURN_OK; return RETURN_OK;
} else { } else {
result = READ_TYPE_TOO_LARGE; result = READ_TYPE_TOO_LARGE;
} }
} else { } else {
//debug << "PoolRawAccess: Size: " << (int)read_out->getSize() << std::endl; //debug << "PoolRawAccess: Size: " << (int)read_out->getSize() << std::endl;
result = READ_INDEX_TOO_LARGE; result = READ_INDEX_TOO_LARGE;
} }
return result; return result;
} }
void PoolRawAccess::handleReadError(ReturnValue_t result) { void PoolRawAccess::handleReadError(ReturnValue_t result) {
sif::error << "PoolRawAccess: read of DP Variable 0x" << std::hex << dataPoolId sif::error << "PoolRawAccess: read of DP Variable 0x" << std::hex << dataPoolId
<< std::dec << " failed, "; << std::dec << " failed, ";
if(result == READ_TYPE_TOO_LARGE) { if(result == READ_TYPE_TOO_LARGE) {
sif::error << "type too large." << std::endl; sif::error << "type too large." << std::endl;
} }
else if(result == READ_INDEX_TOO_LARGE) { else if(result == READ_INDEX_TOO_LARGE) {
sif::error << "index too large." << std::endl; sif::error << "index too large." << std::endl;
} }
else if(result == READ_ENTRY_NON_EXISTENT) { else if(result == READ_ENTRY_NON_EXISTENT) {
sif::error << "entry does not exist." << std::endl; sif::error << "entry does not exist." << std::endl;
} }
valid = INVALID; valid = INVALID;
typeSize = 0; typeSize = 0;
sizeTillEnd = 0; sizeTillEnd = 0;
memset(value, 0, sizeof(value)); memset(value, 0, sizeof(value));
} }
ReturnValue_t PoolRawAccess::commit(uint32_t lockTimeout) { ReturnValue_t PoolRawAccess::commit(uint32_t lockTimeout) {
ReturnValue_t result = glob::dataPool.lockDataPool(lockTimeout); ReturnValue_t result = glob::dataPool.lockDataPool(lockTimeout);
if(result != HasReturnvaluesIF::RETURN_OK) { if(result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
result = commitWithoutLock(); result = commitWithoutLock();
ReturnValue_t unlockResult = glob::dataPool.unlockDataPool(); ReturnValue_t unlockResult = glob::dataPool.unlockDataPool();
if(unlockResult != HasReturnvaluesIF::RETURN_OK) { if(unlockResult != HasReturnvaluesIF::RETURN_OK) {
sif::error << "GlobPoolVar::read: Could not unlock global data pool" sif::error << "GlobPoolVar::read: Could not unlock global data pool"
<< std::endl; << std::endl;
} }
return result; return result;
} }
ReturnValue_t PoolRawAccess::commitWithoutLock() { ReturnValue_t PoolRawAccess::commitWithoutLock() {
PoolEntryIF* write_back = glob::dataPool.getRawData(dataPoolId); PoolEntryIF* write_back = glob::dataPool.getRawData(dataPoolId);
if ((write_back != NULL) && (readWriteMode != VAR_READ)) { if ((write_back != NULL) && (readWriteMode != VAR_READ)) {
write_back->setValid(valid); write_back->setValid(valid);
uint8_t array_position = arrayEntry * typeSize; uint8_t array_position = arrayEntry * typeSize;
uint8_t* ptr = &((uint8_t*) write_back->getRawData())[array_position]; uint8_t* ptr = &((uint8_t*) write_back->getRawData())[array_position];
memcpy(ptr, value, typeSize); memcpy(ptr, value, typeSize);
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} else { } else {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
} }
uint8_t* PoolRawAccess::getEntry() { uint8_t* PoolRawAccess::getEntry() {
return value; return value;
} }
ReturnValue_t PoolRawAccess::getEntryEndianSafe(uint8_t* buffer, ReturnValue_t PoolRawAccess::getEntryEndianSafe(uint8_t* buffer,
size_t* writtenBytes, size_t max_size) { size_t* writtenBytes, size_t max_size) {
uint8_t* data_ptr = getEntry(); uint8_t* data_ptr = getEntry();
// debug << "PoolRawAccess::getEntry: Array position: " << // debug << "PoolRawAccess::getEntry: Array position: " <<
// index * size_of_type << " Size of T: " << (int)size_of_type << // index * size_of_type << " Size of T: " << (int)size_of_type <<
// " ByteSize: " << byte_size << " Position: " << *size << std::endl; // " ByteSize: " << byte_size << " Position: " << *size << std::endl;
if (typeSize == 0) if (typeSize == 0)
return DATA_POOL_ACCESS_FAILED; return DATA_POOL_ACCESS_FAILED;
if (typeSize > max_size) if (typeSize > max_size)
return INCORRECT_SIZE; return INCORRECT_SIZE;
EndianConverter::convertBigEndian(buffer, data_ptr, typeSize); EndianConverter::convertBigEndian(buffer, data_ptr, typeSize);
*writtenBytes = typeSize; *writtenBytes = typeSize;
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
ReturnValue_t PoolRawAccess::serialize(uint8_t** buffer, size_t* size, ReturnValue_t PoolRawAccess::serialize(uint8_t** buffer, size_t* size,
size_t maxSize, Endianness streamEndianness) const { size_t maxSize, Endianness streamEndianness) const {
if (typeSize + *size <= maxSize) { if (typeSize + *size <= maxSize) {
switch(streamEndianness) { switch(streamEndianness) {
case(Endianness::BIG): case(Endianness::BIG):
EndianConverter::convertBigEndian(*buffer, value, typeSize); EndianConverter::convertBigEndian(*buffer, value, typeSize);
break; break;
case(Endianness::LITTLE): case(Endianness::LITTLE):
EndianConverter::convertLittleEndian(*buffer, value, typeSize); EndianConverter::convertLittleEndian(*buffer, value, typeSize);
break; break;
case(Endianness::MACHINE): case(Endianness::MACHINE):
default: default:
memcpy(*buffer, value, typeSize); memcpy(*buffer, value, typeSize);
break; break;
} }
*size += typeSize; *size += typeSize;
(*buffer) += typeSize; (*buffer) += typeSize;
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} else { } else {
return SerializeIF::BUFFER_TOO_SHORT; return SerializeIF::BUFFER_TOO_SHORT;
} }
} }
Type PoolRawAccess::getType() { Type PoolRawAccess::getType() {
return type; return type;
} }
size_t PoolRawAccess::getSizeOfType() { size_t PoolRawAccess::getSizeOfType() {
return typeSize; return typeSize;
} }
size_t PoolRawAccess::getArraySize(){ size_t PoolRawAccess::getArraySize(){
return arraySize; return arraySize;
} }
uint32_t PoolRawAccess::getDataPoolId() const { uint32_t PoolRawAccess::getDataPoolId() const {
return dataPoolId; return dataPoolId;
} }
PoolVariableIF::ReadWriteMode_t PoolRawAccess::getReadWriteMode() const { PoolVariableIF::ReadWriteMode_t PoolRawAccess::getReadWriteMode() const {
return readWriteMode; return readWriteMode;
} }
ReturnValue_t PoolRawAccess::setEntryFromBigEndian(const uint8_t *buffer, ReturnValue_t PoolRawAccess::setEntryFromBigEndian(const uint8_t *buffer,
size_t setSize) { size_t setSize) {
if (typeSize == setSize) { if (typeSize == setSize) {
EndianConverter::convertBigEndian(value, buffer, typeSize); EndianConverter::convertBigEndian(value, buffer, typeSize);
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} else { } else {
sif::error << "PoolRawAccess::setEntryFromBigEndian: Illegal sizes: " sif::error << "PoolRawAccess::setEntryFromBigEndian: Illegal sizes: "
"Internal" << (uint32_t) typeSize << ", Requested: " << setSize "Internal" << (uint32_t) typeSize << ", Requested: " << setSize
<< std::endl; << std::endl;
return INCORRECT_SIZE; return INCORRECT_SIZE;
} }
} }
bool PoolRawAccess::isValid() const { bool PoolRawAccess::isValid() const {
if (valid != INVALID) if (valid != INVALID)
return true; return true;
else else
return false; return false;
} }
void PoolRawAccess::setValid(bool valid) { void PoolRawAccess::setValid(bool valid) {
this->valid = valid; this->valid = valid;
} }
size_t PoolRawAccess::getSizeTillEnd() const { size_t PoolRawAccess::getSizeTillEnd() const {
return sizeTillEnd; return sizeTillEnd;
} }
size_t PoolRawAccess::getSerializedSize() const { size_t PoolRawAccess::getSerializedSize() const {
return typeSize; return typeSize;
} }
ReturnValue_t PoolRawAccess::deSerialize(const uint8_t **buffer, size_t *size, ReturnValue_t PoolRawAccess::deSerialize(const uint8_t **buffer, size_t *size,
Endianness streamEndianness) { Endianness streamEndianness) {
if (*size >= typeSize) { if (*size >= typeSize) {
switch(streamEndianness) { switch(streamEndianness) {
case(Endianness::BIG): case(Endianness::BIG):
EndianConverter::convertBigEndian(value, *buffer, typeSize); EndianConverter::convertBigEndian(value, *buffer, typeSize);
break; break;
case(Endianness::LITTLE): case(Endianness::LITTLE):
EndianConverter::convertLittleEndian(value, *buffer, typeSize); EndianConverter::convertLittleEndian(value, *buffer, typeSize);
break; break;
case(Endianness::MACHINE): case(Endianness::MACHINE):
default: default:
memcpy(value, *buffer, typeSize); memcpy(value, *buffer, typeSize);
break; break;
} }
*size -= typeSize; *size -= typeSize;
*buffer += typeSize; *buffer += typeSize;
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
else { else {
return SerializeIF::STREAM_TOO_SHORT; return SerializeIF::STREAM_TOO_SHORT;
} }
} }

View File

@ -1,220 +1,220 @@
#ifndef POOLRAWACCESS_H_ #ifndef POOLRAWACCESS_H_
#define POOLRAWACCESS_H_ #define POOLRAWACCESS_H_
#include <framework/datapool/DataSetIF.h> #include "../datapool/DataSetIF.h"
#include <framework/datapool/PoolEntryIF.h> #include "../datapool/PoolEntryIF.h"
#include <framework/datapool/PoolVariableIF.h> #include "../datapool/PoolVariableIF.h"
#include <framework/globalfunctions/Type.h> #include "../globalfunctions/Type.h"
/** /**
* @brief This class allows accessing Data Pool variables as raw bytes. * @brief This class allows accessing Data Pool variables as raw bytes.
* @details * @details
* This is necessary to have an access method for HK data, as the PID's alone * This is necessary to have an access method for HK data, as the PID's alone
* do not provide type information. Please note that the the raw pool access * do not provide type information. Please note that the the raw pool access
* read() and commit() calls are not thread-safe. * read() and commit() calls are not thread-safe.
* *
* Please supply a data set and use the data set read(), commit() calls for * Please supply a data set and use the data set read(), commit() calls for
* thread-safe data pool access. * thread-safe data pool access.
* @ingroup data_pool * @ingroup data_pool
*/ */
class PoolRawAccess: public PoolVariableIF, HasReturnvaluesIF { class PoolRawAccess: public PoolVariableIF, HasReturnvaluesIF {
public: public:
/** /**
* This constructor is used to access a data pool entry with a * This constructor is used to access a data pool entry with a
* given ID if the target type is not known. A DataSet object is supplied * given ID if the target type is not known. A DataSet object is supplied
* and the data pool entry with the given ID is registered to that data set. * and the data pool entry with the given ID is registered to that data set.
* Please note that a pool raw access buffer only has a buffer * Please note that a pool raw access buffer only has a buffer
* with a size of double. As such, for vector entries which have * with a size of double. As such, for vector entries which have
* @param data_pool_id Target data pool entry ID * @param data_pool_id Target data pool entry ID
* @param arrayEntry * @param arrayEntry
* @param data_set Dataset to register data pool entry to * @param data_set Dataset to register data pool entry to
* @param setReadWriteMode * @param setReadWriteMode
* @param registerVectors If set to true, the constructor checks if * @param registerVectors If set to true, the constructor checks if
* there are multiple vector entries to registers * there are multiple vector entries to registers
* and registers all of them recursively into the data_set * and registers all of them recursively into the data_set
* *
*/ */
PoolRawAccess(uint32_t data_pool_id, uint8_t arrayEntry, PoolRawAccess(uint32_t data_pool_id, uint8_t arrayEntry,
DataSetIF* data_set, ReadWriteMode_t setReadWriteMode = DataSetIF* data_set, ReadWriteMode_t setReadWriteMode =
PoolVariableIF::VAR_READ); PoolVariableIF::VAR_READ);
/** /**
* @brief This operation returns a pointer to the entry fetched. * @brief This operation returns a pointer to the entry fetched.
* @details Return pointer to the buffer containing the raw data * @details Return pointer to the buffer containing the raw data
* Size and number of data can be retrieved by other means. * Size and number of data can be retrieved by other means.
*/ */
uint8_t* getEntry(); uint8_t* getEntry();
/** /**
* @brief This operation returns the fetched entry from the data pool and * @brief This operation returns the fetched entry from the data pool and
* flips the bytes, if necessary. * flips the bytes, if necessary.
* @details It makes use of the getEntry call of this function, but additionally flips the * @details It makes use of the getEntry call of this function, but additionally flips the
* bytes to big endian, which is the default for external communication (as House- * bytes to big endian, which is the default for external communication (as House-
* keeping telemetry). To achieve this, the data is copied directly to the passed * keeping telemetry). To achieve this, the data is copied directly to the passed
* buffer, if it fits in the given max_size. * buffer, if it fits in the given max_size.
* @param buffer A pointer to a buffer to write to * @param buffer A pointer to a buffer to write to
* @param writtenBytes The number of bytes written is returned with this value. * @param writtenBytes The number of bytes written is returned with this value.
* @param max_size The maximum size that the function may write to buffer. * @param max_size The maximum size that the function may write to buffer.
* @return - @c RETURN_OK if entry could be acquired * @return - @c RETURN_OK if entry could be acquired
* - @c RETURN_FAILED else. * - @c RETURN_FAILED else.
*/ */
ReturnValue_t getEntryEndianSafe(uint8_t *buffer, size_t *size, ReturnValue_t getEntryEndianSafe(uint8_t *buffer, size_t *size,
size_t maxSize); size_t maxSize);
/** /**
* @brief Serialize raw pool entry into provided buffer directly * @brief Serialize raw pool entry into provided buffer directly
* @param buffer Provided buffer. Raw pool data will be copied here * @param buffer Provided buffer. Raw pool data will be copied here
* @param size [out] Increment provided size value by serialized size * @param size [out] Increment provided size value by serialized size
* @param max_size Maximum allowed serialization size * @param max_size Maximum allowed serialization size
* @param bigEndian Specify endianess * @param bigEndian Specify endianess
* @return - @c RETURN_OK if serialization was successfull * @return - @c RETURN_OK if serialization was successfull
* - @c SerializeIF::BUFFER_TOO_SHORT if range check failed * - @c SerializeIF::BUFFER_TOO_SHORT if range check failed
*/ */
ReturnValue_t serialize(uint8_t **buffer, size_t *size, ReturnValue_t serialize(uint8_t **buffer, size_t *size,
size_t maxSize, Endianness streamEndianness) const override; size_t maxSize, Endianness streamEndianness) const override;
size_t getSerializedSize() const override; size_t getSerializedSize() const override;
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size, ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
Endianness streamEndianness) override; Endianness streamEndianness) override;
/** /**
* With this method, the content can be set from a big endian buffer safely. * With this method, the content can be set from a big endian buffer safely.
* @param buffer Pointer to the data to set * @param buffer Pointer to the data to set
* @param size Size of the data to write. Must fit this->size. * @param size Size of the data to write. Must fit this->size.
* @return - @c RETURN_OK on success * @return - @c RETURN_OK on success
* - @c RETURN_FAILED on failure * - @c RETURN_FAILED on failure
*/ */
ReturnValue_t setEntryFromBigEndian(const uint8_t* buffer, ReturnValue_t setEntryFromBigEndian(const uint8_t* buffer,
size_t setSize); size_t setSize);
/** /**
* @brief This operation returns the type of the entry currently stored. * @brief This operation returns the type of the entry currently stored.
*/ */
Type getType(); Type getType();
/** /**
* @brief This operation returns the size of the entry currently stored. * @brief This operation returns the size of the entry currently stored.
*/ */
size_t getSizeOfType(); size_t getSizeOfType();
/** /**
* *
* @return the size of the datapool array * @return the size of the datapool array
*/ */
size_t getArraySize(); size_t getArraySize();
/** /**
* @brief This operation returns the data pool id of the variable. * @brief This operation returns the data pool id of the variable.
*/ */
uint32_t getDataPoolId() const; uint32_t getDataPoolId() const;
static const uint8_t INTERFACE_ID = CLASS_ID::POOL_RAW_ACCESS_CLASS; static const uint8_t INTERFACE_ID = CLASS_ID::POOL_RAW_ACCESS_CLASS;
static const ReturnValue_t INCORRECT_SIZE = MAKE_RETURN_CODE(0x01); static const ReturnValue_t INCORRECT_SIZE = MAKE_RETURN_CODE(0x01);
static const ReturnValue_t DATA_POOL_ACCESS_FAILED = MAKE_RETURN_CODE(0x02); static const ReturnValue_t DATA_POOL_ACCESS_FAILED = MAKE_RETURN_CODE(0x02);
static const ReturnValue_t READ_TYPE_TOO_LARGE = MAKE_RETURN_CODE(0x03); static const ReturnValue_t READ_TYPE_TOO_LARGE = MAKE_RETURN_CODE(0x03);
static const ReturnValue_t READ_INDEX_TOO_LARGE = MAKE_RETURN_CODE(0x04); static const ReturnValue_t READ_INDEX_TOO_LARGE = MAKE_RETURN_CODE(0x04);
static const ReturnValue_t READ_ENTRY_NON_EXISTENT = MAKE_RETURN_CODE(0x05); static const ReturnValue_t READ_ENTRY_NON_EXISTENT = MAKE_RETURN_CODE(0x05);
static const uint8_t RAW_MAX_SIZE = sizeof(double); static const uint8_t RAW_MAX_SIZE = sizeof(double);
uint8_t value[RAW_MAX_SIZE]; uint8_t value[RAW_MAX_SIZE];
/** /**
* @brief The classes destructor is empty. If commit() was not called, the local value is * @brief The classes destructor is empty. If commit() was not called, the local value is
* discarded and not written back to the data pool. * discarded and not written back to the data pool.
*/ */
~PoolRawAccess(); ~PoolRawAccess();
/** /**
* This method returns if the variable is read-write or read-only. * This method returns if the variable is read-write or read-only.
*/ */
ReadWriteMode_t getReadWriteMode() const; ReadWriteMode_t getReadWriteMode() const;
/** /**
* @brief With this call, the valid information of the variable is returned. * @brief With this call, the valid information of the variable is returned.
*/ */
bool isValid() const; bool isValid() const;
void setValid(bool valid); void setValid(bool valid);
/** /**
* Getter for the remaining size. * Getter for the remaining size.
*/ */
size_t getSizeTillEnd() const; size_t getSizeTillEnd() const;
/** /**
* @brief This is a call to read the value from the global data pool. * @brief This is a call to read the value from the global data pool.
* @details * @details
* When executed, this operation tries to fetch the pool entry with matching * When executed, this operation tries to fetch the pool entry with matching
* data pool id from the global data pool and copies the value and the valid * data pool id from the global data pool and copies the value and the valid
* information to its local attributes. In case of a failure (wrong type or * information to its local attributes. In case of a failure (wrong type or
* pool id not found), the variable is set to zero and invalid. * pool id not found), the variable is set to zero and invalid.
* The call is protected by a lock of the global data pool. * The call is protected by a lock of the global data pool.
* @return -@c RETURN_OK Read successfull * @return -@c RETURN_OK Read successfull
* -@c READ_TYPE_TOO_LARGE * -@c READ_TYPE_TOO_LARGE
* -@c READ_INDEX_TOO_LARGE * -@c READ_INDEX_TOO_LARGE
* -@c READ_ENTRY_NON_EXISTENT * -@c READ_ENTRY_NON_EXISTENT
*/ */
ReturnValue_t read(uint32_t lockTimeout = MutexIF::BLOCKING) override; ReturnValue_t read(uint32_t lockTimeout = MutexIF::BLOCKING) override;
/** /**
* @brief The commit call writes back the variable's value to the data pool. * @brief The commit call writes back the variable's value to the data pool.
* @details * @details
* It checks type and size, as well as if the variable is writable. If so, * It checks type and size, as well as if the variable is writable. If so,
* the value is copied and the valid flag is automatically set to "valid". * the value is copied and the valid flag is automatically set to "valid".
* The call is protected by a lock of the global data pool. * The call is protected by a lock of the global data pool.
* *
*/ */
ReturnValue_t commit(uint32_t lockTimeout = MutexIF::BLOCKING) override; ReturnValue_t commit(uint32_t lockTimeout = MutexIF::BLOCKING) override;
protected: protected:
/** /**
* @brief Like #read, but without a lock protection of the global pool. * @brief Like #read, but without a lock protection of the global pool.
* @details * @details
* The operation does NOT provide any mutual exclusive protection by itself. * The operation does NOT provide any mutual exclusive protection by itself.
* This can be used if the lock is handled externally to avoid the overhead * This can be used if the lock is handled externally to avoid the overhead
* of consecutive lock und unlock operations. * of consecutive lock und unlock operations.
* Declared protected to discourage free public usage. * Declared protected to discourage free public usage.
*/ */
ReturnValue_t readWithoutLock() override; ReturnValue_t readWithoutLock() override;
/** /**
* @brief Like #commit, but without a lock protection of the global pool. * @brief Like #commit, but without a lock protection of the global pool.
* @details * @details
* The operation does NOT provide any mutual exclusive protection by itself. * The operation does NOT provide any mutual exclusive protection by itself.
* This can be used if the lock is handled externally to avoid the overhead * This can be used if the lock is handled externally to avoid the overhead
* of consecutive lock und unlock operations. * of consecutive lock und unlock operations.
* Declared protected to discourage free public usage. * Declared protected to discourage free public usage.
*/ */
ReturnValue_t commitWithoutLock() override; ReturnValue_t commitWithoutLock() override;
ReturnValue_t handleReadOut(PoolEntryIF* read_out); ReturnValue_t handleReadOut(PoolEntryIF* read_out);
void handleReadError(ReturnValue_t result); void handleReadError(ReturnValue_t result);
private: private:
/** /**
* @brief To access the correct data pool entry on read and commit calls, the data pool id * @brief To access the correct data pool entry on read and commit calls, the data pool id
* is stored. * is stored.
*/ */
uint32_t dataPoolId; uint32_t dataPoolId;
/** /**
* @brief The array entry that is fetched from the data pool. * @brief The array entry that is fetched from the data pool.
*/ */
uint8_t arrayEntry; uint8_t arrayEntry;
/** /**
* @brief The valid information as it was stored in the data pool is copied to this attribute. * @brief The valid information as it was stored in the data pool is copied to this attribute.
*/ */
uint8_t valid; uint8_t valid;
/** /**
* @brief This value contains the type of the data pool entry. * @brief This value contains the type of the data pool entry.
*/ */
Type type; Type type;
/** /**
* @brief This value contains the size of the data pool entry type in bytes. * @brief This value contains the size of the data pool entry type in bytes.
*/ */
size_t typeSize; size_t typeSize;
/** /**
* The size of the DP array (single values return 1) * The size of the DP array (single values return 1)
*/ */
size_t arraySize; size_t arraySize;
/** /**
* The size (in bytes) from the selected entry till the end of this DataPool variable. * The size (in bytes) from the selected entry till the end of this DataPool variable.
*/ */
size_t sizeTillEnd; size_t sizeTillEnd;
/** /**
* @brief The information whether the class is read-write or read-only is stored here. * @brief The information whether the class is read-write or read-only is stored here.
*/ */
ReadWriteMode_t readWriteMode; ReadWriteMode_t readWriteMode;
}; };
#endif /* POOLRAWACCESS_H_ */ #endif /* POOLRAWACCESS_H_ */

View File

@ -1,8 +1,8 @@
#ifndef FRAMEWORK_DATAPOOL_HASHKPOOLPARAMETERSIF_H_ #ifndef FRAMEWORK_DATAPOOL_HASHKPOOLPARAMETERSIF_H_
#define FRAMEWORK_DATAPOOL_HASHKPOOLPARAMETERSIF_H_ #define FRAMEWORK_DATAPOOL_HASHKPOOLPARAMETERSIF_H_
#include <framework/datapool/PoolEntryIF.h> #include "../datapool/PoolEntryIF.h"
#include <framework/ipc/MessageQueueSenderIF.h> #include "../ipc/MessageQueueSenderIF.h"
#include <framework/housekeeping/HousekeepingMessage.h> #include "../housekeeping/HousekeepingMessage.h"
#include <map> #include <map>
class LocalDataPoolManager; class LocalDataPoolManager;

View File

@ -1,10 +1,9 @@
#include <framework/datapoollocal/LocalDataPoolManager.h> #include "../datapoollocal/LocalDataPoolManager.h"
#include <framework/datapoollocal/LocalPoolDataSetBase.h> #include "../datapoollocal/LocalDataSet.h"
#include <framework/housekeeping/AcceptsHkPacketsIF.h> #include "../housekeeping/AcceptsHkPacketsIF.h"
#include <framework/housekeeping/HousekeepingPacketDownlink.h> #include "../ipc/MutexFactory.h"
#include <framework/ipc/MutexFactory.h> #include "../ipc/MutexHelper.h"
#include <framework/ipc/MutexHelper.h> #include "../ipc/QueueFactory.h"
#include <framework/ipc/QueueFactory.h>
#include <array> #include <array>
#include <cmath> #include <cmath>
@ -264,7 +263,7 @@ void LocalDataPoolManager::performPeriodicHkGeneration(HkReceiver* receiver) {
uint32_t LocalDataPoolManager::intervalSecondsToInterval(bool isDiagnostics, uint32_t LocalDataPoolManager::intervalSecondsToInterval(bool isDiagnostics,
float collectionIntervalSeconds) { float collectionIntervalSeconds) {
if(isDiagnostics) { if(isDiagnostics) {
return std::ceil(collectionIntervalSeconds/diagnosticMinimumInterval); return std::ceil(collectionIntervalSeconds/diagnosticMinimumInterval);
} }
else { else {
return std::ceil(collectionIntervalSeconds/regularMinimumInterval); return std::ceil(collectionIntervalSeconds/regularMinimumInterval);

View File

@ -1,21 +1,21 @@
#ifndef FRAMEWORK_DATAPOOLLOCAL_LOCALDATAPOOLMANAGER_H_ #ifndef FRAMEWORK_DATAPOOLLOCAL_LOCALDATAPOOLMANAGER_H_
#define FRAMEWORK_DATAPOOLLOCAL_LOCALDATAPOOLMANAGER_H_ #define FRAMEWORK_DATAPOOLLOCAL_LOCALDATAPOOLMANAGER_H_
#include <framework/datapool/DataSetIF.h> #include "../housekeeping/HousekeepingPacketDownlink.h"
#include <framework/objectmanager/SystemObjectIF.h> #include "../datapool/DataSetIF.h"
#include <framework/ipc/MutexIF.h> #include "../objectmanager/SystemObjectIF.h"
#include "../ipc/MutexIF.h"
#include <framework/housekeeping/HousekeepingMessage.h> #include "../housekeeping/HousekeepingMessage.h"
#include <framework/datapool/PoolEntry.h> #include "../datapool/PoolEntry.h"
#include <framework/datapoollocal/HasLocalDataPoolIF.h> #include "../datapoollocal/HasLocalDataPoolIF.h"
#include <framework/housekeeping/HousekeepingPacketDownlink.h> #include "../ipc/CommandMessage.h"
#include <framework/ipc/CommandMessage.h> #include "../ipc/MessageQueueIF.h"
#include <framework/ipc/MessageQueueIF.h> #include "../ipc/MutexHelper.h"
#include <framework/ipc/MutexHelper.h>
#include <map> #include <map>
class LocalPoolDataSetBase; class LocalDataSetBase;
/** /**
* @brief This class is the managing instance for local data pool. * @brief This class is the managing instance for local data pool.

View File

@ -1,6 +1,6 @@
#include <framework/datapoollocal/LocalDataPoolManager.h> #include "LocalDataSet.h"
#include <framework/datapoollocal/LocalDataSet.h> #include "../datapoollocal/LocalDataPoolManager.h"
#include <framework/serialize/SerializeAdapter.h> #include "../serialize/SerializeAdapter.h"
#include <cmath> #include <cmath>
#include <cstring> #include <cstring>

View File

@ -1,6 +1,6 @@
#ifndef FRAMEWORK_DATAPOOLLOCAL_LOCALDATASET_H_ #ifndef FRAMEWORK_DATAPOOLLOCAL_LOCALDATASET_H_
#define FRAMEWORK_DATAPOOLLOCAL_LOCALDATASET_H_ #define FRAMEWORK_DATAPOOLLOCAL_LOCALDATASET_H_
#include <framework/datapoollocal/LocalPoolDataSetBase.h> #include "../datapoollocal/LocalPoolDataSetBase.h"
#include <vector> #include <vector>
class LocalDataSet: public LocalPoolDataSetBase { class LocalDataSet: public LocalPoolDataSetBase {

View File

@ -1,6 +1,6 @@
#include <framework/datapoollocal/LocalDataPoolManager.h> #include "LocalPoolDataSetBase.h"
#include <framework/datapoollocal/LocalPoolDataSetBase.h> #include "../datapoollocal/LocalDataPoolManager.h"
#include <framework/serialize/SerializeAdapter.h> #include "../serialize/SerializeAdapter.h"
#include <cmath> #include <cmath>
#include <cstring> #include <cstring>

View File

@ -1,9 +1,9 @@
#ifndef FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLDATASETBASE_H_ #ifndef FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLDATASETBASE_H_
#define FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLDATASETBASE_H_ #define FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLDATASETBASE_H_
#include <framework/datapool/DataSetIF.h> #include "../datapool/DataSetIF.h"
#include <framework/datapool/PoolDataSetBase.h> #include "../datapool/PoolDataSetBase.h"
#include <framework/datapoollocal/HasLocalDataPoolIF.h> #include "../datapoollocal/HasLocalDataPoolIF.h"
#include <framework/serialize/SerializeIF.h> #include "../serialize/SerializeIF.h"
#include <vector> #include <vector>

View File

@ -1,13 +1,13 @@
#ifndef FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLVARIABLE_H_ #ifndef FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLVARIABLE_H_
#define FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLVARIABLE_H_ #define FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLVARIABLE_H_
#include <framework/datapool/PoolVariableIF.h> #include "../datapool/PoolVariableIF.h"
#include <framework/datapool/DataSetIF.h> #include "../datapool/DataSetIF.h"
#include <framework/datapoollocal/HasLocalDataPoolIF.h> #include "../datapoollocal/HasLocalDataPoolIF.h"
#include <framework/datapoollocal/LocalDataPoolManager.h> #include "../datapoollocal/LocalDataPoolManager.h"
#include <framework/objectmanager/ObjectManagerIF.h> #include "../objectmanager/ObjectManagerIF.h"
#include <framework/serialize/SerializeAdapter.h> #include "../serialize/SerializeAdapter.h"
/** /**
* @brief Local Pool Variable class which is used to access the local pools. * @brief Local Pool Variable class which is used to access the local pools.
@ -155,7 +155,7 @@ private:
LocalDataPoolManager* hkManager; LocalDataPoolManager* hkManager;
}; };
#include <framework/datapoollocal/LocalPoolVariable.tpp> #include "LocalPoolVariable.tpp"
template<class T> template<class T>
using lp_var_t = LocalPoolVar<T>; using lp_var_t = LocalPoolVar<T>;

View File

@ -1,200 +1,200 @@
#ifndef FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLVECTOR_H_ #ifndef FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLVECTOR_H_
#define FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLVECTOR_H_ #define FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLVECTOR_H_
#include <framework/datapool/DataSetIF.h> #include "../datapool/DataSetIF.h"
#include <framework/datapool/PoolEntry.h> #include "../datapool/PoolEntry.h"
#include <framework/datapool/PoolVariableIF.h> #include "../datapool/PoolVariableIF.h"
#include <framework/datapoollocal/LocalDataPoolManager.h> #include "../datapoollocal/LocalDataPoolManager.h"
#include <framework/serialize/SerializeAdapter.h> #include "../serialize/SerializeAdapter.h"
#include <framework/serviceinterface/ServiceInterfaceStream.h> #include "../serviceinterface/ServiceInterfaceStream.h"
/** /**
* @brief This is the access class for array-type data pool entries. * @brief This is the access class for array-type data pool entries.
* @details * @details
* To ensure safe usage of the data pool, operation is not done directly on the * To ensure safe usage of the data pool, operation is not done directly on the
* data pool entries, but on local copies. This class provides simple type- * data pool entries, but on local copies. This class provides simple type-
* and length-safe access to vector-style data pool entries (i.e. entries with * and length-safe access to vector-style data pool entries (i.e. entries with
* length > 1). The class can be instantiated as read-write and read only. * length > 1). The class can be instantiated as read-write and read only.
* *
* It provides a commit-and-roll-back semantic, which means that no array * It provides a commit-and-roll-back semantic, which means that no array
* entry in the data pool is changed until the commit call is executed. * entry in the data pool is changed until the commit call is executed.
* There are two template parameters: * There are two template parameters:
* @tparam T * @tparam T
* This template parameter specifies the data type of an array entry. Currently, * This template parameter specifies the data type of an array entry. Currently,
* all plain data types are supported, but in principle any type is possible. * all plain data types are supported, but in principle any type is possible.
* @tparam vector_size * @tparam vector_size
* This template parameter specifies the vector size of this entry. Using a * This template parameter specifies the vector size of this entry. Using a
* template parameter for this is not perfect, but avoids * template parameter for this is not perfect, but avoids
* dynamic memory allocation. * dynamic memory allocation.
* @ingroup data_pool * @ingroup data_pool
*/ */
template<typename T, uint16_t vectorSize> template<typename T, uint16_t vectorSize>
class LocalPoolVector: public PoolVariableIF, public HasReturnvaluesIF { class LocalPoolVector: public PoolVariableIF, public HasReturnvaluesIF {
public: public:
LocalPoolVector() = delete; LocalPoolVector() = delete;
/** /**
* This constructor is used by the data creators to have pool variable * This constructor is used by the data creators to have pool variable
* instances which can also be stored in datasets. * instances which can also be stored in datasets.
* It does not fetch the current value from the data pool. This is performed * It does not fetch the current value from the data pool. This is performed
* by the read() operation (which is not thread-safe). * by the read() operation (which is not thread-safe).
* Datasets can be used to access local pool entires in a thread-safe way. * Datasets can be used to access local pool entires in a thread-safe way.
* @param poolId ID of the local pool entry. * @param poolId ID of the local pool entry.
* @param hkOwner Pointer of the owner. This will generally be the calling * @param hkOwner Pointer of the owner. This will generally be the calling
* class itself which passes "this". * class itself which passes "this".
* @param setReadWriteMode Specify the read-write mode of the pool variable. * @param setReadWriteMode Specify the read-write mode of the pool variable.
* @param dataSet The data set in which the variable shall register itself. * @param dataSet The data set in which the variable shall register itself.
* If nullptr, the variable is not registered. * If nullptr, the variable is not registered.
*/ */
LocalPoolVector(lp_id_t poolId, HasLocalDataPoolIF* hkOwner, LocalPoolVector(lp_id_t poolId, HasLocalDataPoolIF* hkOwner,
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE, pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE,
DataSetIF* dataSet = nullptr); DataSetIF* dataSet = nullptr);
/** /**
* This constructor is used by data users like controllers to have * This constructor is used by data users like controllers to have
* access to the local pool variables of data creators by supplying * access to the local pool variables of data creators by supplying
* the respective creator object ID. * the respective creator object ID.
* It does not fetch the current value from the data pool. This is performed * It does not fetch the current value from the data pool. This is performed
* by the read() operation (which is not thread-safe). * by the read() operation (which is not thread-safe).
* Datasets can be used to access local pool entires in a thread-safe way. * Datasets can be used to access local pool entires in a thread-safe way.
* @param poolId ID of the local pool entry. * @param poolId ID of the local pool entry.
* @param hkOwner Pointer of the owner. This will generally be the calling * @param hkOwner Pointer of the owner. This will generally be the calling
* class itself which passes "this". * class itself which passes "this".
* @param setReadWriteMode Specify the read-write mode of the pool variable. * @param setReadWriteMode Specify the read-write mode of the pool variable.
* @param dataSet The data set in which the variable shall register itself. * @param dataSet The data set in which the variable shall register itself.
* If nullptr, the variable is not registered. * If nullptr, the variable is not registered.
*/ */
LocalPoolVector(lp_id_t poolId, object_id_t poolOwner, LocalPoolVector(lp_id_t poolId, object_id_t poolOwner,
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE, pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE,
DataSetIF* dataSet = nullptr); DataSetIF* dataSet = nullptr);
/** /**
* @brief This is the local copy of the data pool entry. * @brief This is the local copy of the data pool entry.
* @details * @details
* The user can work on this attribute just like he would on a local * The user can work on this attribute just like he would on a local
* array of this type. * array of this type.
*/ */
T value[vectorSize]; T value[vectorSize];
/** /**
* @brief The classes destructor is empty. * @brief The classes destructor is empty.
* @details If commit() was not called, the local value is * @details If commit() was not called, the local value is
* discarded and not written back to the data pool. * discarded and not written back to the data pool.
*/ */
~LocalPoolVector() {}; ~LocalPoolVector() {};
/** /**
* @brief The operation returns the number of array entries * @brief The operation returns the number of array entries
* in this variable. * in this variable.
*/ */
uint8_t getSize() { uint8_t getSize() {
return vectorSize; return vectorSize;
} }
uint32_t getDataPoolId() const override; uint32_t getDataPoolId() const override;
/** /**
* @brief This operation sets the data pool ID of the variable. * @brief This operation sets the data pool ID of the variable.
* @details * @details
* The method is necessary to set id's of data pool member variables * The method is necessary to set id's of data pool member variables
* with bad initialization. * with bad initialization.
*/ */
void setDataPoolId(uint32_t poolId); void setDataPoolId(uint32_t poolId);
/** /**
* This method returns if the variable is write-only, read-write or read-only. * This method returns if the variable is write-only, read-write or read-only.
*/ */
pool_rwm_t getReadWriteMode() const; pool_rwm_t getReadWriteMode() const;
/** /**
* @brief With this call, the valid information of the variable is returned. * @brief With this call, the valid information of the variable is returned.
*/ */
bool isValid() const override; bool isValid() const override;
void setValid(bool valid) override; void setValid(bool valid) override;
uint8_t getValid() const; uint8_t getValid() const;
T& operator [](int i); T& operator [](int i);
const T &operator [](int i) const; const T &operator [](int i) const;
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
const size_t maxSize, const size_t maxSize,
SerializeIF::Endianness streamEndiannes) const override; SerializeIF::Endianness streamEndiannes) const override;
virtual size_t getSerializedSize() const override; virtual size_t getSerializedSize() const override;
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
SerializeIF::Endianness streamEndianness) override; SerializeIF::Endianness streamEndianness) override;
/** /**
* @brief This is a call to read the array's values * @brief This is a call to read the array's values
* from the global data pool. * from the global data pool.
* @details * @details
* When executed, this operation tries to fetch the pool entry with matching * When executed, this operation tries to fetch the pool entry with matching
* data pool id from the data pool and copies all array values and the valid * data pool id from the data pool and copies all array values and the valid
* information to its local attributes. * information to its local attributes.
* In case of a failure (wrong type, size or pool id not found), the * In case of a failure (wrong type, size or pool id not found), the
* variable is set to zero and invalid. * variable is set to zero and invalid.
* The read call is protected with a lock. * The read call is protected with a lock.
* It is recommended to use DataSets to read and commit multiple variables * It is recommended to use DataSets to read and commit multiple variables
* at once to avoid the overhead of unnecessary lock und unlock operations. * at once to avoid the overhead of unnecessary lock und unlock operations.
*/ */
ReturnValue_t read(uint32_t lockTimeout = MutexIF::BLOCKING) override; ReturnValue_t read(uint32_t lockTimeout = MutexIF::BLOCKING) override;
/** /**
* @brief The commit call copies the array values back to the data pool. * @brief The commit call copies the array values back to the data pool.
* @details * @details
* It checks type and size, as well as if the variable is writable. If so, * It checks type and size, as well as if the variable is writable. If so,
* the value is copied and the local valid flag is written back as well. * the value is copied and the local valid flag is written back as well.
* The read call is protected with a lock. * The read call is protected with a lock.
* It is recommended to use DataSets to read and commit multiple variables * It is recommended to use DataSets to read and commit multiple variables
* at once to avoid the overhead of unnecessary lock und unlock operations. * at once to avoid the overhead of unnecessary lock und unlock operations.
*/ */
ReturnValue_t commit(uint32_t lockTimeout = MutexIF::BLOCKING) override; ReturnValue_t commit(uint32_t lockTimeout = MutexIF::BLOCKING) override;
protected: protected:
/** /**
* @brief Like #read, but without a lock protection of the global pool. * @brief Like #read, but without a lock protection of the global pool.
* @details * @details
* The operation does NOT provide any mutual exclusive protection by itself. * The operation does NOT provide any mutual exclusive protection by itself.
* This can be used if the lock is handled externally to avoid the overhead * This can be used if the lock is handled externally to avoid the overhead
* of consecutive lock und unlock operations. * of consecutive lock und unlock operations.
* Declared protected to discourage free public usage. * Declared protected to discourage free public usage.
*/ */
ReturnValue_t readWithoutLock() override; ReturnValue_t readWithoutLock() override;
/** /**
* @brief Like #commit, but without a lock protection of the global pool. * @brief Like #commit, but without a lock protection of the global pool.
* @details * @details
* The operation does NOT provide any mutual exclusive protection by itself. * The operation does NOT provide any mutual exclusive protection by itself.
* This can be used if the lock is handled externally to avoid the overhead * This can be used if the lock is handled externally to avoid the overhead
* of consecutive lock und unlock operations. * of consecutive lock und unlock operations.
* Declared protected to discourage free public usage. * Declared protected to discourage free public usage.
*/ */
ReturnValue_t commitWithoutLock() override; ReturnValue_t commitWithoutLock() override;
private: private:
/** /**
* @brief To access the correct data pool entry on read and commit calls, * @brief To access the correct data pool entry on read and commit calls,
* the data pool id is stored. * the data pool id is stored.
*/ */
uint32_t localPoolId; uint32_t localPoolId;
/** /**
* @brief The valid information as it was stored in the data pool * @brief The valid information as it was stored in the data pool
* is copied to this attribute. * is copied to this attribute.
*/ */
bool valid; bool valid;
/** /**
* @brief The information whether the class is read-write or * @brief The information whether the class is read-write or
* read-only is stored here. * read-only is stored here.
*/ */
ReadWriteMode_t readWriteMode; ReadWriteMode_t readWriteMode;
//! @brief Pointer to the class which manages the HK pool. //! @brief Pointer to the class which manages the HK pool.
LocalDataPoolManager* hkManager; LocalDataPoolManager* hkManager;
// std::ostream is the type for object std::cout // std::ostream is the type for object std::cout
template <typename U, uint16_t otherSize> template <typename U, uint16_t otherSize>
friend std::ostream& operator<< (std::ostream &out, friend std::ostream& operator<< (std::ostream &out,
const LocalPoolVector<U, otherSize> &var); const LocalPoolVector<U, otherSize> &var);
}; };
#include <framework/datapoollocal/LocalPoolVector.tpp> #include "../datapoollocal/LocalPoolVector.tpp"
template<typename T, uint16_t vectorSize> template<typename T, uint16_t vectorSize>
using lp_vec_t = LocalPoolVector<T, vectorSize>; using lp_vec_t = LocalPoolVector<T, vectorSize>;
#endif /* FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLVECTOR_H_ */ #endif /* FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLVECTOR_H_ */

View File

@ -1,4 +1,4 @@
#include <framework/datapoollocal/SharedLocalDataSet.h> #include "SharedLocalDataSet.h"
SharedLocalDataSet::SharedLocalDataSet(object_id_t objectId, object_id_t owner, SharedLocalDataSet::SharedLocalDataSet(object_id_t objectId, object_id_t owner,
const size_t maxSize): SystemObject(objectId), const size_t maxSize): SystemObject(objectId),

View File

@ -1,8 +1,8 @@
#ifndef FRAMEWORK_DATAPOOLLOCAL_SHAREDLOCALDATASET_H_ #ifndef FRAMEWORK_DATAPOOLLOCAL_SHAREDLOCALDATASET_H_
#define FRAMEWORK_DATAPOOLLOCAL_SHAREDLOCALDATASET_H_ #define FRAMEWORK_DATAPOOLLOCAL_SHAREDLOCALDATASET_H_
#include <framework/datapool/SharedDataSetIF.h> #include "../datapool/SharedDataSetIF.h"
#include <framework/datapoollocal/LocalPoolDataSetBase.h> #include "../datapoollocal/LocalPoolDataSetBase.h"
#include <framework/objectmanager/SystemObject.h> #include "../objectmanager/SystemObject.h"
#include <vector> #include <vector>
/** /**

View File

@ -1,7 +1,7 @@
#ifndef FRAMEWORK_DATAPOOLLOCAL_STATICLOCALDATASET_H_ #ifndef FRAMEWORK_DATAPOOLLOCAL_STATICLOCALDATASET_H_
#define FRAMEWORK_DATAPOOLLOCAL_STATICLOCALDATASET_H_ #define FRAMEWORK_DATAPOOLLOCAL_STATICLOCALDATASET_H_
#include <framework/datapoollocal/LocalPoolDataSetBase.h> #include "LocalPoolDataSetBase.h"
#include <framework/objectmanager/SystemObjectIF.h> #include "../objectmanager/SystemObjectIF.h"
#include <array> #include <array>
/** /**

View File

@ -1,19 +1,19 @@
#ifndef FRAMEWORK_DEVICEHANDLERS_ACCEPTSDEVICERESPONSESIF_H_ #ifndef FRAMEWORK_DEVICEHANDLERS_ACCEPTSDEVICERESPONSESIF_H_
#define FRAMEWORK_DEVICEHANDLERS_ACCEPTSDEVICERESPONSESIF_H_ #define FRAMEWORK_DEVICEHANDLERS_ACCEPTSDEVICERESPONSESIF_H_
#include <framework/ipc/MessageQueueSenderIF.h> #include "../ipc/MessageQueueSenderIF.h"
/** /**
* This interface is used by the device handler to send a device response * This interface is used by the device handler to send a device response
* to the queue ID, which is returned in the implemented abstract method. * to the queue ID, which is returned in the implemented abstract method.
*/ */
class AcceptsDeviceResponsesIF { class AcceptsDeviceResponsesIF {
public: public:
/** /**
* Default empty virtual destructor. * Default empty virtual destructor.
*/ */
virtual ~AcceptsDeviceResponsesIF() {} virtual ~AcceptsDeviceResponsesIF() {}
virtual MessageQueueId_t getDeviceQueue() = 0; virtual MessageQueueId_t getDeviceQueue() = 0;
}; };
#endif /* FRAMEWORK_DEVICEHANDLERS_ACCEPTSDEVICERESPONSESIF_H_ */ #endif /* FRAMEWORK_DEVICEHANDLERS_ACCEPTSDEVICERESPONSESIF_H_ */

View File

@ -1,273 +1,273 @@
#include <framework/devicehandlers/AssemblyBase.h> #include "../devicehandlers/AssemblyBase.h"
AssemblyBase::AssemblyBase(object_id_t objectId, object_id_t parentId, AssemblyBase::AssemblyBase(object_id_t objectId, object_id_t parentId,
uint16_t commandQueueDepth) : uint16_t commandQueueDepth) :
SubsystemBase(objectId, parentId, MODE_OFF, commandQueueDepth), SubsystemBase(objectId, parentId, MODE_OFF, commandQueueDepth),
internalState(STATE_NONE), recoveryState(RECOVERY_IDLE), internalState(STATE_NONE), recoveryState(RECOVERY_IDLE),
recoveringDevice(childrenMap.end()), targetMode(MODE_OFF), recoveringDevice(childrenMap.end()), targetMode(MODE_OFF),
targetSubmode(SUBMODE_NONE) { targetSubmode(SUBMODE_NONE) {
recoveryOffTimer.setTimeout(POWER_OFF_TIME_MS); recoveryOffTimer.setTimeout(POWER_OFF_TIME_MS);
} }
AssemblyBase::~AssemblyBase() { AssemblyBase::~AssemblyBase() {
} }
ReturnValue_t AssemblyBase::handleCommandMessage(CommandMessage* message) { ReturnValue_t AssemblyBase::handleCommandMessage(CommandMessage* message) {
return handleHealthReply(message); return handleHealthReply(message);
} }
void AssemblyBase::performChildOperation() { void AssemblyBase::performChildOperation() {
if (isInTransition()) { if (isInTransition()) {
handleChildrenTransition(); handleChildrenTransition();
} else { } else {
handleChildrenChanged(); handleChildrenChanged();
} }
} }
void AssemblyBase::startTransition(Mode_t mode, Submode_t submode) { void AssemblyBase::startTransition(Mode_t mode, Submode_t submode) {
doStartTransition(mode, submode); doStartTransition(mode, submode);
if (modeHelper.isForced()) { if (modeHelper.isForced()) {
triggerEvent(FORCING_MODE, mode, submode); triggerEvent(FORCING_MODE, mode, submode);
} else { } else {
triggerEvent(CHANGING_MODE, mode, submode); triggerEvent(CHANGING_MODE, mode, submode);
} }
} }
void AssemblyBase::doStartTransition(Mode_t mode, Submode_t submode) { void AssemblyBase::doStartTransition(Mode_t mode, Submode_t submode) {
targetMode = mode; targetMode = mode;
targetSubmode = submode; targetSubmode = submode;
internalState = STATE_SINGLE_STEP; internalState = STATE_SINGLE_STEP;
ReturnValue_t result = commandChildren(mode, submode); ReturnValue_t result = commandChildren(mode, submode);
if (result == NEED_SECOND_STEP) { if (result == NEED_SECOND_STEP) {
internalState = STATE_NEED_SECOND_STEP; internalState = STATE_NEED_SECOND_STEP;
} }
} }
bool AssemblyBase::isInTransition() { bool AssemblyBase::isInTransition() {
return (internalState != STATE_NONE) || (recoveryState != RECOVERY_IDLE); return (internalState != STATE_NONE) || (recoveryState != RECOVERY_IDLE);
} }
bool AssemblyBase::handleChildrenChanged() { bool AssemblyBase::handleChildrenChanged() {
if (childrenChangedMode) { if (childrenChangedMode) {
ReturnValue_t result = checkChildrenState(); ReturnValue_t result = checkChildrenState();
if (result != RETURN_OK) { if (result != RETURN_OK) {
handleChildrenLostMode(result); handleChildrenLostMode(result);
} }
return true; return true;
} else { } else {
return handleChildrenChangedHealth(); return handleChildrenChangedHealth();
} }
} }
void AssemblyBase::handleChildrenLostMode(ReturnValue_t result) { void AssemblyBase::handleChildrenLostMode(ReturnValue_t result) {
triggerEvent(CANT_KEEP_MODE, mode, submode); triggerEvent(CANT_KEEP_MODE, mode, submode);
startTransition(MODE_OFF, SUBMODE_NONE); startTransition(MODE_OFF, SUBMODE_NONE);
} }
bool AssemblyBase::handleChildrenChangedHealth() { bool AssemblyBase::handleChildrenChangedHealth() {
auto iter = childrenMap.begin(); auto iter = childrenMap.begin();
for (; iter != childrenMap.end(); iter++) { for (; iter != childrenMap.end(); iter++) {
if (iter->second.healthChanged) { if (iter->second.healthChanged) {
iter->second.healthChanged = false; iter->second.healthChanged = false;
break; break;
} }
} }
if (iter == childrenMap.end()) { if (iter == childrenMap.end()) {
return false; return false;
} }
HealthState healthState = healthHelper.healthTable->getHealth(iter->first); HealthState healthState = healthHelper.healthTable->getHealth(iter->first);
if (healthState == HasHealthIF::NEEDS_RECOVERY) { if (healthState == HasHealthIF::NEEDS_RECOVERY) {
triggerEvent(TRYING_RECOVERY); triggerEvent(TRYING_RECOVERY);
recoveryState = RECOVERY_STARTED; recoveryState = RECOVERY_STARTED;
recoveringDevice = iter; recoveringDevice = iter;
doStartTransition(targetMode, targetSubmode); doStartTransition(targetMode, targetSubmode);
} else { } else {
triggerEvent(CHILD_CHANGED_HEALTH); triggerEvent(CHILD_CHANGED_HEALTH);
doStartTransition(mode, submode); doStartTransition(mode, submode);
} }
if (modeHelper.isForced()) { if (modeHelper.isForced()) {
triggerEvent(FORCING_MODE, targetMode, targetSubmode); triggerEvent(FORCING_MODE, targetMode, targetSubmode);
} }
return true; return true;
} }
void AssemblyBase::handleChildrenTransition() { void AssemblyBase::handleChildrenTransition() {
if (commandsOutstanding <= 0) { if (commandsOutstanding <= 0) {
switch (internalState) { switch (internalState) {
case STATE_NEED_SECOND_STEP: case STATE_NEED_SECOND_STEP:
internalState = STATE_SECOND_STEP; internalState = STATE_SECOND_STEP;
commandChildren(targetMode, targetSubmode); commandChildren(targetMode, targetSubmode);
return; return;
case STATE_OVERWRITE_HEALTH: { case STATE_OVERWRITE_HEALTH: {
internalState = STATE_SINGLE_STEP; internalState = STATE_SINGLE_STEP;
ReturnValue_t result = commandChildren(mode, submode); ReturnValue_t result = commandChildren(mode, submode);
if (result == NEED_SECOND_STEP) { if (result == NEED_SECOND_STEP) {
internalState = STATE_NEED_SECOND_STEP; internalState = STATE_NEED_SECOND_STEP;
} }
return; return;
} }
case STATE_NONE: case STATE_NONE:
//Valid state, used in recovery. //Valid state, used in recovery.
case STATE_SINGLE_STEP: case STATE_SINGLE_STEP:
case STATE_SECOND_STEP: case STATE_SECOND_STEP:
if (checkAndHandleRecovery()) { if (checkAndHandleRecovery()) {
return; return;
} }
break; break;
} }
ReturnValue_t result = checkChildrenState(); ReturnValue_t result = checkChildrenState();
if (result == RETURN_OK) { if (result == RETURN_OK) {
handleModeReached(); handleModeReached();
} else { } else {
handleModeTransitionFailed(result); handleModeTransitionFailed(result);
} }
} }
} }
void AssemblyBase::handleModeReached() { void AssemblyBase::handleModeReached() {
internalState = STATE_NONE; internalState = STATE_NONE;
setMode(targetMode, targetSubmode); setMode(targetMode, targetSubmode);
} }
void AssemblyBase::handleModeTransitionFailed(ReturnValue_t result) { void AssemblyBase::handleModeTransitionFailed(ReturnValue_t result) {
//always accept transition to OFF, there is nothing we can do except sending an info event //always accept transition to OFF, there is nothing we can do except sending an info event
//In theory this should never happen, but we would risk an infinite loop otherwise //In theory this should never happen, but we would risk an infinite loop otherwise
if (targetMode == MODE_OFF) { if (targetMode == MODE_OFF) {
triggerEvent(CHILD_PROBLEMS, result); triggerEvent(CHILD_PROBLEMS, result);
internalState = STATE_NONE; internalState = STATE_NONE;
setMode(targetMode, targetSubmode); setMode(targetMode, targetSubmode);
} else { } else {
if (handleChildrenChangedHealth()) { if (handleChildrenChangedHealth()) {
//If any health change is pending, handle that first. //If any health change is pending, handle that first.
return; return;
} }
triggerEvent(MODE_TRANSITION_FAILED, result); triggerEvent(MODE_TRANSITION_FAILED, result);
startTransition(MODE_OFF, SUBMODE_NONE); startTransition(MODE_OFF, SUBMODE_NONE);
} }
} }
void AssemblyBase::sendHealthCommand(MessageQueueId_t sendTo, void AssemblyBase::sendHealthCommand(MessageQueueId_t sendTo,
HealthState health) { HealthState health) {
CommandMessage command; CommandMessage command;
HealthMessage::setHealthMessage(&command, HealthMessage::HEALTH_SET, HealthMessage::setHealthMessage(&command, HealthMessage::HEALTH_SET,
health); health);
if (commandQueue->sendMessage(sendTo, &command) == RETURN_OK) { if (commandQueue->sendMessage(sendTo, &command) == RETURN_OK) {
commandsOutstanding++; commandsOutstanding++;
} }
} }
ReturnValue_t AssemblyBase::checkChildrenState() { ReturnValue_t AssemblyBase::checkChildrenState() {
if (targetMode == MODE_OFF) { if (targetMode == MODE_OFF) {
return checkChildrenStateOff(); return checkChildrenStateOff();
} else { } else {
return checkChildrenStateOn(targetMode, targetSubmode); return checkChildrenStateOn(targetMode, targetSubmode);
} }
} }
ReturnValue_t AssemblyBase::checkChildrenStateOff() { ReturnValue_t AssemblyBase::checkChildrenStateOff() {
for (const auto& childIter: childrenMap) { for (const auto& childIter: childrenMap) {
if (checkChildOff(childIter.first) != RETURN_OK) { if (checkChildOff(childIter.first) != RETURN_OK) {
return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE; return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE;
} }
} }
return RETURN_OK; return RETURN_OK;
} }
ReturnValue_t AssemblyBase::checkChildOff(uint32_t objectId) { ReturnValue_t AssemblyBase::checkChildOff(uint32_t objectId) {
ChildInfo childInfo = childrenMap.find(objectId)->second; ChildInfo childInfo = childrenMap.find(objectId)->second;
if (healthHelper.healthTable->isCommandable(objectId)) { if (healthHelper.healthTable->isCommandable(objectId)) {
if (childInfo.submode != SUBMODE_NONE) { if (childInfo.submode != SUBMODE_NONE) {
return RETURN_FAILED; return RETURN_FAILED;
} else { } else {
if ((childInfo.mode != MODE_OFF) if ((childInfo.mode != MODE_OFF)
&& (childInfo.mode != DeviceHandlerIF::MODE_ERROR_ON)) { && (childInfo.mode != DeviceHandlerIF::MODE_ERROR_ON)) {
return RETURN_FAILED; return RETURN_FAILED;
} }
} }
} }
return RETURN_OK; return RETURN_OK;
} }
ReturnValue_t AssemblyBase::checkModeCommand(Mode_t mode, Submode_t submode, ReturnValue_t AssemblyBase::checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t* msToReachTheMode) { uint32_t* msToReachTheMode) {
//always accept transition to OFF //always accept transition to OFF
if (mode == MODE_OFF) { if (mode == MODE_OFF) {
if (submode != SUBMODE_NONE) { if (submode != SUBMODE_NONE) {
return INVALID_SUBMODE; return INVALID_SUBMODE;
} }
return RETURN_OK; return RETURN_OK;
} }
if ((mode != MODE_ON) && (mode != DeviceHandlerIF::MODE_NORMAL)) { if ((mode != MODE_ON) && (mode != DeviceHandlerIF::MODE_NORMAL)) {
return INVALID_MODE; return INVALID_MODE;
} }
if (internalState != STATE_NONE) { if (internalState != STATE_NONE) {
return IN_TRANSITION; return IN_TRANSITION;
} }
return isModeCombinationValid(mode, submode); return isModeCombinationValid(mode, submode);
} }
ReturnValue_t AssemblyBase::handleHealthReply(CommandMessage* message) { ReturnValue_t AssemblyBase::handleHealthReply(CommandMessage* message) {
if (message->getCommand() == HealthMessage::HEALTH_INFO) { if (message->getCommand() == HealthMessage::HEALTH_INFO) {
HealthState health = HealthMessage::getHealth(message); HealthState health = HealthMessage::getHealth(message);
if (health != EXTERNAL_CONTROL) { if (health != EXTERNAL_CONTROL) {
updateChildChangedHealth(message->getSender(), true); updateChildChangedHealth(message->getSender(), true);
} }
return RETURN_OK; return RETURN_OK;
} }
if (message->getCommand() == HealthMessage::REPLY_HEALTH_SET if (message->getCommand() == HealthMessage::REPLY_HEALTH_SET
|| (message->getCommand() == CommandMessage::REPLY_REJECTED || (message->getCommand() == CommandMessage::REPLY_REJECTED
&& message->getParameter2() == HealthMessage::HEALTH_SET)) { && message->getParameter2() == HealthMessage::HEALTH_SET)) {
if (isInTransition()) { if (isInTransition()) {
commandsOutstanding--; commandsOutstanding--;
} }
return RETURN_OK; return RETURN_OK;
} }
return RETURN_FAILED; return RETURN_FAILED;
} }
bool AssemblyBase::checkAndHandleRecovery() { bool AssemblyBase::checkAndHandleRecovery() {
switch (recoveryState) { switch (recoveryState) {
case RECOVERY_STARTED: case RECOVERY_STARTED:
recoveryState = RECOVERY_WAIT; recoveryState = RECOVERY_WAIT;
recoveryOffTimer.resetTimer(); recoveryOffTimer.resetTimer();
return true; return true;
case RECOVERY_WAIT: case RECOVERY_WAIT:
if (recoveryOffTimer.isBusy()) { if (recoveryOffTimer.isBusy()) {
return true; return true;
} }
triggerEvent(RECOVERY_STEP, 0); triggerEvent(RECOVERY_STEP, 0);
sendHealthCommand(recoveringDevice->second.commandQueue, HEALTHY); sendHealthCommand(recoveringDevice->second.commandQueue, HEALTHY);
internalState = STATE_NONE; internalState = STATE_NONE;
recoveryState = RECOVERY_ONGOING; recoveryState = RECOVERY_ONGOING;
//Don't check state! //Don't check state!
return true; return true;
case RECOVERY_ONGOING: case RECOVERY_ONGOING:
triggerEvent(RECOVERY_STEP, 1); triggerEvent(RECOVERY_STEP, 1);
recoveryState = RECOVERY_ONGOING_2; recoveryState = RECOVERY_ONGOING_2;
recoveringDevice->second.healthChanged = false; recoveringDevice->second.healthChanged = false;
//Device should be healthy again, so restart a transition. //Device should be healthy again, so restart a transition.
//Might be including second step, but that's already handled. //Might be including second step, but that's already handled.
doStartTransition(targetMode, targetSubmode); doStartTransition(targetMode, targetSubmode);
return true; return true;
case RECOVERY_ONGOING_2: case RECOVERY_ONGOING_2:
triggerEvent(RECOVERY_DONE); triggerEvent(RECOVERY_DONE);
//Now we're through, but not sure if it was successful. //Now we're through, but not sure if it was successful.
recoveryState = RECOVERY_IDLE; recoveryState = RECOVERY_IDLE;
return false; return false;
case RECOVERY_IDLE: case RECOVERY_IDLE:
default: default:
return false; return false;
} }
} }
void AssemblyBase::overwriteDeviceHealth(object_id_t objectId, void AssemblyBase::overwriteDeviceHealth(object_id_t objectId,
HasHealthIF::HealthState oldHealth) { HasHealthIF::HealthState oldHealth) {
triggerEvent(OVERWRITING_HEALTH, objectId, oldHealth); triggerEvent(OVERWRITING_HEALTH, objectId, oldHealth);
internalState = STATE_OVERWRITE_HEALTH; internalState = STATE_OVERWRITE_HEALTH;
modeHelper.setForced(true); modeHelper.setForced(true);
sendHealthCommand(childrenMap[objectId].commandQueue, EXTERNAL_CONTROL); sendHealthCommand(childrenMap[objectId].commandQueue, EXTERNAL_CONTROL);
} }

View File

@ -1,163 +1,163 @@
#ifndef FRAMEWORK_DEVICEHANDLERS_ASSEMBLYBASE_H_ #ifndef FRAMEWORK_DEVICEHANDLERS_ASSEMBLYBASE_H_
#define FRAMEWORK_DEVICEHANDLERS_ASSEMBLYBASE_H_ #define FRAMEWORK_DEVICEHANDLERS_ASSEMBLYBASE_H_
#include <framework/container/FixedArrayList.h> #include "../container/FixedArrayList.h"
#include <framework/devicehandlers/DeviceHandlerBase.h> #include "../devicehandlers/DeviceHandlerBase.h"
#include <framework/subsystem/SubsystemBase.h> #include "../subsystem/SubsystemBase.h"
/** /**
* @brief Base class to implement reconfiguration and failure handling for * @brief Base class to implement reconfiguration and failure handling for
* redundant devices by monitoring their modes health states. * redundant devices by monitoring their modes health states.
* @details * @details
* Documentation: Dissertation Baetz p.156, 157. * Documentation: Dissertation Baetz p.156, 157.
* *
* This class reduces the complexity of controller components which would * This class reduces the complexity of controller components which would
* otherwise be needed for the handling of redundant devices. * otherwise be needed for the handling of redundant devices.
* *
* The template class monitors mode and health state of its children * The template class monitors mode and health state of its children
* and checks availability of devices on every detected change. * and checks availability of devices on every detected change.
* AssemblyBase does not implement any redundancy logic by itself, but provides * AssemblyBase does not implement any redundancy logic by itself, but provides
* adaptation points for implementations to do so. Since most monitoring * adaptation points for implementations to do so. Since most monitoring
* activities rely on mode and health state only and are therefore * activities rely on mode and health state only and are therefore
* generic, it is sufficient for subclasses to provide: * generic, it is sufficient for subclasses to provide:
* *
* 1. check logic when active-> checkChildrenStateOn * 1. check logic when active-> checkChildrenStateOn
* 2. transition logic to change the mode -> commandChildren * 2. transition logic to change the mode -> commandChildren
* *
*/ */
class AssemblyBase: public SubsystemBase { class AssemblyBase: public SubsystemBase {
public: public:
static const uint8_t INTERFACE_ID = CLASS_ID::ASSEMBLY_BASE; static const uint8_t INTERFACE_ID = CLASS_ID::ASSEMBLY_BASE;
static const ReturnValue_t NEED_SECOND_STEP = MAKE_RETURN_CODE(0x01); static const ReturnValue_t NEED_SECOND_STEP = MAKE_RETURN_CODE(0x01);
static const ReturnValue_t NEED_TO_RECONFIGURE = MAKE_RETURN_CODE(0x02); static const ReturnValue_t NEED_TO_RECONFIGURE = MAKE_RETURN_CODE(0x02);
static const ReturnValue_t MODE_FALLBACK = MAKE_RETURN_CODE(0x03); static const ReturnValue_t MODE_FALLBACK = MAKE_RETURN_CODE(0x03);
static const ReturnValue_t CHILD_NOT_COMMANDABLE = MAKE_RETURN_CODE(0x04); static const ReturnValue_t CHILD_NOT_COMMANDABLE = MAKE_RETURN_CODE(0x04);
static const ReturnValue_t NEED_TO_CHANGE_HEALTH = MAKE_RETURN_CODE(0x05); static const ReturnValue_t NEED_TO_CHANGE_HEALTH = MAKE_RETURN_CODE(0x05);
static const ReturnValue_t NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE = static const ReturnValue_t NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE =
MAKE_RETURN_CODE(0xa1); MAKE_RETURN_CODE(0xa1);
AssemblyBase(object_id_t objectId, object_id_t parentId, AssemblyBase(object_id_t objectId, object_id_t parentId,
uint16_t commandQueueDepth = 8); uint16_t commandQueueDepth = 8);
virtual ~AssemblyBase(); virtual ~AssemblyBase();
protected: protected:
// SHOULDDO: Change that OVERWRITE_HEALTH may be returned // SHOULDDO: Change that OVERWRITE_HEALTH may be returned
// (or return internalState directly?) // (or return internalState directly?)
/** /**
* Command children to reach [mode,submode] combination * Command children to reach [mode,submode] combination
* Can be done by setting #commandsOutstanding correctly, * Can be done by setting #commandsOutstanding correctly,
* or using executeTable() * or using executeTable()
* @param mode * @param mode
* @param submode * @param submode
* @return * @return
* - @c RETURN_OK if ok * - @c RETURN_OK if ok
* - @c NEED_SECOND_STEP if children need to be commanded again * - @c NEED_SECOND_STEP if children need to be commanded again
*/ */
virtual ReturnValue_t commandChildren(Mode_t mode, Submode_t submode) = 0; virtual ReturnValue_t commandChildren(Mode_t mode, Submode_t submode) = 0;
/** /**
* Check whether desired assembly mode was achieved by checking the modes * Check whether desired assembly mode was achieved by checking the modes
* or/and health states of child device handlers. * or/and health states of child device handlers.
* The assembly template class will also call this function if a health * The assembly template class will also call this function if a health
* or mode change of a child device handler was detected. * or mode change of a child device handler was detected.
* @param wantedMode * @param wantedMode
* @param wantedSubmode * @param wantedSubmode
* @return * @return
*/ */
virtual ReturnValue_t checkChildrenStateOn(Mode_t wantedMode, virtual ReturnValue_t checkChildrenStateOn(Mode_t wantedMode,
Submode_t wantedSubmode) = 0; Submode_t wantedSubmode) = 0;
virtual ReturnValue_t isModeCombinationValid(Mode_t mode, virtual ReturnValue_t isModeCombinationValid(Mode_t mode,
Submode_t submode) = 0; Submode_t submode) = 0;
enum InternalState { enum InternalState {
STATE_NONE, STATE_NONE,
STATE_OVERWRITE_HEALTH, STATE_OVERWRITE_HEALTH,
STATE_NEED_SECOND_STEP, STATE_NEED_SECOND_STEP,
STATE_SINGLE_STEP, STATE_SINGLE_STEP,
STATE_SECOND_STEP, STATE_SECOND_STEP,
} internalState; } internalState;
enum RecoveryState { enum RecoveryState {
RECOVERY_IDLE, RECOVERY_IDLE,
RECOVERY_STARTED, RECOVERY_STARTED,
RECOVERY_ONGOING, RECOVERY_ONGOING,
RECOVERY_ONGOING_2, RECOVERY_ONGOING_2,
RECOVERY_WAIT RECOVERY_WAIT
} recoveryState; //!< Indicates if one of the children requested a recovery. } recoveryState; //!< Indicates if one of the children requested a recovery.
ChildrenMap::iterator recoveringDevice; ChildrenMap::iterator recoveringDevice;
/** /**
* the mode the current transition is trying to achieve. * the mode the current transition is trying to achieve.
* Can be different from the modehelper.commandedMode! * Can be different from the modehelper.commandedMode!
*/ */
Mode_t targetMode; Mode_t targetMode;
/** /**
* the submode the current transition is trying to achieve. * the submode the current transition is trying to achieve.
* Can be different from the modehelper.commandedSubmode! * Can be different from the modehelper.commandedSubmode!
*/ */
Submode_t targetSubmode; Submode_t targetSubmode;
Countdown recoveryOffTimer; Countdown recoveryOffTimer;
static const uint32_t POWER_OFF_TIME_MS = 1000; static const uint32_t POWER_OFF_TIME_MS = 1000;
virtual ReturnValue_t handleCommandMessage(CommandMessage *message); virtual ReturnValue_t handleCommandMessage(CommandMessage *message);
virtual ReturnValue_t handleHealthReply(CommandMessage *message); virtual ReturnValue_t handleHealthReply(CommandMessage *message);
virtual void performChildOperation(); virtual void performChildOperation();
bool handleChildrenChanged(); bool handleChildrenChanged();
/** /**
* This method is called if the children changed its mode in a way that * This method is called if the children changed its mode in a way that
* the current mode can't be kept. * the current mode can't be kept.
* Default behavior is to go to MODE_OFF. * Default behavior is to go to MODE_OFF.
* @param result The failure code which was returned by checkChildrenState. * @param result The failure code which was returned by checkChildrenState.
*/ */
virtual void handleChildrenLostMode(ReturnValue_t result); virtual void handleChildrenLostMode(ReturnValue_t result);
bool handleChildrenChangedHealth(); bool handleChildrenChangedHealth();
virtual void handleChildrenTransition(); virtual void handleChildrenTransition();
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t *msToReachTheMode); uint32_t *msToReachTheMode);
virtual void startTransition(Mode_t mode, Submode_t submode); virtual void startTransition(Mode_t mode, Submode_t submode);
virtual void doStartTransition(Mode_t mode, Submode_t submode); virtual void doStartTransition(Mode_t mode, Submode_t submode);
virtual bool isInTransition(); virtual bool isInTransition();
virtual void handleModeReached(); virtual void handleModeReached();
virtual void handleModeTransitionFailed(ReturnValue_t result); virtual void handleModeTransitionFailed(ReturnValue_t result);
void sendHealthCommand(MessageQueueId_t sendTo, HealthState health); void sendHealthCommand(MessageQueueId_t sendTo, HealthState health);
virtual ReturnValue_t checkChildrenStateOff(); virtual ReturnValue_t checkChildrenStateOff();
ReturnValue_t checkChildrenState(); ReturnValue_t checkChildrenState();
virtual ReturnValue_t checkChildOff(uint32_t objectId); virtual ReturnValue_t checkChildOff(uint32_t objectId);
/** /**
* Manages recovery of a device * Manages recovery of a device
* @return true if recovery is still ongoing, false else. * @return true if recovery is still ongoing, false else.
*/ */
bool checkAndHandleRecovery(); bool checkAndHandleRecovery();
/** /**
* Helper method to overwrite health state of one of the children. * Helper method to overwrite health state of one of the children.
* Also sets state to STATE_OVERWRITE_HEATH. * Also sets state to STATE_OVERWRITE_HEATH.
* @param objectId Must be a registered child. * @param objectId Must be a registered child.
*/ */
void overwriteDeviceHealth(object_id_t objectId, HasHealthIF::HealthState oldHealth); void overwriteDeviceHealth(object_id_t objectId, HasHealthIF::HealthState oldHealth);
}; };
#endif /* FRAMEWORK_DEVICEHANDLERS_ASSEMBLYBASE_H_ */ #endif /* FRAMEWORK_DEVICEHANDLERS_ASSEMBLYBASE_H_ */

View File

@ -1,47 +1,47 @@
#include <framework/subsystem/SubsystemBase.h> #include "../subsystem/SubsystemBase.h"
#include <framework/devicehandlers/ChildHandlerBase.h> #include "../devicehandlers/ChildHandlerBase.h"
#include <framework/subsystem/SubsystemBase.h> #include "../subsystem/SubsystemBase.h"
ChildHandlerBase::ChildHandlerBase(object_id_t setObjectId, ChildHandlerBase::ChildHandlerBase(object_id_t setObjectId,
object_id_t deviceCommunication, CookieIF * cookie, object_id_t deviceCommunication, CookieIF * cookie,
object_id_t hkDestination, uint32_t thermalStatePoolId, object_id_t hkDestination, uint32_t thermalStatePoolId,
uint32_t thermalRequestPoolId, uint32_t thermalRequestPoolId,
object_id_t parent, object_id_t parent,
FailureIsolationBase* customFdir, size_t cmdQueueSize) : FailureIsolationBase* customFdir, size_t cmdQueueSize) :
DeviceHandlerBase(setObjectId, deviceCommunication, cookie, DeviceHandlerBase(setObjectId, deviceCommunication, cookie,
(customFdir == nullptr? &childHandlerFdir : customFdir), (customFdir == nullptr? &childHandlerFdir : customFdir),
cmdQueueSize), cmdQueueSize),
parentId(parent), childHandlerFdir(setObjectId) { parentId(parent), childHandlerFdir(setObjectId) {
this->setHkDestination(hkDestination); this->setHkDestination(hkDestination);
this->setThermalStateRequestPoolIds(thermalStatePoolId, this->setThermalStateRequestPoolIds(thermalStatePoolId,
thermalRequestPoolId); thermalRequestPoolId);
} }
ChildHandlerBase::~ChildHandlerBase() { ChildHandlerBase::~ChildHandlerBase() {
} }
ReturnValue_t ChildHandlerBase::initialize() { ReturnValue_t ChildHandlerBase::initialize() {
ReturnValue_t result = DeviceHandlerBase::initialize(); ReturnValue_t result = DeviceHandlerBase::initialize();
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
MessageQueueId_t parentQueue = 0; MessageQueueId_t parentQueue = 0;
if (parentId != objects::NO_OBJECT) { if (parentId != objects::NO_OBJECT) {
SubsystemBase *parent = objectManager->get<SubsystemBase>(parentId); SubsystemBase *parent = objectManager->get<SubsystemBase>(parentId);
if (parent == NULL) { if (parent == NULL) {
return RETURN_FAILED; return RETURN_FAILED;
} }
parentQueue = parent->getCommandQueue(); parentQueue = parent->getCommandQueue();
parent->registerChild(getObjectId()); parent->registerChild(getObjectId());
} }
healthHelper.setParentQueue(parentQueue); healthHelper.setParentQueue(parentQueue);
modeHelper.setParentQueue(parentQueue); modeHelper.setParentQueue(parentQueue);
return RETURN_OK; return RETURN_OK;
} }

Some files were not shown because too many files have changed in this diff Show More