WIP: somethings wrong.. #19

Closed
muellerr wants to merge 808 commits from source/master into master
512 changed files with 22118 additions and 9582 deletions

View File

@ -1,9 +1,9 @@
#include <framework/action/ActionHelper.h> #include "ActionHelper.h"
#include <framework/action/HasActionsIF.h> #include "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( owner(setOwner), queueToUse(useThisQueue), ipcStore(nullptr) {
NULL) {
} }
ActionHelper::~ActionHelper() { ActionHelper::~ActionHelper() {
@ -16,16 +16,18 @@ ReturnValue_t ActionHelper::handleActionMessage(CommandMessage* command) {
ActionMessage::getStoreId(command)); ActionMessage::getStoreId(command));
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} else { } else {
return CommandMessage::UNKNOW_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 == NULL) { if (ipcStore == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
setQueueToUse(queueToUse_); if(queueToUse_ != nullptr) {
setQueueToUse(queueToUse_);
}
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
@ -67,22 +69,23 @@ void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t act
} }
} }
ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo, ActionId_t replyId, SerializeIF* data, bool hideSender) { ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo,
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;
uint32_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;
} }
uint32_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, true); 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;

View File

@ -1,9 +1,9 @@
#ifndef ACTIONHELPER_H_ #ifndef ACTIONHELPER_H_
#define ACTIONHELPER_H_ #define ACTIONHELPER_H_
#include <framework/action/ActionMessage.h> #include "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
* *
@ -35,10 +35,10 @@ public:
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, optional if queue was set in constructor
* @return Returns RETURN_OK if successful * @return Returns RETURN_OK if successful
*/ */
ReturnValue_t initialize(MessageQueueIF* queueToUse_); 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.
* *

View File

@ -1,6 +1,6 @@
#include <framework/action/ActionMessage.h> #include "ActionMessage.h"
#include <framework/objectmanager/ObjectManagerIF.h> #include "../objectmanager/ObjectManagerIF.h"
#include <framework/storagemanager/StorageManagerIF.h> #include "../storagemanager/StorageManagerIF.h"
ActionMessage::ActionMessage() { ActionMessage::ActionMessage() {
} }

View File

@ -1,16 +1,16 @@
#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 = MESSAGE_TYPE::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);

View File

@ -1,33 +1,34 @@
#include <framework/action/ActionMessage.h> #include "ActionMessage.h"
#include <framework/action/CommandActionHelper.h> #include "CommandActionHelper.h"
#include <framework/action/CommandsActionsIF.h> #include "CommandsActionsIF.h"
#include <framework/action/HasActionsIF.h> #include "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;
uint32_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;
} }
uint32_t size = 0; size_t size = 0;
result = data->serialize(&storePointer, &size, maxSize, true); result = data->serialize(&storePointer, &size, maxSize,
SerializeIF::Endianness::BIG);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
@ -35,11 +36,11 @@ ReturnValue_t CommandActionHelper::commandAction(object_id_t commandTo,
} }
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;
} }
@ -71,13 +72,13 @@ ReturnValue_t CommandActionHelper::initialize() {
} }
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;
} }
@ -88,7 +89,8 @@ ReturnValue_t CommandActionHelper::handleReply(CommandMessage* reply) {
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
case ActionMessage::COMPLETION_FAILED: case ActionMessage::COMPLETION_FAILED:
commandCount--; commandCount--;
owner->completionFailedReceived(ActionMessage::getActionId(reply), ActionMessage::getReturnCode(reply)); owner->completionFailedReceived(ActionMessage::getActionId(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),
@ -96,11 +98,13 @@ ReturnValue_t CommandActionHelper::handleReply(CommandMessage* reply) {
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
case ActionMessage::STEP_FAILED: case ActionMessage::STEP_FAILED:
commandCount--; commandCount--;
owner->stepFailedReceived(ActionMessage::getActionId(reply), ActionMessage::getStep(reply), owner->stepFailedReceived(ActionMessage::getActionId(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), ActionMessage::getStoreId(reply)); extractDataForOwner(ActionMessage::getActionId(reply),
ActionMessage::getStoreId(reply));
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
default: default:
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;

View File

@ -1,12 +1,12 @@
#ifndef COMMANDACTIONHELPER_H_ #ifndef COMMANDACTIONHELPER_H_
#define COMMANDACTIONHELPER_H_ #define COMMANDACTIONHELPER_H_
#include <framework/action/ActionMessage.h> #include "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;

View File

@ -1,9 +1,9 @@
#ifndef COMMANDSACTIONSIF_H_ #ifndef COMMANDSACTIONSIF_H_
#define COMMANDSACTIONSIF_H_ #define COMMANDSACTIONSIF_H_
#include <framework/action/CommandActionHelper.h> #include "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.

View File

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

View File

@ -1,5 +1,5 @@
#include <framework/action/HasActionsIF.h> #include "HasActionsIF.h"
#include <framework/action/SimpleActionHelper.h> #include "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(

View File

@ -1,7 +1,7 @@
#ifndef SIMPLEACTIONHELPER_H_ #ifndef SIMPLEACTIONHELPER_H_
#define SIMPLEACTIONHELPER_H_ #define SIMPLEACTIONHELPER_H_
#include <framework/action/ActionHelper.h> #include "ActionHelper.h"
class SimpleActionHelper: public ActionHelper { class SimpleActionHelper: public ActionHelper {
public: public:

View File

@ -1,15 +1,15 @@
#ifndef ARRAYLIST_H_ #ifndef FRAMEWORK_CONTAINER_ARRAYLIST_H_
#define 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"
/** /**
* A List that stores its values in an array. * @brief A List that stores its values in an array.
* * @details
* The backend is an array that can be allocated by the class itself or supplied via ctor. * The underlying storage is an array that can be allocated by the class
* * itself or supplied via ctor.
* *
* @ingroup container * @ingroup container
*/ */
@ -20,81 +20,13 @@ 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);
/** /**
* An Iterator to go trough an ArrayList * Copying is forbiden by declaring copy ctor and copy assignment deleted
* * It is too ambigous in this case.
* It stores a pointer to an element and increments the * (Allocate a new backend? Use the same? What to do in an modifying call?)
* pointer when incremented itself. */
*/ ArrayList(const ArrayList& other) = delete;
class Iterator { const ArrayList& operator=(const ArrayList& other) = delete;
public:
/**
* Empty ctor, points to NULL
*/
Iterator() :
value(0) {
}
/**
* Initializes the Iterator to point to an element
*
* @param initialize
*/
Iterator(T *initialize) {
value = initialize;
}
/**
* The current element the iterator points to
*/
T *value;
Iterator& operator++() {
value++;
return *this;
}
Iterator operator++(int) {
Iterator tmp(*this);
operator++();
return tmp;
}
Iterator& operator--() {
value--;
return *this;
}
Iterator operator--(int) {
Iterator tmp(*this);
operator--();
return tmp;
}
T operator*() {
return *value;
}
T *operator->() {
return value;
}
const T *operator->() const{
return value;
}
//SHOULDDO this should be implemented as non-member
bool operator==(const typename ArrayList<T, count_t>::Iterator& other) const{
return (value == other.value);
}
//SHOULDDO this should be implemented as non-member
bool operator!=(const typename ArrayList<T, count_t>::Iterator& other) const {
return !(*this == other);
}
}
;
/** /**
* Number of Elements stored in this List * Number of Elements stored in this List
@ -135,6 +67,78 @@ public:
} }
} }
/**
* An Iterator to go trough an ArrayList
*
* It stores a pointer to an element and increments the
* pointer when incremented itself.
*/
class Iterator {
public:
/**
* Empty ctor, points to NULL
*/
Iterator(): value(0) {}
/**
* Initializes the Iterator to point to an element
*
* @param initialize
*/
Iterator(T *initialize) {
value = initialize;
}
/**
* The current element the iterator points to
*/
T *value;
Iterator& operator++() {
value++;
return *this;
}
Iterator operator++(int) {
Iterator tmp(*this);
operator++();
return tmp;
}
Iterator& operator--() {
value--;
return *this;
}
Iterator operator--(int) {
Iterator tmp(*this);
operator--();
return tmp;
}
T operator*() {
return *value;
}
T *operator->() {
return value;
}
const T *operator->() const{
return value;
}
//SHOULDDO this should be implemented as non-member
bool operator==(const typename ArrayList<T, count_t>::Iterator& other) const{
return (value == other.value);
}
//SHOULDDO this should be implemented as non-member
bool operator!=(const typename ArrayList<T, count_t>::Iterator& other) const {
return !(*this == other);
}
};
/** /**
* Iterator pointing to the first stored elmement * Iterator pointing to the first stored elmement
* *
@ -223,19 +227,7 @@ public:
count_t remaining() { count_t remaining() {
return (maxSize_ - size); return (maxSize_ - size);
} }
private:
/**
* This is the copy constructor
*
* It is private, as copying is too ambigous in this case. (Allocate a new backend? Use the same?
* What to do in an modifying call?)
*
* @param other
*/
ArrayList(const ArrayList& other) :
size(other.size), entries(other.entries), maxSize_(other.maxSize_), allocated(
false) {
}
protected: protected:
/** /**
* pointer to the array in which the entries are stored * pointer to the array in which the entries are stored
@ -250,6 +242,6 @@ protected:
* 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_ */

42
container/DynamicFIFO.h Normal file
View File

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

View File

@ -1,82 +1,35 @@
#ifndef FIFO_H_ #ifndef FSFW_CONTAINER_FIFO_H_
#define FIFO_H_ #define FSFW_CONTAINER_FIFO_H_
#include <framework/returnvalues/HasReturnvaluesIF.h> #include "FIFOBase.h"
#include <array>
/** /**
* @brief Simple First-In-First-Out data structure * @brief Simple First-In-First-Out data structure with size fixed at
* compile time
* @details
* Performs no dynamic memory allocation.
* 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, uint8_t capacity> template<typename T, size_t capacity>
class FIFO { class FIFO: public FIFOBase<T> {
private:
uint8_t readIndex, writeIndex, currentSize;
T data[capacity];
uint8_t next(uint8_t current) {
++current;
if (current == capacity) {
current = 0;
}
return current;
}
public: public:
FIFO() : FIFO(): FIFOBase<T>(nullptr, capacity) {
readIndex(0), writeIndex(0), currentSize(0) { this->setContainer(fifoArray.data());
};
/**
* @brief Custom copy constructor to set pointer correctly.
* @param other
*/
FIFO(const FIFO& other): FIFOBase<T>(other) {
this->setContainer(fifoArray.data());
} }
bool empty() { private:
return (currentSize == 0); std::array<T, capacity> fifoArray;
}
bool full() {
return (currentSize == capacity);
}
uint8_t size(){
return currentSize;
}
ReturnValue_t insert(T value) {
if (full()) {
return FULL;
} else {
data[writeIndex] = value;
writeIndex = next(writeIndex);
++currentSize;
return HasReturnvaluesIF::RETURN_OK;
}
}
ReturnValue_t retrieve(T *value) {
if (empty()) {
return EMPTY;
} else {
*value = data[readIndex];
readIndex = next(readIndex);
--currentSize;
return HasReturnvaluesIF::RETURN_OK;
}
}
ReturnValue_t peek(T * value) {
if(empty()) {
return EMPTY;
} else {
*value = data[readIndex];
return HasReturnvaluesIF::RETURN_OK;
}
}
ReturnValue_t pop() {
T value;
return this->retrieve(&value);
}
static const uint8_t INTERFACE_ID = CLASS_ID::FIFO_CLASS;
static const ReturnValue_t FULL = MAKE_RETURN_CODE(1);
static const ReturnValue_t EMPTY = MAKE_RETURN_CODE(2);
}; };
#endif /* FIFO_H_ */ #endif /* FSFW_CONTAINER_FIFO_H_ */

65
container/FIFOBase.h Normal file
View File

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

87
container/FIFOBase.tpp Normal file
View File

@ -0,0 +1,87 @@
#ifndef FSFW_CONTAINER_FIFOBASE_TPP_
#define FSFW_CONTAINER_FIFOBASE_TPP_
#ifndef FSFW_CONTAINER_FIFOBASE_H_
#error Include FIFOBase.h before FIFOBase.tpp!
#endif
template<typename T>
inline FIFOBase<T>::FIFOBase(T* values, const size_t maxCapacity):
maxCapacity(maxCapacity), values(values){};
template<typename T>
inline ReturnValue_t FIFOBase<T>::insert(T value) {
if (full()) {
return FULL;
} else {
values[writeIndex] = value;
writeIndex = next(writeIndex);
++currentSize;
return HasReturnvaluesIF::RETURN_OK;
}
};
template<typename T>
inline ReturnValue_t FIFOBase<T>::retrieve(T* value) {
if (empty()) {
return EMPTY;
} else {
*value = values[readIndex];
readIndex = next(readIndex);
--currentSize;
return HasReturnvaluesIF::RETURN_OK;
}
};
template<typename T>
inline ReturnValue_t FIFOBase<T>::peek(T* value) {
if(empty()) {
return EMPTY;
} else {
*value = values[readIndex];
return HasReturnvaluesIF::RETURN_OK;
}
};
template<typename T>
inline ReturnValue_t FIFOBase<T>::pop() {
T value;
return this->retrieve(&value);
};
template<typename T>
inline bool FIFOBase<T>::empty() {
return (currentSize == 0);
};
template<typename T>
inline bool FIFOBase<T>::full() {
return (currentSize == maxCapacity);
}
template<typename T>
inline size_t FIFOBase<T>::size() {
return currentSize;
}
template<typename T>
inline size_t FIFOBase<T>::next(size_t current) {
++current;
if (current == maxCapacity) {
current = 0;
}
return current;
}
template<typename T>
inline size_t FIFOBase<T>::getMaxCapacity() const {
return maxCapacity;
}
template<typename T>
inline void FIFOBase<T>::setContainer(T *data) {
this->values = data;
}
#endif

View File

@ -1,19 +1,42 @@
#ifndef FIXEDARRAYLIST_H_ #ifndef FIXEDARRAYLIST_H_
#define FIXEDARRAYLIST_H_ #define FIXEDARRAYLIST_H_
#include <framework/container/ArrayList.h> #include "../container/ArrayList.h"
/** /**
* \ingroup container * @brief Array List with a fixed maximum size
* @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.
* 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
// with data and the known size field
// so it can be used for serialization too (with SerialFixedArrrayListAdapter)
// is this feasible?
/**
* Initialize a fixed array list with data and number of data fields.
* Endianness of entries can be swapped optionally.
* @param data_
* @param count
* @param swapArrayListEndianess
*/
FixedArrayList(T * data_, count_t count):
ArrayList<T, count_t>(data, MAX_SIZE) {
memcpy(this->data, data_, count * sizeof(T));
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));

View File

@ -1,12 +1,16 @@
#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>
/** /**
* \ingroup container * @brief Map implementation for maps with a pre-defined size.
* @details Can be initialized with desired maximum size.
* Iterator is used to access <key,value> pair and
* iterate through map entries. Complexity O(n).
* @ingroup container
*/ */
template<typename key_t, typename T> template<typename key_t, typename T>
class FixedMap: public SerializeIF { class FixedMap: public SerializeIF {
@ -52,12 +56,24 @@ public:
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
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
key_t first() {
return ArrayList<std::pair<key_t, T>, uint32_t>::Iterator::value->first;
}
// Alternative to access value, similar to std::map implementation
T 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]);
} }
@ -72,10 +88,10 @@ public:
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 KEY_ALREADY_EXISTS; return FixedMap::KEY_ALREADY_EXISTS;
} }
if (_size == theMap.maxSize()) { if (_size == theMap.maxSize()) {
return MAP_FULL; return FixedMap::MAP_FULL;
} }
theMap[_size].first = key; theMap[_size].first = key;
theMap[_size].second = value; theMap[_size].second = value;
@ -87,7 +103,7 @@ public:
} }
ReturnValue_t insert(std::pair<key_t, T> pair) { ReturnValue_t insert(std::pair<key_t, T> pair) {
return insert(pair.fist, pair.second); return insert(pair.first, pair.second);
} }
ReturnValue_t exists(key_t key) const { ReturnValue_t exists(key_t key) const {
@ -148,47 +164,57 @@ public:
return theMap.maxSize(); return theMap.maxSize();
} }
virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size,
const uint32_t max_size, bool bigEndian) const { bool full() {
ReturnValue_t result = SerializeAdapter<uint32_t>::serialize(&this->_size, if(_size == theMap.maxSize()) {
buffer, size, max_size, bigEndian); return true;
}
else {
return false;
}
}
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
size_t maxSize, Endianness streamEndianness) const {
ReturnValue_t result = SerializeAdapter::serialize(&this->_size,
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<key_t>::serialize(&theMap[i].first, buffer, result = SerializeAdapter::serialize(&theMap[i].first, buffer,
size, max_size, bigEndian); size, maxSize, streamEndianness);
result = SerializeAdapter<T>::serialize(&theMap[i].second, buffer, size, result = SerializeAdapter::serialize(&theMap[i].second, buffer, size,
max_size, bigEndian); maxSize, streamEndianness);
++i; ++i;
} }
return result; return result;
} }
virtual uint32_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<key_t>::getSerializedSize( printSize += SerializeAdapter::getSerializedSize(
&theMap[i].first); &theMap[i].first);
printSize += SerializeAdapter<T>::getSerializedSize(&theMap[i].second); printSize += SerializeAdapter::getSerializedSize(&theMap[i].second);
} }
return printSize; return printSize;
} }
virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
bool bigEndian) { Endianness streamEndianness) {
ReturnValue_t result = SerializeAdapter<uint32_t>::deSerialize(&this->_size, ReturnValue_t result = SerializeAdapter::deSerialize(&this->_size,
buffer, size, bigEndian); 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<key_t>::deSerialize(&theMap[i].first, buffer, result = SerializeAdapter::deSerialize(&theMap[i].first, buffer,
size, bigEndian); size, streamEndianness);
result = SerializeAdapter<T>::deSerialize(&theMap[i].second, buffer, size, result = SerializeAdapter::deSerialize(&theMap[i].second, buffer, size,
bigEndian); streamEndianness);
++i; ++i;
} }
return result; return result;

View File

@ -1,25 +1,137 @@
#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>
/** /**
* \ingroup container * @brief Map implementation which allows entries with identical keys
* @details
* Performs no dynamic memory allocation except on initialization.
* Uses an ArrayList as the underlying container and thus has a linear
* complexity O(n). As long as the number of entries remains low, this
* should not be an issue.
* The number of insertion and deletion operation should be minimized
* as those incur exensive memory move operations (the underlying container
* is not node based).
* @ingroup container
*/ */
template<typename key_t, typename T, typename KEY_COMPARE = std::less<key_t>> template<typename key_t, typename T, typename KEY_COMPARE = std::less<key_t>>
class FixedOrderedMultimap { class FixedOrderedMultimap {
public: public:
static const uint8_t INTERFACE_ID = CLASS_ID::FIXED_MAP; static const uint8_t INTERFACE_ID = CLASS_ID::FIXED_MULTIMAP;
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);
/**
* Initializes the ordered multimap with a fixed maximum size.
* @param maxSize
*/
FixedOrderedMultimap(size_t maxSize);
virtual ~FixedOrderedMultimap() {}
class Iterator: public ArrayList<std::pair<key_t, T>, uint32_t>::Iterator {
public:
/** Returns an iterator to nullptr */
Iterator();
/** Initializes iterator to given entry */
Iterator(std::pair<key_t, T> *pair);
/** Dereference operator can be used to get value */
T operator*();
/** Arrow operator can be used to get pointer to value */
T *operator->();
};
/** Iterator to start of map */
Iterator begin() const;
/** Iterator to end of map */
Iterator end() const;
/** Current (variable) size of the map */
size_t size() const;
/**
* Insert a key/value pair inside the map. An iterator to the stored
* value might be returned optionally.
* @param key
* @param value
* @param storedValue
* @return
*/
ReturnValue_t insert(key_t key, T value, Iterator *storedValue = nullptr);
/**
* Insert a given std::pair<key, value>
* @param pair
* @return
*/
ReturnValue_t insert(std::pair<key_t, T> pair);
/**
* Checks existence of key in map.
* @param key
* @return
* - @c KEY_DOES_NOT_EXIST if key does not exists.
* - @c RETURN_OK otherwise.
*/
ReturnValue_t exists(key_t key) const;
ReturnValue_t erase(Iterator *iter) {
uint32_t i;
if ((i = findFirstIndex((*iter).value->first)) >= _size) {
return KEY_DOES_NOT_EXIST;
}
removeFromPosition(i);
if (*iter != begin()) {
(*iter)--;
} else {
*iter = begin();
}
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t erase(key_t key) {
uint32_t i;
if ((i = findFirstIndex(key)) >= _size) {
return KEY_DOES_NOT_EXIST;
}
do {
removeFromPosition(i);
i = findFirstIndex(key, i);
} while (i < _size);
return HasReturnvaluesIF::RETURN_OK;
}
Iterator find(key_t key) const {
ReturnValue_t result = exists(key);
if (result != HasReturnvaluesIF::RETURN_OK) {
return end();
}
return Iterator(&theMap[findFirstIndex(key)]);
}
ReturnValue_t find(key_t key, T **value) const {
ReturnValue_t result = exists(key);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
*value = &theMap[findFirstIndex(key)].second;
return HasReturnvaluesIF::RETURN_OK;
}
void clear() {
_size = 0;
}
size_t maxSize() const {
return theMap.maxSize();
}
private: private:
typedef KEY_COMPARE compare; typedef KEY_COMPARE compare;
compare myComp; compare myComp;
ArrayList<std::pair<key_t, T>, uint32_t> theMap; ArrayList<std::pair<key_t, T>, uint32_t> theMap;
uint32_t _size; size_t _size;
uint32_t findFirstIndex(key_t key, uint32_t startAt = 0) const { uint32_t findFirstIndex(key_t key, uint32_t startAt = 0) const {
if (startAt >= _size) { if (startAt >= _size) {
@ -52,130 +164,8 @@ private:
(_size - position - 1) * sizeof(std::pair<key_t,T>)); (_size - position - 1) * sizeof(std::pair<key_t,T>));
--_size; --_size;
} }
public:
FixedOrderedMultimap(uint32_t maxSize) :
theMap(maxSize), _size(0) {
}
virtual ~FixedOrderedMultimap() {
}
class Iterator: public ArrayList<std::pair<key_t, T>, uint32_t>::Iterator {
public:
Iterator() :
ArrayList<std::pair<key_t, T>, uint32_t>::Iterator() {
}
Iterator(std::pair<key_t, T> *pair) :
ArrayList<std::pair<key_t, T>, uint32_t>::Iterator(pair) {
}
T operator*() {
return ArrayList<std::pair<key_t, T>, uint32_t>::Iterator::value->second;
}
T *operator->() {
return &ArrayList<std::pair<key_t, T>, uint32_t>::Iterator::value->second;
}
};
Iterator begin() const {
return Iterator(&theMap[0]);
}
Iterator end() const {
return Iterator(&theMap[_size]);
}
uint32_t size() const {
return _size;
}
ReturnValue_t insert(key_t key, T value, Iterator *storedValue = NULL) {
if (_size == theMap.maxSize()) {
return MAP_FULL;
}
uint32_t position = findNicePlace(key);
memmove(&theMap[position + 1], &theMap[position],
(_size - position) * sizeof(std::pair<key_t,T>));
theMap[position].first = key;
theMap[position].second = value;
++_size;
if (storedValue != NULL) {
*storedValue = Iterator(&theMap[position]);
}
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t insert(std::pair<key_t, T> pair) {
return insert(pair.fist, pair.second);
}
ReturnValue_t exists(key_t key) const {
ReturnValue_t result = KEY_DOES_NOT_EXIST;
if (findFirstIndex(key) < _size) {
result = HasReturnvaluesIF::RETURN_OK;
}
return result;
}
ReturnValue_t erase(Iterator *iter) {
uint32_t i;
if ((i = findFirstIndex((*iter).value->first)) >= _size) {
return KEY_DOES_NOT_EXIST;
}
removeFromPosition(i);
if (*iter != begin()) {
(*iter)--;
} else {
*iter = begin();
}
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t erase(key_t key) {
uint32_t i;
if ((i = findFirstIndex(key)) >= _size) {
return KEY_DOES_NOT_EXIST;
}
do {
removeFromPosition(i);
i = findFirstIndex(key, i);
} while (i < _size);
return HasReturnvaluesIF::RETURN_OK;
}
//This is potentially unsafe
// T *findValue(key_t key) const {
// return &theMap[findFirstIndex(key)].second;
// }
Iterator find(key_t key) const {
ReturnValue_t result = exists(key);
if (result != HasReturnvaluesIF::RETURN_OK) {
return end();
}
return Iterator(&theMap[findFirstIndex(key)]);
}
ReturnValue_t find(key_t key, T **value) const {
ReturnValue_t result = exists(key);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
*value = &theMap[findFirstIndex(key)].second;
return HasReturnvaluesIF::RETURN_OK;
}
void clear() {
_size = 0;
}
uint32_t maxSize() const {
return theMap.maxSize();
}
}; };
#include "FixedOrderedMultimap.tpp"
#endif /* FRAMEWORK_CONTAINER_FIXEDORDEREDMULTIMAP_H_ */ #endif /* FRAMEWORK_CONTAINER_FIXEDORDEREDMULTIMAP_H_ */

View File

@ -0,0 +1,83 @@
#ifndef FRAMEWORK_CONTAINER_FIXEDORDEREDMULTIMAP_TPP_
#define FRAMEWORK_CONTAINER_FIXEDORDEREDMULTIMAP_TPP_
template<typename key_t, typename T, typename KEY_COMPARE>
inline FixedOrderedMultimap<key_t, T, KEY_COMPARE>::Iterator::Iterator():
ArrayList<std::pair<key_t, T>, uint32_t>::Iterator(){}
template<typename key_t, typename T, typename KEY_COMPARE>
inline FixedOrderedMultimap<key_t, T, KEY_COMPARE>::Iterator::Iterator(
std::pair<key_t, T> *pair):
ArrayList<std::pair<key_t, T>, uint32_t>::Iterator(pair){}
template<typename key_t, typename T, typename KEY_COMPARE>
inline T FixedOrderedMultimap<key_t, T, KEY_COMPARE>::Iterator::operator*() {
return ArrayList<std::pair<key_t, T>, uint32_t>::Iterator::value->second;
}
template<typename key_t, typename T, typename KEY_COMPARE>
inline typename FixedOrderedMultimap<key_t, T, KEY_COMPARE>::Iterator
FixedOrderedMultimap<key_t, T, KEY_COMPARE>::begin() const {
return Iterator(&theMap[0]);
}
template<typename key_t, typename T, typename KEY_COMPARE>
inline typename FixedOrderedMultimap<key_t, T, KEY_COMPARE>::Iterator
FixedOrderedMultimap<key_t, T, KEY_COMPARE>::end() const {
return Iterator(&theMap[_size]);
}
template<typename key_t, typename T, typename KEY_COMPARE>
inline size_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::size() const {
return _size;
}
template<typename key_t, typename T, typename KEY_COMPARE>
inline T* FixedOrderedMultimap<key_t, T, KEY_COMPARE>::Iterator::operator->() {
return &ArrayList<std::pair<key_t, T>, uint32_t>::Iterator::value->second;
}
template<typename key_t, typename T, typename KEY_COMPARE>
inline FixedOrderedMultimap<key_t, T, KEY_COMPARE>::FixedOrderedMultimap(
size_t maxSize): theMap(maxSize), _size(0) {}
template<typename key_t, typename T, typename KEY_COMPARE>
inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::insert(
key_t key, T value, Iterator *storedValue) {
if (_size == theMap.maxSize()) {
return MAP_FULL;
}
uint32_t position = findNicePlace(key);
// Compiler might emitt warning because std::pair is not a POD type (yet..)
// See: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2342.htm#std::pair-example
// Should still work without issues.
std::memmove(&theMap[position + 1], &theMap[position],
(_size - position) * sizeof(std::pair<key_t,T>));
theMap[position].first = key;
theMap[position].second = value;
++_size;
if (storedValue != nullptr) {
*storedValue = Iterator(&theMap[position]);
}
return HasReturnvaluesIF::RETURN_OK;
}
template<typename key_t, typename T, typename KEY_COMPARE>
inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::insert(
std::pair<key_t, T> pair) {
return insert(pair.fist, pair.second);
}
template<typename key_t, typename T, typename KEY_COMPARE>
inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::exists(
key_t key) const {
ReturnValue_t result = KEY_DOES_NOT_EXIST;
if (findFirstIndex(key) < _size) {
result = HasReturnvaluesIF::RETURN_OK;
}
return result;
}
#endif /* FRAMEWORK_CONTAINER_FIXEDORDEREDMULTIMAP_TPP_ */

View File

@ -1,41 +1,39 @@
#ifndef HYBRIDITERATOR_H_ #ifndef FRAMEWORK_CONTAINER_HYBRIDITERATOR_H_
#define 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() {}
value(NULL), linked(NULL), end(NULL) {
}
HybridIterator(typename LinkedElement<T>::Iterator *iter) : HybridIterator(typename LinkedElement<T>::Iterator *iter) :
LinkedElement<T>::Iterator(*iter), value( LinkedElement<T>::Iterator(*iter), value(iter->value),
iter->value), linked(true), end(NULL) { linked(true) {
} }
HybridIterator(LinkedElement<T> *start) : HybridIterator(LinkedElement<T> *start) :
LinkedElement<T>::Iterator(start), value( LinkedElement<T>::Iterator(start), value(start->value),
start->value), linked(true), end(NULL) { 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), linked( ArrayList<T, count_t>::Iterator(start), value(start.value),
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), linked( ArrayList<T, count_t>::Iterator(firstElement), value(firstElement),
false), end(++lastElement) { linked(false), end(++lastElement) {
if (value == end) { if (value == end) {
value = NULL; value = NULL;
} }
@ -44,17 +42,17 @@ public:
HybridIterator& operator++() { HybridIterator& operator++() {
if (linked) { if (linked) {
LinkedElement<T>::Iterator::operator++(); LinkedElement<T>::Iterator::operator++();
if (LinkedElement<T>::Iterator::value != NULL) { if (LinkedElement<T>::Iterator::value != nullptr) {
value = LinkedElement<T>::Iterator::value->value; value = LinkedElement<T>::Iterator::value->value;
} else { } else {
value = NULL; 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 = NULL; value = nullptr;
} }
} }
return *this; return *this;
@ -66,11 +64,11 @@ public:
return tmp; return tmp;
} }
bool operator==(HybridIterator other) { bool operator==(const HybridIterator& other) const {
return value == other->value; return value == other.value;
} }
bool operator!=(HybridIterator other) { bool operator!=(const HybridIterator& other) const {
return !(*this == other); return !(*this == other);
} }
@ -82,11 +80,11 @@ public:
return value; return value;
} }
T* value; T* value = nullptr;
private: private:
bool linked; bool linked = false;
T *end; T *end = nullptr;
}; };
#endif /* HYBRIDITERATOR_H_ */ #endif /* FRAMEWORK_CONTAINER_HYBRIDITERATOR_H_ */

View File

@ -1,27 +1,34 @@
#ifndef FRAMEWORK_CONTAINER_INDEXEDRINGMEMORY_H_ #ifndef FRAMEWORK_CONTAINER_INDEXEDRINGMEMORY_H_
#define FRAMEWORK_CONTAINER_INDEXEDRINGMEMORY_H_ #define FRAMEWORK_CONTAINER_INDEXEDRINGMEMORY_H_
#include <framework/container/ArrayList.h> #include "../container/ArrayList.h"
#include <framework/globalfunctions/CRC.h> #include "../globalfunctions/CRC.h"
#include <framework/serviceinterface/ServiceInterfaceStream.h> #include "../serviceinterface/ServiceInterfaceStream.h"
#include <framework/returnvalues/HasReturnvaluesIF.h> #include "../returnvalues/HasReturnvaluesIF.h"
#include <framework/serialize/SerialArrayListAdapter.h> #include "../serialize/SerialArrayListAdapter.h"
#include <cmath> #include <cmath>
/**
* Index is the Type used for the list of indices.
*
* @tparam T Type which destribes the index. Needs to be a child of SerializeIF
* to be able to make it persistent
*/
template<typename T> template<typename T>
class Index: public SerializeIF{ class Index: public SerializeIF{
/** /**
* Index is the Type used for the list of indices. The template parameter is the type which describes the index, it needs to be a child of SerializeIF to be able to make it persistent *
*/ */
static_assert(std::is_base_of<SerializeIF,T>::value,"Wrong Type for Index, Type must implement SerializeIF"); static_assert(std::is_base_of<SerializeIF,T>::value,
"Wrong Type for Index, Type must implement SerializeIF");
public: public:
Index():blockStartAddress(0),size(0),storedPackets(0){} Index():blockStartAddress(0),size(0),storedPackets(0){}
Index(uint32_t startAddress):blockStartAddress(startAddress),size(0),storedPackets(0){ Index(uint32_t startAddress):blockStartAddress(startAddress),
size(0),storedPackets(0) {
} }
void setBlockStartAddress(uint32_t newAddress){ void setBlockStartAddress(uint32_t newAddress) {
this->blockStartAddress = newAddress; this->blockStartAddress = newAddress;
} }
@ -33,7 +40,7 @@ public:
return &indexType; return &indexType;
} }
T* modifyIndexType(){ T* modifyIndexType() {
return &indexType; return &indexType;
} }
/** /**
@ -68,50 +75,50 @@ public:
return this->storedPackets; return this->storedPackets;
} }
ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, ReturnValue_t serialize(uint8_t** buffer, size_t* size,
const uint32_t max_size, bool bigEndian) const { size_t maxSize, Endianness streamEndianness) const {
ReturnValue_t result = AutoSerializeAdapter::serialize(&blockStartAddress,buffer,size,max_size,bigEndian); ReturnValue_t result = SerializeAdapter::serialize(&blockStartAddress,buffer,size,maxSize,streamEndianness);
if(result != HasReturnvaluesIF::RETURN_OK){ if(result != HasReturnvaluesIF::RETURN_OK){
return result; return result;
} }
result = indexType.serialize(buffer,size,max_size,bigEndian); result = indexType.serialize(buffer,size,maxSize,streamEndianness);
if(result != HasReturnvaluesIF::RETURN_OK){ if(result != HasReturnvaluesIF::RETURN_OK){
return result; return result;
} }
result = AutoSerializeAdapter::serialize(&this->size,buffer,size,max_size,bigEndian); result = SerializeAdapter::serialize(&this->size,buffer,size,maxSize,streamEndianness);
if(result != HasReturnvaluesIF::RETURN_OK){ if(result != HasReturnvaluesIF::RETURN_OK){
return result; return result;
} }
result = AutoSerializeAdapter::serialize(&this->storedPackets,buffer,size,max_size,bigEndian); result = SerializeAdapter::serialize(&this->storedPackets,buffer,size,maxSize,streamEndianness);
return result; return result;
} }
ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
bool bigEndian){ Endianness streamEndianness){
ReturnValue_t result = AutoSerializeAdapter::deSerialize(&blockStartAddress,buffer,size,bigEndian); ReturnValue_t result = SerializeAdapter::deSerialize(&blockStartAddress,buffer,size,streamEndianness);
if(result != HasReturnvaluesIF::RETURN_OK){ if(result != HasReturnvaluesIF::RETURN_OK){
return result; return result;
} }
result = indexType.deSerialize(buffer,size,bigEndian); result = indexType.deSerialize(buffer,size,streamEndianness);
if(result != HasReturnvaluesIF::RETURN_OK){ if(result != HasReturnvaluesIF::RETURN_OK){
return result; return result;
} }
result = AutoSerializeAdapter::deSerialize(&this->size,buffer,size,bigEndian); result = SerializeAdapter::deSerialize(&this->size,buffer,size,streamEndianness);
if(result != HasReturnvaluesIF::RETURN_OK){ if(result != HasReturnvaluesIF::RETURN_OK){
return result; return result;
} }
result = AutoSerializeAdapter::deSerialize(&this->storedPackets,buffer,size,bigEndian); result = SerializeAdapter::deSerialize(&this->storedPackets,buffer,size,streamEndianness);
if(result != HasReturnvaluesIF::RETURN_OK){ if(result != HasReturnvaluesIF::RETURN_OK){
return result; return result;
} }
return result; return result;
} }
uint32_t getSerializedSize() const { size_t getSerializedSize() const {
uint32_t size = AutoSerializeAdapter::getSerializedSize(&blockStartAddress); uint32_t size = SerializeAdapter::getSerializedSize(&blockStartAddress);
size += indexType.getSerializedSize(); size += indexType.getSerializedSize();
size += AutoSerializeAdapter::getSerializedSize(&this->size); size += SerializeAdapter::getSerializedSize(&this->size);
size += AutoSerializeAdapter::getSerializedSize(&this->storedPackets); size += SerializeAdapter::getSerializedSize(&this->storedPackets);
return size; return size;
} }
@ -128,26 +135,35 @@ private:
}; };
/**
* @brief Indexed Ring Memory Array is a class for a ring memory with indices.
* @details
* It assumes that the newest data comes in last
* It uses the currentWriteBlock as pointer to the current writing position
* The currentReadBlock must be set manually
* @tparam T
*/
template<typename T> template<typename T>
class IndexedRingMemoryArray: public SerializeIF, public ArrayList<Index<T>, uint32_t>{ class IndexedRingMemoryArray: public SerializeIF, public ArrayList<Index<T>, uint32_t>{
/** /**
* Indexed Ring Memory Array is a class for a ring memory with indices. It assumes that the newest data comes in last *
* It uses the currentWriteBlock as pointer to the current writing position
* The currentReadBlock must be set manually
*/ */
public: public:
IndexedRingMemoryArray(uint32_t startAddress, uint32_t size, uint32_t bytesPerBlock, SerializeIF* additionalInfo, IndexedRingMemoryArray(uint32_t startAddress, uint32_t size, uint32_t bytesPerBlock,
bool overwriteOld) :ArrayList<Index<T>,uint32_t>(NULL,(uint32_t)10,(uint32_t)0),totalSize(size),indexAddress(startAddress),currentReadSize(0),currentReadBlockSizeCached(0),lastBlockToReadSize(0), additionalInfo(additionalInfo),overwriteOld(overwriteOld){ SerializeIF* additionalInfo, bool overwriteOld):
ArrayList<Index<T>,uint32_t>(NULL,(uint32_t)10,(uint32_t)0),totalSize(size),
indexAddress(startAddress),currentReadSize(0),currentReadBlockSizeCached(0),
lastBlockToReadSize(0), additionalInfo(additionalInfo),overwriteOld(overwriteOld)
{
//Calculate the maximum number of indices needed for this blocksize //Calculate the maximum number of indices needed for this blocksize
uint32_t maxNrOfIndices = floor(static_cast<double>(size)/static_cast<double>(bytesPerBlock)); uint32_t maxNrOfIndices = floor(static_cast<double>(size)/static_cast<double>(bytesPerBlock));
//Calculate the Size needeed for the index itself //Calculate the Size needeed for the index itself
uint32_t serializedSize = 0; size_t serializedSize = 0;
if(additionalInfo!=NULL){ if(additionalInfo!=NULL) {
serializedSize += additionalInfo->getSerializedSize(); serializedSize += additionalInfo->getSerializedSize();
} }
//Size of current iterator type //Size of current iterator type
Index<T> tempIndex; Index<T> tempIndex;
serializedSize += tempIndex.getSerializedSize(); serializedSize += tempIndex.getSerializedSize();
@ -162,6 +178,7 @@ public:
error << "IndexedRingMemory: Store is too small for index" << std::endl; error << "IndexedRingMemory: Store is too small for index" << std::endl;
} }
uint32_t useableSize = totalSize - serializedSize; uint32_t useableSize = totalSize - serializedSize;
//Update the totalSize for calculations //Update the totalSize for calculations
totalSize = useableSize; totalSize = useableSize;
@ -178,12 +195,10 @@ public:
this->allocated = true; this->allocated = true;
//Check trueNumberOfBlocks //Check trueNumberOfBlocks
if(trueNumberOfBlocks<1){ if(trueNumberOfBlocks<1) {
error << "IndexedRingMemory: Invalid Number of Blocks: " << trueNumberOfBlocks; error << "IndexedRingMemory: Invalid Number of Blocks: " << trueNumberOfBlocks;
} }
//Fill address into index //Fill address into index
uint32_t address = trueStartAddress; uint32_t address = trueStartAddress;
for (typename IndexedRingMemoryArray<T>::Iterator it = this->begin();it!=this->end();++it) { for (typename IndexedRingMemoryArray<T>::Iterator it = this->begin();it!=this->end();++it) {
@ -193,7 +208,6 @@ public:
address += bytesPerBlock; address += bytesPerBlock;
} }
//Initialize iterators //Initialize iterators
currentWriteBlock = this->begin(); currentWriteBlock = this->begin();
currentReadBlock = this->begin(); currentReadBlock = this->begin();
@ -232,10 +246,10 @@ public:
(*typeResetFnc)(it->modifyIndexType()); (*typeResetFnc)(it->modifyIndexType());
} }
/* /**
* Reading * Reading
* @param it
*/ */
void setCurrentReadBlock(typename IndexedRingMemoryArray<T>::Iterator it){ void setCurrentReadBlock(typename IndexedRingMemoryArray<T>::Iterator it){
currentReadBlock = it; currentReadBlock = it;
currentReadBlockSizeCached = it->getSize(); currentReadBlockSizeCached = it->getSize();
@ -248,6 +262,7 @@ public:
lastBlockToRead = currentWriteBlock; lastBlockToRead = currentWriteBlock;
lastBlockToReadSize = currentWriteBlock->getSize(); lastBlockToReadSize = currentWriteBlock->getSize();
} }
/** /**
* Sets the last block to read to this iterator. * Sets the last block to read to this iterator.
* Can be used to dump until block x * Can be used to dump until block x
@ -292,33 +307,39 @@ public:
uint32_t getCurrentReadAddress() const { uint32_t getCurrentReadAddress() const {
return getAddressOfCurrentReadBlock() + currentReadSize; return getAddressOfCurrentReadBlock() + currentReadSize;
} }
/** /**
* Adds readSize to the current size and checks if the read has no more data left and advances the read block * Adds readSize to the current size and checks if the read has no more data
* left and advances the read block.
* @param readSize The size that was read * @param readSize The size that was read
* @return Returns true if the read can go on * @return Returns true if the read can go on
*/ */
bool addReadSize(uint32_t readSize) { bool addReadSize(uint32_t readSize) {
if(currentReadBlock == lastBlockToRead){ if(currentReadBlock == lastBlockToRead) {
//The current read block is the last to read //The current read block is the last to read
if((currentReadSize+readSize)<lastBlockToReadSize){ if((currentReadSize+readSize)<lastBlockToReadSize) {
//the block has more data -> return true //the block has more data -> return true
currentReadSize += readSize; currentReadSize += readSize;
return true; return true;
}else{ }
else {
//Reached end of read -> return false //Reached end of read -> return false
currentReadSize = lastBlockToReadSize; currentReadSize = lastBlockToReadSize;
return false; return false;
} }
}else{ }
else {
//We are not in the last Block //We are not in the last Block
if((currentReadSize + readSize)<currentReadBlockSizeCached){ if((currentReadSize + readSize)<currentReadBlockSizeCached) {
//The current Block has more data //The current Block has more data
currentReadSize += readSize; currentReadSize += readSize;
return true; return true;
}else{ }
// TODO: Maybe some logic blocks should be extracted
else {
//The current block is written completely //The current block is written completely
readNext(); readNext();
if(currentReadBlockSizeCached==0){ if(currentReadBlockSizeCached==0) {
//Next block is empty //Next block is empty
typename IndexedRingMemoryArray<T>::Iterator it(currentReadBlock); typename IndexedRingMemoryArray<T>::Iterator it(currentReadBlock);
//Search if any block between this and the last block is not empty //Search if any block between this and the last block is not empty
@ -421,13 +442,13 @@ public:
T* modifyCurrentWriteBlockIndexType(){ T* modifyCurrentWriteBlockIndexType(){
return currentWriteBlock->modifyIndexType(); return currentWriteBlock->modifyIndexType();
} }
void updatePreviousWriteSize(uint32_t size, uint32_t storedPackets){ void updatePreviousWriteSize(uint32_t size, uint32_t storedPackets){
typename IndexedRingMemoryArray<T>::Iterator it = getPreviousBlock(currentWriteBlock); typename IndexedRingMemoryArray<T>::Iterator it = getPreviousBlock(currentWriteBlock);
it->addSize(size); it->addSize(size);
it->addStoredPackets(storedPackets); it->addStoredPackets(storedPackets);
} }
/** /**
* Checks if the block has enough space for sizeToWrite * Checks if the block has enough space for sizeToWrite
* @param sizeToWrite The data to be written in the Block * @param sizeToWrite The data to be written in the Block
@ -436,7 +457,10 @@ public:
bool hasCurrentWriteBlockEnoughSpace(uint32_t sizeToWrite){ bool hasCurrentWriteBlockEnoughSpace(uint32_t sizeToWrite){
typename IndexedRingMemoryArray<T>::Iterator next = getNextWrite(); typename IndexedRingMemoryArray<T>::Iterator next = getNextWrite();
uint32_t addressOfNextBlock = next->getBlockStartAddress(); uint32_t addressOfNextBlock = next->getBlockStartAddress();
uint32_t availableSize = ((addressOfNextBlock+totalSize) - (getAddressOfCurrentWriteBlock()+getSizeOfCurrentWriteBlock()))%totalSize; uint32_t availableSize =
( ( addressOfNextBlock + totalSize ) -
(getAddressOfCurrentWriteBlock() + getSizeOfCurrentWriteBlock()))
% totalSize;
return (sizeToWrite < availableSize); return (sizeToWrite < availableSize);
} }
@ -485,37 +509,37 @@ public:
* Parameters according to HasSerializeIF * Parameters according to HasSerializeIF
* @param buffer * @param buffer
* @param size * @param size
* @param max_size * @param maxSize
* @param bigEndian * @param streamEndianness
* @return * @return
*/ */
ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, ReturnValue_t serialize(uint8_t** buffer, size_t* size,
const uint32_t max_size, bool bigEndian) const{ size_t maxSize, Endianness streamEndianness) const{
uint8_t* crcBuffer = *buffer; uint8_t* crcBuffer = *buffer;
uint32_t oldSize = *size; uint32_t oldSize = *size;
if(additionalInfo!=NULL){ if(additionalInfo!=NULL){
additionalInfo->serialize(buffer,size,max_size,bigEndian); additionalInfo->serialize(buffer,size,maxSize,streamEndianness);
} }
ReturnValue_t result = currentWriteBlock->serialize(buffer,size,max_size,bigEndian); ReturnValue_t result = currentWriteBlock->serialize(buffer,size,maxSize,streamEndianness);
if(result != HasReturnvaluesIF::RETURN_OK){ if(result != HasReturnvaluesIF::RETURN_OK){
return result; return result;
} }
result = AutoSerializeAdapter::serialize(&this->size,buffer,size,max_size,bigEndian); result = SerializeAdapter::serialize(&this->size,buffer,size,maxSize,streamEndianness);
if(result != HasReturnvaluesIF::RETURN_OK){ if(result != HasReturnvaluesIF::RETURN_OK){
return result; return result;
} }
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<Index<T> >::serialize(&this->entries[i], buffer, size, result = SerializeAdapter::serialize(&this->entries[i], buffer, size,
max_size, bigEndian); maxSize, streamEndianness);
++i; ++i;
} }
if(result != HasReturnvaluesIF::RETURN_OK){ if(result != HasReturnvaluesIF::RETURN_OK){
return result; return result;
} }
uint16_t crc = Calculate_CRC(crcBuffer,(*size-oldSize)); uint16_t crc = Calculate_CRC(crcBuffer,(*size-oldSize));
result = AutoSerializeAdapter::serialize(&crc,buffer,size,max_size,bigEndian); result = SerializeAdapter::serialize(&crc,buffer,size,maxSize,streamEndianness);
return result; return result;
} }
@ -524,17 +548,17 @@ public:
* Get the serialized Size of the index * Get the serialized Size of the index
* @return The serialized size of the index * @return The serialized size of the index
*/ */
uint32_t getSerializedSize() const { size_t getSerializedSize() const {
uint32_t size = 0; size_t size = 0;
if(additionalInfo!=NULL){ if(additionalInfo!=NULL){
size += additionalInfo->getSerializedSize(); size += additionalInfo->getSerializedSize();
} }
size += currentWriteBlock->getSerializedSize(); size += currentWriteBlock->getSerializedSize();
size += AutoSerializeAdapter::getSerializedSize(&this->size); size += SerializeAdapter::getSerializedSize(&this->size);
size += (this->entries[0].getSerializedSize()) * this->size; size += (this->entries[0].getSerializedSize()) * this->size;
uint16_t crc = 0; uint16_t crc = 0;
size += AutoSerializeAdapter::getSerializedSize(&crc); size += SerializeAdapter::getSerializedSize(&crc);
return size; return size;
} }
/** /**
@ -542,28 +566,28 @@ public:
* CRC Has to be checked before! * CRC Has to be checked before!
* @param buffer * @param buffer
* @param size * @param size
* @param bigEndian * @param streamEndianness
* @return * @return
*/ */
ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
bool bigEndian){ Endianness streamEndianness){
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
if(additionalInfo!=NULL){ if(additionalInfo!=NULL){
result = additionalInfo->deSerialize(buffer,size,bigEndian); result = additionalInfo->deSerialize(buffer,size,streamEndianness);
} }
if(result != HasReturnvaluesIF::RETURN_OK){ if(result != HasReturnvaluesIF::RETURN_OK){
return result; return result;
} }
Index<T> tempIndex; Index<T> tempIndex;
result = tempIndex.deSerialize(buffer,size,bigEndian); result = tempIndex.deSerialize(buffer,size,streamEndianness);
if(result != HasReturnvaluesIF::RETURN_OK){ if(result != HasReturnvaluesIF::RETURN_OK){
return result; return result;
} }
uint32_t tempSize = 0; uint32_t tempSize = 0;
result = AutoSerializeAdapter::deSerialize(&tempSize,buffer,size,bigEndian); result = SerializeAdapter::deSerialize(&tempSize,buffer,size,streamEndianness);
if(result != HasReturnvaluesIF::RETURN_OK){ if(result != HasReturnvaluesIF::RETURN_OK){
return result; return result;
} }
@ -572,9 +596,9 @@ public:
} }
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<Index<T> >::deSerialize( result = SerializeAdapter::deSerialize(
&this->entries[i], buffer, size, &this->entries[i], buffer, size,
bigEndian); streamEndianness);
++i; ++i;
} }
if(result != HasReturnvaluesIF::RETURN_OK){ if(result != HasReturnvaluesIF::RETURN_OK){
@ -694,7 +718,4 @@ private:
}; };
#endif /* FRAMEWORK_CONTAINER_INDEXEDRINGMEMORY_H_ */ #endif /* FRAMEWORK_CONTAINER_INDEXEDRINGMEMORY_H_ */

View File

@ -1,6 +1,13 @@
#ifndef ISDERIVEDFROM_H_ #ifndef ISDERIVEDFROM_H_
#define ISDERIVEDFROM_H_ #define ISDERIVEDFROM_H_
/**
* These template type checks are based on SFINAE
* (https://en.cppreference.com/w/cpp/language/sfinae)
*
* @tparam D Derived Type
* @tparam B Base Type
*/
template<typename D, typename B> template<typename D, typename B>
class IsDerivedFrom { class IsDerivedFrom {
class No { class No {
@ -9,7 +16,9 @@ class IsDerivedFrom {
No no[3]; No no[3];
}; };
// This will be chosen if B is the base type
static Yes Test(B*); // declared, but not defined static Yes Test(B*); // declared, but not defined
// This will be chosen for anything else
static No Test(... ); // declared, but not defined static No Test(... ); // declared, but not defined
public: public:

View File

@ -1,7 +1,7 @@
#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 {

View File

@ -1,89 +1,69 @@
#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>
template<uint8_t N_READ_PTRS = 1> template<uint8_t N_READ_PTRS = 1>
class RingBufferBase { class RingBufferBase {
public: public:
RingBufferBase(uint32_t startAddress, uint32_t size, bool overwriteOld) : RingBufferBase(size_t startAddress, const size_t size, bool overwriteOld) :
start(startAddress), write(startAddress), size(size), overwriteOld(overwriteOld) { start(startAddress), write(startAddress), size(size),
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;
} }
} }
ReturnValue_t readData(uint32_t amount, uint8_t n = 0) {
if (availableReadData(n) >= amount) { virtual ~RingBufferBase() {}
incrementRead(amount, n);
return HasReturnvaluesIF::RETURN_OK;
} else {
return HasReturnvaluesIF::RETURN_FAILED;
}
}
ReturnValue_t writeData(uint32_t amount) {
if (availableWriteSpace() >= amount || overwriteOld) {
incrementWrite(amount);
return HasReturnvaluesIF::RETURN_OK;
} else {
return HasReturnvaluesIF::RETURN_FAILED;
}
}
uint32_t availableReadData(uint8_t n = 0) const {
return ((write + size) - read[n]) % size;
}
uint32_t availableWriteSpace(uint8_t n = 0) const {
//One less to avoid ambiguous full/empty problem.
return (((read[n] + size) - write - 1) % size);
}
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);
} }
virtual ~RingBufferBase() {
size_t getAvailableReadData(uint8_t n = 0) const {
return ((write + size) - read[n]) % size;
} }
uint32_t getRead(uint8_t n = 0) const { size_t availableWriteSpace(uint8_t n = 0) const {
return read[n]; //One less to avoid ambiguous full/empty problem.
return (((read[n] + size) - write - 1) % size);
} }
void setRead(uint32_t read, uint8_t n = 0) {
if (read >= start && read < (start+size)) { bool overwritesOld() const {
this->read[n] = read; return overwriteOld;
}
} }
uint32_t getWrite() const {
return write; size_t getMaxSize() const {
} return size - 1;
void setWrite(uint32_t write) {
this->write = write;
} }
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;
} }
} }
uint32_t writeTillWrap() {
size_t writeTillWrap() {
return (start + size) - write; return (start + size) - write;
} }
uint32_t readTillWrap(uint8_t n = 0) {
size_t readTillWrap(uint8_t n = 0) {
return (start + size) - read[n]; return (start + size) - read[n];
} }
uint32_t getStart() const {
size_t getStart() const {
return start; return start;
} }
bool overwritesOld() const {
return overwriteOld;
}
uint32_t maxSize() const {
return size - 1;
}
protected: protected:
const uint32_t start; const size_t start;
uint32_t write; size_t write;
uint32_t read[N_READ_PTRS]; size_t read[N_READ_PTRS];
const uint32_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;
@ -91,6 +71,43 @@ protected:
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) {
if (getAvailableReadData(n) >= amount) {
incrementRead(amount, n);
return HasReturnvaluesIF::RETURN_OK;
} else {
return HasReturnvaluesIF::RETURN_FAILED;
}
}
ReturnValue_t writeData(uint32_t amount) {
if (availableWriteSpace() >= amount or overwriteOld) {
incrementWrite(amount);
return HasReturnvaluesIF::RETURN_OK;
} else {
return HasReturnvaluesIF::RETURN_FAILED;
}
}
size_t getRead(uint8_t n = 0) const {
return read[n];
}
void setRead(uint32_t read, uint8_t n = 0) {
if (read >= start && read < (start+size)) {
this->read[n] = read;
}
}
uint32_t getWrite() const {
return write;
}
void setWrite(uint32_t write) {
this->write = write;
}
}; };
#endif /* FRAMEWORK_CONTAINER_RINGBUFFERBASE_H_ */ #endif /* FRAMEWORK_CONTAINER_RINGBUFFERBASE_H_ */

View File

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

View File

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

View File

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

View File

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

View File

@ -1,10 +1,13 @@
#ifndef SINGLYLINKEDLIST_H_ #ifndef FRAMEWORK_CONTAINER_SINGLYLINKEDLIST_H_
#define SINGLYLINKEDLIST_H_ #define FRAMEWORK_CONTAINER_SINGLYLINKEDLIST_H_
#include <cstddef>
#include <cstdint>
#include <stddef.h>
#include <stdint.h>
/** /**
* \ingroup container * @brief Linked list data structure,
* each entry has a pointer to the next entry (singly)
* @ingroup container
*/ */
template<typename T> template<typename T>
class LinkedElement { class LinkedElement {
@ -12,11 +15,8 @@ public:
T *value; T *value;
class Iterator { class Iterator {
public: public:
LinkedElement<T> *value; LinkedElement<T> *value = nullptr;
Iterator() : Iterator() {}
value(NULL) {
}
Iterator(LinkedElement<T> *element) : Iterator(LinkedElement<T> *element) :
value(element) { value(element) {
@ -45,12 +45,11 @@ public:
} }
}; };
LinkedElement(T* setElement, LinkedElement<T>* setNext = NULL) : value(setElement), LinkedElement(T* setElement, LinkedElement<T>* setNext = nullptr):
next(setNext) { value(setElement), next(setNext) {}
}
virtual ~LinkedElement(){ virtual ~LinkedElement(){}
}
virtual LinkedElement* getNext() const { virtual LinkedElement* getNext() const {
return next; return next;
} }
@ -58,11 +57,16 @@ public:
virtual void setNext(LinkedElement* next) { virtual void setNext(LinkedElement* next) {
this->next = next; this->next = next;
} }
virtual void setEnd() {
this->next = nullptr;
}
LinkedElement* begin() { LinkedElement* begin() {
return this; return this;
} }
LinkedElement* end() { LinkedElement* end() {
return NULL; return nullptr;
} }
private: private:
LinkedElement *next; LinkedElement *next;
@ -71,37 +75,80 @@ private:
template<typename T> template<typename T>
class SinglyLinkedList { class SinglyLinkedList {
public: public:
SinglyLinkedList() : using ElementIterator = typename LinkedElement<T>::Iterator;
start(NULL) {
} SinglyLinkedList() {}
SinglyLinkedList(ElementIterator start) :
start(start.value) {}
SinglyLinkedList(typename LinkedElement<T>::Iterator start) :
start(start.value) {
}
SinglyLinkedList(LinkedElement<T>* startElement) : SinglyLinkedList(LinkedElement<T>* startElement) :
start(startElement) { start(startElement) {}
}
typename LinkedElement<T>::Iterator begin() const { ElementIterator begin() const {
return LinkedElement<T>::Iterator::Iterator(start); return ElementIterator::Iterator(start);
}
typename LinkedElement<T>::Iterator::Iterator end() const {
return LinkedElement<T>::Iterator::Iterator();
} }
uint32_t getSize() const { /** Returns iterator to nulltr */
uint32_t size = 0; ElementIterator end() const {
return ElementIterator::Iterator();
}
/**
* Returns last element in singly linked list.
* @return
*/
ElementIterator back() const {
LinkedElement<T> *element = start;
while (element != nullptr) {
element = element->getNext();
}
return ElementIterator::Iterator(element);
}
size_t getSize() const {
size_t size = 0;
LinkedElement<T> *element = start; LinkedElement<T> *element = start;
while (element != NULL) { while (element != nullptr) {
size++; size++;
element = element->getNext(); element = element->getNext();
} }
return size; return size;
} }
void setStart(LinkedElement<T>* setStart) { void setStart(LinkedElement<T>* firstElement) {
start = setStart; start = firstElement;
} }
void setNext(LinkedElement<T>* currentElement,
LinkedElement<T>* nextElement) {
currentElement->setNext(nextElement);
}
void setLast(LinkedElement<T>* lastElement) {
lastElement->setEnd();
}
void insertElement(LinkedElement<T>* element, size_t position) {
LinkedElement<T> *currentElement = start;
for(size_t count = 0; count < position; count++) {
if(currentElement == nullptr) {
return;
}
currentElement = currentElement->getNext();
}
LinkedElement<T>* elementAfterCurrent = currentElement->next;
currentElement->setNext(element);
if(elementAfterCurrent != nullptr) {
element->setNext(elementAfterCurrent);
}
}
void insertBack(LinkedElement<T>* lastElement) {
back().value->setNext(lastElement);
}
protected: protected:
LinkedElement<T> *start; LinkedElement<T> *start = nullptr;
}; };
#endif /* SINGLYLINKEDLIST_H_ */ #endif /* SINGLYLINKEDLIST_H_ */

View File

@ -4,11 +4,9 @@
/** /**
* @defgroup container Container * @defgroup container Container
* *
* General Purpose Container to store various elements. * General Purpose Containers to store various elements.
* * As opposed to the STL library implementation, these implementations
* Also contains Adapter classes to print elements to a * don't allocate memory dynamically.
* bytestream and to read them from a bytestream, as well
* as an Adapter to swap the endianness.
*/ */

File diff suppressed because it is too large Load Diff

View File

@ -1,117 +1,117 @@
#ifndef _sgp4unit_ #ifndef _sgp4unit_
#define _sgp4unit_ #define _sgp4unit_
/* ---------------------------------------------------------------- /* ----------------------------------------------------------------
* *
* sgp4unit.h * sgp4unit.h
* *
* this file contains the sgp4 procedures for analytical propagation * this file contains the sgp4 procedures for analytical propagation
* of a satellite. the code was originally released in the 1980 and 1986 * of a satellite. the code was originally released in the 1980 and 1986
* spacetrack papers. a detailed discussion of the theory and history * spacetrack papers. a detailed discussion of the theory and history
* may be found in the 2006 aiaa paper by vallado, crawford, hujsak, * may be found in the 2006 aiaa paper by vallado, crawford, hujsak,
* and kelso. * and kelso.
* *
* companion code for * companion code for
* fundamentals of astrodynamics and applications * fundamentals of astrodynamics and applications
* 2007 * 2007
* by david vallado * by david vallado
* *
* (w) 719-573-2600, email dvallado@agi.com * (w) 719-573-2600, email dvallado@agi.com
* *
* current : * current :
* 20 apr 07 david vallado * 20 apr 07 david vallado
* misc fixes for constants * misc fixes for constants
* changes : * changes :
* 11 aug 06 david vallado * 11 aug 06 david vallado
* chg lyddane choice back to strn3, constants, misc doc * chg lyddane choice back to strn3, constants, misc doc
* 15 dec 05 david vallado * 15 dec 05 david vallado
* misc fixes * misc fixes
* 26 jul 05 david vallado * 26 jul 05 david vallado
* fixes for paper * fixes for paper
* note that each fix is preceded by a * note that each fix is preceded by a
* comment with "sgp4fix" and an explanation of * comment with "sgp4fix" and an explanation of
* what was changed * what was changed
* 10 aug 04 david vallado * 10 aug 04 david vallado
* 2nd printing baseline working * 2nd printing baseline working
* 14 may 01 david vallado * 14 may 01 david vallado
* 2nd edition baseline * 2nd edition baseline
* 80 norad * 80 norad
* original baseline * original baseline
* ---------------------------------------------------------------- */ * ---------------------------------------------------------------- */
#include <math.h> #include <math.h>
#include <stdio.h> #include <stdio.h>
// -------------------------- structure declarations ---------------------------- // -------------------------- structure declarations ----------------------------
typedef enum typedef enum
{ {
wgs72old, wgs72old,
wgs72, wgs72,
wgs84 wgs84
} gravconsttype; } gravconsttype;
typedef struct elsetrec typedef struct elsetrec
{ {
long int satnum; long int satnum;
int epochyr, epochtynumrev; int epochyr, epochtynumrev;
int error; int error;
char init, method; char init, method;
/* Near Earth */ /* Near Earth */
int isimp; int isimp;
double aycof , con41 , cc1 , cc4 , cc5 , d2 , d3 , d4 , double aycof , con41 , cc1 , cc4 , cc5 , d2 , d3 , d4 ,
delmo , eta , argpdot, omgcof , sinmao , t , t2cof, t3cof , delmo , eta , argpdot, omgcof , sinmao , t , t2cof, t3cof ,
t4cof , t5cof , x1mth2 , x7thm1 , mdot , nodedot, xlcof , xmcof , t4cof , t5cof , x1mth2 , x7thm1 , mdot , nodedot, xlcof , xmcof ,
nodecf; nodecf;
/* Deep Space */ /* Deep Space */
int irez; int irez;
double d2201 , d2211 , d3210 , d3222 , d4410 , d4422 , d5220 , d5232 , double d2201 , d2211 , d3210 , d3222 , d4410 , d4422 , d5220 , d5232 ,
d5421 , d5433 , dedt , del1 , del2 , del3 , didt , dmdt , d5421 , d5433 , dedt , del1 , del2 , del3 , didt , dmdt ,
dnodt , domdt , e3 , ee2 , peo , pgho , pho , pinco , dnodt , domdt , e3 , ee2 , peo , pgho , pho , pinco ,
plo , se2 , se3 , sgh2 , sgh3 , sgh4 , sh2 , sh3 , plo , se2 , se3 , sgh2 , sgh3 , sgh4 , sh2 , sh3 ,
si2 , si3 , sl2 , sl3 , sl4 , gsto , xfact , xgh2 , si2 , si3 , sl2 , sl3 , sl4 , gsto , xfact , xgh2 ,
xgh3 , xgh4 , xh2 , xh3 , xi2 , xi3 , xl2 , xl3 , xgh3 , xgh4 , xh2 , xh3 , xi2 , xi3 , xl2 , xl3 ,
xl4 , xlamo , zmol , zmos , atime , xli , xni; xl4 , xlamo , zmol , zmos , atime , xli , xni;
double a , altp , alta , epochdays, jdsatepoch , nddot , ndot , double a , altp , alta , epochdays, jdsatepoch , nddot , ndot ,
bstar , rcse , inclo , nodeo , ecco , argpo , mo , bstar , rcse , inclo , nodeo , ecco , argpo , mo ,
no; no;
} elsetrec; } elsetrec;
// --------------------------- function declarations ---------------------------- // --------------------------- function declarations ----------------------------
int sgp4init int sgp4init
( (
gravconsttype whichconst, const int satn, const double epoch, gravconsttype whichconst, const int satn, const double epoch,
const double xbstar, const double xecco, const double xargpo, const double xbstar, const double xecco, const double xargpo,
const double xinclo, const double xmo, const double xno, const double xinclo, const double xmo, const double xno,
const double xnodeo, const double xnodeo,
elsetrec& satrec elsetrec& satrec
); );
int sgp4 int sgp4
( (
gravconsttype whichconst, gravconsttype whichconst,
elsetrec& satrec, double tsince, elsetrec& satrec, double tsince,
double r[], double v[] double r[], double v[]
); );
double gstime double gstime
( (
double double
); );
void getgravconst void getgravconst
( (
gravconsttype, gravconsttype,
double&, double&,
double&, double&,
double&, double&,
double&, double&,
double&, double&,
double&, double&,
double&, double&,
double& double&
); );
#endif #endif

View File

@ -1,16 +1,15 @@
#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(object_id_t setObjectId, object_id_t parentId,
size_t commandQueueDepth) : size_t commandQueueDepth) :
SystemObject(setObjectId), parentId(parentId), mode(MODE_OFF), submode( SystemObject(setObjectId), parentId(parentId), mode(MODE_OFF),
SUBMODE_NONE), commandQueue(NULL), modeHelper( submode(SUBMODE_NONE), modeHelper(this),
this), healthHelper(this, setObjectId),hkSwitcher(this),executingTask(NULL) { healthHelper(this, setObjectId), hkSwitcher(this) {
commandQueue = QueueFactory::instance()->createMessageQueue(commandQueueDepth); commandQueue = QueueFactory::instance()->createMessageQueue(commandQueueDepth);
} }
ControllerBase::~ControllerBase() { ControllerBase::~ControllerBase() {
@ -24,7 +23,7 @@ ReturnValue_t ControllerBase::initialize() {
} }
MessageQueueId_t parentQueue = 0; MessageQueueId_t parentQueue = 0;
if (parentId != 0) { 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;
@ -56,26 +55,26 @@ MessageQueueId_t ControllerBase::getCommandQueue() const {
} }
void ControllerBase::handleQueue() { void ControllerBase::handleQueue() {
CommandMessage message; CommandMessage command;
ReturnValue_t result; ReturnValue_t result;
for (result = commandQueue->receiveMessage(&message); result == RETURN_OK; for (result = commandQueue->receiveMessage(&command); result == RETURN_OK;
result = commandQueue->receiveMessage(&message)) { result = commandQueue->receiveMessage(&command)) {
result = modeHelper.handleModeCommand(&message); result = modeHelper.handleModeCommand(&command);
if (result == RETURN_OK) { if (result == RETURN_OK) {
continue; continue;
} }
result = healthHelper.handleHealthCommand(&message); result = healthHelper.handleHealthCommand(&command);
if (result == RETURN_OK) { if (result == RETURN_OK) {
continue; continue;
} }
result = handleCommandMessage(&message); result = handleCommandMessage(&command);
if (result == RETURN_OK) { if (result == RETURN_OK) {
continue; continue;
} }
message.setToUnknownCommand(); command.setToUnknownCommand();
commandQueue->reply(&message); commandQueue->reply(&command);
} }
} }
@ -135,3 +134,7 @@ void ControllerBase::setTaskIF(PeriodicTaskIF* task_){
void ControllerBase::changeHK(Mode_t mode, Submode_t submode, bool enable) { void ControllerBase::changeHK(Mode_t mode, Submode_t submode, bool enable) {
} }
ReturnValue_t ControllerBase::initializeAfterTaskCreation() {
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -1,37 +1,40 @@
#ifndef CONTROLLERBASE_H_ #ifndef FSFW_CONTROLLER_CONTROLLERBASE_H_
#define CONTROLLERBASE_H_ #define FSFW_CONTROLLER_CONTROLLERBASE_H_
#include <framework/health/HasHealthIF.h>
#include <framework/health/HealthHelper.h>
#include <framework/modes/HasModesIF.h>
#include <framework/modes/ModeHelper.h>
#include <framework/objectmanager/SystemObject.h>
#include <framework/tasks/ExecutableObjectIF.h>
#include <framework/datapool/HkSwitchHelper.h>
#include "../health/HasHealthIF.h"
#include "../health/HealthHelper.h"
#include "../modes/HasModesIF.h"
#include "../modes/ModeHelper.h"
#include "../objectmanager/SystemObject.h"
#include "../tasks/ExecutableObjectIF.h"
#include "../datapool/HkSwitchHelper.h"
/**
* @brief Generic base class for controller classes
* @details
* Implements common interfaces for controllers.
*/
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(object_id_t setObjectId, object_id_t parentId,
size_t commandQueueDepth = 3); size_t commandQueueDepth = 3);
virtual ~ControllerBase(); virtual ~ControllerBase();
ReturnValue_t initialize(); virtual ReturnValue_t initialize() override;
virtual MessageQueueId_t getCommandQueue() const; virtual MessageQueueId_t getCommandQueue() const override;
virtual ReturnValue_t performOperation(uint8_t opCode); virtual ReturnValue_t performOperation(uint8_t opCode) override;
virtual ReturnValue_t setHealth(HealthState health); virtual ReturnValue_t setHealth(HealthState health) override;
virtual HasHealthIF::HealthState getHealth(); virtual HasHealthIF::HealthState getHealth() override;
/** /**
* Implementation of ExecutableObjectIF function * Implementation of ExecutableObjectIF function
@ -39,17 +42,32 @@ public:
* 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_) override;
virtual ReturnValue_t initializeAfterTaskCreation() override;
protected: protected:
const uint32_t parentId;
/**
* Implemented by child class. Handle command messages which are not
* mode or health messages.
* @param message
* @return
*/
virtual ReturnValue_t handleCommandMessage(CommandMessage *message) = 0;
virtual void performControlOperation() = 0;
virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t *msToReachTheMode) = 0;
const object_id_t parentId;
Mode_t mode; Mode_t mode;
Submode_t submode; Submode_t submode;
MessageQueueIF* commandQueue; MessageQueueIF* commandQueue = nullptr;
ModeHelper modeHelper; ModeHelper modeHelper;
@ -58,16 +76,13 @@ protected:
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 = nullptr;
void handleQueue(); void handleQueue();
virtual ReturnValue_t handleCommandMessage(CommandMessage *message) = 0;
virtual void performControlOperation() = 0;
virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
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);
@ -76,4 +91,4 @@ protected:
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 /* FSFW_CONTROLLER_CONTROLLERBASE_H_ */

View File

@ -1,7 +1,7 @@
#include <framework/coordinates/CoordinateTransformations.h> #include "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>

View File

@ -1,7 +1,7 @@
#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 {

View File

@ -2,10 +2,10 @@
#define FRAMEWORK_COORDINATES_JGM3MODEL_H_ #define FRAMEWORK_COORDINATES_JGM3MODEL_H_
#include <stdint.h> #include <stdint.h>
#include <framework/coordinates/CoordinateTransformations.h> #include "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>

View File

@ -1,9 +1,9 @@
#include <framework/coordinates/CoordinateTransformations.h> #include "CoordinateTransformations.h"
#include <framework/coordinates/Sgp4Propagator.h> #include "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) {

View File

@ -3,7 +3,7 @@
#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:

View File

@ -8,7 +8,7 @@
#ifndef BCFRAME_H_ #ifndef BCFRAME_H_
#define BCFRAME_H_ #define BCFRAME_H_
#include <framework/datalinklayer/CCSDSReturnValuesIF.h> #include "CCSDSReturnValuesIF.h"
/** /**
* Small helper class to identify a BcFrame. * Small helper class to identify a BcFrame.

View File

@ -8,7 +8,7 @@
#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

View File

@ -7,8 +7,8 @@
#include <framework/datalinklayer/Clcw.h> #include "Clcw.h"
#include <framework/serviceinterface/ServiceInterfaceStream.h> #include "../serviceinterface/ServiceInterfaceStream.h"
Clcw::Clcw() { Clcw::Clcw() {
content.raw = 0; content.raw = 0;

View File

@ -8,7 +8,7 @@
#ifndef CLCW_H_ #ifndef CLCW_H_
#define CLCW_H_ #define CLCW_H_
#include <framework/datalinklayer/ClcwIF.h> #include "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.

View File

@ -1,6 +1,6 @@
#include <framework/datalinklayer/DataLinkLayer.h> #include "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) :

View File

@ -1,11 +1,11 @@
#ifndef DATALINKLAYER_H_ #ifndef DATALINKLAYER_H_
#define DATALINKLAYER_H_ #define DATALINKLAYER_H_
#include <framework/datalinklayer/CCSDSReturnValuesIF.h> #include "CCSDSReturnValuesIF.h"
#include <framework/datalinklayer/ClcwIF.h> #include "ClcwIF.h"
#include <framework/datalinklayer/TcTransferFrame.h> #include "TcTransferFrame.h"
#include <framework/datalinklayer/VirtualChannelReceptionIF.h> #include "VirtualChannelReceptionIF.h"
#include <framework/events/Event.h> #include "../events/Event.h"
#include <map> #include <map>

View File

@ -8,7 +8,7 @@
#ifndef FARM1STATEIF_H_ #ifndef FARM1STATEIF_H_
#define FARM1STATEIF_H_ #define FARM1STATEIF_H_
#include <framework/datalinklayer/CCSDSReturnValuesIF.h> #include "CCSDSReturnValuesIF.h"
class VirtualChannelReception; class VirtualChannelReception;
class TcTransferFrame; class TcTransferFrame;
class ClcwIF; class ClcwIF;

View File

@ -7,10 +7,10 @@
#include <framework/datalinklayer/ClcwIF.h> #include "ClcwIF.h"
#include <framework/datalinklayer/Farm1StateLockout.h> #include "Farm1StateLockout.h"
#include <framework/datalinklayer/TcTransferFrame.h> #include "TcTransferFrame.h"
#include <framework/datalinklayer/VirtualChannelReception.h> #include "VirtualChannelReception.h"
Farm1StateLockout::Farm1StateLockout(VirtualChannelReception* setMyVC) : myVC(setMyVC) { Farm1StateLockout::Farm1StateLockout(VirtualChannelReception* setMyVC) : myVC(setMyVC) {
} }

View File

@ -8,7 +8,7 @@
#ifndef FARM1STATELOCKOUT_H_ #ifndef FARM1STATELOCKOUT_H_
#define FARM1STATELOCKOUT_H_ #define FARM1STATELOCKOUT_H_
#include <framework/datalinklayer/Farm1StateIF.h> #include "Farm1StateIF.h"
/** /**
* This class represents the FARM-1 "Lockout" State. * This class represents the FARM-1 "Lockout" State.

View File

@ -8,10 +8,10 @@
#include <framework/datalinklayer/ClcwIF.h> #include "ClcwIF.h"
#include <framework/datalinklayer/Farm1StateOpen.h> #include "Farm1StateOpen.h"
#include <framework/datalinklayer/TcTransferFrame.h> #include "TcTransferFrame.h"
#include <framework/datalinklayer/VirtualChannelReception.h> #include "VirtualChannelReception.h"
Farm1StateOpen::Farm1StateOpen(VirtualChannelReception* setMyVC) : myVC(setMyVC) { Farm1StateOpen::Farm1StateOpen(VirtualChannelReception* setMyVC) : myVC(setMyVC) {
} }

View File

@ -8,7 +8,7 @@
#ifndef FARM1STATEOPEN_H_ #ifndef FARM1STATEOPEN_H_
#define FARM1STATEOPEN_H_ #define FARM1STATEOPEN_H_
#include <framework/datalinklayer/Farm1StateIF.h> #include "Farm1StateIF.h"
/** /**
* This class represents the FARM-1 "Open" State. * This class represents the FARM-1 "Open" State.

View File

@ -6,10 +6,10 @@
*/ */
#include <framework/datalinklayer/ClcwIF.h> #include "ClcwIF.h"
#include <framework/datalinklayer/Farm1StateWait.h> #include "Farm1StateWait.h"
#include <framework/datalinklayer/TcTransferFrame.h> #include "TcTransferFrame.h"
#include <framework/datalinklayer/VirtualChannelReception.h> #include "VirtualChannelReception.h"
Farm1StateWait::Farm1StateWait(VirtualChannelReception* setMyVC) : myVC(setMyVC) { Farm1StateWait::Farm1StateWait(VirtualChannelReception* setMyVC) : myVC(setMyVC) {
} }

View File

@ -8,7 +8,7 @@
#ifndef FARM1STATEWAIT_H_ #ifndef FARM1STATEWAIT_H_
#define FARM1STATEWAIT_H_ #define FARM1STATEWAIT_H_
#include <framework/datalinklayer/Farm1StateIF.h> #include "Farm1StateIF.h"
/** /**
* This class represents the FARM-1 "Wait" State. * This class represents the FARM-1 "Wait" State.

View File

@ -1,25 +1,18 @@
/** #include "MapPacketExtraction.h"
* @file MapPacketExtraction.cpp #include "../ipc/QueueFactory.h"
* @brief This file defines the MapPacketExtraction class. #include "../serviceinterface/ServiceInterfaceStream.h"
* @date 26.03.2013 #include "../storagemanager/StorageManagerIF.h"
* @author baetz #include "../tmtcpacket/SpacePacketBase.h"
*/ #include "../tmtcservices/AcceptsTelecommandsIF.h"
#include "../tmtcservices/TmTcMessage.h"
#include <framework/datalinklayer/MapPacketExtraction.h> #include <cstring>
#include <framework/ipc/QueueFactory.h>
#include <framework/serviceinterface/ServiceInterfaceStream.h>
#include <framework/storagemanager/StorageManagerIF.h>
#include <framework/tmtcpacket/SpacePacketBase.h>
#include <framework/tmtcservices/AcceptsTelecommandsIF.h>
#include <framework/tmtcservices/TmTcMessage.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), bufferPosition( lastSegmentationFlag(NO_SEGMENTATION), mapId(setMapId), packetLength(0),
packetBuffer), packetDestination(setPacketDestination), packetStore( bufferPosition(packetBuffer), packetDestination(setPacketDestination),
NULL), tcQueueId(MessageQueueSenderIF::NO_QUEUE) { packetStore(NULL), tcQueueId(MessageQueueIF::NO_QUEUE) {
memset(packetBuffer, 0, sizeof(packetBuffer)); std::memset(packetBuffer, 0, sizeof(packetBuffer));
} }
ReturnValue_t MapPacketExtraction::extractPackets(TcTransferFrame* frame) { ReturnValue_t MapPacketExtraction::extractPackets(TcTransferFrame* frame) {

View File

@ -1,17 +1,10 @@
/**
* @file MapPacketExtraction.h
* @brief This file defines the MapPacketExtraction class.
* @date 26.03.2013
* @author baetz
*/
#ifndef MAPPACKETEXTRACTION_H_ #ifndef MAPPACKETEXTRACTION_H_
#define MAPPACKETEXTRACTION_H_ #define MAPPACKETEXTRACTION_H_
#include <framework/datalinklayer/MapPacketExtractionIF.h> #include "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;
@ -20,6 +13,7 @@ class StorageManagerIF;
* 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.
* @author B. Baetz
*/ */
class MapPacketExtraction: public MapPacketExtractionIF { class MapPacketExtraction: public MapPacketExtractionIF {
private: private:

View File

@ -8,8 +8,8 @@
#ifndef MAPPACKETEXTRACTIONIF_H_ #ifndef MAPPACKETEXTRACTIONIF_H_
#define MAPPACKETEXTRACTIONIF_H_ #define MAPPACKETEXTRACTIONIF_H_
#include <framework/datalinklayer/CCSDSReturnValuesIF.h> #include "CCSDSReturnValuesIF.h"
#include <framework/datalinklayer/TcTransferFrame.h> #include "TcTransferFrame.h"
/** /**
* This is the interface for MAP Packet Extraction classes. * This is the interface for MAP Packet Extraction classes.

View File

@ -7,8 +7,8 @@
#include <framework/datalinklayer/TcTransferFrame.h> #include "TcTransferFrame.h"
#include <framework/serviceinterface/ServiceInterfaceStream.h> #include "../serviceinterface/ServiceInterfaceStream.h"
TcTransferFrame::TcTransferFrame() { TcTransferFrame::TcTransferFrame() {
frame = NULL; frame = NULL;

View File

@ -5,9 +5,9 @@
* @author baetz * @author baetz
*/ */
#include <framework/datalinklayer/TcTransferFrameLocal.h> #include "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,

View File

@ -8,7 +8,7 @@
#ifndef TCTRANSFERFRAMELOCAL_H_ #ifndef TCTRANSFERFRAMELOCAL_H_
#define TCTRANSFERFRAMELOCAL_H_ #define TCTRANSFERFRAMELOCAL_H_
#include <framework/datalinklayer/TcTransferFrame.h> #include "TcTransferFrame.h"
/** /**
* This is a helper class to locally create TC Transfer Frames. * This is a helper class to locally create TC Transfer Frames.

View File

@ -5,9 +5,9 @@
* @author baetz * @author baetz
*/ */
#include <framework/datalinklayer/BCFrame.h> #include "BCFrame.h"
#include <framework/datalinklayer/VirtualChannelReception.h> #include "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) :

View File

@ -8,14 +8,14 @@
#ifndef VIRTUALCHANNELRECEPTION_H_ #ifndef VIRTUALCHANNELRECEPTION_H_
#define VIRTUALCHANNELRECEPTION_H_ #define VIRTUALCHANNELRECEPTION_H_
#include <framework/datalinklayer/CCSDSReturnValuesIF.h> #include "CCSDSReturnValuesIF.h"
#include <framework/datalinklayer/Clcw.h> #include "Clcw.h"
#include <framework/datalinklayer/Farm1StateIF.h> #include "Farm1StateIF.h"
#include <framework/datalinklayer/Farm1StateLockout.h> #include "Farm1StateLockout.h"
#include <framework/datalinklayer/Farm1StateOpen.h> #include "Farm1StateOpen.h"
#include <framework/datalinklayer/Farm1StateWait.h> #include "Farm1StateWait.h"
#include <framework/datalinklayer/MapPacketExtractionIF.h> #include "MapPacketExtractionIF.h"
#include <framework/datalinklayer/VirtualChannelReceptionIF.h> #include "VirtualChannelReceptionIF.h"
#include <map> #include <map>
/** /**
* Implementation of a TC Virtual Channel. * Implementation of a TC Virtual Channel.

View File

@ -8,9 +8,9 @@
#ifndef VIRTUALCHANNELRECEPTIONIF_H_ #ifndef VIRTUALCHANNELRECEPTIONIF_H_
#define VIRTUALCHANNELRECEPTIONIF_H_ #define VIRTUALCHANNELRECEPTIONIF_H_
#include <framework/datalinklayer/ClcwIF.h> #include "ClcwIF.h"
#include <framework/datalinklayer/TcTransferFrame.h> #include "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.

View File

@ -1,4 +1,4 @@
#include <framework/datapool/ControllerSet.h> #include "../datapool/ControllerSet.h"
ControllerSet::ControllerSet() { ControllerSet::ControllerSet() {

View File

@ -1,9 +1,9 @@
#ifndef CONTROLLERSET_H_ #ifndef CONTROLLERSET_H_
#define CONTROLLERSET_H_ #define CONTROLLERSET_H_
#include <framework/datapool/DataSet.h> #include "../datapoolglob/GlobalDataSet.h"
class ControllerSet :public DataSet { class ControllerSet :public GlobDataSet {
public: public:
ControllerSet(); ControllerSet();
virtual ~ControllerSet(); virtual ~ControllerSet();

View File

@ -1,131 +0,0 @@
#include <framework/datapool/DataPool.h>
#include <framework/serviceinterface/ServiceInterfaceStream.h>
#include <framework/ipc/MutexFactory.h>
DataPool::DataPool( void ( *initFunction )( std::map<uint32_t, PoolEntryIF*>* pool_map ) ) {
mutex = MutexFactory::instance()->createMutex();
if (initFunction != NULL ) {
initFunction( &this->data_pool );
}
}
DataPool::~DataPool() {
MutexFactory::instance()->deleteMutex(mutex);
for ( std::map<uint32_t, PoolEntryIF*>::iterator it = this->data_pool.begin(); it != this->data_pool.end(); ++it ) {
delete it->second;
}
}
//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.
template <typename T> PoolEntry<T>* DataPool::getData( uint32_t data_pool_id, uint8_t sizeOrPosition ) {
std::map<uint32_t, PoolEntryIF*>::iterator it = this->data_pool.find( data_pool_id );
if ( it != this->data_pool.end() ) {
PoolEntry<T>* entry = dynamic_cast< PoolEntry<T>* >( it->second );
if (entry != NULL ) {
if ( sizeOrPosition <= entry->length ) {
return entry;
}
}
}
return NULL;
}
PoolEntryIF* DataPool::getRawData( uint32_t data_pool_id ) {
std::map<uint32_t, PoolEntryIF*>::iterator it = this->data_pool.find( data_pool_id );
if ( it != this->data_pool.end() ) {
return it->second;
} else {
return NULL;
}
}
//uint8_t DataPool::getRawData( uint32_t data_pool_id, uint8_t* address, uint16_t* size, uint32_t max_size ) {
// std::map<uint32_t, PoolEntryIF*>::iterator it = this->data_pool.find( data_pool_id );
// if ( it != this->data_pool.end() ) {
// if ( it->second->getByteSize() <= max_size ) {
// *size = it->second->getByteSize();
// memcpy( address, it->second->getRawData(), *size );
// return DP_SUCCESSFUL;
// }
// }
// *size = 0;
// return DP_FAILURE;
//}
ReturnValue_t DataPool::freeDataPoolLock() {
ReturnValue_t status = mutex->unlockMutex();
if ( status != RETURN_OK ) {
sif::error << "DataPool::DataPool: unlock of mutex failed with error code: " << status << std::endl;
}
return status;
}
ReturnValue_t DataPool::lockDataPool() {
ReturnValue_t status = mutex->lockMutex(MutexIF::NO_TIMEOUT);
if ( status != RETURN_OK ) {
sif::error << "DataPool::DataPool: lock of mutex failed with error code: " << status << std::endl;
}
return status;
}
void DataPool::print() {
sif::debug << "DataPool contains: " << std::endl;
std::map<uint32_t, PoolEntryIF*>::iterator dataPoolIt;
dataPoolIt = this->data_pool.begin();
while( dataPoolIt != this->data_pool.end() ) {
sif::debug << std::hex << dataPoolIt->first << std::dec << " |";
dataPoolIt->second->print();
dataPoolIt++;
}
}
template PoolEntry<uint8_t>* DataPool::getData<uint8_t>( uint32_t data_pool_id, uint8_t size );
template PoolEntry<uint16_t>* DataPool::getData<uint16_t>( uint32_t data_pool_id, uint8_t size );
template PoolEntry<uint32_t>* DataPool::getData<uint32_t>( uint32_t data_pool_id, uint8_t size );
template PoolEntry<uint64_t>* DataPool::getData<uint64_t>(uint32_t data_pool_id,
uint8_t size);
template PoolEntry<int8_t>* DataPool::getData<int8_t>( uint32_t data_pool_id, uint8_t size );
template PoolEntry<int16_t>* DataPool::getData<int16_t>( uint32_t data_pool_id, uint8_t size );
template PoolEntry<int32_t>* DataPool::getData<int32_t>( uint32_t data_pool_id, uint8_t size );
template PoolEntry<float>* DataPool::getData<float>( uint32_t data_pool_id, uint8_t size );
template PoolEntry<double>* DataPool::getData<double>(uint32_t data_pool_id,
uint8_t size);
uint32_t DataPool::PIDToDataPoolId(uint32_t parameter_id) {
return (parameter_id >> 8) & 0x00FFFFFF;
}
uint8_t DataPool::PIDToArrayIndex(uint32_t parameter_id) {
return (parameter_id & 0x000000FF);
}
uint32_t DataPool::poolIdAndPositionToPid(uint32_t poolId, uint8_t index) {
return (poolId << 8) + index;
}
//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.
//there is no guarantee in the standard, but it seems to me that the implementation is safe -UM
ReturnValue_t DataPool::getType(uint32_t parameter_id, Type* type) {
std::map<uint32_t, PoolEntryIF*>::iterator it = this->data_pool.find( PIDToDataPoolId(parameter_id));
if ( it != this->data_pool.end() ) {
*type = it->second->getType();
return RETURN_OK;
} else {
*type = Type::UNKNOWN_TYPE;
return RETURN_FAILED;
}
}
bool DataPool::exists(uint32_t parameterId) {
uint32_t poolId = PIDToDataPoolId(parameterId);
uint32_t index = PIDToArrayIndex(parameterId);
std::map<uint32_t, PoolEntryIF*>::iterator it = this->data_pool.find( poolId );
if (it != data_pool.end()) {
if (it->second->getSize() >= index) {
return true;
}
}
return false;
}

View File

@ -1,135 +0,0 @@
/**
* \file DataPool.h
*
* \date 10/17/2012
* \author Bastian Baetz
*
* \brief This file contains the definition of the DataPool class and (temporarily)
* the "extern" definition of the global dataPool instance.
*/
#ifndef DATAPOOL_H_
#define DATAPOOL_H_
#include <framework/datapool/PoolEntry.h>
#include <framework/globalfunctions/Type.h>
#include <framework/ipc/MutexIF.h>
#include <map>
/**
* \defgroup data_pool Data Pool
* This is the group, where all classes associated with Data Pool Handling belong to.
* This includes classes to access Data Pool variables.
*/
#define DP_SUCCESSFUL 0
#define DP_FAILURE 1
/**
* \brief This class represents the OBSW global data-pool.
*
* \details All variables are registered and space is allocated in an initialization
* function, which is passed do the constructor.
* Space for the variables is allocated on the heap (with a new call).
* 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,
* which means read data is valid (if flagged so), but not necessarily up-to-date.
* Variables are either single values or arrays.
* \ingroup data_pool
*/
class DataPool : public HasReturnvaluesIF {
private:
/**
* \brief This is the actual data pool itself.
* \details It is represented by a map
* with the data pool id as index and a pointer to a single PoolEntry as value.
*/
std::map<uint32_t, PoolEntryIF*> data_pool;
public:
/**
* \brief The mutex is created in the constructor and makes access mutual exclusive.
* \details Locking and unlocking the pool is only done by the DataSet class.
*/
MutexIF* mutex;
/**
* \brief In the classes constructor, the passed initialization function is called.
* \details To enable filling the pool,
* a pointer to the map is passed, allowing direct access to the pool's content.
* On runtime, adding or removing variables is forbidden.
*/
DataPool( void ( *initFunction )( std::map<uint32_t, PoolEntryIF*>* pool_map ) );
/**
* \brief The destructor iterates through the data_pool map and calls all Entries destructors to clean up the heap.
*/
~DataPool();
/**
* \brief This is the default call to access the pool.
* \details A pointer to the PoolEntry object is returned.
* The call checks data pool id, type and array size. Returns NULL in case of failure.
* \param data_pool_id The data pool id to search.
* \param sizeOrPosition The array size (not byte size!) of the pool entry, or the position the user wants to read.
* If smaller than the entry size, everything's ok.
*/
template <typename T> PoolEntry<T>* getData( uint32_t data_pool_id, uint8_t sizeOrPosition );
/**
* \brief An alternative call to get a data pool entry in case the type is not implicitly known
* (i.e. in Housekeeping Telemetry).
* \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.
* Returns NULL in case the entry is not found.
* \param data_pool_id The data pool id to search.
*/
PoolEntryIF* getRawData( uint32_t data_pool_id );
/**
* \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.
*/
ReturnValue_t lockDataPool();
/**
* \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.
*/
ReturnValue_t freeDataPoolLock();
/**
* \brief The print call is a simple debug method.
* \details It prints the current content of the data pool.
* It iterates through the data_pool map and calls each entry's print() method.
*/
void print();
/**
* Extracts the data pool id from a SCOS 2000 PID.
* @param parameter_id The passed Parameter ID.
* @return The data pool id as used within the OBSW.
*/
static uint32_t PIDToDataPoolId( uint32_t parameter_id );
/**
* Extracts an array index out of a SCOS 2000 PID.
* @param parameter_id The passed Parameter ID.
* @return The index of the corresponding data pool entry.
*/
static uint8_t PIDToArrayIndex( uint32_t parameter_id );
/**
* Retransforms a data pool id and an array index to a SCOS 2000 PID.
*/
static uint32_t poolIdAndPositionToPid( uint32_t poolId, uint8_t index );
/**
* Method to return the type of a pool variable.
* @param parameter_id A parameterID (not pool id) of a DP member.
* @param type Returns the type or TYPE::UNKNOWN_TYPE
* @return RETURN_OK if parameter exists, RETURN_FAILED else.
*/
ReturnValue_t getType( uint32_t parameter_id, Type* type );
/**
* 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.
* @param parameterId The PID (not pool id!) of a parameter.
* @return true if exists, false else.
*/
bool exists(uint32_t parameterId);
};
//We assume someone globally instantiates a DataPool.
extern DataPool dataPool;
#endif /* DATAPOOL_H_ */

View File

@ -1,150 +0,0 @@
#include <framework/datapool/DataSet.h>
#include <framework/serviceinterface/ServiceInterfaceStream.h>
DataSet::DataSet() :
fill_count(0), state(DATA_SET_UNINITIALISED) {
for (unsigned count = 0; count < DATA_SET_MAX_SIZE; count++) {
registeredVariables[count] = NULL;
}
}
DataSet::~DataSet() {
//Don't do anything with your variables, they are dead already! (Destructor is already called)
}
ReturnValue_t DataSet::read() {
ReturnValue_t result = RETURN_OK;
if (state == DATA_SET_UNINITIALISED) {
lockDataPool();
for (uint16_t count = 0; count < fill_count; count++) {
if (registeredVariables[count]->getReadWriteMode()
!= PoolVariableIF::VAR_WRITE
&& registeredVariables[count]->getDataPoolId()
!= PoolVariableIF::NO_PARAMETER) {
ReturnValue_t status = registeredVariables[count]->read();
if (status != RETURN_OK) {
result = INVALID_PARAMETER_DEFINITION;
break;
}
}
}
state = DATA_SET_WAS_READ;
freeDataPoolLock();
} else {
sif::error << "DataSet::read(): Call made in wrong position." << std::endl;
result = SET_WAS_ALREADY_READ;
}
return result;
}
ReturnValue_t DataSet::commit(uint8_t valid) {
setValid(valid);
return commit();
}
ReturnValue_t DataSet::commit() {
if (state == DATA_SET_WAS_READ) {
lockDataPool();
for (uint16_t count = 0; count < fill_count; count++) {
if (registeredVariables[count]->getReadWriteMode()
!= PoolVariableIF::VAR_READ
&& registeredVariables[count]->getDataPoolId()
!= PoolVariableIF::NO_PARAMETER) {
registeredVariables[count]->commit();
}
}
state = DATA_SET_UNINITIALISED;
freeDataPoolLock();
return RETURN_OK;
} else {
ReturnValue_t result = RETURN_OK;
lockDataPool();
for (uint16_t count = 0; count < fill_count; count++) {
if (registeredVariables[count]->getReadWriteMode()
== PoolVariableIF::VAR_WRITE
&& registeredVariables[count]->getDataPoolId()
!= PoolVariableIF::NO_PARAMETER) {
registeredVariables[count]->commit();
} else if (registeredVariables[count]->getDataPoolId()
!= PoolVariableIF::NO_PARAMETER) {
if (result != COMMITING_WITHOUT_READING) {
sif::error <<
"DataSet::commit(): commit-without-read "
"call made with non write-only variable." << std::endl;
result = COMMITING_WITHOUT_READING;
}
}
}
state = DATA_SET_UNINITIALISED;
freeDataPoolLock();
return result;
}
}
void DataSet::registerVariable(PoolVariableIF* variable) {
if (state == DATA_SET_UNINITIALISED) {
if (variable != NULL) {
if (fill_count < DATA_SET_MAX_SIZE) {
registeredVariables[fill_count] = variable;
fill_count++;
return;
}
}
}
sif::error
<< "DataSet::registerVariable: failed. Either NULL, or set is full, or call made in wrong position."
<< std::endl;
return;
}
uint8_t DataSet::freeDataPoolLock() {
return ::dataPool.freeDataPoolLock();
}
uint8_t DataSet::lockDataPool() {
return ::dataPool.lockDataPool();
}
ReturnValue_t DataSet::serialize(uint8_t** buffer, uint32_t* size,
const uint32_t max_size, bool bigEndian) const {
ReturnValue_t result = RETURN_FAILED;
for (uint16_t count = 0; count < fill_count; count++) {
result = registeredVariables[count]->serialize(buffer, size, max_size,
bigEndian);
if (result != RETURN_OK) {
return result;
}
}
return result;
}
uint32_t DataSet::getSerializedSize() const {
uint32_t size = 0;
for (uint16_t count = 0; count < fill_count; count++) {
size += registeredVariables[count]->getSerializedSize();
}
return size;
}
void DataSet::setValid(uint8_t valid) {
for (uint16_t count = 0; count < fill_count; count++) {
if (registeredVariables[count]->getReadWriteMode()
!= PoolVariableIF::VAR_READ) {
registeredVariables[count]->setValid(valid);
}
}
}
ReturnValue_t DataSet::deSerialize(const uint8_t** buffer, int32_t* size,
bool bigEndian) {
ReturnValue_t result = RETURN_FAILED;
for (uint16_t count = 0; count < fill_count; count++) {
result = registeredVariables[count]->deSerialize(buffer, size,
bigEndian);
if (result != RETURN_OK) {
return result;
}
}
return result;
}

View File

@ -1,159 +0,0 @@
/*
* \file DataSet.h
*
* \brief This file contains the DataSet class and a small structure called DataSetContent.
*
* \date 10/17/2012
*
* \author Bastian Baetz
*
*/
#ifndef DATASET_H_
#define DATASET_H_
#include <framework/datapool/DataPool.h>
#include <framework/datapool/DataSetIF.h>
#include <framework/datapool/PoolRawAccess.h>
#include <framework/datapool/PoolVariable.h>
#include <framework/datapool/PoolVarList.h>
#include <framework/datapool/PoolVector.h>
#include <framework/serialize/SerializeAdapter.h>
/**
* \brief The DataSet class manages a set of locally checked out variables.
*
* \details This class manages a list, where a set of local variables (or pool variables) are
* registered. They are checked-out (i.e. their values are looked up and copied)
* with the read call. After the user finishes working with the pool variables,
* he can write back all variable values to the pool with the commit call.
* The data set manages locking and freeing the data pool, to ensure that all values
* are read and written back at once.
* An internal state manages usage of this class. Variables may only be registered before
* the read call is made, and the commit call only after the read call.
* If pool variables are writable and not committed until destruction of the set, the
* DataSet class automatically sets the valid flag in the data pool to invalid (without)
* changing the variable's value.
*
* \ingroup data_pool
*/
class DataSet: public DataSetIF, public HasReturnvaluesIF, public SerializeIF {
private:
//SHOULDDO we could use a linked list of datapool variables
static const uint8_t DATA_SET_MAX_SIZE = 63; //!< This definition sets the maximum number of variables to register in one DataSet.
/**
* \brief This array represents all pool variables registered in this set.
* \details It has a maximum size of DATA_SET_MAX_SIZE.
*/
PoolVariableIF* registeredVariables[DATA_SET_MAX_SIZE];
/**
* \brief The fill_count attribute ensures that the variables register in the correct array
* position and that the maximum number of variables is not exceeded.
*/
uint16_t fill_count;
/**
* States of the seet.
*/
enum States {
DATA_SET_UNINITIALISED, //!< DATA_SET_UNINITIALISED
DATA_SET_WAS_READ //!< DATA_SET_WAS_READ
};
/**
* \brief state manages the internal state of the data set, which is important e.g. for the
* behavior on destruction.
*/
States state;
/**
* \brief This is a small helper function to facilitate locking the global data pool.
* \details It makes use of the lockDataPool method offered by the DataPool class.
*/
uint8_t lockDataPool();
/**
* \brief This is a small helper function to facilitate unlocking the global data pool.
* \details It makes use of the freeDataPoolLock method offered by the DataPool class.
*/
uint8_t freeDataPoolLock();
public:
static const uint8_t INTERFACE_ID = CLASS_ID::DATA_SET_CLASS;
static const ReturnValue_t INVALID_PARAMETER_DEFINITION =
MAKE_RETURN_CODE( 0x01 );
static const ReturnValue_t SET_WAS_ALREADY_READ = MAKE_RETURN_CODE( 0x02 );
static const ReturnValue_t COMMITING_WITHOUT_READING =
MAKE_RETURN_CODE(0x03);
/**
* \brief The constructor simply sets the fill_count to zero and sets the state to "uninitialized".
*/
DataSet();
/**
* \brief The destructor automatically manages writing the valid information of variables.
* \details In case the data set was read out, but not committed (indicated by state),
* the destructor parses all variables that are still registered to the set.
* For each, the valid flag in the data pool is set to "invalid".
*/
~DataSet();
/**
* \brief The read call initializes reading out all registered variables.
* \details It iterates through the list of registered variables and calls all read()
* functions of the registered pool variables (which read out their values from the
* data pool) which are not write-only. In case of an error (e.g. a wrong data type,
* or an invalid data pool id), the operation is aborted and
* \c INVALID_PARAMETER_DEFINITION returned.
* The data pool is locked during the whole read operation and freed afterwards.
* The state changes to "was written" after this operation.
* \return - \c RETURN_OK if all variables were read successfully.
* - \c INVALID_PARAMETER_DEFINITION if PID, size or type of the
* requested variable is invalid.
* - \c SET_WAS_ALREADY_READ if read() is called twice without calling
* commit() in between
*/
ReturnValue_t read();
/**
* \brief The commit call initializes writing back the registered variables.
* \details It iterates through the list of registered variables and calls
* the commit() method of the remaining registered variables (which write back
* their values to the pool).
* The data pool is locked during the whole commit operation and freed afterwards.
* The state changes to "was committed" after this operation.
* If the set does contain at least one variable which is not write-only commit()
* can only be called after read(). If the set only contains variables which are
* write only, commit() can be called without a preceding read() call.
* \return - \c RETURN_OK if all variables were read successfully.
* - \c COMMITING_WITHOUT_READING if set was not read yet and contains non write-only
* variables
*/
ReturnValue_t commit(void);
/**
* Variant of method above which sets validity of all elements of the set.
* @param valid Validity information from PoolVariableIF.
* \return - \c RETURN_OK if all variables were read successfully.
* - \c COMMITING_WITHOUT_READING if set was not read yet and contains non write-only
* variables
*/
ReturnValue_t commit(uint8_t valid);
/**
* \brief This operation is used to register the local variables in the set.
* \details It copies all required information to the currently
* free space in the registeredVariables list.
*/
void registerVariable(PoolVariableIF* variable);
/**
* Set the valid information of all variables contained in the set which are not readonly
*
* @param valid Validity information from PoolVariableIF.
*/
void setValid(uint8_t valid);
ReturnValue_t serialize(uint8_t** buffer, uint32_t* size,
const uint32_t max_size, bool bigEndian) const;
uint32_t getSerializedSize() const;
ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size,
bool bigEndian);
};
#endif /* DATASET_H_ */

View File

@ -1,39 +1,48 @@
/**
* \file DataSetIF.h
*
* \brief This file contains the small interface to access the DataSet class.
*
* \date 10/23/2012
*
* \author Bastian Baetz
*
*/
#ifndef DATASETIF_H_ #ifndef DATASETIF_H_
#define DATASETIF_H_ #define DATASETIF_H_
#include "../returnvalues/HasReturnvaluesIF.h"
#include "../timemanager/Clock.h"
class PoolVariableIF; class PoolVariableIF;
/** /**
* \brief This class defines a small interface to register on a DataSet. * @brief This class defines a small interface to register on a DataSet.
* *
* \details Currently, the only purpose of this interface is to provide a method for locally * @details
* checked-out variables to register on a data set. Still, it may become useful for * Currently, the only purpose of this interface is to provide a
* other purposes as well. * method for locally checked-out variables to register on a data set.
* * Still, it may become useful for other purposes as well.
* \ingroup data_pool * @author Bastian Baetz
* @ingroup data_pool
*/ */
class DataSetIF { class DataSetIF {
public: public:
static constexpr uint8_t INTERFACE_ID = CLASS_ID::DATA_SET_CLASS;
static constexpr ReturnValue_t INVALID_PARAMETER_DEFINITION =
MAKE_RETURN_CODE( 0x01 );
static constexpr ReturnValue_t SET_WAS_ALREADY_READ = MAKE_RETURN_CODE( 0x02 );
static constexpr ReturnValue_t COMMITING_WITHOUT_READING =
MAKE_RETURN_CODE(0x03);
static constexpr ReturnValue_t DATA_SET_UNINITIALISED = MAKE_RETURN_CODE( 0x04 );
static constexpr ReturnValue_t DATA_SET_FULL = MAKE_RETURN_CODE( 0x05 );
static constexpr ReturnValue_t POOL_VAR_NULL = MAKE_RETURN_CODE( 0x06 );
/** /**
* \brief This is an empty virtual destructor, as it is proposed for C++ interfaces. * @brief This is an empty virtual destructor,
* as it is proposed for C++ interfaces.
*/ */
virtual ~DataSetIF() {} virtual ~DataSetIF() {}
/** /**
* \brief This operation provides a method to register local data pool variables * @brief This operation provides a method to register local data pool
* to register in a data set by passing itself to this DataSet operation. * variables to register in a data set by passing itself
* to this DataSet operation.
*/ */
virtual void registerVariable( PoolVariableIF* variable ) = 0; virtual ReturnValue_t registerVariable(PoolVariableIF* variable) = 0;
virtual uint16_t getFillCount() const = 0;
}; };
#endif /* DATASETIF_H_ */ #endif /* FRAMEWORK_DATAPOOL_DATASETIF_H_ */

View File

@ -1,6 +1,5 @@
#include <framework/datapool/HkSwitchHelper.h> #include "../datapool/HkSwitchHelper.h"
//#include <mission/tmtcservices/HKService_03.h> #include "../ipc/QueueFactory.h"
#include <framework/ipc/QueueFactory.h>
HkSwitchHelper::HkSwitchHelper(EventReportingProxyIF* eventProxy) : HkSwitchHelper::HkSwitchHelper(EventReportingProxyIF* eventProxy) :
commandActionHelper(this), eventProxy(eventProxy) { commandActionHelper(this), eventProxy(eventProxy) {
@ -22,14 +21,14 @@ ReturnValue_t HkSwitchHelper::initialize() {
} }
ReturnValue_t HkSwitchHelper::performOperation(uint8_t operationCode) { ReturnValue_t HkSwitchHelper::performOperation(uint8_t operationCode) {
CommandMessage message; CommandMessage command;
while (actionQueue->receiveMessage(&message) == HasReturnvaluesIF::RETURN_OK) { while (actionQueue->receiveMessage(&command) == HasReturnvaluesIF::RETURN_OK) {
ReturnValue_t result = commandActionHelper.handleReply(&message); ReturnValue_t result = commandActionHelper.handleReply(&command);
if (result == HasReturnvaluesIF::RETURN_OK) { if (result == HasReturnvaluesIF::RETURN_OK) {
continue; continue;
} }
message.setToUnknownCommand(); command.setToUnknownCommand();
actionQueue->reply(&message); actionQueue->reply(&command);
} }
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;

View File

@ -1,9 +1,9 @@
#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

View File

@ -0,0 +1,169 @@
#include "PoolDataSetBase.h"
#include "../serviceinterface/ServiceInterfaceStream.h"
PoolDataSetBase::PoolDataSetBase(PoolVariableIF** registeredVariablesArray,
const size_t maxFillCount):
registeredVariables(registeredVariablesArray),
maxFillCount(maxFillCount) {
}
PoolDataSetBase::~PoolDataSetBase() {}
ReturnValue_t PoolDataSetBase::registerVariable(
PoolVariableIF *variable) {
if (state != States::DATA_SET_UNINITIALISED) {
sif::error << "DataSet::registerVariable: "
"Call made in wrong position." << std::endl;
return DataSetIF::DATA_SET_UNINITIALISED;
}
if (variable == nullptr) {
sif::error << "DataSet::registerVariable: "
"Pool variable is nullptr." << std::endl;
return DataSetIF::POOL_VAR_NULL;
}
if (fillCount >= maxFillCount) {
sif::error << "DataSet::registerVariable: "
"DataSet is full." << std::endl;
return DataSetIF::DATA_SET_FULL;
}
registeredVariables[fillCount] = variable;
fillCount++;
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t PoolDataSetBase::read(uint32_t lockTimeout) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
if (state == States::DATA_SET_UNINITIALISED) {
lockDataPool(lockTimeout);
for (uint16_t count = 0; count < fillCount; count++) {
result = readVariable(count);
if(result != RETURN_OK) {
break;
}
}
state = States::DATA_SET_WAS_READ;
unlockDataPool();
}
else {
sif::error << "DataSet::read(): "
"Call made in wrong position. Don't forget to commit"
" member datasets!" << std::endl;
result = SET_WAS_ALREADY_READ;
}
return result;
}
uint16_t PoolDataSetBase::getFillCount() const {
return fillCount;
}
ReturnValue_t PoolDataSetBase::readVariable(uint16_t count) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
// These checks are often performed by the respective
// variable implementation too, but I guess a double check does not hurt.
if (registeredVariables[count]->getReadWriteMode() !=
PoolVariableIF::VAR_WRITE and
registeredVariables[count]->getDataPoolId()
!= PoolVariableIF::NO_PARAMETER)
{
result = registeredVariables[count]->readWithoutLock();
if(result != HasReturnvaluesIF::RETURN_OK) {
result = INVALID_PARAMETER_DEFINITION;
}
}
return result;
}
ReturnValue_t PoolDataSetBase::commit(uint32_t lockTimeout) {
if (state == States::DATA_SET_WAS_READ) {
handleAlreadyReadDatasetCommit(lockTimeout);
return HasReturnvaluesIF::RETURN_OK;
}
else {
return handleUnreadDatasetCommit(lockTimeout);
}
}
void PoolDataSetBase::handleAlreadyReadDatasetCommit(uint32_t lockTimeout) {
lockDataPool(lockTimeout);
for (uint16_t count = 0; count < fillCount; count++) {
if (registeredVariables[count]->getReadWriteMode()
!= PoolVariableIF::VAR_READ
&& registeredVariables[count]->getDataPoolId()
!= PoolVariableIF::NO_PARAMETER) {
registeredVariables[count]->commitWithoutLock();
}
}
state = States::DATA_SET_UNINITIALISED;
unlockDataPool();
}
ReturnValue_t PoolDataSetBase::handleUnreadDatasetCommit(uint32_t lockTimeout) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
lockDataPool(lockTimeout);
for (uint16_t count = 0; count < fillCount; count++) {
if (registeredVariables[count]->getReadWriteMode()
== PoolVariableIF::VAR_WRITE
&& registeredVariables[count]->getDataPoolId()
!= PoolVariableIF::NO_PARAMETER) {
registeredVariables[count]->commitWithoutLock();
} else if (registeredVariables[count]->getDataPoolId()
!= PoolVariableIF::NO_PARAMETER) {
if (result != COMMITING_WITHOUT_READING) {
sif::error << "DataSet::commit(): commit-without-read call made "
"with non write-only variable." << std::endl;
result = COMMITING_WITHOUT_READING;
}
}
}
state = States::DATA_SET_UNINITIALISED;
unlockDataPool();
return result;
}
ReturnValue_t PoolDataSetBase::lockDataPool(uint32_t timeoutMs) {
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t PoolDataSetBase::unlockDataPool() {
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t PoolDataSetBase::serialize(uint8_t** buffer, size_t* size,
const size_t maxSize, SerializeIF::Endianness streamEndianness) const {
ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED;
for (uint16_t count = 0; count < fillCount; count++) {
result = registeredVariables[count]->serialize(buffer, size, maxSize,
streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
}
return result;
}
ReturnValue_t PoolDataSetBase::deSerialize(const uint8_t** buffer, size_t* size,
SerializeIF::Endianness streamEndianness) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED;
for (uint16_t count = 0; count < fillCount; count++) {
result = registeredVariables[count]->deSerialize(buffer, size,
streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
}
return result;
}
size_t PoolDataSetBase::getSerializedSize() const {
uint32_t size = 0;
for (uint16_t count = 0; count < fillCount; count++) {
size += registeredVariables[count]->getSerializedSize();
}
return size;
}
void PoolDataSetBase::setContainer(PoolVariableIF **variablesContainer) {
this->registeredVariables = variablesContainer;
}

151
datapool/PoolDataSetBase.h Normal file
View File

@ -0,0 +1,151 @@
#ifndef FRAMEWORK_DATAPOOL_DATASETBASE_H_
#define FRAMEWORK_DATAPOOL_DATASETBASE_H_
#include "../datapool/PoolDataSetIF.h"
#include "../datapool/PoolVariableIF.h"
#include "../ipc/MutexIF.h"
/**
* @brief The DataSetBase class manages a set of locally checked out variables.
* @details
* This class manages a list, where a set of local variables (or pool variables)
* are registered. They are checked-out (i.e. their values are looked
* up and copied) with the read call. After the user finishes working with the
* pool variables, he can write back all variable values to the pool with
* the commit call. The data set manages locking and freeing the data pool,
* to ensure that all values are read and written back at once.
*
* An internal state manages usage of this class. Variables may only be
* registered before the read call is made, and the commit call only
* after the read call.
*
* If pool variables are writable and not committed until destruction
* of the set, the DataSet class automatically sets the valid flag in the
* data pool to invalid (without) changing the variable's value.
*
* The base class lockDataPool und unlockDataPool implementation are empty
* and should be implemented to protect the underlying pool type.
* @author Bastian Baetz
* @ingroup data_pool
*/
class PoolDataSetBase: public PoolDataSetIF,
public SerializeIF,
public HasReturnvaluesIF {
public:
/**
* @brief Creates an empty dataset. Use registerVariable or
* supply a pointer to this dataset to PoolVariable
* initializations to register pool variables.
*/
PoolDataSetBase(PoolVariableIF** registeredVariablesArray,
const size_t maxFillCount);
virtual~ PoolDataSetBase();
/**
* @brief The read call initializes reading out all registered variables.
* @details
* It iterates through the list of registered variables and calls all read()
* functions of the registered pool variables (which read out their values
* from the data pool) which are not write-only.
* In case of an error (e.g. a wrong data type, or an invalid data pool id),
* the operation is aborted and @c INVALID_PARAMETER_DEFINITION returned.
*
* The data pool is locked during the whole read operation and
* freed afterwards.The state changes to "was written" after this operation.
* @return
* - @c RETURN_OK if all variables were read successfully.
* - @c INVALID_PARAMETER_DEFINITION if PID, size or type of the
* requested variable is invalid.
* - @c SET_WAS_ALREADY_READ if read() is called twice without calling
* commit() in between
*/
virtual ReturnValue_t read(uint32_t lockTimeout =
MutexIF::BLOCKING) override;
/**
* @brief The commit call initializes writing back the registered variables.
* @details
* It iterates through the list of registered variables and calls the
* commit() method of the remaining registered variables (which write back
* their values to the pool).
*
* The data pool is locked during the whole commit operation and
* freed afterwards. The state changes to "was committed" after this operation.
*
* If the set does contain at least one variable which is not write-only
* commit() can only be called after read(). If the set only contains
* variables which are write only, commit() can be called without a
* preceding read() call.
* @return - @c RETURN_OK if all variables were read successfully.
* - @c COMMITING_WITHOUT_READING if set was not read yet and
* contains non write-only variables
*/
virtual ReturnValue_t commit(uint32_t lockTimeout =
MutexIF::BLOCKING) override;
/**
* Register the passed pool variable instance into the data set.
* @param variable
* @return
*/
virtual ReturnValue_t registerVariable( PoolVariableIF* variable) override;
/**
* Provides the means to lock the underlying data structure to ensure
* thread-safety. Default implementation is empty
* @return Always returns -@c RETURN_OK
*/
virtual ReturnValue_t lockDataPool(uint32_t timeoutMs =
MutexIF::BLOCKING) override;
/**
* Provides the means to unlock the underlying data structure to ensure
* thread-safety. Default implementation is empty
* @return Always returns -@c RETURN_OK
*/
virtual ReturnValue_t unlockDataPool() override;
virtual uint16_t getFillCount() const;
/* SerializeIF implementations */
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
const size_t maxSize,
SerializeIF::Endianness streamEndianness) const override;
virtual size_t getSerializedSize() const override;
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
SerializeIF::Endianness streamEndianness) override;
protected:
/**
* @brief The fill_count attribute ensures that the variables
* register in the correct array position and that the maximum
* number of variables is not exceeded.
*/
uint16_t fillCount = 0;
/**
* States of the seet.
*/
enum class States {
DATA_SET_UNINITIALISED, //!< DATA_SET_UNINITIALISED
DATA_SET_WAS_READ //!< DATA_SET_WAS_READ
};
/**
* @brief state manages the internal state of the data set,
* which is important e.g. for the behavior on destruction.
*/
States state = States::DATA_SET_UNINITIALISED;
/**
* @brief This array represents all pool variables registered in this set.
* Child classes can use a static or dynamic container to create
* an array of registered variables and assign the first entry here.
*/
PoolVariableIF** registeredVariables = nullptr;
const size_t maxFillCount = 0;
void setContainer(PoolVariableIF** variablesContainer);
private:
ReturnValue_t readVariable(uint16_t count);
void handleAlreadyReadDatasetCommit(uint32_t lockTimeout);
ReturnValue_t handleUnreadDatasetCommit(uint32_t lockTimeout);
};
#endif /* FRAMEWORK_DATAPOOL_POOLPOOLDATASETBASE_H_ */

28
datapool/PoolDataSetIF.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef FRAMEWORK_DATAPOOL_POOLDATASETIF_H_
#define FRAMEWORK_DATAPOOL_POOLDATASETIF_H_
#include "DataSetIF.h"
class PoolDataSetIF: public DataSetIF {
public:
virtual~ PoolDataSetIF() {};
virtual ReturnValue_t read(dur_millis_t lockTimeout) = 0;
virtual ReturnValue_t commit(dur_millis_t lockTimeout) = 0;
/**
* @brief Most underlying data structures will have a pool like structure
* and will require a lock and unlock mechanism to ensure
* thread-safety
* @return Lock operation result
*/
virtual ReturnValue_t lockDataPool(dur_millis_t timeoutMs) = 0;
/**
* @brief Unlock call corresponding to the lock call.
* @return Unlock operation result
*/
virtual ReturnValue_t unlockDataPool() = 0;
virtual bool isValid() const = 0;
};
#endif /* FRAMEWORK_DATAPOOL_POOLDATASETIF_H_ */

View File

@ -1,13 +1,34 @@
#include <framework/datapool/PoolEntry.h> #include "../datapool/PoolEntry.h"
#include <framework/serviceinterface/ServiceInterfaceStream.h> #include "../serviceinterface/ServiceInterfaceStream.h"
#include "../globalfunctions/arrayprinter.h"
#include <cstring>
template <typename T> template <typename T>
PoolEntry<T>::PoolEntry( T* initValue, uint8_t set_length, uint8_t set_valid ) : length(set_length), valid(set_valid) { PoolEntry<T>::PoolEntry(std::initializer_list<T> initValue, uint8_t setLength,
bool setValid ) : length(setLength), valid(setValid) {
this->address = new T[this->length]; this->address = new T[this->length];
if (initValue != NULL) { if(initValue.size() == 0) {
memcpy(this->address, initValue, this->getByteSize() ); std::memset(this->address, 0, this->getByteSize());
}
else if (initValue.size() != setLength){
sif::warning << "PoolEntry: setLength is not equal to initializer list"
"length! Performing zero initialization with given setLength"
<< std::endl;
std::memset(this->address, 0, this->getByteSize());
}
else {
std::copy(initValue.begin(), initValue.end(), this->address);
}
}
template <typename T>
PoolEntry<T>::PoolEntry( T* initValue, uint8_t setLength, bool setValid ) :
length(setLength), valid(setValid) {
this->address = new T[this->length];
if (initValue != nullptr) {
std::memcpy(this->address, initValue, this->getByteSize() );
} else { } else {
memset(this->address, 0, this->getByteSize() ); std::memset(this->address, 0, this->getByteSize() );
} }
} }
@ -34,21 +55,20 @@ void* PoolEntry<T>::getRawData() {
} }
template <typename T> template <typename T>
void PoolEntry<T>::setValid( uint8_t isValid ) { void PoolEntry<T>::setValid(bool isValid) {
this->valid = isValid; this->valid = isValid;
} }
template <typename T> template <typename T>
uint8_t 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() {
for (uint8_t size = 0; size < this->length; size++ ) { sif::debug << "Pool Entry Validity: " <<
sif::debug << "| " << std::hex << (double)this->address[size] (this->valid? " (valid) " : " (invalid) ") << std::endl;
<< (this->valid? " (valid) " : " (invalid) "); arrayprinter::print(reinterpret_cast<uint8_t*>(address), length);
}
sif::debug << std::dec << std::endl; sif::debug << std::dec << std::endl;
} }

View File

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

View File

@ -1,62 +1,57 @@
/** #ifndef FRAMEWORK_DATAPOOL_POOLENTRYIF_H_
* \file PoolEntryIF.h #define FRAMEWORK_DATAPOOL_POOLENTRYIF_H_
*
* \brief This file holds the class that defines the Interface for Pool Entry elements.
*
* \date 10/18/2012
*
* \author Bastian Baetz
*/
#ifndef POOLENTRYIF_H_
#define POOLENTRYIF_H_
#include <framework/globalfunctions/Type.h>
#include <stdint.h>
#include "../globalfunctions/Type.h"
#include <cstdint>
/** /**
* \brief This interface defines the access possibilities to a single data pool entry. * @brief This interface defines the access possibilities to a
* single data pool entry.
* @details
* 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
* raw data content. It is mainly used by DataPool itself, but also as a
* return pointer.
* *
* \details The interface provides methods to determine the size and the validity information of a value. * @author Bastian Baetz
* It also defines a method to receive a pointer to the raw data content. * @ingroup data_pool
* It is mainly used by DataPool itself, but also as a return pointer.
*
* \ingroup data_pool
* *
*/ */
class PoolEntryIF { class PoolEntryIF {
public: public:
/** /**
* \brief This is an empty virtual destructor, as it is proposed for C++ interfaces. * @brief This is an empty virtual destructor,
* as it is required for C++ interfaces.
*/ */
virtual ~PoolEntryIF() { virtual ~PoolEntryIF() {
} }
/** /**
* \brief getSize returns the array size of the entry. A single variable parameter has size 1. * @brief getSize returns the array size of the entry.
* 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(uint8_t 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 uint8_t getValid() = 0; virtual bool getValid() = 0;
/** /**
* \brief This is a debug method that prints all values and the valid information to the screen. * @brief This is a debug method that prints all values and the valid
* It prints all array entries in a row. * information to the screen. It prints all array entries in a row.
* @details
* Also displays whether the pool entry is valid or invalid.
*/ */
virtual void print() = 0; virtual void print() = 0;
/** /**

View File

@ -1,199 +0,0 @@
#include <framework/datapool/DataPool.h>
#include <framework/datapool/PoolEntryIF.h>
#include <framework/datapool/PoolRawAccess.h>
#include <framework/serviceinterface/ServiceInterfaceStream.h>
#include <framework/osal/Endiness.h>
PoolRawAccess::PoolRawAccess(uint32_t set_id, uint8_t setArrayEntry,
DataSetIF* data_set, ReadWriteMode_t setReadWriteMode) :
dataPoolId(set_id), arrayEntry(setArrayEntry), valid(false), type(Type::UNKNOWN_TYPE), typeSize(
0), arraySize(0), sizeTillEnd(0), readWriteMode(setReadWriteMode) {
memset(value, 0, sizeof(value));
if (data_set != NULL) {
data_set->registerVariable(this);
}
}
PoolRawAccess::~PoolRawAccess() {
}
ReturnValue_t PoolRawAccess::read() {
PoolEntryIF* read_out = ::dataPool.getRawData(dataPoolId);
if (read_out != NULL) {
valid = read_out->getValid();
if (read_out->getSize() > arrayEntry) {
arraySize = read_out->getSize();
typeSize = read_out->getByteSize() / read_out->getSize();
type = read_out->getType();
if (typeSize <= sizeof(value)) {
uint16_t arrayPosition = arrayEntry * typeSize;
sizeTillEnd = read_out->getByteSize() - arrayPosition;
uint8_t* ptr =
&((uint8_t*) read_out->getRawData())[arrayPosition];
memcpy(value, ptr, typeSize);
return HasReturnvaluesIF::RETURN_OK;
} else {
//Error value type too large.
}
} else {
//Error index requested too large
}
} else {
//Error entry does not exist.
}
sif::error << "PoolRawAccess: read of DP Variable 0x" << std::hex << dataPoolId
<< std::dec << " failed." << std::endl;
valid = INVALID;
typeSize = 0;
sizeTillEnd = 0;
memset(value, 0, sizeof(value));
return HasReturnvaluesIF::RETURN_FAILED;
}
ReturnValue_t PoolRawAccess::commit() {
PoolEntryIF* write_back = ::dataPool.getRawData(dataPoolId);
if ((write_back != NULL) && (readWriteMode != VAR_READ)) {
write_back->setValid(valid);
uint8_t array_position = arrayEntry * typeSize;
uint8_t* ptr = &((uint8_t*) write_back->getRawData())[array_position];
memcpy(ptr, value, typeSize);
return HasReturnvaluesIF::RETURN_OK;
} else {
return HasReturnvaluesIF::RETURN_FAILED;
}
}
uint8_t* PoolRawAccess::getEntry() {
return value;
}
ReturnValue_t PoolRawAccess::getEntryEndianSafe(uint8_t* buffer,
uint32_t* writtenBytes, uint32_t max_size) {
uint8_t* data_ptr = getEntry();
// debug << "PoolRawAccess::getEntry: Array position: " << index * size_of_type << " Size of T: " << (int)size_of_type << " ByteSize: " << byte_size << " Position: " << *size << std::endl;
if (typeSize == 0)
return DATA_POOL_ACCESS_FAILED;
if (typeSize > max_size)
return INCORRECT_SIZE;
#ifndef BYTE_ORDER_SYSTEM
#error BYTE_ORDER_SYSTEM not defined
#elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN
for (uint8_t count = 0; count < typeSize; count++) {
buffer[count] = data_ptr[typeSize - count - 1];
}
#elif BYTE_ORDER_SYSTEM == BIG_ENDIAN
memcpy(buffer, data_ptr, typeSize);
#endif
*writtenBytes = typeSize;
return HasReturnvaluesIF::RETURN_OK;
}
Type PoolRawAccess::getType() {
return type;
}
uint8_t PoolRawAccess::getSizeOfType() {
return typeSize;
}
uint8_t PoolRawAccess::getArraySize(){
return arraySize;
}
uint32_t PoolRawAccess::getDataPoolId() const {
return dataPoolId;
}
PoolVariableIF::ReadWriteMode_t PoolRawAccess::getReadWriteMode() const {
return readWriteMode;
}
ReturnValue_t PoolRawAccess::setEntryFromBigEndian(const uint8_t* buffer,
uint32_t setSize) {
if (typeSize == setSize) {
#ifndef BYTE_ORDER_SYSTEM
#error BYTE_ORDER_SYSTEM not defined
#elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN
for (uint8_t count = 0; count < typeSize; count++) {
value[count] = buffer[typeSize - count - 1];
}
#elif BYTE_ORDER_SYSTEM == BIG_ENDIAN
memcpy(value, buffer, typeSize);
#endif
return HasReturnvaluesIF::RETURN_OK;
} else {
sif::error << "PoolRawAccess::setEntryFromBigEndian: Illegal sizes: Internal"
<< (uint32_t) typeSize << ", Requested: " << setSize
<< std::endl;
return INCORRECT_SIZE;
}
}
bool PoolRawAccess::isValid() const {
if (valid != INVALID)
return true;
else
return false;
}
void PoolRawAccess::setValid(uint8_t valid) {
this->valid = valid;
}
uint16_t PoolRawAccess::getSizeTillEnd() const {
return sizeTillEnd;
}
ReturnValue_t PoolRawAccess::serialize(uint8_t** buffer, uint32_t* size,
const uint32_t max_size, bool bigEndian) const {
if (typeSize + *size <= max_size) {
if (bigEndian) {
#ifndef BYTE_ORDER_SYSTEM
#error BYTE_ORDER_SYSTEM not defined
#elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN
for (uint8_t count = 0; count < typeSize; count++) {
(*buffer)[count] = value[typeSize - count - 1];
}
#elif BYTE_ORDER_SYSTEM == BIG_ENDIAN
memcpy(*buffer, value, typeSize);
#endif
} else {
memcpy(*buffer, value, typeSize);
}
*size += typeSize;
(*buffer) += typeSize;
return HasReturnvaluesIF::RETURN_OK;
} else {
return SerializeIF::BUFFER_TOO_SHORT;
}
}
uint32_t PoolRawAccess::getSerializedSize() const {
return typeSize;
}
ReturnValue_t PoolRawAccess::deSerialize(const uint8_t** buffer, int32_t* size,
bool bigEndian) {
*size -= typeSize;
if (*size >= 0) {
if (bigEndian) {
#ifndef BYTE_ORDER_SYSTEM
#error BYTE_ORDER_SYSTEM not defined
#elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN
for (uint8_t count = 0; count < typeSize; count++) {
value[count] = (*buffer)[typeSize - count - 1];
}
#elif BYTE_ORDER_SYSTEM == BIG_ENDIAN
memcpy(value, *buffer, typeSize);
#endif
} else {
memcpy(value, *buffer, typeSize);
}
*buffer += typeSize;
return HasReturnvaluesIF::RETURN_OK;
} else {
return SerializeIF::STREAM_TOO_SHORT;
}
}

View File

@ -1,152 +0,0 @@
#ifndef POOLRAWACCESS_H_
#define POOLRAWACCESS_H_
#include <framework/datapool/DataSetIF.h>
#include <framework/datapool/PoolVariableIF.h>
/**
* This class allows accessing Data Pool variables as raw bytes.
* This is necessary to have an access method for HK data, as the PID's alone do not
* provide a type information.
* \ingroup data_pool
*/
class PoolRawAccess: public PoolVariableIF {
private:
/**
* \brief To access the correct data pool entry on read and commit calls, the data pool id
* is stored.
*/
uint32_t dataPoolId;
/**
* \brief The array entry that is fetched from the data pool.
*/
uint8_t arrayEntry;
/**
* \brief The valid information as it was stored in the data pool is copied to this attribute.
*/
uint8_t valid;
/**
* \brief This value contains the type of the data pool entry.
*/
Type type;
/**
* \brief This value contains the size of the data pool entry in bytes.
*/
uint8_t typeSize;
/**
* The size of the DP array (single values return 1)
*/
uint8_t arraySize;
/**
* The size (in bytes) from the selected entry till the end of this DataPool variable.
*/
uint16_t sizeTillEnd;
/**
* \brief The information whether the class is read-write or read-only is stored here.
*/
ReadWriteMode_t readWriteMode;
static const uint8_t RAW_MAX_SIZE = sizeof(double);
protected:
/**
* \brief This is a call to read the value from the global data pool.
* \details 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
* 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.
* The operation does NOT provide any mutual exclusive protection by itself.
*/
ReturnValue_t read();
/**
* \brief The commit call writes back the variable's value to the data pool.
* \details 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 operation does NOT provide any mutual exclusive protection by itself.
*
*/
ReturnValue_t commit();
public:
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 DATA_POOL_ACCESS_FAILED = MAKE_RETURN_CODE(0x02);
uint8_t value[RAW_MAX_SIZE];
PoolRawAccess(uint32_t data_pool_id, uint8_t arrayEntry,
DataSetIF* data_set, ReadWriteMode_t setReadWriteMode =
PoolVariableIF::VAR_READ);
/**
* \brief The classes destructor is empty. If commit() was not called, the local value is
* discarded and not written back to the data pool.
*/
~PoolRawAccess();
/**
* \brief This operation returns a pointer to the entry fetched.
* \details This means, it does not return a pointer to byte "index", but to the start byte of
* array entry "index". Example: If the original data pool array consists of an double
* array of size four, getEntry(1) returns &(this->value[8]).
*/
uint8_t* getEntry();
/**
* \brief This operation returns the fetched entry from the data pool and
* flips the bytes, if necessary.
* \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-
* keeping telemetry). To achieve this, the data is copied directly to the passed
* buffer, if it fits in the given max_size.
* \param buffer A pointer to a buffer to write to
* \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.
* \return - \c RETURN_OK if entry could be acquired
* - \c RETURN_FAILED else.
*/
ReturnValue_t getEntryEndianSafe(uint8_t* buffer, uint32_t* size,
uint32_t max_size);
/**
* With this method, the content can be set from a big endian buffer safely.
* @param buffer Pointer to the data to set
* @param size Size of the data to write. Must fit this->size.
* @return - \c RETURN_OK on success
* - \c RETURN_FAILED on failure
*/
ReturnValue_t setEntryFromBigEndian(const uint8_t* buffer,
uint32_t setSize);
/**
* \brief This operation returns the type of the entry currently stored.
*/
Type getType();
/**
* \brief This operation returns the size of the entry currently stored.
*/
uint8_t getSizeOfType();
/**
*
* @return the size of the datapool array
*/
uint8_t getArraySize();
/**
* \brief This operation returns the data pool id of the variable.
*/
uint32_t getDataPoolId() const;
/**
* This method returns if the variable is read-write or read-only.
*/
ReadWriteMode_t getReadWriteMode() const;
/**
* \brief With this call, the valid information of the variable is returned.
*/
bool isValid() const;
void setValid(uint8_t valid);
/**
* Getter for the remaining size.
*/
uint16_t getSizeTillEnd() const;
ReturnValue_t serialize(uint8_t** buffer, uint32_t* size,
const uint32_t max_size, bool bigEndian) const;
uint32_t getSerializedSize() const;
ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size,
bool bigEndian);
};
#endif /* POOLRAWACCESS_H_ */

View File

@ -0,0 +1,188 @@
/**
* @file PoolRawAccessHelper.cpp
*
* @date 22.12.2019
* @author R. Mueller
*/
#include "../datapool/PoolRawAccessHelper.h"
#include "../datapoolglob/GlobalDataSet.h"
#include "../serialize/SerializeAdapter.h"
#include "../serviceinterface/ServiceInterfaceStream.h"
#include <cmath>
#include <cstring>
PoolRawAccessHelper::PoolRawAccessHelper(uint32_t * poolIdBuffer_,
uint8_t numberOfParameters_):
poolIdBuffer(reinterpret_cast<uint8_t * >(poolIdBuffer_)),
numberOfParameters(numberOfParameters_), validBufferIndex(0),
validBufferIndexBit(1) {
}
PoolRawAccessHelper::~PoolRawAccessHelper() {
}
ReturnValue_t PoolRawAccessHelper::serialize(uint8_t **buffer, size_t *size,
const size_t max_size, SerializeIF::Endianness streamEndianness) {
SerializationArgs serializationArgs = {buffer, size, max_size,
streamEndianness};
ReturnValue_t result = RETURN_OK;
size_t remainingParametersSize = numberOfParameters * 4;
for(uint8_t count=0; count < numberOfParameters; count++) {
result = serializeCurrentPoolEntryIntoBuffer(serializationArgs,
&remainingParametersSize, false);
if(result != RETURN_OK) {
return result;
}
}
if(remainingParametersSize != 0) {
sif::debug << "PoolRawAccessHelper: "
"Remaining parameters size not 0 !" << std::endl;
result = RETURN_FAILED;
}
return result;
}
ReturnValue_t PoolRawAccessHelper::serializeWithValidityMask(uint8_t ** buffer,
size_t * size, const size_t max_size,
SerializeIF::Endianness streamEndianness) {
ReturnValue_t result = RETURN_OK;
SerializationArgs argStruct = {buffer, size, max_size, streamEndianness};
size_t remainingParametersSize = numberOfParameters * 4;
uint8_t validityMaskSize = ceil((float)numberOfParameters/8.0);
uint8_t validityMask[validityMaskSize];
memset(validityMask,0, validityMaskSize);
for(uint8_t count = 0; count < numberOfParameters; count++) {
result = serializeCurrentPoolEntryIntoBuffer(argStruct,
&remainingParametersSize,true,validityMask);
if (result != RETURN_OK) {
return result;
}
}
if(remainingParametersSize != 0) {
sif::debug << "PoolRawAccessHelper: Remaining "
"parameters size not 0 !" << std::endl;
result = RETURN_FAILED;
}
memcpy(*argStruct.buffer, validityMask, validityMaskSize);
*size += validityMaskSize;
validBufferIndex = 1;
validBufferIndexBit = 0;
return result;
}
ReturnValue_t PoolRawAccessHelper::serializeCurrentPoolEntryIntoBuffer(
SerializationArgs argStruct, size_t * remainingParameters,
bool withValidMask, uint8_t * validityMask) {
uint32_t currentPoolId;
// Deserialize current pool ID from pool ID buffer
ReturnValue_t result = SerializeAdapter::deSerialize(&currentPoolId,
&poolIdBuffer,remainingParameters, SerializeIF::Endianness::MACHINE);
if(result != RETURN_OK) {
sif::debug << std::hex << "PoolRawAccessHelper: Error deSeralizing "
"pool IDs" << std::dec << std::endl;
return result;
}
result = handlePoolEntrySerialization(currentPoolId, argStruct,
withValidMask, validityMask);
return result;
}
ReturnValue_t PoolRawAccessHelper::handlePoolEntrySerialization(
uint32_t currentPoolId,SerializationArgs argStruct, bool withValidMask,
uint8_t * validityMask) {
ReturnValue_t result = RETURN_FAILED;
uint8_t arrayPosition = 0;
uint8_t counter = 0;
bool poolEntrySerialized = false;
//debug << "Pool Raw Access Helper: Handling Pool ID: "
// << std::hex << currentPoolId << std::endl;
while(not poolEntrySerialized) {
if(counter > GlobDataSet::DATA_SET_MAX_SIZE) {
sif::error << "PoolRawAccessHelper: Config error, "
"max. number of possible data set variables exceeded"
<< std::endl;
return result;
}
counter ++;
GlobDataSet currentDataSet;
//debug << "Current array position: " << (int)arrayPosition << std::endl;
PoolRawAccess currentPoolRawAccess(currentPoolId, arrayPosition,
&currentDataSet, PoolVariableIF::VAR_READ);
result = currentDataSet.read();
if (result != RETURN_OK) {
sif::debug << std::hex << "PoolRawAccessHelper: Error reading raw "
"dataset with returncode 0x" << result << std::dec << std::endl;
return result;
}
result = checkRemainingSize(&currentPoolRawAccess, &poolEntrySerialized,
&arrayPosition);
if(result != RETURN_OK) {
sif::error << "Pool Raw Access Helper: Configuration Error at pool ID "
<< std::hex << currentPoolId
<< ". Size till end smaller than 0" << std::dec << std::endl;
return result;
}
// set valid mask bit if necessary
if(withValidMask) {
if(currentPoolRawAccess.isValid()) {
handleMaskModification(validityMask);
}
validBufferIndexBit ++;
}
result = currentDataSet.serialize(argStruct.buffer, argStruct.size,
argStruct.max_size, argStruct.streamEndianness);
if (result != RETURN_OK) {
sif::debug << "Pool Raw Access Helper: Error serializing pool data with "
"ID 0x" << std::hex << currentPoolId << " into send buffer "
"with return code " << result << std::dec << std::endl;
return result;
}
}
return result;
}
ReturnValue_t PoolRawAccessHelper::checkRemainingSize(PoolRawAccess*
currentPoolRawAccess, bool * isSerialized, uint8_t * arrayPosition) {
int8_t remainingSize = currentPoolRawAccess->getSizeTillEnd() -
currentPoolRawAccess->getSizeOfType();
if(remainingSize == 0) {
*isSerialized = true;
}
else if(remainingSize > 0) {
*arrayPosition += 1;
}
else {
return RETURN_FAILED;
}
return RETURN_OK;
}
void PoolRawAccessHelper::handleMaskModification(uint8_t * validityMask) {
validityMask[validBufferIndex] =
bitSetter(validityMask[validBufferIndex], validBufferIndexBit, true);
if(validBufferIndexBit == 8) {
validBufferIndex ++;
validBufferIndexBit = 1;
}
}
uint8_t PoolRawAccessHelper::bitSetter(uint8_t byte, uint8_t position,
bool value) {
if(position < 1 or position > 8) {
sif::debug << "Pool Raw Access: Bit setting invalid position" << std::endl;
return byte;
}
uint8_t shiftNumber = position + (6 - 2 * (position - 1));
byte |= 1UL << shiftNumber;
return byte;
}

View File

@ -0,0 +1,111 @@
/**
* @file PoolRawAccessHelper.h
*
* @date 22.12.2019
*/
#ifndef FRAMEWORK_DATAPOOL_POOLRAWACCESSHELPER_H_
#define FRAMEWORK_DATAPOOL_POOLRAWACCESSHELPER_H_
#include "../returnvalues/HasReturnvaluesIF.h"
#include "../datapoolglob/GlobalDataSet.h"
#include "../datapoolglob/PoolRawAccess.h"
/**
* @brief This helper function simplifies accessing data pool entries
* via PoolRawAccess
* @details Can be used for a Housekeeping Service
* like ECSS PUS Service 3 if the type of the datapool entries is unknown.
* The provided dataset can be serialized into a provided buffer automatically by
* providing a buffer of pool IDs
* @ingroup data_pool
*/
class PoolRawAccessHelper: public HasReturnvaluesIF {
public:
/**
* Call this constructor if a dataset needs to be serialized via
* Pool Raw Access
* @param dataSet_ This dataset will be used to perform thread-safe reading
* @param poolIdBuffer_ A buffer of uint32_t pool IDs
* @param numberOfParameters_ The number of parameters / pool IDs
*/
PoolRawAccessHelper(uint32_t * poolIdBuffer_, uint8_t numberOfParameters_);
virtual ~PoolRawAccessHelper();
/**
* Serialize the datapool entries derived from the pool ID buffer
* directly into a provided buffer
* @param [out] buffer
* @param [out] size Size of the serialized buffer
* @param max_size
* @param bigEndian
* @return @c RETURN_OK On success
* @c RETURN_FAILED on failure
*/
ReturnValue_t serialize(uint8_t ** buffer, size_t * size,
const size_t max_size, SerializeIF::Endianness streamEndianness);
/**
* Serializes data pool entries into provided buffer with the validity mask buffer
* at the end of the buffer. Every bit of the validity mask denotes
* the validity of a corresponding data pool entry from left to right.
* @param [out] buffer
* @param [out] size Size of the serialized buffer plus size
* of the validity mask
* @return @c RETURN_OK On success
* @c RETURN_FAILED on failure
*/
ReturnValue_t serializeWithValidityMask(uint8_t ** buffer, size_t * size,
const size_t max_size, SerializeIF::Endianness streamEndianness);
private:
// DataSet * dataSet;
const uint8_t * poolIdBuffer;
uint8_t numberOfParameters;
uint8_t validBufferIndex;
uint8_t validBufferIndexBit;
struct SerializationArgs {
uint8_t ** buffer;
size_t * size;
const size_t max_size;
SerializeIF::Endianness streamEndianness;
};
/**
* Helper function to serialize single pool entries
* @param pPoolIdBuffer
* @param buffer
* @param remainingParameters
* @param hkDataSize
* @param max_size
* @param bigEndian
* @param withValidMask Can be set optionally to set a
* provided validity mask
* @param validityMask Can be supplied and will be set if
* @c withValidMask is set to true
* @return
*/
ReturnValue_t serializeCurrentPoolEntryIntoBuffer(
SerializationArgs argStruct, size_t * remainingParameters,
bool withValidMask = false, uint8_t * validityMask = nullptr);
ReturnValue_t handlePoolEntrySerialization(uint32_t currentPoolId,
SerializationArgs argStruct, bool withValidMask = false,
uint8_t * validityMask = nullptr);
ReturnValue_t checkRemainingSize(PoolRawAccess * currentPoolRawAccess,
bool * isSerialized, uint8_t * arrayPosition);
void handleMaskModification(uint8_t * validityMask);
/**
* Sets specific bit of a byte
* @param byte
* @param position Position of byte to set from 1 to 8
* @param value Binary value to set
* @return
*/
uint8_t bitSetter(uint8_t byte, uint8_t position, bool value);
};
#endif /* FRAMEWORK_DATAPOOL_POOLRAWACCESSHELPER_H_ */

View File

@ -1,12 +1,12 @@
#ifndef POOLVARLIST_H_ #ifndef POOLVARLIST_H_
#define POOLVARLIST_H_ #define POOLVARLIST_H_
#include <framework/datapool/PoolVariable.h> #include "../datapool/PoolVariableIF.h"
#include <framework/datapool/PoolVariableIF.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:
PoolVariable<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.
@ -20,7 +20,7 @@ public:
} }
} }
PoolVariable<T> &operator [](int i) { return variables[i]; } GlobPoolVar<T> &operator [](int i) { return variables[i]; }
}; };

View File

@ -1,295 +0,0 @@
/*
* \file PoolVariable.h
*
* \brief This file contains the PoolVariable class, which locally represents a non-array data pool variable.
*
* \date 10/17/2012
*
* \author Bastian Baetz
*/
#ifndef POOLVARIABLE_H_
#define POOLVARIABLE_H_
#include <framework/datapool/DataSetIF.h>
#include <framework/datapool/PoolEntry.h>
#include <framework/datapool/PoolVariableIF.h>
#include <framework/serialize/SerializeAdapter.h>
#include <framework/serviceinterface/ServiceInterfaceStream.h>
template<typename T, uint8_t n_var> class PoolVarList;
/**
* \brief This is the access class for non-array data pool entries.
*
* \details 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-safe access to single
* data pool entries (i.e. entries with length = 1).
* The class can be instantiated as read-write and read only.
* It provides a commit-and-roll-back semantic, which means that the variable's value in
* the data pool is not changed until the commit call is executed.
* \tparam T The template parameter sets the type of the variable. Currently, all plain data types
* are supported, but in principle any type is possible.
* \ingroup data_pool
*/
template<typename T>
class PoolVariable: public PoolVariableIF {
template<typename U, uint8_t n_var> friend class PoolVarList;
protected:
/**
* \brief To access the correct data pool entry on read and commit calls, the data pool id
* is stored.
*/
uint32_t dataPoolId;
/**
* \brief The valid information as it was stored in the data pool is copied to this attribute.
*/
uint8_t valid;
/**
* \brief The information whether the class is read-write or read-only is stored here.
*/
ReadWriteMode_t readWriteMode;
/**
* \brief This is a call to read the value from the global data pool.
* \details 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
* 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.
* The operation does NOT provide any mutual exclusive protection by itself.
*/
ReturnValue_t read() {
PoolEntry<T>* read_out = ::dataPool.getData<T>(dataPoolId, 1);
if (read_out != NULL) {
valid = read_out->valid;
value = *(read_out->address);
return HasReturnvaluesIF::RETURN_OK;
} else {
value = 0;
valid = false;
sif::error << "PoolVariable: read of DP Variable 0x" << std::hex
<< dataPoolId << std::dec << " failed." << std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
}
/**
* \brief The commit call writes back the variable's value to the data pool.
* \details 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 operation does NOT provide any mutual exclusive protection by itself.
*
*/
ReturnValue_t commit() {
PoolEntry<T>* write_back = ::dataPool.getData<T>(dataPoolId, 1);
if ((write_back != NULL) && (readWriteMode != VAR_READ)) {
write_back->valid = valid;
*(write_back->address) = value;
return HasReturnvaluesIF::RETURN_OK;
} else {
return HasReturnvaluesIF::RETURN_FAILED;
}
}
/**
* Empty ctor for List initialization
*/
PoolVariable() :
dataPoolId(PoolVariableIF::NO_PARAMETER), valid(
PoolVariableIF::INVALID), readWriteMode(VAR_READ), value(0) {
}
public:
/**
* \brief This is the local copy of the data pool entry.
* \details The user can work on this attribute
* just like he would on a simple local variable.
*/
T value;
/**
* \brief In the constructor, the variable can register itself in a DataSet (if not NULL is
* passed).
* \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.
* \param set_id This is the id in the global data pool this instance of the access class
* corresponds to.
* \param dataSet The data set in which the variable shall register itself. If NULL,
* the variable is not registered.
* \param setWritable If this flag is set to true, changes in the value attribute can be
* written back to the data pool, otherwise not.
*/
PoolVariable(uint32_t set_id, DataSetIF* dataSet,
ReadWriteMode_t setReadWriteMode) :
dataPoolId(set_id), valid(PoolVariableIF::INVALID), readWriteMode(
setReadWriteMode), value(0) {
if (dataSet != NULL) {
dataSet->registerVariable(this);
}
}
/**
* Copy ctor to copy classes containing Pool Variables.
*/
PoolVariable(const PoolVariable& rhs) :
dataPoolId(rhs.dataPoolId), valid(rhs.valid), readWriteMode(
rhs.readWriteMode), value(rhs.value) {
}
/**
* \brief The classes destructor is empty.
* \details If commit() was not called, the local value is
* discarded and not written back to the data pool.
*/
~PoolVariable() {
}
/**
* \brief This operation returns the data pool id of the variable.
*/
uint32_t getDataPoolId() const {
return dataPoolId;
}
/**
* 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.
*/
void setDataPoolId(uint32_t poolId) {
dataPoolId = poolId;
}
/**
* This method returns if the variable is write-only, read-write or read-only.
*/
ReadWriteMode_t getReadWriteMode() const {
return readWriteMode;
}
/**
* \brief With this call, the valid information of the variable is returned.
*/
bool isValid() const {
if (valid)
return true;
else
return false;
}
uint8_t getValid() {
return valid;
}
void setValid(uint8_t valid) {
this->valid = valid;
}
operator T() {
return value;
}
operator T() const {
return value;
}
PoolVariable<T> &operator=(T newValue) {
value = newValue;
return *this;
}
PoolVariable<T> &operator=(PoolVariable<T> newPoolVariable) {
value = newPoolVariable.value;
return *this;
}
virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size,
const uint32_t max_size, bool bigEndian) const {
return SerializeAdapter<T>::serialize(&value, buffer, size, max_size,
bigEndian);
}
virtual uint32_t getSerializedSize() const {
return SerializeAdapter<T>::getSerializedSize(&value);
}
virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size,
bool bigEndian) {
return SerializeAdapter<T>::deSerialize(&value, buffer, size, bigEndian);
}
};
typedef PoolVariable<uint8_t> db_uint8_t;
typedef PoolVariable<uint16_t> db_uint16_t;
typedef PoolVariable<uint32_t> db_uint32_t;
typedef PoolVariable<int8_t> db_int8_t;
typedef PoolVariable<int16_t> db_int16_t;
typedef PoolVariable<int32_t> db_int32_t;
typedef PoolVariable<uint8_t> db_bool_t;
typedef PoolVariable<float> db_float_t;
typedef PoolVariable<double> db_double_t;
//Alternative (but I thing this is not as useful: code duplication, differences too small):
//template <typename T>
//class PoolReader : public PoolVariableIF {
//private:
// uint32_t parameter_id;
// uint8_t valid;
//public:
// T value;
// PoolReader( uint32_t set_id, DataSetIF* set ) : parameter_id(set_id), valid(false), value(0) {
// set->registerVariable( this );
// }
//
// ~PoolReader() {};
//
// uint8_t commit() {
// return HasReturnvaluesIF::RETURN_OK;
// }
//
// uint8_t read() {
// PoolEntry<T>* read_out = ::dataPool.getData<T>( parameter_id, 1 );
// if ( read_out != NULL ) {
// valid = read_out->valid;
// value = *(read_out->address);
// return HasReturnvaluesIF::RETURN_OK;
// } else {
// value = 0;
// valid = false;
// return CHECKOUT_FAILED;
// }
// }
// uint32_t getParameterId() { return parameter_id; }
// bool isWritable() { return false; };
// bool isValid() { if (valid) return true; else return false; }
//};
//
//template <typename T>
//class PoolWriter : public PoolVariableIF {
//private:
// uint32_t parameter_id;
//public:
// T value;
// PoolWriter( uint32_t set_id, DataSetIF* set ) : parameter_id(set_id), value(0) {
// set->registerVariable( this );
// }
//
// ~PoolWriter() {};
//
// uint8_t commit() {
// PoolEntry<T>* write_back = ::dataPool.getData<T>( parameter_id, 1 );
// if ( write_back != NULL ) {
// write_back->valid = true;
// *(write_back->address) = value;
// return HasReturnvaluesIF::RETURN_OK;
// } else {
// return CHECKOUT_FAILED;
// }
// }
// uint8_t read() {
// PoolEntry<T>* read_out = ::dataPool.getData<T>( parameter_id, 1 );
// if ( read_out != NULL ) {
// value = *(read_out->address);
// return HasReturnvaluesIF::RETURN_OK;
// } else {
// value = 0;
// return CHECKOUT_FAILED;
// }
// }
// uint32_t getParameterId() { return parameter_id; }
// bool isWritable() { return true; };
// bool isValid() { return false; }
//};
#endif /* POOLVARIABLE_H_ */

View File

@ -1,71 +1,99 @@
/* #ifndef FRAMEWORK_DATAPOOL_POOLVARIABLEIF_H_
* \file PoolVariableIF.h #define FRAMEWORK_DATAPOOL_POOLVARIABLEIF_H_
*
* \brief This file contains the interface definition for pool variables.
*
* \date 10/17/2012
*
* \author Bastian Baetz
*/
#ifndef POOLVARIABLEIF_H_ #include "../returnvalues/HasReturnvaluesIF.h"
#define POOLVARIABLEIF_H_ #include "../serialize/SerializeIF.h"
#include <framework/returnvalues/HasReturnvaluesIF.h>
#include <framework/serialize/SerializeIF.h>
/** /**
* \brief This interface is used to control local data pool variable representations. * @brief This interface is used to control data pool
* * variable representations.
* \details To securely handle data pool variables, all pool entries are locally managed by * @details
* data pool variable access classes, which are called pool variables. To ensure a * To securely handle data pool variables, all pool entries are locally
* common state of a set of variables needed in a function, these local pool variables * managed by data pool variable access classes, which are called pool
* again are managed by other classes, e.g. the DataSet. This interface provides unified * variables. To ensure a common state of a set of variables needed in a
* access to local pool variables for such manager classes. * function, these local pool variables again are managed by other classes,
* \ingroup data_pool * like the DataSet classes. This interface provides unified access to
* local pool variables for such manager classes.
* @author Bastian Baetz
* @ingroup data_pool
*/ */
class PoolVariableIF : public SerializeIF { class PoolVariableIF : public SerializeIF {
friend class DataSet; friend class PoolDataSetBase;
protected: friend class GlobDataSet;
/** friend class LocalPoolDataSetBase;
* \brief The commit call shall write back a newly calculated local value to the data pool.
*/
virtual ReturnValue_t commit() = 0;
/**
* \brief The read call shall read the value of this parameter from the data pool and store
* the content locally.
*/
virtual ReturnValue_t read() = 0;
public: public:
static const uint8_t VALID = 1; static constexpr uint8_t INTERFACE_ID = CLASS_ID::POOL_VARIABLE_IF;
static const uint8_t INVALID = 0; static constexpr ReturnValue_t INVALID_READ_WRITE_MODE = MAKE_RETURN_CODE(0xA0);
static const uint32_t NO_PARAMETER = 0;
static constexpr bool VALID = 1;
static constexpr bool INVALID = 0;
static constexpr uint32_t NO_PARAMETER = 0xffffffff;
enum ReadWriteMode_t { enum ReadWriteMode_t {
VAR_READ, VAR_WRITE, VAR_READ_WRITE VAR_READ, VAR_WRITE, VAR_READ_WRITE
}; };
/** /**
* \brief This is an empty virtual destructor, as it is proposed for C++ interfaces. * @brief This is an empty virtual destructor,
* as it is proposed for C++ interfaces.
*/ */
virtual ~PoolVariableIF() { virtual ~PoolVariableIF() {}
}
/** /**
* \brief This method returns if the variable is write-only, read-write or read-only. * @brief This method returns if the variable is write-only,
* read-write or read-only.
*/ */
virtual ReadWriteMode_t getReadWriteMode() const = 0; virtual ReadWriteMode_t getReadWriteMode() const = 0;
/** /**
* \brief This operation shall return the data pool id of the variable. * @brief This operation shall return the data pool id of the variable.
*/ */
virtual uint32_t getDataPoolId() const = 0; virtual uint32_t getDataPoolId() const = 0;
/** /**
* \brief With this call, the valid information of the variable is returned. * @brief With this call, the valid information of the
* variable is returned.
*/ */
virtual bool isValid() const = 0; virtual bool isValid() const = 0;
/** /**
* \brief With this call, the valid information of the variable is set. * @brief With this call, the valid information of the variable is set.
*/ */
virtual void setValid(uint8_t validity) = 0; virtual void setValid(bool validity) = 0;
/**
* @brief The commit call shall write back a newly calculated local
* value to the data pool.
* @details
* It is assumed that these calls are implemented in a thread-safe manner!
*/
virtual ReturnValue_t commit(uint32_t lockTimeout) = 0;
/**
* @brief The read call shall read the value of this parameter from
* the data pool and store the content locally.
* @details
* It is assumbed that these calls are implemented in a thread-safe manner!
*/
virtual ReturnValue_t read(uint32_t lockTimeout) = 0;
protected:
/**
* @brief Same as commit with the difference that comitting will be
* performed without a lock
* @return
* This can be used if the lock protection is handled externally
* to avoid the overhead of locking and unlocking consecutively.
* Declared protected to avoid free public usage.
*/
virtual ReturnValue_t readWithoutLock() = 0;
/**
* @brief Same as commit with the difference that comitting will be
* performed without a lock
* @return
* This can be used if the lock protection is handled externally
* to avoid the overhead of locking and unlocking consecutively.
* Declared protected to avoid free public usage.
*/
virtual ReturnValue_t commitWithoutLock() = 0;
}; };
using pool_rwm_t = PoolVariableIF::ReadWriteMode_t;
#endif /* POOLVARIABLEIF_H_ */ #endif /* POOLVARIABLEIF_H_ */

View File

@ -1,233 +0,0 @@
/*
* \file PoolVector.h
*
* \brief This file contains the PoolVector class, the header only class to handle data pool vectors.
*
* \date 10/23/2012
*
* \author Bastian Baetz
*/
#ifndef POOLVECTOR_H_
#define POOLVECTOR_H_
#include <framework/datapool/DataSetIF.h>
#include <framework/datapool/PoolEntry.h>
#include <framework/datapool/PoolVariableIF.h>
#include <framework/serialize/SerializeAdapter.h>
#include <framework/serviceinterface/ServiceInterfaceStream.h>
/**
* \brief This is the access class for array-type data pool entries.
*
* \details 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- 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.
* 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.
* There are two template parameters:
* \tparam T 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.
* \tparam vector_size This template parameter specifies the vector size of this entry.
* Using a template parameter for this is not perfect, but avoids dynamic memory allocation.
* \ingroup data_pool
*/
template<typename T, uint16_t vector_size>
class PoolVector: public PoolVariableIF {
private:
/**
* \brief To access the correct data pool entry on read and commit calls, the data pool id
* is stored.
*/
uint32_t dataPoolId;
/**
* \brief The valid information as it was stored in the data pool is copied to this attribute.
*/
uint8_t valid;
/**
* \brief The information whether the class is read-write or read-only is stored here.
*/
ReadWriteMode_t readWriteMode;
protected:
/**
* \brief This is a call to read the array's values from the global data pool.
* \details 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 and the valid
* information to its local attributes. In case of a failure (wrong type, size or
* pool id not found), the variable is set to zero and invalid.
* The operation does NOT provide any mutual exclusive protection by itself.
*/
ReturnValue_t read() {
PoolEntry<T>* read_out = ::dataPool.getData<T>(this->dataPoolId,
vector_size);
if (read_out != NULL) {
this->valid = read_out->valid;
memcpy(this->value, read_out->address, read_out->getByteSize());
return HasReturnvaluesIF::RETURN_OK;
} else {
memset(this->value, 0, vector_size * sizeof(T));
sif::error << "PoolVector: read of DP Variable 0x" << std::hex
<< dataPoolId << std::dec << " failed." << std::endl;
this->valid = INVALID;
return HasReturnvaluesIF::RETURN_FAILED;
}
}
/**
* \brief The commit call copies the array values back to the data pool.
* \details 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 operation does NOT provide any mutual exclusive protection by itself.
*
*/
ReturnValue_t commit() {
PoolEntry<T>* write_back = ::dataPool.getData<T>(this->dataPoolId,
vector_size);
if ((write_back != NULL) && (this->readWriteMode != VAR_READ)) {
write_back->valid = valid;
memcpy(write_back->address, this->value, write_back->getByteSize());
return HasReturnvaluesIF::RETURN_OK;
} else {
return HasReturnvaluesIF::RETURN_FAILED;
}
}
public:
/**
* \brief This is the local copy of the data pool entry.
* \detials The user can work on this attribute
* just like he would on a local array of this type.
*/
T value[vector_size];
/**
* \brief In the constructor, the variable can register itself in a DataSet (if not NULL is
* passed).
* \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.
* \param set_id This is the id in the global data pool this instance of the access class
* corresponds to.
* \param dataSet The data set in which the variable shall register itself. If NULL,
* the variable is not registered.
* \param setWritable If this flag is set to true, changes in the value attribute can be
* written back to the data pool, otherwise not.
*/
PoolVector(uint32_t set_id, DataSetIF* set,
ReadWriteMode_t setReadWriteMode) :
dataPoolId(set_id), valid(false), readWriteMode(setReadWriteMode) {
memset(this->value, 0, vector_size * sizeof(T));
if (set != NULL) {
set->registerVariable(this);
}
}
/**
* Copy ctor to copy classes containing Pool Variables.
*/
// PoolVector(const PoolVector& rhs) {
// PoolVector<T, vector_size> temp(rhs.dataPoolId, rhs.)
// memcpy(value, rhs.value, sizeof(T)*vector_size);
// }
/**
* \brief The classes destructor is empty.
* \details If commit() was not called, the local value is
* discarded and not written back to the data pool.
*/
~PoolVector() {
}
;
/**
* \brief The operation returns the number of array entries in this variable.
*/
uint8_t getSize() {
return vector_size;
}
/**
* \brief This operation returns the data pool id of the variable.
*/
uint32_t getDataPoolId() const {
return dataPoolId;
}
/**
* 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.
*/
void setDataPoolId(uint32_t poolId) {
dataPoolId = poolId;
}
/**
* This method returns if the variable is write-only, read-write or read-only.
*/
ReadWriteMode_t getReadWriteMode() const {
return readWriteMode;
}
;
/**
* \brief With this call, the valid information of the variable is returned.
*/
bool isValid() const {
if (valid != INVALID)
return true;
else
return false;
}
void setValid(uint8_t valid) {
this->valid = valid;
}
uint8_t getValid() {
return valid;
}
T &operator [](int i) {
return value[i];
}
const T &operator [](int i) const {
return value[i];
}
PoolVector<T, vector_size> &operator=(
PoolVector<T, vector_size> newPoolVector) {
for (uint16_t i = 0; i < vector_size; i++) {
this->value[i] = newPoolVector.value[i];
}
return *this;
}
virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size,
const uint32_t max_size, bool bigEndian) const {
uint16_t i;
ReturnValue_t result;
for (i = 0; i < vector_size; i++) {
result = SerializeAdapter<T>::serialize(&(value[i]), buffer, size,
max_size, bigEndian);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
}
return result;
}
virtual uint32_t getSerializedSize() const {
return vector_size * SerializeAdapter<T>::getSerializedSize(value);
}
virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size,
bool bigEndian) {
uint16_t i;
ReturnValue_t result;
for (i = 0; i < vector_size; i++) {
result = SerializeAdapter<T>::deSerialize(&(value[i]), buffer, size,
bigEndian);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
}
return result;
}
};
#endif /* POOLVECTOR_H_ */

View File

@ -0,0 +1,14 @@
#ifndef FRAMEWORK_DATAPOOL_SHAREDDATASETIF_H_
#define FRAMEWORK_DATAPOOL_SHAREDDATASETIF_H_
#include "PoolDataSetIF.h"
class SharedDataSetIF: public PoolDataSetIF {
public:
virtual ~SharedDataSetIF() {};
private:
virtual ReturnValue_t lockDataset(dur_millis_t mutexTimeout) = 0;
virtual ReturnValue_t unlockDataset() = 0;
};
#endif /* FRAMEWORK_DATAPOOL_SHAREDDATASETIF_H_ */

View File

@ -1,10 +1,10 @@
#include <framework/datapool/DataPool.h> #include "../datapoolglob/DataPoolAdmin.h"
#include <framework/datapool/DataPoolAdmin.h> #include "../datapoolglob/GlobalDataSet.h"
#include <framework/datapool/DataSet.h> #include "../datapoolglob/GlobalDataPool.h"
#include <framework/datapool/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(
@ -26,7 +26,7 @@ MessageQueueId_t DataPoolAdmin::getCommandQueue() const {
} }
ReturnValue_t DataPoolAdmin::executeAction(ActionId_t actionId, ReturnValue_t DataPoolAdmin::executeAction(ActionId_t actionId,
MessageQueueId_t commandedBy, const uint8_t* data, uint32_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;
} }
@ -40,9 +40,9 @@ ReturnValue_t DataPoolAdmin::executeAction(ActionId_t actionId,
uint8_t valid = data[4]; uint8_t valid = data[4];
uint32_t poolId = ::dataPool.PIDToDataPoolId(address); uint32_t poolId = glob::dataPool.PIDToDataPoolId(address);
DataSet 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) {
@ -91,10 +91,10 @@ void DataPoolAdmin::handleCommand() {
} }
ReturnValue_t DataPoolAdmin::handleMemoryLoad(uint32_t address, ReturnValue_t DataPoolAdmin::handleMemoryLoad(uint32_t address,
const uint8_t* data, uint32_t size, uint8_t** dataPointer) { const uint8_t* data, size_t size, uint8_t** dataPointer) {
uint32_t poolId = ::dataPool.PIDToDataPoolId(address); uint32_t poolId = glob::dataPool.PIDToDataPoolId(address);
uint8_t arrayIndex = ::dataPool.PIDToArrayIndex(address); uint8_t arrayIndex = glob::dataPool.PIDToArrayIndex(address);
DataSet 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();
@ -113,7 +113,7 @@ ReturnValue_t DataPoolAdmin::handleMemoryLoad(uint32_t address,
const uint8_t* readPosition = data; const uint8_t* readPosition = data;
for (; size > 0; size -= typeSize) { for (; size > 0; size -= typeSize) {
DataSet 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();
@ -129,11 +129,11 @@ ReturnValue_t DataPoolAdmin::handleMemoryLoad(uint32_t address,
return ACTIVITY_COMPLETED; return ACTIVITY_COMPLETED;
} }
ReturnValue_t DataPoolAdmin::handleMemoryDump(uint32_t address, uint32_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 = ::dataPool.PIDToDataPoolId(address); uint32_t poolId = glob::dataPool.PIDToDataPoolId(address);
uint8_t arrayIndex = ::dataPool.PIDToArrayIndex(address); uint8_t arrayIndex = glob::dataPool.PIDToArrayIndex(address);
DataSet 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();
@ -146,12 +146,12 @@ ReturnValue_t DataPoolAdmin::handleMemoryDump(uint32_t address, uint32_t size,
} }
uint8_t* ptrToCopy = copyHere; uint8_t* ptrToCopy = copyHere;
for (; size > 0; size -= typeSize) { for (; size > 0; size -= typeSize) {
DataSet 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) {
uint32_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;
@ -261,7 +261,7 @@ ReturnValue_t DataPoolAdmin::handleParameterCommand(CommandMessage* command) {
//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) {
uint32_t serializedSize = wrapper->getSerializedSize(); size_t serializedSize = wrapper->getSerializedSize();
uint8_t *storeElement; uint8_t *storeElement;
store_address_t address; store_address_t address;
@ -272,10 +272,10 @@ ReturnValue_t DataPoolAdmin::sendParameter(MessageQueueId_t to, uint32_t id,
return result; return result;
} }
uint32_t storeElementSize = 0; size_t storeElementSize = 0;
result = wrapper->serialize(&storeElement, &storeElementSize, result = wrapper->serialize(&storeElement, &storeElementSize,
serializedSize, true); serializedSize, SerializeIF::Endianness::BIG);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
storage->deleteData(address); storage->deleteData(address);

View File

@ -1,15 +1,16 @@
#ifndef DATAPOOLADMIN_H_ #ifndef DATAPOOLADMIN_H_
#define DATAPOOLADMIN_H_ #define DATAPOOLADMIN_H_
#include <framework/memory/MemoryHelper.h> #include "../objectmanager/SystemObject.h"
#include <framework/action/HasActionsIF.h> #include "../returnvalues/HasReturnvaluesIF.h"
#include <framework/action/SimpleActionHelper.h> #include "../tasks/ExecutableObjectIF.h"
#include <framework/objectmanager/SystemObject.h> #include "../action/HasActionsIF.h"
#include <framework/returnvalues/HasReturnvaluesIF.h> #include "../ipc/MessageQueueIF.h"
#include <framework/tasks/ExecutableObjectIF.h> #include "../parameters/ReceivesParameterMessagesIF.h"
#include <framework/parameters/ReceivesParameterMessagesIF.h>
#include <framework/datapool/DataPoolParameterWrapper.h> #include "../memory/MemoryHelper.h"
#include <framework/ipc/MessageQueueIF.h> #include "../action/SimpleActionHelper.h"
#include "../datapoolglob/DataPoolParameterWrapper.h"
class DataPoolAdmin: public HasActionsIF, class DataPoolAdmin: public HasActionsIF,
public ExecutableObjectIF, public ExecutableObjectIF,
@ -29,12 +30,12 @@ public:
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,
uint32_t size, uint8_t** dataPointer); size_t size, uint8_t** dataPointer);
ReturnValue_t handleMemoryDump(uint32_t address, uint32_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, uint32_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,

View File

@ -1,10 +1,8 @@
#include "DataPoolParameterWrapper.h" #include "../datapoolglob/GlobalDataSet.h"
#include "../datapoolglob/DataPoolParameterWrapper.h"
#include "../datapoolglob/PoolRawAccess.h"
#include "../parameters/HasParametersIF.h"
//for returncodes
#include <framework/parameters/HasParametersIF.h>
#include <framework/datapool/DataSet.h>
#include <framework/datapool/PoolRawAccess.h>
DataPoolParameterWrapper::DataPoolParameterWrapper() : DataPoolParameterWrapper::DataPoolParameterWrapper() :
type(Type::UNKNOWN_TYPE), rows(0), columns(0), poolId( type(Type::UNKNOWN_TYPE), rows(0), columns(0), poolId(
@ -20,7 +18,7 @@ ReturnValue_t DataPoolParameterWrapper::set(uint8_t domainId,
uint16_t parameterId) { uint16_t parameterId) {
poolId = (domainId << 16) + parameterId; poolId = (domainId << 16) + parameterId;
DataSet 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) {
@ -36,31 +34,31 @@ ReturnValue_t DataPoolParameterWrapper::set(uint8_t domainId,
} }
ReturnValue_t DataPoolParameterWrapper::serialize(uint8_t** buffer, ReturnValue_t DataPoolParameterWrapper::serialize(uint8_t** buffer,
uint32_t* size, const uint32_t max_size, bool bigEndian) const { size_t* size, size_t maxSize, Endianness streamEndianness) const {
ReturnValue_t result; ReturnValue_t result;
result = SerializeAdapter<Type>::serialize(&type, buffer, size, max_size, result = SerializeAdapter::serialize(&type, buffer, size, maxSize,
bigEndian); streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
result = SerializeAdapter<uint8_t>::serialize(&columns, buffer, size, result = SerializeAdapter::serialize(&columns, buffer, size,
max_size, bigEndian); maxSize, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
result = SerializeAdapter<uint8_t>::serialize(&rows, buffer, size, max_size, result = SerializeAdapter::serialize(&rows, buffer, size, maxSize,
bigEndian); 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++){
DataSet 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,max_size,bigEndian); result = raw.serialize(buffer,size,maxSize,streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK){ if (result != HasReturnvaluesIF::RETURN_OK){
return result; return result;
} }
@ -69,8 +67,8 @@ ReturnValue_t DataPoolParameterWrapper::serialize(uint8_t** buffer,
} }
//same as ParameterWrapper //same as ParameterWrapper
uint32_t DataPoolParameterWrapper::getSerializedSize() const { size_t DataPoolParameterWrapper::getSerializedSize() const {
uint32_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);
@ -80,7 +78,7 @@ uint32_t DataPoolParameterWrapper::getSerializedSize() const {
} }
ReturnValue_t DataPoolParameterWrapper::deSerialize(const uint8_t** buffer, ReturnValue_t DataPoolParameterWrapper::deSerialize(const uint8_t** buffer,
int32_t* size, bool bigEndian) { size_t* size, Endianness streamEndianness) {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
@ -94,7 +92,7 @@ ReturnValue_t DataPoolParameterWrapper::deSerializeData(uint8_t startingRow,
for (uint8_t fromRow = 0; fromRow < fromRows; fromRow++) { for (uint8_t fromRow = 0; fromRow < fromRows; fromRow++) {
DataSet 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();

View File

@ -1,8 +1,8 @@
#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:
@ -11,13 +11,13 @@ public:
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, uint32_t* size, virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
const uint32_t max_size, bool bigEndian) const; size_t maxSize, Endianness streamEndianness) const override;
virtual uint32_t getSerializedSize() const; virtual size_t getSerializedSize() const override;
virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
bool bigEndian); Endianness streamEndianness) override;
ReturnValue_t copyFrom(const ParameterWrapper *from, ReturnValue_t copyFrom(const ParameterWrapper *from,
uint16_t startWritingAtIndex); uint16_t startWritingAtIndex);

View File

@ -0,0 +1,133 @@
#include "../datapoolglob/GlobalDataPool.h"
#include "../serviceinterface/ServiceInterfaceStream.h"
#include "../ipc/MutexFactory.h"
GlobalDataPool::GlobalDataPool(
void(*initFunction)(GlobPoolMap* pool_map)) {
mutex = MutexFactory::instance()->createMutex();
if (initFunction != NULL ) {
initFunction( &this->globDataPool );
}
}
GlobalDataPool::~GlobalDataPool() {
MutexFactory::instance()->deleteMutex(mutex);
for(GlobPoolMapIter it = this->globDataPool.begin();
it != this->globDataPool.end(); ++it )
{
delete it->second;
}
}
// 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.
template <typename T> PoolEntry<T>* GlobalDataPool::getData( uint32_t data_pool_id,
uint8_t sizeOrPosition ) {
GlobPoolMapIter it = this->globDataPool.find( data_pool_id );
if ( it != this->globDataPool.end() ) {
PoolEntry<T>* entry = dynamic_cast< PoolEntry<T>* >( it->second );
if (entry != nullptr ) {
if ( sizeOrPosition <= entry->length ) {
return entry;
}
}
}
return nullptr;
}
PoolEntryIF* GlobalDataPool::getRawData( uint32_t data_pool_id ) {
GlobPoolMapIter it = this->globDataPool.find( data_pool_id );
if ( it != this->globDataPool.end() ) {
return it->second;
} else {
return nullptr;
}
}
ReturnValue_t GlobalDataPool::unlockDataPool() {
ReturnValue_t status = mutex->unlockMutex();
if(status != RETURN_OK) {
sif::error << "DataPool::DataPool: unlock of mutex failed with"
" error code: " << status << std::endl;
}
return status;
}
ReturnValue_t GlobalDataPool::lockDataPool(uint32_t timeoutMs) {
ReturnValue_t status = mutex->lockMutex(MutexIF::TimeoutType::WAITING,
timeoutMs);
if(status != RETURN_OK) {
sif::error << "DataPool::DataPool: lock of mutex failed "
"with error code: " << status << std::endl;
}
return status;
}
void GlobalDataPool::print() {
sif::debug << "DataPool contains: " << std::endl;
std::map<uint32_t, PoolEntryIF*>::iterator dataPoolIt;
dataPoolIt = this->globDataPool.begin();
while( dataPoolIt != this->globDataPool.end() ) {
sif::debug << std::hex << dataPoolIt->first << std::dec << " |";
dataPoolIt->second->print();
dataPoolIt++;
}
}
uint32_t GlobalDataPool::PIDToDataPoolId(uint32_t parameter_id) {
return (parameter_id >> 8) & 0x00FFFFFF;
}
uint8_t GlobalDataPool::PIDToArrayIndex(uint32_t parameter_id) {
return (parameter_id & 0x000000FF);
}
uint32_t GlobalDataPool::poolIdAndPositionToPid(uint32_t poolId, uint8_t index) {
return (poolId << 8) + index;
}
//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.
//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) {
GlobPoolMapIter it = this->globDataPool.find( PIDToDataPoolId(parameter_id));
if ( it != this->globDataPool.end() ) {
*type = it->second->getType();
return RETURN_OK;
} else {
*type = Type::UNKNOWN_TYPE;
return RETURN_FAILED;
}
}
bool GlobalDataPool::exists(uint32_t parameterId) {
uint32_t poolId = PIDToDataPoolId(parameterId);
uint32_t index = PIDToArrayIndex(parameterId);
GlobPoolMapIter it = this->globDataPool.find( poolId );
if (it != globDataPool.end()) {
if (it->second->getSize() >= index) {
return true;
}
}
return false;
}
template PoolEntry<uint8_t>* GlobalDataPool::getData<uint8_t>(
uint32_t data_pool_id, uint8_t size );
template PoolEntry<uint16_t>* GlobalDataPool::getData<uint16_t>(
uint32_t data_pool_id, uint8_t size );
template PoolEntry<uint32_t>* GlobalDataPool::getData<uint32_t>(
uint32_t data_pool_id, uint8_t size );
template PoolEntry<uint64_t>* GlobalDataPool::getData<uint64_t>(
uint32_t data_pool_id, uint8_t size);
template PoolEntry<int8_t>* GlobalDataPool::getData<int8_t>(
uint32_t data_pool_id, uint8_t size );
template PoolEntry<int16_t>* GlobalDataPool::getData<int16_t>(
uint32_t data_pool_id, uint8_t size );
template PoolEntry<int32_t>* GlobalDataPool::getData<int32_t>(
uint32_t data_pool_id, uint8_t size );
template PoolEntry<float>* GlobalDataPool::getData<float>(
uint32_t data_pool_id, uint8_t size );
template PoolEntry<double>* GlobalDataPool::getData<double>(
uint32_t data_pool_id, uint8_t size);

View File

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

View File

@ -0,0 +1,48 @@
#include "../datapoolglob/GlobalDataPool.h"
#include "../datapoolglob/GlobalDataSet.h"
#include "../serviceinterface/ServiceInterfaceStream.h"
GlobDataSet::GlobDataSet(): PoolDataSetBase(
reinterpret_cast<PoolVariableIF**>(&registeredVariables),
DATA_SET_MAX_SIZE) {}
// Don't do anything with your variables, they are dead already!
// (Destructor is already called)
GlobDataSet::~GlobDataSet() {}
ReturnValue_t GlobDataSet::commit(bool valid, uint32_t lockTimeout) {
setEntriesValid(valid);
setSetValid(valid);
return commit(lockTimeout);
}
ReturnValue_t GlobDataSet::commit(uint32_t lockTimeout) {
return PoolDataSetBase::commit(lockTimeout);
}
bool GlobDataSet::isValid() const {
return this->valid;
}
ReturnValue_t GlobDataSet::unlockDataPool() {
return glob::dataPool.unlockDataPool();
}
ReturnValue_t GlobDataSet::lockDataPool(uint32_t timeoutMs) {
return glob::dataPool.lockDataPool(timeoutMs);
}
void GlobDataSet::setEntriesValid(bool valid) {
for (uint16_t count = 0; count < fillCount; count++) {
if (registeredVariables[count]->getReadWriteMode()
!= PoolVariableIF::VAR_READ) {
registeredVariables[count]->setValid(valid);
}
}
}
void GlobDataSet::setSetValid(bool valid) {
this->valid = valid;
}

View File

@ -0,0 +1,98 @@
#ifndef FRAMEWORK_DATAPOOLGLOB_DATASET_H_
#define FRAMEWORK_DATAPOOLGLOB_DATASET_H_
#include "../datapool/PoolDataSetBase.h"
/**
* @brief The DataSet class manages a set of locally checked out variables
* for the global data pool.
* @details
* This class uses the read-commit() semantic provided by the DataSetBase class.
* It extends the base class by using the global data pool,
* having a valid state and implementing lock und unlock calls for the global
* datapool.
*
* For more information on how this class works, see the DataSetBase
* documentation.
* @author Bastian Baetz
* @ingroup data_pool
*/
class GlobDataSet: public PoolDataSetBase {
public:
/**
* @brief Creates an empty GlobDataSet. Use registerVariable or
* supply a pointer to this dataset to PoolVariable
* initializations to register pool variables.
*/
GlobDataSet();
/**
* @brief The destructor automatically manages writing the valid
* information of variables.
* @details
* In case the data set was read out, but not committed(indicated by state),
* the destructor parses all variables that are still registered to the set.
* For each, the valid flag in the data pool is set to "invalid".
*/
~GlobDataSet();
/**
* Variant of method above which sets validity of all elements of the set.
* @param valid Validity information from PoolVariableIF.
* @return - @c RETURN_OK if all variables were read successfully.
* - @c COMMITING_WITHOUT_READING if set was not read yet and
* contains non write-only variables
*/
ReturnValue_t commit(bool valid, uint32_t lockTimeout = MutexIF::BLOCKING);
ReturnValue_t commit(uint32_t lockTimeout = MutexIF::BLOCKING) override;
/**
* Set all entries
* @param valid
*/
void setSetValid(bool valid);
bool isValid() const override;
/**
* Set the valid information of all variables contained in the set which
* are not read-only
*
* @param valid Validity information from PoolVariableIF.
*/
void setEntriesValid(bool valid);
//!< This definition sets the maximum number of variables to
//! register in one DataSet.
static const uint8_t DATA_SET_MAX_SIZE = 63;
private:
/**
* If the valid state of a dataset is always relevant to the whole
* data set we can use this flag.
*/
bool valid = false;
/**
* @brief This is a small helper function to facilitate locking
* the global data pool.
* @details
* It makes use of the lockDataPool method offered by the DataPool class.
*/
ReturnValue_t lockDataPool(uint32_t timeoutMs) override;
/**
* @brief This is a small helper function to facilitate
* unlocking the global data pool
* @details
* It makes use of the freeDataPoolLock method offered by the DataPool class.
*/
ReturnValue_t unlockDataPool() override;
void handleAlreadyReadDatasetCommit();
ReturnValue_t handleUnreadDatasetCommit();
PoolVariableIF* registeredVariables[DATA_SET_MAX_SIZE];
};
#endif /* FRAMEWORK_DATAPOOLGLOB_DATASET_H_ */

View File

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

View File

@ -0,0 +1,117 @@
#ifndef GLOBALPOOLVARIABLE_TPP_
#define GLOBALPOOLVARIABLE_TPP_
template <class T>
inline GlobPoolVar<T>::GlobPoolVar(uint32_t set_id,
DataSetIF* dataSet, ReadWriteMode_t setReadWriteMode):
dataPoolId(set_id), valid(PoolVariableIF::INVALID),
readWriteMode(setReadWriteMode)
{
if (dataSet != nullptr) {
dataSet->registerVariable(this);
}
}
template<typename T>
inline ReturnValue_t GlobPoolVar<T>::read(uint32_t lockTimeout) {
ReturnValue_t result = glob::dataPool.lockDataPool(lockTimeout);
if(result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = readWithoutLock();
ReturnValue_t unlockResult = glob::dataPool.unlockDataPool();
if(unlockResult != HasReturnvaluesIF::RETURN_OK) {
sif::error << "GlobPoolVar::read: Could not unlock global data pool"
<< std::endl;
}
return result;
}
template<typename T>
inline ReturnValue_t GlobPoolVar<T>::commit(uint32_t lockTimeout) {
ReturnValue_t result = glob::dataPool.lockDataPool(lockTimeout);
if(result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = commitWithoutLock();
ReturnValue_t unlockResult = glob::dataPool.unlockDataPool();
if(unlockResult != HasReturnvaluesIF::RETURN_OK) {
sif::error << "GlobPoolVar::read: Could not unlock global data pool"
<< std::endl;
}
return result;
}
template <class T>
inline ReturnValue_t GlobPoolVar<T>::readWithoutLock() {
PoolEntry<T>* read_out = glob::dataPool.getData<T>(dataPoolId, 1);
if (read_out != NULL) {
valid = read_out->valid;
value = *(read_out->address);
return HasReturnvaluesIF::RETURN_OK;
} else {
value = 0;
valid = false;
sif::error << "PoolVariable: read of DP Variable 0x" << std::hex
<< dataPoolId << std::dec << " failed." << std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
}
template <class T>
inline ReturnValue_t GlobPoolVar<T>::commitWithoutLock() {
PoolEntry<T>* write_back = glob::dataPool.getData<T>(dataPoolId, 1);
if ((write_back != NULL) && (readWriteMode != VAR_READ)) {
write_back->valid = valid;
*(write_back->address) = value;
return HasReturnvaluesIF::RETURN_OK;
} else {
return HasReturnvaluesIF::RETURN_FAILED;
}
}
template <class T>
inline GlobPoolVar<T>::GlobPoolVar():
dataPoolId(PoolVariableIF::NO_PARAMETER),
valid(PoolVariableIF::INVALID),
readWriteMode(VAR_READ), value(0) {}
template <class T>
inline GlobPoolVar<T>::GlobPoolVar(const GlobPoolVar& rhs) :
dataPoolId(rhs.dataPoolId), valid(rhs.valid), readWriteMode(
rhs.readWriteMode), value(rhs.value) {}
template <class T>
inline pool_rwm_t GlobPoolVar<T>::getReadWriteMode() const {
return readWriteMode;
}
template <class T>
inline uint32_t GlobPoolVar<T>::getDataPoolId() const {
return dataPoolId;
}
template <class T>
inline void GlobPoolVar<T>::setDataPoolId(uint32_t poolId) {
dataPoolId = poolId;
}
template <class T>
inline bool GlobPoolVar<T>::isValid() const {
if (valid)
return true;
else
return false;
}
template <class T>
inline uint8_t GlobPoolVar<T>::getValid() {
return valid;
}
template <class T>
inline void GlobPoolVar<T>::setValid(bool valid) {
this->valid = valid;
}
#endif

View File

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

View File

@ -0,0 +1,117 @@
#ifndef GLOBALPOOLVECTOR_TPP_
#define GLOBALPOOLVECTOR_TPP_
template<typename T, uint16_t vectorSize>
inline GlobPoolVector<T, vectorSize>::GlobPoolVector(uint32_t set_id,
DataSetIF* set, ReadWriteMode_t setReadWriteMode) :
dataPoolId(set_id), valid(false), readWriteMode(setReadWriteMode) {
memset(this->value, 0, vectorSize * sizeof(T));
if (set != nullptr) {
set->registerVariable(this);
}
}
template<typename T, uint16_t vectorSize>
inline ReturnValue_t GlobPoolVector<T, vectorSize>::read(uint32_t lockTimeout) {
ReturnValue_t result = glob::dataPool.lockDataPool(lockTimeout);
if(result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = readWithoutLock();
ReturnValue_t unlockResult = glob::dataPool.unlockDataPool();
if(unlockResult != HasReturnvaluesIF::RETURN_OK) {
sif::error << "GlobPoolVar::read: Could not unlock global data pool"
<< std::endl;
}
return result;
}
template<typename T, uint16_t vectorSize>
inline ReturnValue_t GlobPoolVector<T, vectorSize>::commit(
uint32_t lockTimeout) {
ReturnValue_t result = glob::dataPool.lockDataPool(lockTimeout);
if(result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = commitWithoutLock();
ReturnValue_t unlockResult = glob::dataPool.unlockDataPool();
if(unlockResult != HasReturnvaluesIF::RETURN_OK) {
sif::error << "GlobPoolVar::read: Could not unlock global data pool"
<< std::endl;
}
return result;
}
template<typename T, uint16_t vectorSize>
inline ReturnValue_t GlobPoolVector<T, vectorSize>::readWithoutLock() {
PoolEntry<T>* read_out = glob::dataPool.getData<T>(this->dataPoolId,
vectorSize);
if (read_out != nullptr) {
this->valid = read_out->valid;
memcpy(this->value, read_out->address, read_out->getByteSize());
return HasReturnvaluesIF::RETURN_OK;
} else {
memset(this->value, 0, vectorSize * sizeof(T));
sif::error << "PoolVector: Read of DP Variable 0x" << std::hex
<< std::setw(8) << std::setfill('0') << dataPoolId <<
std::dec << " failed." << std::endl;
this->valid = INVALID;
return HasReturnvaluesIF::RETURN_FAILED;
}
}
template<typename T, uint16_t vectorSize>
inline ReturnValue_t GlobPoolVector<T, vectorSize>::commitWithoutLock() {
PoolEntry<T>* writeBack = glob::dataPool.getData<T>(this->dataPoolId,
vectorSize);
if ((writeBack != nullptr) && (this->readWriteMode != VAR_READ)) {
writeBack->valid = valid;
memcpy(writeBack->address, this->value, writeBack->getByteSize());
return HasReturnvaluesIF::RETURN_OK;
} else {
return HasReturnvaluesIF::RETURN_FAILED;
}
}
template<typename T, uint16_t vectorSize>
inline ReturnValue_t GlobPoolVector<T, vectorSize>::serialize(uint8_t** buffer,
size_t* size, size_t max_size,
SerializeIF::Endianness streamEndianness) const {
uint16_t i;
ReturnValue_t result;
for (i = 0; i < vectorSize; i++) {
result = SerializeAdapter::serialize(&(value[i]), buffer, size,
max_size, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
}
return result;
}
template<typename T, uint16_t vectorSize>
inline size_t GlobPoolVector<T, vectorSize>::getSerializedSize() const {
return vectorSize * SerializeAdapter::getSerializedSize(value);
}
template<typename T, uint16_t vectorSize>
inline ReturnValue_t GlobPoolVector<T, vectorSize>::deSerialize(
const uint8_t** buffer, size_t* size,
SerializeIF::Endianness streamEndianness) {
uint16_t i;
ReturnValue_t result;
for (i = 0; i < vectorSize; i++) {
result = SerializeAdapter::deSerialize(&(value[i]), buffer, size,
streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
}
return result;
}
#endif

View File

@ -1,11 +1,11 @@
#ifndef PIDREADER_H_ #ifndef PIDREADER_H_
#define PIDREADER_H_ #define PIDREADER_H_
#include <framework/datapool/DataPool.h> #include "../datapool/DataSetIF.h"
#include <framework/datapool/DataSetIF.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;
@ -15,10 +15,10 @@ class PIDReader: public PoolVariableIF {
protected: protected:
uint32_t parameterId; uint32_t parameterId;
uint8_t valid; uint8_t valid;
ReturnValue_t read() { ReturnValue_t readWithoutLock() {
uint8_t arrayIndex = DataPool::PIDToArrayIndex(parameterId); uint8_t arrayIndex = GlobalDataPool::PIDToArrayIndex(parameterId);
PoolEntry<T>* read_out = ::dataPool.getData<T>( PoolEntry<T> *read_out = glob::dataPool.getData<T>(
DataPool::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];
@ -36,14 +36,19 @@ protected:
* 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() { ReturnValue_t commit(uint32_t lockTimeout) override {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
ReturnValue_t commitWithoutLock() override {
return HasReturnvaluesIF::RETURN_FAILED;
}
/** /**
* Empty ctor for List initialization * Empty ctor for List initialization
*/ */
PIDReader() : PIDReader() :
parameterId(PoolVariableIF::NO_PARAMETER), valid(PoolVariableIF::INVALID), value(0) { parameterId(PoolVariableIF::NO_PARAMETER), valid(
PoolVariableIF::INVALID), value(0) {
} }
public: public:
@ -63,18 +68,31 @@ public:
* \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( parameterId(setParameterId), valid(PoolVariableIF::INVALID), value(
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 result = glob::dataPool.lockDataPool();
if(result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = readWithoutLock();
ReturnValue_t unlockResult = glob::dataPool.unlockDataPool();
if(unlockResult != HasReturnvaluesIF::RETURN_OK) {
sif::error << "PIDReader::read: Could not unlock data pool!"
<< std::endl;
}
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) {
} }
@ -88,7 +106,7 @@ 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 { uint32_t getDataPoolId() const {
return DataPool::PIDToDataPoolId(parameterId); return GlobalDataPool::PIDToDataPoolId(parameterId);
} }
uint32_t getParameterId() const { uint32_t getParameterId() const {
return parameterId; return parameterId;
@ -113,7 +131,7 @@ public:
return valid; return valid;
} }
void setValid(uint8_t valid) { void setValid(bool valid) {
this->valid = valid; this->valid = valid;
} }
@ -121,24 +139,25 @@ public:
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, uint32_t* size, virtual ReturnValue_t serialize(uint8_t **buffer, size_t *size,
const uint32_t max_size, bool bigEndian) const { size_t maxSize, Endianness streamEndianness) const override {
return SerializeAdapter<T>::serialize(&value, buffer, size, max_size, return SerializeAdapter::serialize(&value, buffer, size, maxSize,
bigEndian); streamEndianness);
} }
virtual uint32_t getSerializedSize() const { virtual size_t getSerializedSize() const override {
return SerializeAdapter<T>::getSerializedSize(&value); return SerializeAdapter::getSerializedSize(&value);
} }
virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
bool bigEndian) { Endianness streamEndianness) override {
return SerializeAdapter<T>::deSerialize(&value, buffer, size, bigEndian); return SerializeAdapter::deSerialize(&value, buffer, size,
streamEndianness);
} }
}; };

View File

@ -1,8 +1,8 @@
#ifndef FRAMEWORK_DATAPOOL_PIDREADERLIST_H_ #ifndef FRAMEWORK_DATAPOOLGLOB_PIDREADERLIST_H_
#define FRAMEWORK_DATAPOOL_PIDREADERLIST_H_ #define FRAMEWORK_DATAPOOLGLOB_PIDREADERLIST_H_
#include <framework/datapool/PIDReader.h> #include "../datapool/PoolVariableIF.h"
#include <framework/datapool/PoolVariableIF.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:
@ -24,4 +24,4 @@ public:
#endif /* FRAMEWORK_DATAPOOL_PIDREADERLIST_H_ */ #endif /* FRAMEWORK_DATAPOOLGLOB_PIDREADERLIST_H_ */

View File

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

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