diff --git a/action/ActionHelper.cpp b/action/ActionHelper.cpp index b43c676d0..8122885bb 100644 --- a/action/ActionHelper.cpp +++ b/action/ActionHelper.cpp @@ -1,9 +1,11 @@ #include "ActionHelper.h" #include "HasActionsIF.h" +#include "../ipc/MessageQueueSenderIF.h" #include "../objectmanager/ObjectManagerIF.h" -ActionHelper::ActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue) : - owner(setOwner), queueToUse(useThisQueue), ipcStore(nullptr) { +ActionHelper::ActionHelper(HasActionsIF* setOwner, + MessageQueueIF* useThisQueue) : + owner(setOwner), queueToUse(useThisQueue) { } ActionHelper::~ActionHelper() { @@ -32,13 +34,15 @@ ReturnValue_t ActionHelper::initialize(MessageQueueIF* queueToUse_) { return HasReturnvaluesIF::RETURN_OK; } -void ActionHelper::step(uint8_t step, MessageQueueId_t reportTo, ActionId_t commandId, ReturnValue_t result) { +void ActionHelper::step(uint8_t step, MessageQueueId_t reportTo, + ActionId_t commandId, ReturnValue_t result) { CommandMessage reply; ActionMessage::setStepReply(&reply, commandId, step + STEP_OFFSET, result); queueToUse->sendMessage(reportTo, &reply); } -void ActionHelper::finish(MessageQueueId_t reportTo, ActionId_t commandId, ReturnValue_t result) { +void ActionHelper::finish(MessageQueueId_t reportTo, ActionId_t commandId, + ReturnValue_t result) { CommandMessage reply; ActionMessage::setCompletionReply(&reply, commandId, result); queueToUse->sendMessage(reportTo, &reply); @@ -48,8 +52,8 @@ void ActionHelper::setQueueToUse(MessageQueueIF* queue) { queueToUse = queue; } -void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId, - store_address_t dataAddress) { +void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, + ActionId_t actionId, store_address_t dataAddress) { const uint8_t* dataPtr = NULL; size_t size = 0; ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size); @@ -85,22 +89,28 @@ ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo, if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = data->serialize(&dataPtr, &size, maxSize, SerializeIF::Endianness::BIG); + result = data->serialize(&dataPtr, &size, maxSize, + SerializeIF::Endianness::BIG); if (result != HasReturnvaluesIF::RETURN_OK) { ipcStore->deleteData(storeAddress); return result; } - //We don't need to report the objectId, as we receive REQUESTED data before the completion success message. - //True aperiodic replies need to be reported with another dedicated message. + // We don't need to report the objectId, as we receive REQUESTED data + // before the completion success message. + // True aperiodic replies need to be reported with + // another dedicated message. ActionMessage::setDataReply(&reply, replyId, storeAddress); - //TODO Service Implementation sucks at the moment - if (hideSender){ + // TODO: Service Implementation sucks at the moment + // TODO: why does it suck and why would someone need to hide the sender? + if (hideSender) { result = MessageQueueSenderIF::sendMessage(reportTo, &reply); - } else { + } + else { result = queueToUse->sendMessage(reportTo, &reply); } - if ( result != HasReturnvaluesIF::RETURN_OK){ + + if (result != HasReturnvaluesIF::RETURN_OK){ ipcStore->deleteData(storeAddress); } return result; @@ -108,3 +118,39 @@ ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo, void ActionHelper::resetHelper() { } + +ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo, + ActionId_t replyId, const uint8_t *data, size_t dataSize, + bool hideSender) { + CommandMessage reply; + store_address_t storeAddress; + ReturnValue_t result = ipcStore->addData(&storeAddress, data, dataSize); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + + if (result != HasReturnvaluesIF::RETURN_OK) { + ipcStore->deleteData(storeAddress); + return result; + } + + // We don't need to report the objectId, as we receive REQUESTED data + // before the completion success message. + // True aperiodic replies need to be reported with + // another dedicated message. + ActionMessage::setDataReply(&reply, replyId, storeAddress); + + // TODO: Service Implementation sucks at the moment + // TODO: why does it suck and why would someone need to hide the sender? + if (hideSender) { + result = MessageQueueSenderIF::sendMessage(reportTo, &reply); + } + else { + result = queueToUse->sendMessage(reportTo, &reply); + } + + if (result != HasReturnvaluesIF::RETURN_OK){ + ipcStore->deleteData(storeAddress); + } + return result; +} diff --git a/action/ActionHelper.h b/action/ActionHelper.h index bbc6d114d..17ca3ebdc 100644 --- a/action/ActionHelper.h +++ b/action/ActionHelper.h @@ -1,15 +1,18 @@ -#ifndef ACTIONHELPER_H_ -#define ACTIONHELPER_H_ +#ifndef FSFW_ACTION_ACTIONHELPER_H_ +#define FSFW_ACTION_ACTIONHELPER_H_ #include "ActionMessage.h" #include "../serialize/SerializeIF.h" #include "../ipc/MessageQueueIF.h" /** - * \brief Action Helper is a helper class which handles action messages + * @brief Action Helper is a helper class which handles action messages * - * Components which use the HasActionIF this helper can be used to handle the action messages. - * It does handle step messages as well as other answers to action calls. It uses the executeAction function - * of its owner as callback. The call of the initialize function is mandatory and it needs a valid messageQueueIF pointer! + * Components which use the HasActionIF this helper can be used to handle + * the action messages. + * It does handle step messages as well as other answers to action calls. + * It uses the executeAction function of its owner as callback. + * The call of the initialize function is mandatory and needs a + * valid MessageQueueIF pointer! */ class HasActionsIF; @@ -18,7 +21,8 @@ public: /** * Constructor of the action helper * @param setOwner Pointer to the owner of the interface - * @param useThisQueue messageQueue to be used, can be set during initialize function as well. + * @param useThisQueue messageQueue to be used, can be set during + * initialize function as well. */ ActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue); @@ -26,28 +30,35 @@ public: /** * Function to be called from the owner with a new command message * - * If the message is a valid action message the helper will use the executeAction function from HasActionsIF. - * If the message is invalid or the callback fails a message reply will be send to the sender of the message automatically. + * If the message is a valid action message the helper will use the + * executeAction function from HasActionsIF. + * If the message is invalid or the callback fails a message reply will be + * send to the sender of the message automatically. * * @param command Pointer to a command message received by the owner - * @return HasReturnvaluesIF::RETURN_OK if the message is a action message, CommandMessage::UNKNOW_COMMAND if this message ID is unkown + * @return HasReturnvaluesIF::RETURN_OK if the message is a action message, + * CommandMessage::UNKNOW_COMMAND if this message ID is unkown */ ReturnValue_t handleActionMessage(CommandMessage* command); /** - * Helper initialize function. Must be called before use of any other helper function - * @param queueToUse_ Pointer to the messageQueue to be used, optional if queue was set in constructor + * Helper initialize function. Must be called before use of any other + * helper function + * @param queueToUse_ Pointer to the messageQueue to be used, optional + * if queue was set in constructor * @return Returns RETURN_OK if successful */ ReturnValue_t initialize(MessageQueueIF* queueToUse_ = nullptr); /** - * Function to be called from the owner to send a step message. Success or failure will be determined by the result value. + * Function to be called from the owner to send a step message. + * Success or failure will be determined by the result value. * * @param step Number of steps already done * @param reportTo The messageQueueId to report the step message to * @param commandId ID of the executed command * @param result Result of the execution */ - void step(uint8_t step, MessageQueueId_t reportTo, ActionId_t commandId, ReturnValue_t result = HasReturnvaluesIF::RETURN_OK); + void step(uint8_t step, MessageQueueId_t reportTo, ActionId_t commandId, + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK); /** * Function to be called by the owner to send a action completion message * @@ -55,39 +66,59 @@ public: * @param commandId ID of the executed command * @param result Result of the execution */ - void finish(MessageQueueId_t reportTo, ActionId_t commandId, ReturnValue_t result = HasReturnvaluesIF::RETURN_OK); + void finish(MessageQueueId_t reportTo, ActionId_t commandId, + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK); /** - * Function to be called by the owner if an action does report data - * - * @param reportTo MessageQueueId_t to report the action completion message to + * Function to be called by the owner if an action does report data. + * Takes a SerializeIF* pointer and serializes it into the IPC store. + * @param reportTo MessageQueueId_t to report the action completion + * message to * @param replyId ID of the executed command * @param data Pointer to the data * @return Returns RETURN_OK if successful, otherwise failure code */ - ReturnValue_t reportData(MessageQueueId_t reportTo, ActionId_t replyId, SerializeIF* data, bool hideSender = false); + ReturnValue_t reportData(MessageQueueId_t reportTo, ActionId_t replyId, + SerializeIF* data, bool hideSender = false); + /** + * Function to be called by the owner if an action does report data. + * Takes the raw data and writes it into the IPC store. + * @param reportTo MessageQueueId_t to report the action completion + * message to + * @param replyId ID of the executed command + * @param data Pointer to the data + * @return Returns RETURN_OK if successful, otherwise failure code + */ + ReturnValue_t reportData(MessageQueueId_t reportTo, ActionId_t replyId, + const uint8_t* data, size_t dataSize, bool hideSender = false); /** - * Function to setup the MessageQueueIF* of the helper. Can be used to set the messageQueueIF* if - * message queue is unavailable at construction and initialize but must be setup before first call of other functions. + * Function to setup the MessageQueueIF* of the helper. Can be used to + * set the MessageQueueIF* if message queue is unavailable at construction + * and initialize but must be setup before first call of other functions. * @param queue Queue to be used by the helper */ void setQueueToUse(MessageQueueIF *queue); protected: - static const uint8_t STEP_OFFSET = 1;//!< Increase of value of this per step + //!< Increase of value of this per step + static const uint8_t STEP_OFFSET = 1; HasActionsIF* owner;//!< Pointer to the owner - MessageQueueIF* queueToUse;//!< Queue to be used as response sender, has to be set with - StorageManagerIF* ipcStore;//!< Pointer to an IPC Store, initialized during construction or initialize(MessageQueueIF* queueToUse_) or with setQueueToUse(MessageQueueIF *queue) + //! Queue to be used as response sender, has to be set in ctor or with + //! setQueueToUse + MessageQueueIF* queueToUse; + //! Pointer to an IPC Store, initialized during construction or + StorageManagerIF* ipcStore = nullptr; + /** - *Internal function called by handleActionMessage(CommandMessage* command) - * + * Internal function called by handleActionMessage * @param commandedBy MessageQueueID of Commander * @param actionId ID of action to be done * @param dataAddress Address of additional data in IPC Store */ - virtual void prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId, store_address_t dataAddress); + virtual void prepareExecution(MessageQueueId_t commandedBy, + ActionId_t actionId, store_address_t dataAddress); /** - * + * @brief Default implementation is empty. */ virtual void resetHelper(); }; -#endif /* ACTIONHELPER_H_ */ +#endif /* FSFW_ACTION_ACTIONHELPER_H_ */ diff --git a/action/HasActionsIF.h b/action/HasActionsIF.h index 886d08377..a26ed5883 100644 --- a/action/HasActionsIF.h +++ b/action/HasActionsIF.h @@ -47,10 +47,9 @@ public: virtual MessageQueueId_t getCommandQueue() const = 0; /** * Execute or initialize the execution of a certain function. - * Returning #EXECUTION_FINISHED or a failure code, nothing else needs to - * be done. When needing more steps, return RETURN_OK and issue steps and - * completion manually. - * One "step failed" or completion report must be issued! + * When used in conjunction with the ActionHelper class, returning + * a return code which is not equal to RETURN_OK will trigger a step reply + * with step 0. */ virtual ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, const uint8_t* data, size_t size) = 0; diff --git a/container/ArrayList.h b/container/ArrayList.h index 9f5e76dee..6bd5c1d5a 100644 --- a/container/ArrayList.h +++ b/container/ArrayList.h @@ -1,5 +1,5 @@ -#ifndef FRAMEWORK_CONTAINER_ARRAYLIST_H_ -#define FRAMEWORK_CONTAINER_ARRAYLIST_H_ +#ifndef FSFW_CONTAINER_ARRAYLIST_H_ +#define FSFW_CONTAINER_ARRAYLIST_H_ #include "../returnvalues/HasReturnvaluesIF.h" #include "../serialize/SerializeAdapter.h" @@ -20,11 +20,35 @@ public: static const uint8_t INTERFACE_ID = CLASS_ID::ARRAY_LIST; static const ReturnValue_t FULL = MAKE_RETURN_CODE(0x01); - /** - * Copying is forbiden by declaring copy ctor and copy assignment deleted - * It is too ambigous in this case. - * (Allocate a new backend? Use the same? What to do in an modifying call?) - */ + /** + * This is the allocating constructor. + * It allocates an array of the specified size. + * @param maxSize + */ + ArrayList(count_t maxSize) : + size(0), maxSize_(maxSize), allocated(true) { + entries = new T[maxSize]; + } + + /** + * This is the non-allocating constructor + * + * It expects a pointer to an array of a certain size and initializes + * itself to it. + * + * @param storage the array to use as backend + * @param maxSize size of storage + * @param size size of data already present in storage + */ + ArrayList(T *storage, count_t maxSize, count_t size = 0) : + size(size), entries(storage), maxSize_(maxSize), allocated(false) { + } + + /** + * Copying is forbiden by declaring copy ctor and copy assignment deleted + * It is too ambigous in this case. + * (Allocate a new backend? Use the same? What to do in an modifying call?) + */ ArrayList(const ArrayList& other) = delete; const ArrayList& operator=(const ArrayList& other) = delete; @@ -33,30 +57,6 @@ public: */ count_t size; - /** - * This is the allocating constructor; - * - * It allocates an array of the specified size. - * - * @param maxSize - */ - ArrayList(count_t maxSize) : - size(0), maxSize_(maxSize), allocated(true) { - entries = new T[maxSize]; - } - - /** - * This is the non-allocating constructor - * - * It expects a pointer to an array of a certain size and initializes itself to it. - * - * @param storage the array to use as backend - * @param maxSize size of storage - * @param size size of data already present in storage - */ - ArrayList(T *storage, count_t maxSize, count_t size = 0) : - size(size), entries(storage), maxSize_(maxSize), allocated(false) { - } /** * Destructor, if the allocating constructor was used, it deletes the array. @@ -67,77 +67,81 @@ 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) {} + /** + * An Iterator to go trough an ArrayList + * + * It stores a pointer to an element and increments the + * pointer when incremented itself. + */ + class Iterator { + public: + /** + * Empty ctor, points to NULL + */ + Iterator(): value(0) {} - /** - * Initializes the Iterator to point to an element - * - * @param initialize - */ - Iterator(T *initialize) { - value = initialize; - } + /** + * Initializes the Iterator to point to an element + * + * @param initialize + */ + Iterator(T *initialize) { + value = initialize; + } - /** - * The current element the iterator points to - */ - T *value; + /** + * The current element the iterator points to + */ + T *value; - Iterator& operator++() { - value++; - return *this; - } + Iterator& operator++() { + value++; + return *this; + } - Iterator operator++(int) { - Iterator tmp(*this); - operator++(); - return tmp; - } + Iterator operator++(int) { + Iterator tmp(*this); + operator++(); + return tmp; + } - Iterator& operator--() { - value--; - return *this; - } + Iterator& operator--() { + value--; + return *this; + } - Iterator operator--(int) { - Iterator tmp(*this); - operator--(); - return tmp; - } + Iterator operator--(int) { + Iterator tmp(*this); + operator--(); + return tmp; + } - T operator*() { - return *value; - } + T& operator*() { + return *value; + } - T *operator->() { - return value; - } + const T& operator*() const { + return *value; + } - const T *operator->() const{ - return value; - } + T *operator->() { + return value; + } - //SHOULDDO this should be implemented as non-member - bool operator==(const typename ArrayList::Iterator& other) const{ - return (value == other.value); - } + const T *operator->() const { + return value; + } + }; - //SHOULDDO this should be implemented as non-member - bool operator!=(const typename ArrayList::Iterator& other) const { - return !(*this == other); - } - }; + friend bool operator==(const ArrayList::Iterator& lhs, + const ArrayList::Iterator& rhs) { + return (lhs.value == rhs.value); + } + + friend bool operator!=(const ArrayList::Iterator& lhs, + const ArrayList::Iterator& rhs) { + return not (lhs.value == rhs.value); + } /** * Iterator pointing to the first stored elmement @@ -192,7 +196,7 @@ public: * * @return maximum number of elements */ - uint32_t maxSize() const { + size_t maxSize() const { return this->maxSize_; } @@ -236,7 +240,7 @@ protected: /** * remembering the maximum size */ - uint32_t maxSize_; + size_t maxSize_; /** * true if the array was allocated and needs to be deleted in the destructor. @@ -244,4 +248,6 @@ protected: bool allocated; }; -#endif /* ARRAYLIST_H_ */ + + +#endif /* FSFW_CONTAINER_ARRAYLIST_H_ */ diff --git a/container/DynamicFIFO.h b/container/DynamicFIFO.h index abb533308..86d43f7d7 100644 --- a/container/DynamicFIFO.h +++ b/container/DynamicFIFO.h @@ -27,14 +27,27 @@ public: /** * @brief Custom copy constructor which prevents setting the - * underlying pointer wrong. + * underlying pointer wrong. This function allocates memory! + * @details This is a very heavy operation so try to avoid this! + * */ DynamicFIFO(const DynamicFIFO& other): FIFOBase(other), fifoVector(other.maxCapacity) { + this->fifoVector = other.fifoVector; this->setContainer(fifoVector.data()); } - + /** + * @brief Custom assignment operator + * @details This is a very heavy operation so try to avoid this! + * @param other DyamicFIFO to copy from + */ + DynamicFIFO& operator=(const DynamicFIFO& other){ + FIFOBase::operator=(other); + this->fifoVector = other.fifoVector; + this->setContainer(fifoVector.data()); + return *this; + } private: std::vector fifoVector; }; diff --git a/container/FIFO.h b/container/FIFO.h index 19f763fc8..701138520 100644 --- a/container/FIFO.h +++ b/container/FIFO.h @@ -25,9 +25,21 @@ public: * @param other */ FIFO(const FIFO& other): FIFOBase(other) { + this->fifoArray = other.fifoArray; this->setContainer(fifoArray.data()); } + /** + * @brief Custom assignment operator + * @param other + */ + FIFO& operator=(const FIFO& other){ + FIFOBase::operator=(other); + this->fifoArray = other.fifoArray; + this->setContainer(fifoArray.data()); + return *this; + } + private: std::array fifoArray; }; diff --git a/container/FIFOBase.h b/container/FIFOBase.h index b744706d4..edd66d37a 100644 --- a/container/FIFOBase.h +++ b/container/FIFOBase.h @@ -19,32 +19,46 @@ public: /** * Insert value into FIFO * @param value - * @return + * @return RETURN_OK on success, FULL if full */ ReturnValue_t insert(T value); /** * Retrieve item from FIFO. This removes the item from the FIFO. - * @param value - * @return + * @param value Must point to a valid T + * @return RETURN_OK on success, EMPTY if empty and FAILED if nullptr check failed */ ReturnValue_t retrieve(T *value); /** * Retrieve item from FIFO without removing it from FIFO. - * @param value - * @return + * @param value Must point to a valid T + * @return RETURN_OK on success, EMPTY if empty and FAILED if nullptr check failed */ ReturnValue_t peek(T * value); /** * Remove item from FIFO. - * @return + * @return RETURN_OK on success, EMPTY if empty */ ReturnValue_t pop(); + /*** + * Check if FIFO is empty + * @return True if empty, False if not + */ bool empty(); + /*** + * Check if FIFO is Full + * @return True if full, False if not + */ bool full(); + /*** + * Current used size (elements) used + * @return size_t in elements + */ size_t size(); - - + /*** + * Get maximal capacity of fifo + * @return size_t with max capacity of this fifo + */ size_t getMaxCapacity() const; protected: diff --git a/container/FIFOBase.tpp b/container/FIFOBase.tpp index d54b3f8f9..763004b6f 100644 --- a/container/FIFOBase.tpp +++ b/container/FIFOBase.tpp @@ -26,6 +26,9 @@ inline ReturnValue_t FIFOBase::retrieve(T* value) { if (empty()) { return EMPTY; } else { + if (value == nullptr){ + return HasReturnvaluesIF::RETURN_FAILED; + } *value = values[readIndex]; readIndex = next(readIndex); --currentSize; @@ -38,6 +41,9 @@ inline ReturnValue_t FIFOBase::peek(T* value) { if(empty()) { return EMPTY; } else { + if (value == nullptr){ + return HasReturnvaluesIF::RETURN_FAILED; + } *value = values[readIndex]; return HasReturnvaluesIF::RETURN_OK; } diff --git a/container/FixedArrayList.h b/container/FixedArrayList.h index da85c6233..e9e127cf0 100644 --- a/container/FixedArrayList.h +++ b/container/FixedArrayList.h @@ -1,51 +1,32 @@ #ifndef FIXEDARRAYLIST_H_ #define FIXEDARRAYLIST_H_ -#include "../container/ArrayList.h" - +#include "ArrayList.h" +#include /** - * @brief Array List with a fixed maximum size - * @ingroup container + * \ingroup container */ -template +template class FixedArrayList: public ArrayList { + static_assert(MAX_SIZE <= (pow(2,sizeof(count_t)*8)-1), "count_t is not large enough to hold MAX_SIZE"); private: T data[MAX_SIZE]; public: - /** - * (Robin) Maybe we should also implement move assignment and move ctor. - * Or at least delete them. - */ FixedArrayList() : ArrayList(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(data, MAX_SIZE) { - memcpy(this->data, data_, count * sizeof(T)); - this->size = count; - } - FixedArrayList(const FixedArrayList& other) : ArrayList(data, MAX_SIZE) { memcpy(this->data, other.data, sizeof(this->data)); this->entries = data; + this->size = other.size; } FixedArrayList& operator=(FixedArrayList other) { memcpy(this->data, other.data, sizeof(this->data)); this->entries = data; + this->size = other.size; return *this; } diff --git a/container/FixedMap.h b/container/FixedMap.h index 3da65784b..7a5220faa 100644 --- a/container/FixedMap.h +++ b/container/FixedMap.h @@ -1,19 +1,27 @@ -#ifndef FIXEDMAP_H_ -#define FIXEDMAP_H_ +#ifndef FSFW_CONTAINER_FIXEDMAP_H_ +#define FSFW_CONTAINER_FIXEDMAP_H_ -#include "../container/ArrayList.h" +#include "ArrayList.h" #include "../returnvalues/HasReturnvaluesIF.h" #include +#include /** - * @brief Map implementation for maps with a pre-defined size. - * @details Can be initialized with desired maximum size. - * Iterator is used to access pair and - * iterate through map entries. Complexity O(n). + * @brief Map implementation for maps with a pre-defined size. + * @details + * Can be initialized with desired maximum size. + * Iterator is used to access pair and iterate through map entries. + * Complexity O(n). + * @warning Iterators return a non-const key_t in the pair. + * @warning A User is not allowed to change the key, otherwise the map is corrupted. * @ingroup container */ template class FixedMap: public SerializeIF { + static_assert (std::is_trivially_copyable::value or + std::is_base_of::value, + "Types used in FixedMap must either be trivial copy-able or a " + "derived class from SerializeIF to be serialize-able"); public: static const uint8_t INTERFACE_ID = CLASS_ID::FIXED_MAP; static const ReturnValue_t KEY_ALREADY_EXISTS = MAKE_RETURN_CODE(0x01); @@ -51,28 +59,17 @@ public: Iterator(std::pair *pair) : ArrayList, uint32_t>::Iterator(pair) { } - - T operator*() { - return ArrayList, uint32_t>::Iterator::value->second; - } - - // -> operator overloaded, can be used to access value - T *operator->() { - return &ArrayList, uint32_t>::Iterator::value->second; - } - - // Can be used to access the key of the iterator - key_t first() { - return ArrayList, uint32_t>::Iterator::value->first; - } - - // Alternative to access value, similar to std::map implementation - T second() { - return ArrayList, uint32_t>::Iterator::value->second; - } }; + friend bool operator==(const typename FixedMap::Iterator& lhs, + const typename FixedMap::Iterator& rhs) { + return (lhs.value == rhs.value); + } + friend bool operator!=(const typename FixedMap::Iterator& lhs, + const typename FixedMap::Iterator& rhs) { + return not (lhs.value == rhs.value); + } Iterator begin() const { return Iterator(&theMap[0]); @@ -86,16 +83,16 @@ public: return _size; } - ReturnValue_t insert(key_t key, T value, Iterator *storedValue = NULL) { + ReturnValue_t insert(key_t key, T value, Iterator *storedValue = nullptr) { if (exists(key) == HasReturnvaluesIF::RETURN_OK) { - return FixedMap::KEY_ALREADY_EXISTS; + return KEY_ALREADY_EXISTS; } if (_size == theMap.maxSize()) { - return FixedMap::MAP_FULL; + return MAP_FULL; } theMap[_size].first = key; theMap[_size].second = value; - if (storedValue != NULL) { + if (storedValue != nullptr) { *storedValue = Iterator(&theMap[_size]); } ++_size; @@ -156,6 +153,24 @@ public: return HasReturnvaluesIF::RETURN_OK; } + bool empty() { + if(_size == 0) { + return true; + } + else { + return false; + } + } + + bool full() { + if(_size >= theMap.maxSize()) { + return true; + } + else { + return false; + } + } + void clear() { _size = 0; } @@ -164,16 +179,6 @@ public: return theMap.maxSize(); } - - bool full() { - if(_size == theMap.maxSize()) { - 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, @@ -222,4 +227,4 @@ public: }; -#endif /* FIXEDMAP_H_ */ +#endif /* FSFW_CONTAINER_FIXEDMAP_H_ */ diff --git a/container/FixedOrderedMultimap.h b/container/FixedOrderedMultimap.h index 41465c335..96bc00735 100644 --- a/container/FixedOrderedMultimap.h +++ b/container/FixedOrderedMultimap.h @@ -1,171 +1,206 @@ -#ifndef FRAMEWORK_CONTAINER_FIXEDORDEREDMULTIMAP_H_ -#define FRAMEWORK_CONTAINER_FIXEDORDEREDMULTIMAP_H_ +#ifndef FSFW_CONTAINER_FIXEDORDEREDMULTIMAP_H_ +#define FSFW_CONTAINER_FIXEDORDEREDMULTIMAP_H_ -#include "../container/ArrayList.h" +#include "ArrayList.h" #include -#include /** - * @brief Map implementation which allows entries with identical keys + * @brief An associative container which allows multiple entries of the same key. * @details - * Performs no dynamic memory allocation except on initialization. - * Uses an ArrayList as the underlying container and thus has a linear + * Same keys are ordered by KEY_COMPARE function which is std::less > by default. + * + * It uses the ArrayList, so technically this is not a real map, it is an array of pairs + * of type key_t, T. It is ordered by key_t as FixedMap but allows same keys. Thus it 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 + * as those incur extensive memory move operations (the underlying container * is not node based). - * @ingroup container + * + * Its of fixed size so no allocations are performed after the construction. + * + * The maximum size is given as first parameter of the constructor. + * + * It provides an iterator to do list iterations. + * + * The type T must have a copy constructor if it is not trivial copy-able. + * + * @warning Iterators return a non-const key_t in the pair. + * @warning A User is not allowed to change the key, otherwise the map is corrupted. + * + * \ingroup container */ template> class FixedOrderedMultimap { public: 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 MAP_FULL = MAKE_RETURN_CODE(0x02); - static const ReturnValue_t KEY_DOES_NOT_EXIST = MAKE_RETURN_CODE(0x03); + static const ReturnValue_t MAP_FULL = MAKE_RETURN_CODE(0x01); + static const ReturnValue_t KEY_DOES_NOT_EXIST = MAKE_RETURN_CODE(0x02); + + /*** + * Constructor which needs a size_t for the maximum allowed size + * + * Can not be resized during runtime + * + * Allocates memory at construction + * @param maxSize size_t of Maximum allowed size + */ + FixedOrderedMultimap(size_t maxSize):theMap(maxSize), _size(0){ + } + + /*** + * Virtual destructor frees Memory by deleting its member + */ + virtual ~FixedOrderedMultimap() { + } + + /*** + * Special iterator for FixedOrderedMultimap + */ + class Iterator: public ArrayList, size_t>::Iterator { + public: + Iterator() : + ArrayList, size_t>::Iterator() { + } + + Iterator(std::pair *pair) : + ArrayList, size_t>::Iterator(pair) { + } + }; + + /*** + * Returns an iterator pointing to the first element + * @return Iterator pointing to first element + */ + Iterator begin() const { + return Iterator(&theMap[0]); + } /** - * Initializes the ordered multimap with a fixed maximum size. - * @param maxSize + * Returns an iterator pointing to one element past the end + * @return Iterator pointing to one element past the end */ - FixedOrderedMultimap(size_t maxSize); + Iterator end() const { + return Iterator(&theMap[_size]); + } - virtual ~FixedOrderedMultimap() {} + /*** + * Returns the current size of the map (not maximum size!) + * @return Current size + */ + size_t size() const{ + return _size; + } - class Iterator: public ArrayList, uint32_t>::Iterator { - public: - /** Returns an iterator to nullptr */ - Iterator(); - /** Initializes iterator to given entry */ - Iterator(std::pair *pair); - /** Dereference operator can be used to get value */ - T operator*(); - /** Arrow operator can be used to get pointer to value */ - T *operator->(); - }; + /** + * Clears the map, does not deallocate any memory + */ + void clear(){ + _size = 0; + } - /** 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; + /** + * Returns the maximum size of the map + * @return Maximum size of the map + */ + size_t maxSize() const{ + return theMap.maxSize(); + } - /** - * 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 - * @param pair - * @return - */ - ReturnValue_t insert(std::pair 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; + /*** + * Used to insert a key and value separately. + * + * @param[in] key Key of the new element + * @param[in] value Value of the new element + * @param[in/out] (optional) storedValue On success this points to the new value, otherwise a nullptr + * @return RETURN_OK if insert was successful, MAP_FULL if no space is available + */ + ReturnValue_t insert(key_t key, T value, Iterator *storedValue = nullptr); - 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; - } + /*** + * Used to insert new pair instead of single values + * + * @param pair Pair to be inserted + * @return RETURN_OK if insert was successful, MAP_FULL if no space is available + */ + ReturnValue_t insert(std::pair pair); - 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; - } + /*** + * Can be used to check if a certain key is in the map + * @param key Key to be checked + * @return RETURN_OK if the key exists KEY_DOES_NOT_EXIST otherwise + */ + ReturnValue_t exists(key_t key) const; - Iterator find(key_t key) const { - ReturnValue_t result = exists(key); - if (result != HasReturnvaluesIF::RETURN_OK) { - return end(); - } - return Iterator(&theMap[findFirstIndex(key)]); - } + /*** + * Used to delete the element in the iterator + * + * The iterator will point to the element before or begin(), + * but never to one element in front of the map. + * + * @warning The iterator needs to be valid and dereferenceable + * @param[in/out] iter Pointer to iterator to the element that needs to be ereased + * @return RETURN_OK if erased, KEY_DOES_NOT_EXIST if the there is no element like this + */ + ReturnValue_t erase(Iterator *iter); - 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; - } + /*** + * Used to erase by key + * @param key Key to be erased + * @return RETURN_OK if erased, KEY_DOES_NOT_EXIST if the there is no element like this + */ + ReturnValue_t erase(key_t key); - void clear() { - _size = 0; - } + /*** + * Find returns the first appearance of the key + * + * If the key does not exist, it points to end() + * + * @param key Key to search for + * @return Iterator pointing to the first entry of key + */ + Iterator find(key_t key) const{ + ReturnValue_t result = exists(key); + if (result != HasReturnvaluesIF::RETURN_OK) { + return end(); + } + return Iterator(&theMap[findFirstIndex(key)]); + }; - size_t maxSize() const { - return theMap.maxSize(); - } + /*** + * Finds first entry of the given key and returns a + * pointer to the value + * + * @param key Key to search for + * @param value Found value + * @return RETURN_OK if it points to the value, + * KEY_DOES_NOT_EXIST if the key is not in the map + */ + ReturnValue_t find(key_t key, T **value) const; + + friend bool operator==(const typename FixedOrderedMultimap::Iterator& lhs, + const typename FixedOrderedMultimap::Iterator& rhs) { + return (lhs.value == rhs.value); + } + + friend bool operator!=(const typename FixedOrderedMultimap::Iterator& lhs, + const typename FixedOrderedMultimap::Iterator& rhs) { + return not (lhs.value == rhs.value); + } private: typedef KEY_COMPARE compare; compare myComp; - ArrayList, uint32_t> theMap; + ArrayList, size_t> theMap; size_t _size; - uint32_t findFirstIndex(key_t key, uint32_t startAt = 0) const { - if (startAt >= _size) { - return startAt + 1; - } - uint32_t i = startAt; - for (i = startAt; i < _size; ++i) { - if (theMap[i].first == key) { - return i; - } - } - return i; - } + size_t findFirstIndex(key_t key, size_t startAt = 0) const; - uint32_t findNicePlace(key_t key) const { - uint32_t i = 0; - for (i = 0; i < _size; ++i) { - if (myComp(key, theMap[i].first)) { - return i; - } - } - return i; - } + size_t findNicePlace(key_t key) const; - void removeFromPosition(uint32_t position) { - if (_size <= position) { - return; - } - memmove(&theMap[position], &theMap[position + 1], - (_size - position - 1) * sizeof(std::pair)); - --_size; - } + void removeFromPosition(size_t position); }; #include "FixedOrderedMultimap.tpp" -#endif /* FRAMEWORK_CONTAINER_FIXEDORDEREDMULTIMAP_H_ */ +#endif /* FSFW_CONTAINER_FIXEDORDEREDMULTIMAP_H_ */ diff --git a/container/FixedOrderedMultimap.tpp b/container/FixedOrderedMultimap.tpp index 74edbf9ae..4aa85e974 100644 --- a/container/FixedOrderedMultimap.tpp +++ b/container/FixedOrderedMultimap.tpp @@ -1,83 +1,109 @@ #ifndef FRAMEWORK_CONTAINER_FIXEDORDEREDMULTIMAP_TPP_ #define FRAMEWORK_CONTAINER_FIXEDORDEREDMULTIMAP_TPP_ -template -inline FixedOrderedMultimap::Iterator::Iterator(): - ArrayList, uint32_t>::Iterator(){} template -inline FixedOrderedMultimap::Iterator::Iterator( - std::pair *pair): - ArrayList, uint32_t>::Iterator(pair){} - +inline ReturnValue_t FixedOrderedMultimap::insert(key_t key, T value, Iterator *storedValue) { + if (_size == theMap.maxSize()) { + return MAP_FULL; + } + size_t position = findNicePlace(key); + memmove(static_cast(&theMap[position + 1]),static_cast(&theMap[position]), + (_size - position) * sizeof(std::pair)); + theMap[position].first = key; + theMap[position].second = value; + ++_size; + if (storedValue != nullptr) { + *storedValue = Iterator(&theMap[position]); + } + return HasReturnvaluesIF::RETURN_OK; +} template -inline T FixedOrderedMultimap::Iterator::operator*() { - return ArrayList, uint32_t>::Iterator::value->second; +inline ReturnValue_t FixedOrderedMultimap::insert(std::pair pair) { + return insert(pair.first, pair.second); } template -inline typename FixedOrderedMultimap::Iterator -FixedOrderedMultimap::begin() const { - return Iterator(&theMap[0]); +inline ReturnValue_t FixedOrderedMultimap::exists(key_t key) const { + ReturnValue_t result = KEY_DOES_NOT_EXIST; + if (findFirstIndex(key) < _size) { + result = HasReturnvaluesIF::RETURN_OK; + } + return result; } template -inline typename FixedOrderedMultimap::Iterator -FixedOrderedMultimap::end() const { - return Iterator(&theMap[_size]); -} - - -template -inline size_t FixedOrderedMultimap::size() const { - return _size; +inline ReturnValue_t FixedOrderedMultimap::erase(Iterator *iter) { + size_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; } template -inline T* FixedOrderedMultimap::Iterator::operator->() { - return &ArrayList, uint32_t>::Iterator::value->second; +inline ReturnValue_t FixedOrderedMultimap::erase(key_t key) { + size_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; } template -inline FixedOrderedMultimap::FixedOrderedMultimap( - size_t maxSize): theMap(maxSize), _size(0) {} - - -template -inline ReturnValue_t FixedOrderedMultimap::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)); - theMap[position].first = key; - theMap[position].second = value; - ++_size; - if (storedValue != nullptr) { - *storedValue = Iterator(&theMap[position]); - } - return HasReturnvaluesIF::RETURN_OK; +inline ReturnValue_t FixedOrderedMultimap::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; } template -inline ReturnValue_t FixedOrderedMultimap::insert( - std::pair pair) { - return insert(pair.fist, pair.second); +inline size_t FixedOrderedMultimap::findFirstIndex(key_t key, size_t startAt) const { + if (startAt >= _size) { + return startAt + 1; + } + size_t i = startAt; + for (i = startAt; i < _size; ++i) { + if (theMap[i].first == key) { + return i; + } + } + return i; } template -inline ReturnValue_t FixedOrderedMultimap::exists( - key_t key) const { - ReturnValue_t result = KEY_DOES_NOT_EXIST; - if (findFirstIndex(key) < _size) { - result = HasReturnvaluesIF::RETURN_OK; - } - return result; +inline size_t FixedOrderedMultimap::findNicePlace(key_t key) const { + size_t i = 0; + for (i = 0; i < _size; ++i) { + if (myComp(key, theMap[i].first)) { + return i; + } + } + return i; } +template +inline void FixedOrderedMultimap::removeFromPosition(size_t position) { + if (_size <= position) { + return; + } + memmove(static_cast(&theMap[position]), static_cast(&theMap[position + 1]), + (_size - position - 1) * sizeof(std::pair)); + --_size; +} + + #endif /* FRAMEWORK_CONTAINER_FIXEDORDEREDMULTIMAP_TPP_ */ diff --git a/container/HybridIterator.h b/container/HybridIterator.h index 630bae28d..8d020cb93 100644 --- a/container/HybridIterator.h +++ b/container/HybridIterator.h @@ -1,8 +1,8 @@ #ifndef FRAMEWORK_CONTAINER_HYBRIDITERATOR_H_ #define FRAMEWORK_CONTAINER_HYBRIDITERATOR_H_ -#include "../container/ArrayList.h" -#include "../container/SinglyLinkedList.h" +#include "ArrayList.h" +#include "SinglyLinkedList.h" template class HybridIterator: public LinkedElement::Iterator, diff --git a/container/IsDerivedFrom.h b/container/IsDerivedFrom.h deleted file mode 100644 index 8142a3781..000000000 --- a/container/IsDerivedFrom.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef 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 -class IsDerivedFrom { - class No { - }; - class Yes { - No no[3]; - }; - - // This will be chosen if B is the base type - static Yes Test(B*); // declared, but not defined - // This will be chosen for anything else - static No Test(... ); // declared, but not defined - -public: - enum { - Is = sizeof(Test(static_cast(0))) == sizeof(Yes) - }; -}; - -template -struct is_same { - static bool const value = false; -}; - -template -struct is_same { - static bool const value = true; -}; - - -template -struct enable_if { - typedef T type; -}; - -template -struct enable_if { }; - - -#endif /* ISDERIVEDFROM_H_ */ diff --git a/container/PlacementFactory.h b/container/PlacementFactory.h index 055384780..a0aebb7d1 100644 --- a/container/PlacementFactory.h +++ b/container/PlacementFactory.h @@ -3,26 +3,62 @@ #include "../storagemanager/StorageManagerIF.h" #include - +/** + * The Placement Factory is used to create objects at runtime in a specific pool. + * In general, this should be avoided and it should only be used if you know what you are doing. + * You are not allowed to use this container with a type that allocates memory internally like ArrayList. + * + * Also, you have to check the returned pointer in generate against nullptr! + * + * A backend of Type StorageManagerIF must be given as a place to store the new objects. + * Therefore ThreadSafety is only provided by your StorageManager Implementation. + * + * Objects must be destroyed by the user with "destroy"! Otherwise the pool will not be cleared. + * + * The concept is based on the placement new operator. + * + * @warning Do not use with any Type that allocates memory internally! + * @ingroup container + */ class PlacementFactory { public: PlacementFactory(StorageManagerIF* backend) : dataBackend(backend) { } + + /*** + * Generates an object of type T in the backend storage. + * + * @warning Do not use with any Type that allocates memory internally! + * + * @tparam T Type of Object + * @param args Constructor Arguments to be passed + * @return A pointer to the new object or a nullptr in case of failure + */ template T* generate(Args&&... args) { store_address_t tempId; - uint8_t* pData = NULL; + uint8_t* pData = nullptr; ReturnValue_t result = dataBackend->getFreeElement(&tempId, sizeof(T), &pData); if (result != HasReturnvaluesIF::RETURN_OK) { - return NULL; + return nullptr; } T* temp = new (pData) T(std::forward(args)...); return temp; } + /*** + * Function to destroy the object allocated with generate and free space in backend. + * This must be called by the user. + * + * @param thisElement Element to be destroyed + * @return RETURN_OK if the element was destroyed, different errors on failure + */ template ReturnValue_t destroy(T* thisElement) { + if (thisElement == nullptr){ + return HasReturnvaluesIF::RETURN_FAILED; + } //Need to call destructor first, in case something was allocated by the object (shouldn't do that, however). thisElement->~T(); uint8_t* pointer = (uint8_t*) (thisElement); diff --git a/container/RingBufferBase.h b/container/RingBufferBase.h index 243a2915e..886b9fab9 100644 --- a/container/RingBufferBase.h +++ b/container/RingBufferBase.h @@ -1,5 +1,5 @@ -#ifndef FRAMEWORK_CONTAINER_RINGBUFFERBASE_H_ -#define FRAMEWORK_CONTAINER_RINGBUFFERBASE_H_ +#ifndef FSFW_CONTAINER_RINGBUFFERBASE_H_ +#define FSFW_CONTAINER_RINGBUFFERBASE_H_ #include "../returnvalues/HasReturnvaluesIF.h" #include @@ -65,6 +65,7 @@ protected: size_t read[N_READ_PTRS]; const size_t size; const bool overwriteOld; + void incrementWrite(uint32_t amount) { write = ((write + amount - start) % size) + start; } @@ -90,7 +91,6 @@ protected: } } - size_t getRead(uint8_t n = 0) const { return read[n]; } @@ -110,4 +110,4 @@ protected: } }; -#endif /* FRAMEWORK_CONTAINER_RINGBUFFERBASE_H_ */ +#endif /* FSFW_CONTAINER_RINGBUFFERBASE_H_ */ diff --git a/container/RingBufferTest.cpp.ignore b/container/RingBufferTest.cpp.ignore deleted file mode 100644 index d660e29c9..000000000 --- a/container/RingBufferTest.cpp.ignore +++ /dev/null @@ -1,79 +0,0 @@ - -#include -#include "SimpleRingBuffer.h" - - -int main() { - using namespace std; - SimpleRingBuffer buffer(64, false); - uint8_t data[8] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'}; - ReturnValue_t result = buffer.writeData(data, 8); - if (result != HasReturnvaluesIF::RETURN_OK) { - cout << "writeData failed." << endl; - } - result = buffer.writeData(data, 8); - if (result != HasReturnvaluesIF::RETURN_OK) { - cout << "writeData failed." << endl; - } - uint8_t buffer2[47] = {0}; - for (uint8_t count = 0; countcreateMutex(); } + SharedRingBuffer::SharedRingBuffer(object_id_t objectId, uint8_t *buffer, const size_t size, bool overwriteOld, size_t maxExcessBytes): SystemObject(objectId), SimpleRingBuffer(buffer, size, overwriteOld, @@ -16,6 +17,11 @@ SharedRingBuffer::SharedRingBuffer(object_id_t objectId, uint8_t *buffer, mutex = MutexFactory::instance()->createMutex(); } + +void SharedRingBuffer::setToUseReceiveSizeFIFO(uint32_t fifoDepth) { + this->fifoDepth = fifoDepth; +} + ReturnValue_t SharedRingBuffer::lockRingBufferMutex( MutexIF::TimeoutType timeoutType, dur_millis_t timeout) { return mutex->lockMutex(timeoutType, timeout); @@ -25,6 +31,25 @@ ReturnValue_t SharedRingBuffer::unlockRingBufferMutex() { return mutex->unlockMutex(); } + + MutexIF* SharedRingBuffer::getMutexHandle() const { return mutex; } + +ReturnValue_t SharedRingBuffer::initialize() { + if(fifoDepth > 0) { + receiveSizesFIFO = new DynamicFIFO(fifoDepth); + } + return SystemObject::initialize(); +} + +DynamicFIFO* SharedRingBuffer::getReceiveSizesFIFO() { + if(receiveSizesFIFO == nullptr) { + // Configuration error. + sif::warning << "SharedRingBuffer::getReceiveSizesFIFO: Ring buffer" + << " was not configured to have sizes FIFO, returning nullptr!" + << std::endl; + } + return receiveSizesFIFO; +} diff --git a/container/SharedRingBuffer.h b/container/SharedRingBuffer.h index 394dcaaa5..fdc9d6267 100644 --- a/container/SharedRingBuffer.h +++ b/container/SharedRingBuffer.h @@ -1,7 +1,8 @@ -#ifndef FRAMEWORK_CONTAINER_SHAREDRINGBUFFER_H_ -#define FRAMEWORK_CONTAINER_SHAREDRINGBUFFER_H_ +#ifndef FSFW_CONTAINER_SHAREDRINGBUFFER_H_ +#define FSFW_CONTAINER_SHAREDRINGBUFFER_H_ -#include "../container/SimpleRingBuffer.h" +#include "SimpleRingBuffer.h" +#include "DynamicFIFO.h" #include "../ipc/MutexIF.h" #include "../objectmanager/SystemObject.h" #include "../timemanager/Clock.h" @@ -26,6 +27,8 @@ public: SharedRingBuffer(object_id_t objectId, const size_t size, bool overwriteOld, size_t maxExcessBytes); + void setToUseReceiveSizeFIFO(uint32_t fifoDepth); + /** * This constructor takes an external buffer with the specified size. * @param buffer @@ -59,10 +62,23 @@ public: * @return */ MutexIF* getMutexHandle() const; + + ReturnValue_t initialize() override; + + /** + * If the shared ring buffer was configured to have a sizes FIFO, a handle + * to that FIFO can be retrieved with this function. + * Do not forget to protect access with a lock if required! + * @return + */ + DynamicFIFO* getReceiveSizesFIFO(); private: MutexIF* mutex = nullptr; + + size_t fifoDepth = 0; + DynamicFIFO* receiveSizesFIFO = nullptr; }; -#endif /* FRAMEWORK_CONTAINER_SHAREDRINGBUFFER_H_ */ +#endif /* FSFW_CONTAINER_SHAREDRINGBUFFER_H_ */ diff --git a/container/SimpleRingBuffer.cpp b/container/SimpleRingBuffer.cpp index d6b6f5aff..88c9290ef 100644 --- a/container/SimpleRingBuffer.cpp +++ b/container/SimpleRingBuffer.cpp @@ -1,4 +1,4 @@ -#include "../container/SimpleRingBuffer.h" +#include "SimpleRingBuffer.h" #include SimpleRingBuffer::SimpleRingBuffer(const size_t size, bool overwriteOld, @@ -25,12 +25,10 @@ SimpleRingBuffer::SimpleRingBuffer(uint8_t *buffer, const size_t size, } } - SimpleRingBuffer::~SimpleRingBuffer() { delete[] buffer; } - ReturnValue_t SimpleRingBuffer::getFreeElement(uint8_t **writePointer, size_t amount) { if (availableWriteSpace() >= amount or overwriteOld) { @@ -131,5 +129,3 @@ ReturnValue_t SimpleRingBuffer::deleteData(size_t amount, incrementRead(amount, READ_PTR); return HasReturnvaluesIF::RETURN_OK; } - - diff --git a/container/SimpleRingBuffer.h b/container/SimpleRingBuffer.h index dcf2684bd..37ad5679f 100644 --- a/container/SimpleRingBuffer.h +++ b/container/SimpleRingBuffer.h @@ -1,7 +1,7 @@ -#ifndef FRAMEWORK_CONTAINER_SIMPLERINGBUFFER_H_ -#define FRAMEWORK_CONTAINER_SIMPLERINGBUFFER_H_ +#ifndef FSFW_CONTAINER_SIMPLERINGBUFFER_H_ +#define FSFW_CONTAINER_SIMPLERINGBUFFER_H_ -#include "../container/RingBufferBase.h" +#include "RingBufferBase.h" #include /** @@ -117,6 +117,7 @@ public: */ ReturnValue_t deleteData(size_t amount, bool deleteRemaining = false, size_t* trueAmount = nullptr); + private: static const uint8_t READ_PTR = 0; uint8_t* buffer = nullptr; @@ -124,5 +125,5 @@ private: size_t excessBytes = 0; }; -#endif /* FRAMEWORK_CONTAINER_SIMPLERINGBUFFER_H_ */ +#endif /* FSFW_CONTAINER_SIMPLERINGBUFFER_H_ */ diff --git a/container/SinglyLinkedList.h b/container/SinglyLinkedList.h index 7d5fc4a9d..eb6ae276a 100644 --- a/container/SinglyLinkedList.h +++ b/container/SinglyLinkedList.h @@ -100,7 +100,7 @@ public: */ ElementIterator back() const { LinkedElement *element = start; - while (element != nullptr) { + while (element->getNext() != nullptr) { element = element->getNext(); } return ElementIterator::Iterator(element); diff --git a/container/listTest.cpp.ignore b/container/listTest.cpp.ignore deleted file mode 100644 index 257b733f5..000000000 --- a/container/listTest.cpp.ignore +++ /dev/null @@ -1,365 +0,0 @@ -#include "FixedArrayList.h" -#include "SinglyLinkedList.h" -#include "HybridIterator.h" - -#include "FixedMap.h" - -#include - -/* - -class Packet: public SinglyLinkedList { -public: - SinglyLinkedList::Element element1; - SinglyLinkedList::Element element2; - - Packet() { - this->start = &element1; - element1.next = &element2; - } -}; - -class Packet2: public SinglyLinkedList { -public: - SinglyLinkedList::Element element1; - SinglyLinkedList::Element, 2>> element2; - SinglyLinkedList::Element element3; - - Packet2() { - this->start = &element1; - element1.next = &element2; - element2.next = &element3; - } -}; - -class Packet3: public SinglyLinkedList { -public: - SinglyLinkedList::TypedElement element1; - SinglyLinkedList::TypedElement element2; - - Packet3() { - this->start = &element1; - element1.next = &element2; - } -}; - -void arrayList() { - puts("** Array List **"); - FixedArrayList list; - FixedArrayList list2; - - list.size = 2; - - list[0] = 0xcafecafe; - - list[1] = 0x12345678; - - uint8_t buffer[100]; - uint8_t *pointer = buffer; - uint32_t size = 0; - uint32_t maxSize = 100; - uint32_t i; - int32_t size2; - - printf("printsize: %i\n", list.getPrintSize()); - - list.print(&pointer, &size, 100, true); - - printf("buffer(%i):", size); - for (i = 0; i < size; ++i) { - printf("%02x", buffer[i]); - } - printf("\n"); - - pointer = buffer; - - size2 = size; - - printf("list2 read: %x\n", list2.read(&pointer, &size2, true)); - - printf("list2(%i):", list2.size); - for (ArrayList::Iterator iter = list2.begin(); - iter != list2.end(); iter++) { - printf("0x%04x ", *iter); - } - printf("\n"); - - HybridIterator hiter(list.begin(),list.end()); - - printf("hybrid1: 0x%04x\n", *(hiter++)); - printf("hybrid2: 0x%04x\n", *hiter); - -} - -void allocatingList() { - puts("** Allocating List **"); - ArrayList myList(3), myList2(2); - myList[0] = 0xab; - myList[1] = 0xcd; - myList.size = 2; - - uint8_t buffer[100]; - uint8_t *pointer = buffer; - uint32_t size = 0; - uint32_t maxSize = 100; - uint32_t i; - int32_t size2; - - myList.print(&pointer, &size, 100, true); - - pointer = buffer; - size2 = size; - - printf("Read %x\n", myList2.read(&pointer, &size2, true)); - - printf("%x,%x\n", myList2[0], myList2[1]); - -} - -void linkedList() { - puts("** Linked List **"); - uint8_t buffer[100]; - uint8_t *pointer = buffer; - uint32_t size = 0; - uint32_t maxSize = 100; - uint32_t i; - int32_t size2; - - Packet myPacket; - myPacket.element1.entry = 0x12345678; - myPacket.element2.entry = 0x9abcdef0; - - pointer = buffer; - size = 0; - ReturnValue_t result = myPacket.print(&pointer, &size, 100, true); - - printf("result %02x\n", result); - - printf("printsize: %i\n", myPacket.getPrintSize()); - - printf("buffer(%i):", size); - for (i = 0; i < size; ++i) { - printf("%02x", buffer[i]); - } - printf("\n"); - - Packet3 myPacket3; - - myPacket3.element1.entry = 0x12345678; - myPacket3.element2.entry = 0xabcdeff; - - SinglyLinkedList::TypedIterator titer(&myPacket3.element1); - - printf("0x%04x\n", *titer); - - HybridIterator hiter(&myPacket3.element1); - - printf("hybrid1: 0x%04x\n", *hiter); - hiter++; - printf("hybrid2: 0x%04x\n", *hiter); -} - -void complex() { - puts("** complex **"); - uint8_t buffer[100]; - uint8_t *pointer = buffer; - uint32_t size = 0; - uint32_t maxSize = 100; - uint32_t i; - int32_t size2 = size; - - Packet myPacket2; - - size2 = size; - pointer = buffer; - - myPacket2.read(&pointer, &size2, true); - - printf("packet: 0x%04x, 0x%04x\n", myPacket2.element1.entry, - myPacket2.element2.entry); - - buffer[0] = 0x12; - buffer[1] = 0x34; - buffer[2] = 0x56; - buffer[3] = 0x78; - buffer[4] = 0x2; - buffer[5] = 0x3; - buffer[6] = 0xab; - buffer[7] = 0xcd; - buffer[8] = 0xef; - buffer[9] = 0x2; - buffer[10] = 0x11; - buffer[11] = 0x22; - buffer[12] = 0xca; - buffer[13] = 0xfe; - buffer[14] = 0x5a; - buffer[15] = 0xfe; - - pointer = buffer; - size2 = 23; - - Packet2 p2; - - ReturnValue_t result = p2.read(&pointer, &size2, true); - printf("result is %02x\n", result); - - printf("%04x; %i: %i: %x %x %x; %i: %x %x;; %04x\n", p2.element1.entry, - p2.element2.entry.size, p2.element2.entry[0].size, - p2.element2.entry[0][0], p2.element2.entry[0][1], - p2.element2.entry[0][2], p2.element2.entry[1].size, - p2.element2.entry[1][0], p2.element2.entry[1][1], - p2.element3.entry); - -} -*/ -struct Test { - uint32_t a; - uint32_t b; -}; - -template -void printMap(FixedMap *map) { - typename FixedMap::Iterator iter; - printf("Map (%i): ", map->getSize()); - for (iter = map->begin(); iter != map->end(); ++iter) { - printf("%x:%08x,%08x ", iter.value->first, (*iter).a, (*iter).b); - } - printf("\n"); -} - -template -void map() { - puts("** Map **"); - typename FixedMap::Iterator iter; - ReturnValue_t result; - FixedMap myMap(5); - - printMap(&myMap); - - Test a; - a.a = 0x01234567; - a.b = 0xabcdef89; - - myMap.insert(1, a); - printMap(&myMap); - - a.a = 0; - - myMap.insert(2, a); - printMap(&myMap); - - printf("2 exists: %x\n", myMap.exists(0x02)); - - printf("ff exists: %x\n", myMap.exists(0xff)); - - a.a = 1; - printf("insert 0x2: %x\n", myMap.insert(2, a)); - - result = myMap.insert(0xff, a); - a.a = 0x44; - result = myMap.insert(0xab, a); - result = myMap.insert(0xa, a); - - printMap(&myMap); - - printf("insert 0x5: %x\n", myMap.insert(5, a)); - - printf("erase 0xfe: %x\n", myMap.erase(0xfe)); - - printf("erase 0x2: %x\n", myMap.erase(0x2)); - - printMap(&myMap); - - printf("erase 0xab: %x\n", myMap.erase(0xab)); - printMap(&myMap); - - printf("insert 0x5: %x\n", myMap.insert(5, a)); - printMap(&myMap); - - iter = myMap.begin(); - ++iter; - ++iter; - ++iter; - - printf("iter: %i: %x,%x\n",iter.value->first, iter->a, iter->b); - - myMap.erase(&iter); - - printf("iter: %i: %x,%x\n",iter.value->first, iter->a, iter->b); - printMap(&myMap); - -} - -/* -void mapPrint() { - puts("** Map Print **"); - FixedMap myMap(5); - Packet2 myPacket; - myPacket.element1.entry = 0x12345678; - - myPacket.element2.entry[0][0] = 0xab; - myPacket.element2.entry[0][1] = 0xcd; - myPacket.element2.entry[0].size = 2; - myPacket.element2.entry.size = 1; - - myPacket.element3.entry = 0xabcdef90; - - myMap.insert(0x1234, myPacket); - - uint8_t buffer[100]; - uint32_t size = 0, i; - uint8_t *pointer = buffer; - - printf("printsize: %i\n", myMap.getPrintSize()); - - SerializeAdapter>::print(&myMap, &pointer, - &size, 100, false); - - printf("buffer(%i):", size); - for (i = 0; i < size; ++i) { - printf("%02x", buffer[i]); - } - printf("\n"); - - int32_t size2 = size; - pointer = buffer; - - FixedMap myMap2(5); - - ReturnValue_t result = SerializeAdapter>::read( - &myMap2, &pointer, &size2, false); - - Packet2 *myPacket2 = myMap2.find(0x1234); - - printf("Map (%i): Packet2: %x, Array (%i): Array (%i): %x, %x; %x\n", - myMap2.getSize(), myPacket2->element1.entry, - myPacket2->element2.entry.size, myPacket2->element2.entry[0].size, - myPacket2->element2.entry[0][0], myPacket2->element2.entry[0][1], - myPacket2->element3.entry); - -} - -void empty() { - puts("** Empty **"); - ArrayList list(0); - printf("%p %p\n", list.front(), list.back()); -} -*/ - -int main(void) { - -// arrayList(); -// linkedList(); -// allocatingList(); -// complex(); - - map(); -// -// mapPrint(); - -// empty(); - - - - return 0; -} diff --git a/controller/ControllerBase.cpp b/controller/ControllerBase.cpp index da84ed277..45e678eb4 100644 --- a/controller/ControllerBase.cpp +++ b/controller/ControllerBase.cpp @@ -1,5 +1,5 @@ -#include "../subsystem/SubsystemBase.h" -#include "../controller/ControllerBase.h" +#include "ControllerBase.h" + #include "../subsystem/SubsystemBase.h" #include "../ipc/QueueFactory.h" #include "../action/HasActionsIF.h" @@ -9,7 +9,8 @@ ControllerBase::ControllerBase(object_id_t setObjectId, object_id_t parentId, SystemObject(setObjectId), parentId(parentId), mode(MODE_OFF), submode(SUBMODE_NONE), modeHelper(this), healthHelper(this, setObjectId), hkSwitcher(this) { - commandQueue = QueueFactory::instance()->createMessageQueue(commandQueueDepth); + commandQueue = QueueFactory::instance()->createMessageQueue( + commandQueueDepth); } ControllerBase::~ControllerBase() { @@ -25,7 +26,7 @@ ReturnValue_t ControllerBase::initialize() { MessageQueueId_t parentQueue = 0; if (parentId != objects::NO_OBJECT) { SubsystemBase *parent = objectManager->get(parentId); - if (parent == NULL) { + if (parent == nullptr) { return RETURN_FAILED; } parentQueue = parent->getCommandQueue(); @@ -56,8 +57,9 @@ MessageQueueId_t ControllerBase::getCommandQueue() const { void ControllerBase::handleQueue() { CommandMessage command; - ReturnValue_t result; - for (result = commandQueue->receiveMessage(&command); result == RETURN_OK; + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + for (result = commandQueue->receiveMessage(&command); + result == RETURN_OK; result = commandQueue->receiveMessage(&command)) { result = modeHelper.handleModeCommand(&command); diff --git a/controller/ControllerBase.h b/controller/ControllerBase.h index 400c3bb6c..25d3ab1f3 100644 --- a/controller/ControllerBase.h +++ b/controller/ControllerBase.h @@ -7,12 +7,14 @@ #include "../modes/ModeHelper.h" #include "../objectmanager/SystemObject.h" #include "../tasks/ExecutableObjectIF.h" +#include "../tasks/PeriodicTaskIF.h" #include "../datapool/HkSwitchHelper.h" /** - * @brief Generic base class for controller classes + * @brief Generic base class for controller classes * @details - * Implements common interfaces for controllers. + * Implements common interfaces for controllers, which generally have + * a mode and a health state. This avoids boilerplate code. */ class ControllerBase: public HasModesIF, public HasHealthIF, @@ -26,24 +28,18 @@ public: size_t commandQueueDepth = 3); virtual ~ControllerBase(); + /** SystemObject override */ virtual ReturnValue_t initialize() override; virtual MessageQueueId_t getCommandQueue() const override; - virtual ReturnValue_t performOperation(uint8_t opCode) override; - + /** HasHealthIF overrides */ virtual ReturnValue_t setHealth(HealthState health) override; - virtual HasHealthIF::HealthState getHealth() override; - /** - * Implementation of ExecutableObjectIF function - * - * Used to setup the reference of the task, that executes this component - * @param task_ Pointer to the taskIF of this task - */ - virtual void setTaskIF(PeriodicTaskIF* task_) override; - + /** ExecutableObjectIF overrides */ + virtual ReturnValue_t performOperation(uint8_t opCode) override; + virtual void setTaskIF(PeriodicTaskIF* task) override; virtual ReturnValue_t initializeAfterTaskCreation() override; protected: @@ -56,6 +52,9 @@ protected: */ virtual ReturnValue_t handleCommandMessage(CommandMessage *message) = 0; + /** + * Periodic helper, implemented by child class. + */ virtual void performControlOperation() = 0; virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, @@ -73,6 +72,7 @@ protected: HealthHelper healthHelper; + // Is this still needed? HkSwitchHelper hkSwitcher; /** @@ -81,13 +81,16 @@ protected: */ PeriodicTaskIF* executingTask = nullptr; - void handleQueue(); + /** Handle mode and health messages */ + virtual void handleQueue(); + /** Mode helpers */ virtual void modeChanged(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 setToExternalControl(); virtual void announceMode(bool recursive); + /** HK helpers */ virtual void changeHK(Mode_t mode, Submode_t submode, bool enable); }; diff --git a/controller/ExtendedControllerBase.cpp b/controller/ExtendedControllerBase.cpp new file mode 100644 index 000000000..f69d2ea1a --- /dev/null +++ b/controller/ExtendedControllerBase.cpp @@ -0,0 +1,114 @@ +#include "ExtendedControllerBase.h" + + +ExtendedControllerBase::ExtendedControllerBase(object_id_t objectId, + object_id_t parentId, size_t commandQueueDepth): + ControllerBase(objectId, parentId, commandQueueDepth), + localPoolManager(this, commandQueue), + actionHelper(this, commandQueue) { +} + +ReturnValue_t ExtendedControllerBase::executeAction(ActionId_t actionId, + MessageQueueId_t commandedBy, const uint8_t *data, size_t size) { + // needs to be overriden and implemented by child class. + return HasReturnvaluesIF::RETURN_OK; +} + + + +ReturnValue_t ExtendedControllerBase::initializeLocalDataPool( + LocalDataPool &localDataPoolMap, LocalDataPoolManager &poolManager) { + // needs to be overriden and implemented by child class. + return HasReturnvaluesIF::RETURN_OK; +} + +object_id_t ExtendedControllerBase::getObjectId() const { + return SystemObject::getObjectId(); +} + +LocalDataPoolManager* ExtendedControllerBase::getHkManagerHandle() { + return &localPoolManager; +} + +uint32_t ExtendedControllerBase::getPeriodicOperationFrequency() const { + return this->executingTask->getPeriodMs(); +} + +ReturnValue_t ExtendedControllerBase::handleCommandMessage( + CommandMessage *message) { + ReturnValue_t result = actionHelper.handleActionMessage(message); + if(result == HasReturnvaluesIF::RETURN_OK) { + return result; + } + return localPoolManager.handleHousekeepingMessage(message); +} + +void ExtendedControllerBase::handleQueue() { + CommandMessage command; + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + for (result = commandQueue->receiveMessage(&command); + result == RETURN_OK; + result = commandQueue->receiveMessage(&command)) { + result = actionHelper.handleActionMessage(&command); + if (result == RETURN_OK) { + continue; + } + + result = modeHelper.handleModeCommand(&command); + if (result == RETURN_OK) { + continue; + } + + result = healthHelper.handleHealthCommand(&command); + if (result == RETURN_OK) { + continue; + } + + result = localPoolManager.handleHousekeepingMessage(&command); + if (result == RETURN_OK) { + continue; + } + + result = handleCommandMessage(&command); + if (result == RETURN_OK) { + continue; + } + command.setToUnknownCommand(); + commandQueue->reply(&command); + } +} + +ReturnValue_t ExtendedControllerBase::initialize() { + ReturnValue_t result = ControllerBase::initialize(); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = actionHelper.initialize(commandQueue); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + + return localPoolManager.initialize(commandQueue); +} + +ReturnValue_t ExtendedControllerBase::initializeAfterTaskCreation() { + return localPoolManager.initializeAfterTaskCreation(); +} + +ReturnValue_t ExtendedControllerBase::performOperation(uint8_t opCode) { + handleQueue(); + hkSwitcher.performOperation(); + localPoolManager.performHkOperation(); + performControlOperation(); + return RETURN_OK; +} + +MessageQueueId_t ExtendedControllerBase::getCommandQueue() const { + return commandQueue->getId(); +} + +LocalPoolDataSetBase* ExtendedControllerBase::getDataSetHandle(sid_t sid) { + sif::warning << "ExtendedControllerBase::getDataSetHandle: No child " + << " implementation provided, returning nullptr!" << std::endl; + return nullptr; +} diff --git a/controller/ExtendedControllerBase.h b/controller/ExtendedControllerBase.h new file mode 100644 index 000000000..02c5728e1 --- /dev/null +++ b/controller/ExtendedControllerBase.h @@ -0,0 +1,72 @@ +#ifndef FSFW_CONTROLLER_EXTENDEDCONTROLLERBASE_H_ +#define FSFW_CONTROLLER_EXTENDEDCONTROLLERBASE_H_ + +#include "ControllerBase.h" + +#include "../action/HasActionsIF.h" +#include "../datapoollocal/HasLocalDataPoolIF.h" +#include "../action/ActionHelper.h" +#include "../datapoollocal/LocalDataPoolManager.h" + +/** + * @brief Extendes the basic ControllerBase with the common components + * HasActionsIF for commandability and HasLocalDataPoolIF to keep + * a pool of local data pool variables. + * @details + * Default implementations required for the interfaces will be empty and have + * to be implemented by child class. + */ +class ExtendedControllerBase: public ControllerBase, + public HasActionsIF, + public HasLocalDataPoolIF { +public: + ExtendedControllerBase(object_id_t objectId, object_id_t parentId, + size_t commandQueueDepth = 3); + + /** SystemObjectIF overrides */ + virtual ReturnValue_t initialize() override; + + virtual MessageQueueId_t getCommandQueue() const override; + + /** ExecutableObjectIF overrides */ + virtual ReturnValue_t performOperation(uint8_t opCode) override; + virtual ReturnValue_t initializeAfterTaskCreation() override; + +protected: + LocalDataPoolManager localPoolManager; + ActionHelper actionHelper; + + /** + * Implemented by child class. Handle all command messages which are + * not health, mode, action or housekeeping messages. + * @param message + * @return + */ + virtual ReturnValue_t handleCommandMessage(CommandMessage *message) = 0; + + /** + * Periodic helper from ControllerBase, implemented by child class. + */ + virtual void performControlOperation() = 0; + + /** Handle the four messages mentioned above */ + void handleQueue() override; + + /** HasActionsIF overrides */ + virtual ReturnValue_t executeAction(ActionId_t actionId, + MessageQueueId_t commandedBy, const uint8_t* data, + size_t size) override; + + /** HasLocalDatapoolIF overrides */ + virtual object_id_t getObjectId() const override; + virtual ReturnValue_t initializeLocalDataPool( + LocalDataPool& localDataPoolMap, + LocalDataPoolManager& poolManager) override; + virtual LocalDataPoolManager* getHkManagerHandle() override; + virtual uint32_t getPeriodicOperationFrequency() const override; + virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override; +}; + + + +#endif /* FSFW_CONTROLLER_EXTENDEDCONTROLLERBASE_H_ */ diff --git a/datapool/DataSetIF.h b/datapool/DataSetIF.h index b51da3a47..a6634a5c7 100644 --- a/datapool/DataSetIF.h +++ b/datapool/DataSetIF.h @@ -1,5 +1,5 @@ -#ifndef DATASETIF_H_ -#define DATASETIF_H_ +#ifndef FSFW_DATAPOOL_DATASETIF_H_ +#define FSFW_DATAPOOL_DATASETIF_H_ #include "../returnvalues/HasReturnvaluesIF.h" #include "../timemanager/Clock.h" @@ -34,7 +34,6 @@ public: */ virtual ~DataSetIF() {} - /** * @brief This operation provides a method to register local data pool * variables to register in a data set by passing itself @@ -45,4 +44,4 @@ public: virtual uint16_t getFillCount() const = 0; }; -#endif /* FRAMEWORK_DATAPOOL_DATASETIF_H_ */ +#endif /* FSFW_DATAPOOL_DATASETIF_H_ */ diff --git a/datapool/PoolDataSetBase.cpp b/datapool/PoolDataSetBase.cpp index 1acd3fd3b..cb2348f72 100644 --- a/datapool/PoolDataSetBase.cpp +++ b/datapool/PoolDataSetBase.cpp @@ -59,6 +59,11 @@ uint16_t PoolDataSetBase::getFillCount() const { ReturnValue_t PoolDataSetBase::readVariable(uint16_t count) { ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + if(registeredVariables[count] == nullptr) { + // configuration error. + return HasReturnvaluesIF::RETURN_FAILED; + } + // These checks are often performed by the respective // variable implementation too, but I guess a double check does not hurt. if (registeredVariables[count]->getReadWriteMode() != diff --git a/datapool/PoolDataSetBase.h b/datapool/PoolDataSetBase.h index 666624138..a8931d628 100644 --- a/datapool/PoolDataSetBase.h +++ b/datapool/PoolDataSetBase.h @@ -1,7 +1,8 @@ -#ifndef FRAMEWORK_DATAPOOL_DATASETBASE_H_ -#define FRAMEWORK_DATAPOOL_DATASETBASE_H_ -#include "../datapool/PoolDataSetIF.h" -#include "../datapool/PoolVariableIF.h" +#ifndef FSFW_DATAPOOL_POOLDATASETBASE_H_ +#define FSFW_DATAPOOL_POOLDATASETBASE_H_ + +#include "PoolDataSetIF.h" +#include "PoolVariableIF.h" #include "../ipc/MutexIF.h" /** @@ -148,4 +149,4 @@ private: ReturnValue_t handleUnreadDatasetCommit(uint32_t lockTimeout); }; -#endif /* FRAMEWORK_DATAPOOL_POOLPOOLDATASETBASE_H_ */ +#endif /* FSFW_DATAPOOL_POOLDATASETBASE_H_ */ diff --git a/datapool/PoolDataSetIF.h b/datapool/PoolDataSetIF.h index 44ca468bd..aa45fa548 100644 --- a/datapool/PoolDataSetIF.h +++ b/datapool/PoolDataSetIF.h @@ -1,7 +1,12 @@ -#ifndef FRAMEWORK_DATAPOOL_POOLDATASETIF_H_ -#define FRAMEWORK_DATAPOOL_POOLDATASETIF_H_ +#ifndef FSFW_DATAPOOL_POOLDATASETIF_H_ +#define FSFW_DATAPOOL_POOLDATASETIF_H_ + #include "DataSetIF.h" +/** + * @brief Extendes the DataSetIF by adding abstract functions to lock + * and unlock a data pool and read/commit semantics. + */ class PoolDataSetIF: public DataSetIF { public: virtual~ PoolDataSetIF() {}; @@ -25,4 +30,4 @@ public: virtual bool isValid() const = 0; }; -#endif /* FRAMEWORK_DATAPOOL_POOLDATASETIF_H_ */ +#endif /* FSFW_DATAPOOL_POOLDATASETIF_H_ */ diff --git a/datapool/PoolEntry.cpp b/datapool/PoolEntry.cpp index b0506b824..fb73328ca 100644 --- a/datapool/PoolEntry.cpp +++ b/datapool/PoolEntry.cpp @@ -1,4 +1,5 @@ -#include "../datapool/PoolEntry.h" +#include "PoolEntry.h" + #include "../serviceinterface/ServiceInterfaceStream.h" #include "../globalfunctions/arrayprinter.h" #include diff --git a/datapool/PoolEntry.h b/datapool/PoolEntry.h index 6a3daacf9..033db40d0 100644 --- a/datapool/PoolEntry.h +++ b/datapool/PoolEntry.h @@ -1,7 +1,7 @@ -#ifndef FRAMEWORK_DATAPOOL_POOLENTRY_H_ -#define FRAMEWORK_DATAPOOL_POOLENTRY_H_ +#ifndef FSFW_DATAPOOL_POOLENTRY_H_ +#define FSFW_DATAPOOL_POOLENTRY_H_ -#include "../datapool/PoolEntryIF.h" +#include "PoolEntryIF.h" #include #include @@ -127,4 +127,4 @@ public: Type getType(); }; -#endif /* POOLENTRY_H_ */ +#endif /* FSFW_DATAPOOL_POOLENTRY_H_ */ diff --git a/datapool/PoolEntryIF.h b/datapool/PoolEntryIF.h index 462de18b8..d9db52375 100644 --- a/datapool/PoolEntryIF.h +++ b/datapool/PoolEntryIF.h @@ -1,5 +1,5 @@ -#ifndef FRAMEWORK_DATAPOOL_POOLENTRYIF_H_ -#define FRAMEWORK_DATAPOOL_POOLENTRYIF_H_ +#ifndef FSFW_DATAPOOL_POOLENTRYIF_H_ +#define FSFW_DATAPOOL_POOLENTRYIF_H_ #include "../globalfunctions/Type.h" #include @@ -60,4 +60,4 @@ public: virtual Type getType() = 0; }; -#endif /* POOLENTRYIF_H_ */ +#endif /* FSFW_DATAPOOL_POOLENTRYIF_H_ */ diff --git a/datapool/PoolRawAccessHelper.cpp b/datapool/PoolRawAccessHelper.cpp deleted file mode 100644 index 3696a21d1..000000000 --- a/datapool/PoolRawAccessHelper.cpp +++ /dev/null @@ -1,188 +0,0 @@ -/** - * @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 -#include - -PoolRawAccessHelper::PoolRawAccessHelper(uint32_t * poolIdBuffer_, - uint8_t numberOfParameters_): - poolIdBuffer(reinterpret_cast(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(¤tPoolId, - &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, - ¤tDataSet, 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(¤tPoolRawAccess, &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; -} diff --git a/datapool/PoolRawAccessHelper.h b/datapool/PoolRawAccessHelper.h deleted file mode 100644 index db25acdf8..000000000 --- a/datapool/PoolRawAccessHelper.h +++ /dev/null @@ -1,111 +0,0 @@ -/** - * @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_ */ diff --git a/datapool/PoolVarList.h b/datapool/PoolVarList.h index 1c8a7be48..0b2b0f064 100644 --- a/datapool/PoolVarList.h +++ b/datapool/PoolVarList.h @@ -1,5 +1,5 @@ -#ifndef POOLVARLIST_H_ -#define POOLVARLIST_H_ +#ifndef FSFW_DATAPOOL_POOLVARLIST_H_ +#define FSFW_DATAPOOL_POOLVARLIST_H_ #include "../datapool/PoolVariableIF.h" #include "../datapoolglob/GlobalPoolVariable.h" @@ -8,7 +8,8 @@ class PoolVarList { private: GlobPoolVar variables[n_var]; 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. if (dataSet == NULL) { return; @@ -25,4 +26,4 @@ public: -#endif /* POOLVARLIST_H_ */ +#endif /* FSFW_DATAPOOL_POOLVARLIST_H_ */ diff --git a/datapool/PoolVariableIF.h b/datapool/PoolVariableIF.h index 2aa269dd4..cd15f7445 100644 --- a/datapool/PoolVariableIF.h +++ b/datapool/PoolVariableIF.h @@ -1,5 +1,5 @@ -#ifndef FRAMEWORK_DATAPOOL_POOLVARIABLEIF_H_ -#define FRAMEWORK_DATAPOOL_POOLVARIABLEIF_H_ +#ifndef FSFW_DATAPOOL_POOLVARIABLEIF_H_ +#define FSFW_DATAPOOL_POOLVARIABLEIF_H_ #include "../returnvalues/HasReturnvaluesIF.h" #include "../serialize/SerializeIF.h" @@ -96,4 +96,4 @@ protected: using pool_rwm_t = PoolVariableIF::ReadWriteMode_t; -#endif /* POOLVARIABLEIF_H_ */ +#endif /* FSFW_DATAPOOL_POOLVARIABLEIF_H_ */ diff --git a/datapool/ControllerSet.cpp b/datapoolglob/ControllerSet.cpp similarity index 79% rename from datapool/ControllerSet.cpp rename to datapoolglob/ControllerSet.cpp index 4055158bc..54fc6e8c9 100644 --- a/datapool/ControllerSet.cpp +++ b/datapoolglob/ControllerSet.cpp @@ -1,4 +1,4 @@ -#include "../datapool/ControllerSet.h" +#include ControllerSet::ControllerSet() { diff --git a/datapool/ControllerSet.h b/datapoolglob/ControllerSet.h similarity index 59% rename from datapool/ControllerSet.h rename to datapoolglob/ControllerSet.h index 43e1cbf21..5da113973 100644 --- a/datapool/ControllerSet.h +++ b/datapoolglob/ControllerSet.h @@ -1,5 +1,5 @@ -#ifndef CONTROLLERSET_H_ -#define CONTROLLERSET_H_ +#ifndef FSFW_DATAPOOLGLOB_CONTROLLERSET_H_ +#define FSFW_DATAPOOLGLOB_CONTROLLERSET_H_ #include "../datapoolglob/GlobalDataSet.h" @@ -12,4 +12,4 @@ public: void setInvalid(); }; -#endif /* CONTROLLERSET_H_ */ +#endif /* FSFW_DATAPOOLGLOB_CONTROLLERSET_H_ */ diff --git a/datapoolglob/DataPoolAdmin.cpp b/datapoolglob/DataPoolAdmin.cpp index 029a336d1..6ede0841e 100644 --- a/datapoolglob/DataPoolAdmin.cpp +++ b/datapoolglob/DataPoolAdmin.cpp @@ -1,7 +1,8 @@ -#include "../datapoolglob/DataPoolAdmin.h" -#include "../datapoolglob/GlobalDataSet.h" -#include "../datapoolglob/GlobalDataPool.h" -#include "../datapoolglob/PoolRawAccess.h" +#include "DataPoolAdmin.h" +#include "GlobalDataSet.h" +#include "GlobalDataPool.h" +#include "PoolRawAccess.h" + #include "../ipc/CommandMessage.h" #include "../ipc/QueueFactory.h" #include "../parameters/ParameterMessage.h" diff --git a/datapoolglob/DataPoolAdmin.h b/datapoolglob/DataPoolAdmin.h index a08f322d9..d8871b651 100644 --- a/datapoolglob/DataPoolAdmin.h +++ b/datapoolglob/DataPoolAdmin.h @@ -1,5 +1,7 @@ -#ifndef DATAPOOLADMIN_H_ -#define DATAPOOLADMIN_H_ +#ifndef FSFW_DATAPOOLGLOB_DATAPOOLADMIN_H_ +#define FSFW_DATAPOOLGLOB_DATAPOOLADMIN_H_ + +#include "DataPoolParameterWrapper.h" #include "../objectmanager/SystemObject.h" #include "../returnvalues/HasReturnvaluesIF.h" @@ -7,10 +9,9 @@ #include "../action/HasActionsIF.h" #include "../ipc/MessageQueueIF.h" #include "../parameters/ReceivesParameterMessagesIF.h" - -#include "../memory/MemoryHelper.h" #include "../action/SimpleActionHelper.h" -#include "../datapoolglob/DataPoolParameterWrapper.h" +#include "../memory/MemoryHelper.h" + class DataPoolAdmin: public HasActionsIF, public ExecutableObjectIF, @@ -56,4 +57,4 @@ private: Command_t initialCommand); }; -#endif /* DATAPOOLADMIN_H_ */ +#endif /* FSFW_DATAPOOLGLOB_DATAPOOLADMIN_H_ */ diff --git a/datapoolglob/GlobalPoolVector.h b/datapoolglob/GlobalPoolVector.h index 6b592fc67..0f5daacd8 100644 --- a/datapoolglob/GlobalPoolVector.h +++ b/datapoolglob/GlobalPoolVector.h @@ -1,5 +1,5 @@ -#ifndef GLOBALPOOLVECTOR_H_ -#define GLOBALPOOLVECTOR_H_ +#ifndef FSFW_DATAPOOLGLOB_GLOBALPOOLVECTOR_H_ +#define FSFW_DATAPOOLGLOB_GLOBALPOOLVECTOR_H_ #include "../datapool/DataSetIF.h" #include "../datapool/PoolEntry.h" @@ -182,4 +182,4 @@ private: template using gp_vec_t = GlobPoolVector; -#endif /* POOLVECTOR_H_ */ +#endif /* FSFW_DATAPOOLGLOB_GLOBALPOOLVECTOR_H_ */ diff --git a/datapoolglob/GlobalPoolVector.tpp b/datapoolglob/GlobalPoolVector.tpp index ccf33138d..013a682a4 100644 --- a/datapoolglob/GlobalPoolVector.tpp +++ b/datapoolglob/GlobalPoolVector.tpp @@ -1,5 +1,5 @@ -#ifndef GLOBALPOOLVECTOR_TPP_ -#define GLOBALPOOLVECTOR_TPP_ +#ifndef FSFW_DATAPOOLGLOB_GLOBALPOOLVECTOR_TPP_ +#define FSFW_DATAPOOLGLOB_GLOBALPOOLVECTOR_TPP_ template diff --git a/datapoollocal/HasLocalDataPoolIF.h b/datapoollocal/HasLocalDataPoolIF.h index 9eb1c9f11..f8f4ef4c4 100644 --- a/datapoollocal/HasLocalDataPoolIF.h +++ b/datapoollocal/HasLocalDataPoolIF.h @@ -1,12 +1,15 @@ -#ifndef FRAMEWORK_DATAPOOL_HASHKPOOLPARAMETERSIF_H_ -#define FRAMEWORK_DATAPOOL_HASHKPOOLPARAMETERSIF_H_ +#ifndef FSFW_DATAPOOLLOCAL_HASLOCALDATAPOOLIF_H_ +#define FSFW_DATAPOOLLOCAL_HASLOCALDATAPOOLIF_H_ + #include "../datapool/PoolEntryIF.h" #include "../ipc/MessageQueueSenderIF.h" #include "../housekeeping/HousekeepingMessage.h" + #include class LocalDataPoolManager; -class DataSetIF; +class LocalPoolDataSetBase; + /** * @brief Type definition for local pool entries. */ @@ -61,11 +64,11 @@ public: virtual LocalDataPoolManager* getHkManagerHandle() = 0; /** - * Returns the minimum sampling frequency, which will usually be the - * period the pool owner performs its periodic operation- + * Returns the minimum sampling frequency in milliseconds, which will + * usually be the period the pool owner performs its periodic operation. * @return */ - virtual dur_millis_t getPeriodicOperationFrequency() const = 0; + virtual uint32_t getPeriodicOperationFrequency() const = 0; /** * This function is used by the pool manager to get a valid dataset @@ -73,7 +76,7 @@ public: * @param sid Corresponding structure ID * @return */ - virtual DataSetIF* getDataSetHandle(sid_t sid) = 0; + virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) = 0; /* These function can be implemented by pool owner, as they are required * by the housekeeping message interface */ @@ -84,9 +87,9 @@ public: return HasReturnvaluesIF::RETURN_FAILED; }; virtual ReturnValue_t changeCollectionInterval(sid_t sid, - dur_seconds_t newInterval) { + float newIntervalSeconds) { return HasReturnvaluesIF::RETURN_FAILED; }; }; -#endif /* FRAMEWORK_DATAPOOL_HASHKPOOLPARAMETERSIF_H_ */ +#endif /* FSFW_DATAPOOLLOCAL_HASLOCALDATAPOOLIF_H_ */ diff --git a/datapoollocal/LocalDataPoolManager.cpp b/datapoollocal/LocalDataPoolManager.cpp index 87a0a3cb8..4f124e7fe 100644 --- a/datapoollocal/LocalDataPoolManager.cpp +++ b/datapoollocal/LocalDataPoolManager.cpp @@ -1,63 +1,75 @@ -#include "../datapoollocal/LocalDataPoolManager.h" -#include "../datapoollocal/LocalDataSet.h" +#include "LocalDataPoolManager.h" +#include "LocalPoolDataSetBase.h" + +#include "../housekeeping/HousekeepingSetPacket.h" #include "../housekeeping/AcceptsHkPacketsIF.h" #include "../ipc/MutexFactory.h" #include "../ipc/MutexHelper.h" #include "../ipc/QueueFactory.h" +#include "../objectmanager/frameworkObjects.h" #include #include -object_id_t LocalDataPoolManager::defaultHkDestination = objects::NO_OBJECT; +object_id_t LocalDataPoolManager::defaultHkDestination = + objects::PUS_SERVICE_3_HOUSEKEEPING; LocalDataPoolManager::LocalDataPoolManager(HasLocalDataPoolIF* owner, MessageQueueIF* queueToUse, bool appendValidityBuffer): appendValidityBuffer(appendValidityBuffer) { - if(owner == nullptr) { - sif::error << "HkManager: Invalid supplied owner!" << std::endl; - return; - } - this->owner = owner; - mutex = MutexFactory::instance()->createMutex(); - if(mutex == nullptr) { - sif::error << "LocalDataPoolManager::LocalDataPoolManager: " - "Could not create mutex." << std::endl; - } - ipcStore = objectManager->get(objects::IPC_STORE); - if(ipcStore == nullptr) { - sif::error << "LocalDataPoolManager::LocalDataPoolManager: " - "Could not set IPC store." << std::endl; - } + if(owner == nullptr) { + sif::error << "LocalDataPoolManager::LocalDataPoolManager: " + << "Invalid supplied owner!" << std::endl; + return; + } + this->owner = owner; + mutex = MutexFactory::instance()->createMutex(); + if(mutex == nullptr) { + sif::error << "LocalDataPoolManager::LocalDataPoolManager: " + << "Could not create mutex." << std::endl; + } - hkQueue = queueToUse; - - if(defaultHkDestination != objects::NO_OBJECT) { - AcceptsHkPacketsIF* hkPacketReceiver = - objectManager->get(defaultHkDestination); - if(hkPacketReceiver != nullptr) { - defaultHkDestinationId = hkPacketReceiver->getHkQueue(); - } - } + hkQueue = queueToUse; } LocalDataPoolManager::~LocalDataPoolManager() {} ReturnValue_t LocalDataPoolManager::initialize(MessageQueueIF* queueToUse) { if(queueToUse == nullptr) { - sif::error << "LocalDataPoolManager::initialize: Supplied queue " - "invalid!" << std::endl; + sif::error << "LocalDataPoolManager::initialize: " + << std::hex << "0x" << owner->getObjectId() << ". Supplied " + << "queue invalid!" << std::dec << std::endl; } hkQueue = queueToUse; + ipcStore = objectManager->get(objects::IPC_STORE); + if(ipcStore == nullptr) { + sif::error << "LocalDataPoolManager::initialize: " + << std::hex << "0x" << owner->getObjectId() << ": Could not " + << "set IPC store." <get(defaultHkDestination); + if(hkPacketReceiver != nullptr) { + hkDestinationId = hkPacketReceiver->getHkQueue(); + } + else { + sif::error << "LocalDataPoolManager::LocalDataPoolManager: " + << "Default HK destination object is invalid!" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + } + return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t LocalDataPoolManager::initializeAfterTaskCreation( uint8_t nonDiagInvlFactor) { setNonDiagnosticIntervalFactor(nonDiagInvlFactor); - diagnosticMinimumInterval = owner->getPeriodicOperationFrequency(); - regularMinimumInterval = diagnosticMinimumInterval * - nonDiagnosticIntervalFactor; return initializeHousekeepingPoolEntriesOnce(); } @@ -71,20 +83,17 @@ ReturnValue_t LocalDataPoolManager::initializeHousekeepingPoolEntriesOnce() { return result; } sif::warning << "HousekeepingManager: The map should only be initialized " - "once!" << std::endl; + << "once!" << std::endl; return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t LocalDataPoolManager::performHkOperation() { - for(auto& hkReceiversIter: hkReceiversMap) { - HkReceiver* receiver = &hkReceiversIter.second; - if(not receiver->reportingEnabled) { - return HasReturnvaluesIF::RETURN_OK; - } + for(auto& receiver: hkReceiversMap) { + //HkReceiver* receiver = &hkReceiversIter.second; - switch(receiver->reportingType) { + switch(receiver.reportingType) { case(ReportingType::PERIODIC): { - if(receiver->dataId.dataSetSid.notSet()) { + if(receiver.dataType == DataType::LOCAL_POOL_VARIABLE) { // Periodic packets shall only be generated from datasets. continue; } @@ -110,50 +119,100 @@ ReturnValue_t LocalDataPoolManager::subscribeForPeriodicPacket(sid_t sid, objectManager->get(packetDestination); if(hkReceiverObject == nullptr) { sif::error << "LocalDataPoolManager::subscribeForPeriodicPacket:" - " Invalid receiver!"<< std::endl; + << " Invalid receiver!"<< std::endl; return HasReturnvaluesIF::RETURN_OK; } struct HkReceiver hkReceiver; - hkReceiver.dataId.dataSetSid = sid; + hkReceiver.dataId.sid = sid; hkReceiver.reportingType = ReportingType::PERIODIC; hkReceiver.destinationQueue = hkReceiverObject->getHkQueue(); - hkReceiver.reportingEnabled = enableReporting; - if(not isDiagnostics) { - hkReceiver.hkParameter.collectionIntervalTicks = - intervalSecondsToInterval(isDiagnostics, collectionInterval * - nonDiagnosticIntervalFactor); - } - else { - hkReceiver.hkParameter.collectionIntervalTicks = - intervalSecondsToInterval(isDiagnostics, collectionInterval); + + LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid); + if(dataSet != nullptr) { + dataSet->setReportingEnabled(enableReporting); + dataSet->setDiagnostic(isDiagnostics); + dataSet->initializePeriodicHelper(collectionInterval, + owner->getPeriodicOperationFrequency(), isDiagnostics); } - hkReceiver.isDiagnostics = isDiagnostics; - hkReceiver.intervalCounter = 1; - - hkReceiversMap.emplace(packetDestination, hkReceiver); + hkReceiversMap.push_back(hkReceiver); return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage( CommandMessage* message) { Command_t command = message->getCommand(); + sid_t sid = HousekeepingMessage::getSid(message); + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; switch(command) { - // I think those are the only commands which can be handled here.. - case(HousekeepingMessage::ADD_HK_REPORT_STRUCT): - case(HousekeepingMessage::ADD_DIAGNOSTICS_REPORT_STRUCT): - // We should use OwnsLocalPoolDataIF to specify those functions.. - return HasReturnvaluesIF::RETURN_OK; + case(HousekeepingMessage::ENABLE_PERIODIC_DIAGNOSTICS_GENERATION): { + result = togglePeriodicGeneration(sid, true, true); + break; + } + + case(HousekeepingMessage::DISABLE_PERIODIC_DIAGNOSTICS_GENERATION): { + result = togglePeriodicGeneration(sid, false, true); + break; + } + + case(HousekeepingMessage::ENABLE_PERIODIC_HK_REPORT_GENERATION): { + result = togglePeriodicGeneration(sid, true, false); + break; + } + + case(HousekeepingMessage::DISABLE_PERIODIC_HK_REPORT_GENERATION): { + result = togglePeriodicGeneration(sid, false, false); + break; + } + case(HousekeepingMessage::REPORT_DIAGNOSTICS_REPORT_STRUCTURES): + return generateSetStructurePacket(sid, true); case(HousekeepingMessage::REPORT_HK_REPORT_STRUCTURES): - //return generateSetStructurePacket(message->getSid()); + return generateSetStructurePacket(sid, false); + case(HousekeepingMessage::MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL): + case(HousekeepingMessage::MODIFY_PARAMETER_REPORT_COLLECTION_INTERVAL): { + float newCollIntvl = 0; + HousekeepingMessage::getCollectionIntervalModificationCommand(message, + &newCollIntvl); + if(command == HousekeepingMessage:: + MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL) { + result = changeCollectionInterval(sid, newCollIntvl, true); + } + else { + result = changeCollectionInterval(sid, newCollIntvl, false); + } + break; + } + case(HousekeepingMessage::GENERATE_ONE_PARAMETER_REPORT): - case(HousekeepingMessage::GENERATE_ONE_DIAGNOSTICS_REPORT): - //return generateHousekeepingPacket(message->getSid()); + case(HousekeepingMessage::GENERATE_ONE_DIAGNOSTICS_REPORT): { + LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid); + if(command == HousekeepingMessage::GENERATE_ONE_PARAMETER_REPORT + and dataSet->isDiagnostics()) { + return WRONG_HK_PACKET_TYPE; + } + else if(command == HousekeepingMessage::GENERATE_ONE_DIAGNOSTICS_REPORT + and not dataSet->isDiagnostics()) { + return WRONG_HK_PACKET_TYPE; + } + return generateHousekeepingPacket(HousekeepingMessage::getSid(message), + dataSet, true); + } + default: return CommandMessageIF::UNKNOWN_COMMAND; } + + CommandMessage reply; + if(result != HasReturnvaluesIF::RETURN_OK) { + HousekeepingMessage::setHkRequestFailureReply(&reply, sid, result); + } + else { + HousekeepingMessage::setHkRequestSuccessReply(&reply, sid); + } + hkQueue->sendMessage(hkDestinationId, &reply); + return result; } ReturnValue_t LocalDataPoolManager::printPoolEntry( @@ -161,7 +220,7 @@ ReturnValue_t LocalDataPoolManager::printPoolEntry( auto poolIter = localPoolMap.find(localPoolId); if (poolIter == localPoolMap.end()) { sif::debug << "HousekeepingManager::fechPoolEntry:" - " Pool entry not found." << std::endl; + << " Pool entry not found." << std::endl; return POOL_ENTRY_NOT_FOUND; } poolIter->second->print(); @@ -172,40 +231,47 @@ MutexIF* LocalDataPoolManager::getMutexHandle() { return mutex; } -const HasLocalDataPoolIF* LocalDataPoolManager::getOwner() const { +HasLocalDataPoolIF* LocalDataPoolManager::getOwner() { return owner; } ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid, - float collectionInterval, MessageQueueId_t destination) { - LocalPoolDataSetBase* dataSetToSerialize = - dynamic_cast(owner->getDataSetHandle(sid)); - if(dataSetToSerialize == nullptr) { + LocalPoolDataSetBase* dataSet, bool forDownlink, + MessageQueueId_t destination) { + if(dataSet == nullptr) { + // Configuration error. sif::warning << "HousekeepingManager::generateHousekeepingPacket:" - " Set ID not found or dataset not assigned!" << std::endl; + << " Set ID not found or dataset not assigned!" << std::endl; return HasReturnvaluesIF::RETURN_FAILED; } - sif::info << "hk gen called" << std::endl; + store_address_t storeId; - HousekeepingPacketDownlink hkPacket(sid, collectionInterval, - dataSetToSerialize->getFillCount(), dataSetToSerialize); - ReturnValue_t result = serializeHkPacketIntoStore(hkPacket, &storeId); - if(result != HasReturnvaluesIF::RETURN_OK) { + HousekeepingPacketDownlink hkPacket(sid, dataSet); + size_t serializedSize = 0; + ReturnValue_t result = serializeHkPacketIntoStore(hkPacket, storeId, + forDownlink, &serializedSize); + if(result != HasReturnvaluesIF::RETURN_OK or serializedSize == 0) { return result; } // and now we set a HK message and send it the HK packet destination. CommandMessage hkMessage; - HousekeepingMessage::setHkReportMessage(&hkMessage, sid, storeId); + if(dataSet->isDiagnostics()) { + HousekeepingMessage::setHkDiagnosticsReply(&hkMessage, sid, storeId); + } + else { + HousekeepingMessage::setHkReportReply(&hkMessage, sid, storeId); + } + if(hkQueue == nullptr) { return QUEUE_OR_DESTINATION_NOT_SET; } if(destination == MessageQueueIF::NO_QUEUE) { - if(defaultHkDestinationId == MessageQueueIF::NO_QUEUE) { + if(hkDestinationId == MessageQueueIF::NO_QUEUE) { // error, all destinations invalid return HasReturnvaluesIF::RETURN_FAILED; } - destination = defaultHkDestinationId; + destination = hkDestinationId; } return hkQueue->sendMessage(destination, &hkMessage); @@ -213,46 +279,22 @@ ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid, ReturnValue_t LocalDataPoolManager::serializeHkPacketIntoStore( HousekeepingPacketDownlink& hkPacket, - store_address_t *storeId) { + store_address_t& storeId, bool forDownlink, + size_t* serializedSize) { uint8_t* dataPtr = nullptr; - size_t serializedSize = 0; const size_t maxSize = hkPacket.getSerializedSize(); - ReturnValue_t result = ipcStore->getFreeElement(storeId, - serializedSize, &dataPtr); - if(result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - - return hkPacket.serialize(&dataPtr, &serializedSize, maxSize, - SerializeIF::Endianness::MACHINE); -} - -ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid) { - LocalPoolDataSetBase* dataSet = dynamic_cast( - owner->getDataSetHandle(sid)); - if(dataSet == nullptr) { - sif::warning << "HousekeepingManager::generateHousekeepingPacket:" - " Set ID not found" << std::endl; - return HasReturnvaluesIF::RETURN_FAILED; - } - size_t expectedSize = dataSet->getFillCount() * sizeof(lp_id_t); - uint8_t* storePtr = nullptr; - store_address_t storeId; ReturnValue_t result = ipcStore->getFreeElement(&storeId, - expectedSize,&storePtr); + maxSize, &dataPtr); if(result != HasReturnvaluesIF::RETURN_OK) { - sif::error << "HousekeepingManager::generateHousekeepingPacket: " - "Could not get free element from IPC store." << std::endl; return result; } - size_t size = 0; - result = dataSet->serializeLocalPoolIds(&storePtr, &size, - expectedSize, SerializeIF::Endianness::BIG); - if(expectedSize != size) { - sif::error << "HousekeepingManager::generateSetStructurePacket: " - "Expected size is not equal to serialized size" << std::endl; + + if(forDownlink) { + return hkPacket.serialize(&dataPtr, serializedSize, maxSize, + SerializeIF::Endianness::BIG); } - return result; + return hkPacket.serialize(&dataPtr, serializedSize, maxSize, + SerializeIF::Endianness::MACHINE); } void LocalDataPoolManager::setNonDiagnosticIntervalFactor( @@ -260,46 +302,126 @@ void LocalDataPoolManager::setNonDiagnosticIntervalFactor( this->nonDiagnosticIntervalFactor = nonDiagInvlFactor; } +void LocalDataPoolManager::performPeriodicHkGeneration(HkReceiver& receiver) { + sid_t sid = receiver.dataId.sid; + LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid); + if(not dataSet->getReportingEnabled()) { + return; + } -void LocalDataPoolManager::performPeriodicHkGeneration(HkReceiver* receiver) { - if(receiver->intervalCounter >= - receiver->hkParameter.collectionIntervalTicks) { - ReturnValue_t result = generateHousekeepingPacket( - receiver->dataId.dataSetSid); - if(result != HasReturnvaluesIF::RETURN_OK) { - // configuration error - sif::debug << "LocalDataPoolManager::performHkOperation:" - << "0x" << std::setfill('0') << std::setw(8) - << owner->getObjectId() << " Error generating " - << "HK packet" << std::setfill(' ') << std::endl; - } - receiver->intervalCounter = 1; - } - else { - receiver->intervalCounter++; - } + if(dataSet->periodicHelper == nullptr) { + // Configuration error. + return; + } + + if(not dataSet->periodicHelper->checkOpNecessary()) { + return; + } + + ReturnValue_t result = generateHousekeepingPacket( + sid, dataSet, true); + if(result != HasReturnvaluesIF::RETURN_OK) { + // configuration error + sif::debug << "LocalDataPoolManager::performHkOperation:" + << "0x" << std::hex << std::setfill('0') << std::setw(8) + << owner->getObjectId() << " Error generating " + << "HK packet" << std::setfill(' ') << std::dec << std::endl; + } } -uint32_t LocalDataPoolManager::intervalSecondsToInterval(bool isDiagnostics, - float collectionIntervalSeconds) { - if(isDiagnostics) { - return std::ceil(collectionIntervalSeconds * 1000 - /diagnosticMinimumInterval); - } - else { - return std::ceil(collectionIntervalSeconds * 1000 - /regularMinimumInterval); - } + +ReturnValue_t LocalDataPoolManager::togglePeriodicGeneration(sid_t sid, + bool enable, bool isDiagnostics) { + LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid); + if((dataSet->isDiagnostics() and not isDiagnostics) or + (not dataSet->isDiagnostics() and isDiagnostics)) { + return WRONG_HK_PACKET_TYPE; + } + + if((dataSet->getReportingEnabled() and enable) or + (not dataSet->getReportingEnabled() and not enable)) { + return REPORTING_STATUS_UNCHANGED; + } + + dataSet->setReportingEnabled(enable); + return HasReturnvaluesIF::RETURN_OK; } -float LocalDataPoolManager::intervalToIntervalSeconds(bool isDiagnostics, - uint32_t collectionInterval) { - if(isDiagnostics) { - return static_cast(collectionInterval * - diagnosticMinimumInterval); - } - else { - return static_cast(collectionInterval * - regularMinimumInterval); - } +ReturnValue_t LocalDataPoolManager::changeCollectionInterval(sid_t sid, + float newCollectionInterval, bool isDiagnostics) { + LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid); + bool targetIsDiagnostics = dataSet->isDiagnostics(); + if((targetIsDiagnostics and not isDiagnostics) or + (not targetIsDiagnostics and isDiagnostics)) { + return WRONG_HK_PACKET_TYPE; + } + + if(dataSet->periodicHelper == nullptr) { + // config error + return PERIODIC_HELPER_INVALID; + } + + dataSet->periodicHelper->changeCollectionInterval(newCollectionInterval); + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid, + bool isDiagnostics) { + // Get and check dataset first. + LocalPoolDataSetBase* dataSet = dynamic_cast( + owner->getDataSetHandle(sid)); + if(dataSet == nullptr) { + sif::warning << "HousekeepingManager::generateHousekeepingPacket:" + << " Set ID not found" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + + + bool targetIsDiagnostics = dataSet->isDiagnostics(); + if((targetIsDiagnostics and not isDiagnostics) or + (not targetIsDiagnostics and isDiagnostics)) { + return WRONG_HK_PACKET_TYPE; + } + + bool valid = dataSet->isValid(); + bool reportingEnabled = dataSet->getReportingEnabled(); + float collectionInterval = + dataSet->periodicHelper->getCollectionIntervalInSeconds(); + + // Generate set packet which can be serialized. + HousekeepingSetPacket setPacket(sid, + reportingEnabled, valid, collectionInterval, dataSet); + size_t expectedSize = setPacket.getSerializedSize(); + uint8_t* storePtr = nullptr; + store_address_t storeId; + ReturnValue_t result = ipcStore->getFreeElement(&storeId, + expectedSize,&storePtr); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "HousekeepingManager::generateHousekeepingPacket: " + << "Could not get free element from IPC store." << std::endl; + return result; + } + + // Serialize set packet into store. + size_t size = 0; + result = setPacket.serialize(&storePtr, &size, expectedSize, + SerializeIF::Endianness::BIG); + if(expectedSize != size) { + sif::error << "HousekeepingManager::generateSetStructurePacket: " + << "Expected size is not equal to serialized size" << std::endl; + } + + // Send structure reporting reply. + CommandMessage reply; + if(isDiagnostics) { + HousekeepingMessage::setDiagnosticsStuctureReportReply(&reply, + sid, storeId); + } + else { + HousekeepingMessage::setHkStuctureReportReply(&reply, + sid, storeId); + } + + hkQueue->reply(&reply); + return result; } diff --git a/datapoollocal/LocalDataPoolManager.h b/datapoollocal/LocalDataPoolManager.h index c851978c4..779e30500 100644 --- a/datapoollocal/LocalDataPoolManager.h +++ b/datapoollocal/LocalDataPoolManager.h @@ -1,14 +1,15 @@ -#ifndef FRAMEWORK_DATAPOOLLOCAL_LOCALDATAPOOLMANAGER_H_ -#define FRAMEWORK_DATAPOOLLOCAL_LOCALDATAPOOLMANAGER_H_ +#ifndef FSFW_DATAPOOLLOCAL_LOCALDATAPOOLMANAGER_H_ +#define FSFW_DATAPOOLLOCAL_LOCALDATAPOOLMANAGER_H_ + +#include "HasLocalDataPoolIF.h" #include "../housekeeping/HousekeepingPacketDownlink.h" +#include "../housekeeping/HousekeepingMessage.h" +#include "../housekeeping/PeriodicHousekeepingHelper.h" #include "../datapool/DataSetIF.h" +#include "../datapool/PoolEntry.h" #include "../objectmanager/SystemObjectIF.h" #include "../ipc/MutexIF.h" - -#include "../housekeeping/HousekeepingMessage.h" -#include "../datapool/PoolEntry.h" -#include "../datapoollocal/HasLocalDataPoolIF.h" #include "../ipc/CommandMessage.h" #include "../ipc/MessageQueueIF.h" #include "../ipc/MutexHelper.h" @@ -23,7 +24,7 @@ class LocalDataSetBase; /** - * @brief This class is the managing instance for local data pool. + * @brief This class is the managing instance for the local data pool. * @details * The actual data pool structure is a member of this class. Any class which * has a local data pool shall have this class as a member and implement @@ -37,7 +38,7 @@ class LocalDataSetBase; * value is stored. The helper classes offer a read() and commit() interface * through the PoolVariableIF which is used to read and update values. * Each pool entry has a valid state too. - * @author R. Mueller + * @author R. Mueller */ class LocalDataPoolManager { template @@ -49,10 +50,14 @@ class LocalDataPoolManager { public: static constexpr uint8_t INTERFACE_ID = CLASS_ID::HOUSEKEEPING_MANAGER; - static constexpr ReturnValue_t POOL_ENTRY_NOT_FOUND = MAKE_RETURN_CODE(0x0); - static constexpr ReturnValue_t POOL_ENTRY_TYPE_CONFLICT = MAKE_RETURN_CODE(0x1); + static constexpr ReturnValue_t POOL_ENTRY_NOT_FOUND = MAKE_RETURN_CODE(0x00); + static constexpr ReturnValue_t POOL_ENTRY_TYPE_CONFLICT = MAKE_RETURN_CODE(0x01); - static constexpr ReturnValue_t QUEUE_OR_DESTINATION_NOT_SET = MAKE_RETURN_CODE(0x2); + static constexpr ReturnValue_t QUEUE_OR_DESTINATION_NOT_SET = MAKE_RETURN_CODE(0x02); + + static constexpr ReturnValue_t WRONG_HK_PACKET_TYPE = MAKE_RETURN_CODE(0x03); + static constexpr ReturnValue_t REPORTING_STATUS_UNCHANGED = MAKE_RETURN_CODE(0x04); + static constexpr ReturnValue_t PERIODIC_HELPER_INVALID = MAKE_RETURN_CODE(0x05); /** * This constructor is used by a class which wants to implement @@ -69,16 +74,30 @@ public: virtual~ LocalDataPoolManager(); /** - * Initializes the map by calling the map initialization function of the - * owner and assigns the queue to use. + * Assigns the queue to use. * @param queueToUse * @param nonDiagInvlFactor See #setNonDiagnosticIntervalFactor doc * @return */ ReturnValue_t initialize(MessageQueueIF* queueToUse); + /** + * Initializes the map by calling the map initialization function and + * setting the periodic factor for non-diagnostic packets. + * Don't forget to call this, otherwise the map will be invalid! + * @param nonDiagInvlFactor + * @return + */ ReturnValue_t initializeAfterTaskCreation(uint8_t nonDiagInvlFactor = 5); + /** + * This should be called in the periodic handler of the owner. + * It performs all the periodic functionalities of the data pool manager, + * for example generating periodic HK packets. + * @return + */ + ReturnValue_t performHkOperation(); + /** * @return */ @@ -97,12 +116,6 @@ public: */ void setNonDiagnosticIntervalFactor(uint8_t nonDiagInvlFactor); - /** - * This should be called in the periodic handler of the owner. - * It performs all the periodic functionalities of the data pool manager. - * @return - */ - ReturnValue_t performHkOperation(); /** * Generate a housekeeping packet with a given SID. @@ -110,9 +123,8 @@ public: * @return */ ReturnValue_t generateHousekeepingPacket(sid_t sid, - float collectionInterval = 0, - MessageQueueId_t destination = MessageQueueIF::NO_QUEUE); - ReturnValue_t generateSetStructurePacket(sid_t sid); + LocalPoolDataSetBase* dataSet, bool forDownlink, + MessageQueueId_t destination = MessageQueueIF::NO_QUEUE); ReturnValue_t handleHousekeepingMessage(CommandMessage* message); @@ -124,26 +136,27 @@ public: */ ReturnValue_t initializeHousekeepingPoolEntriesOnce(); - const HasLocalDataPoolIF* getOwner() const; + HasLocalDataPoolIF* getOwner(); ReturnValue_t printPoolEntry(lp_id_t localPoolId); /** * Different types of housekeeping reporting are possible. - * 1. PERIODIC: HK packets are generated in fixed intervals and sent to + * 1. PERIODIC: + * HK packets are generated in fixed intervals and sent to * destination. Fromat will be raw. - * 2. UPDATED: Notification will be sent out if HK data has changed. - * Question: Send Raw data directly or just the message? - * 3. REQUESTED: HK packets are only generated if explicitely requested. + * 2. UPDATE_NOTIFICATION: + * Notification will be sent out if HK data has changed. + * 3. UPDATE_SNAPSHOT: + * HK packets are only generated if explicitely requested. * Propably not necessary, just use multiple local data sets or * shared datasets. - * - * Notifications should also be possible for single variables instead of - * full dataset updates. */ enum class ReportingType: uint8_t { //! Periodic generation of HK packets. PERIODIC, + //! Housekeeping packet will be generated if values have changed. + UPDATE_HK, //! Update notification will be sent out as message. UPDATE_NOTIFICATION, //! Notification will be sent out as message and a snapshot of the @@ -151,6 +164,17 @@ public: UPDATE_SNAPSHOT, }; + /** + * Different data types are possible in the HK receiver map. + * For example, updates can be requested for full datasets or + * for single pool variables. Periodic reporting is only possible for + * data sets. + */ + enum class DataType: uint8_t { + LOCAL_POOL_VARIABLE, + DATA_SET + }; + /* Copying forbidden */ LocalDataPoolManager(const LocalDataPoolManager &) = delete; LocalDataPoolManager operator=(const LocalDataPoolManager&) = delete; @@ -160,51 +184,37 @@ private: //! Every housekeeping data manager has a mutex to protect access //! to it's data pool. MutexIF* mutex = nullptr; + /** The class which actually owns the manager (and its datapool). */ HasLocalDataPoolIF* owner = nullptr; uint8_t nonDiagnosticIntervalFactor = 0; - dur_millis_t regularMinimumInterval = 0; - dur_millis_t diagnosticMinimumInterval = 0; /** Default receiver for periodic HK packets */ static object_id_t defaultHkDestination; - MessageQueueId_t defaultHkDestinationId = MessageQueueIF::NO_QUEUE; + MessageQueueId_t hkDestinationId = MessageQueueIF::NO_QUEUE; /** The data pool manager will keep an internal map of HK receivers. */ struct HkReceiver { - /** Different member of this union will be used depending on the - type of data the receiver is interested in (full datasets or - single data variables. */ + /** Object ID of receiver */ + object_id_t objectId = objects::NO_OBJECT; + + DataType dataType = DataType::DATA_SET; union DataId { - DataId(): dataSetSid() {} - /** Will be initialized to INVALID_ADDRESS */ - sid_t dataSetSid; - lp_id_t localPoolId = HasLocalDataPoolIF::NO_POOL_ID; + DataId(): sid() {}; + sid_t sid; + lp_id_t localPoolId; }; DataId dataId; ReportingType reportingType = ReportingType::PERIODIC; MessageQueueId_t destinationQueue = MessageQueueIF::NO_QUEUE; - bool reportingEnabled = true; - /** Different members of this union will be used depending on reporting - type */ - union HkParameter { - /** This parameter will be used for the PERIODIC type */ - uint32_t collectionIntervalTicks = 0; - /** This parameter will be used for the ON_UPDATE type */ - bool hkDataChanged; - }; - HkParameter hkParameter; - bool isDiagnostics; - /** General purpose counter which is used for periodic generation. */ - uint32_t intervalCounter; }; - /** Using a multimap as the same object might request multiple datasets */ - using HkReceiversMap = std::multimap; + /** This vector will contain the list of HK receivers. */ + using HkReceivers = std::vector; - HkReceiversMap hkReceiversMap; + HkReceivers hkReceiversMap; /** This is the map holding the actual data. Should only be initialized * once ! */ @@ -245,17 +255,16 @@ private: template ReturnValue_t fetchPoolEntry(lp_id_t localPoolId, PoolEntry **poolEntry); - void setMinimalSamplingFrequency(float frequencySeconds); ReturnValue_t serializeHkPacketIntoStore( HousekeepingPacketDownlink& hkPacket, - store_address_t *storeId); + store_address_t& storeId, bool forDownlink, size_t* serializedSize); - uint32_t intervalSecondsToInterval(bool isDiagnostics, - float collectionIntervalSeconds); - float intervalToIntervalSeconds(bool isDiagnostics, - uint32_t collectionInterval); - - void performPeriodicHkGeneration(HkReceiver* hkReceiver); + void performPeriodicHkGeneration(HkReceiver& hkReceiver); + ReturnValue_t togglePeriodicGeneration(sid_t sid, bool enable, + bool isDiagnostics); + ReturnValue_t changeCollectionInterval(sid_t sid, + float newCollectionInterval, bool isDiagnostics); + ReturnValue_t generateSetStructurePacket(sid_t sid, bool isDiagnostics); }; @@ -279,4 +288,4 @@ ReturnValue_t LocalDataPoolManager::fetchPoolEntry(lp_id_t localPoolId, } -#endif /* FRAMEWORK_DATAPOOLLOCAL_LOCALDATAPOOLMANAGER_H_ */ +#endif /* FSFW_DATAPOOLLOCAL_LOCALDATAPOOLMANAGER_H_ */ diff --git a/datapoollocal/LocalDataSet.h b/datapoollocal/LocalDataSet.h index 5641ebfbc..0368f26d1 100644 --- a/datapoollocal/LocalDataSet.h +++ b/datapoollocal/LocalDataSet.h @@ -1,6 +1,7 @@ -#ifndef FRAMEWORK_DATAPOOLLOCAL_LOCALDATASET_H_ -#define FRAMEWORK_DATAPOOLLOCAL_LOCALDATASET_H_ -#include "../datapoollocal/LocalPoolDataSetBase.h" +#ifndef FSFW_DATAPOOLLOCAL_LOCALDATASET_H_ +#define FSFW_DATAPOOLLOCAL_LOCALDATASET_H_ + +#include "LocalPoolDataSetBase.h" #include class LocalDataSet: public LocalPoolDataSetBase { @@ -17,4 +18,4 @@ private: std::vector poolVarList; }; -#endif /* FRAMEWORK_DATAPOOLLOCAL_LOCALDATASET_H_ */ +#endif /* FSFW_DATAPOOLLOCAL_LOCALDATASET_H_ */ diff --git a/datapoollocal/LocalPoolDataSetBase.cpp b/datapoollocal/LocalPoolDataSetBase.cpp index 8abdc0e35..da0a86b2c 100644 --- a/datapoollocal/LocalPoolDataSetBase.cpp +++ b/datapoollocal/LocalPoolDataSetBase.cpp @@ -1,5 +1,6 @@ #include "LocalPoolDataSetBase.h" #include "../datapoollocal/LocalDataPoolManager.h" +#include "../housekeeping/PeriodicHousekeepingHelper.h" #include "../serialize/SerializeAdapter.h" #include @@ -7,16 +8,22 @@ LocalPoolDataSetBase::LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner, uint32_t setId, PoolVariableIF** registeredVariablesArray, - const size_t maxNumberOfVariables): - PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) { - if(hkOwner == nullptr) { - sif::error << "LocalDataSet::LocalDataSet: Owner can't be nullptr!" - << std::endl; - return; - } + const size_t maxNumberOfVariables, bool noPeriodicHandling): + PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) { + if(hkOwner == nullptr) { + // Configuration error. + sif::error << "LocalPoolDataSetBase::LocalPoolDataSetBase: Owner " + << "invalid!" << std::endl; + return; + } hkManager = hkOwner->getHkManagerHandle(); this->sid.objectId = hkOwner->getObjectId(); this->sid.ownerSetId = setId; + + // Data creators get a periodic helper for periodic HK data generation. + if(not noPeriodicHandling) { + periodicHelper = new PeriodicHousekeepingHelper(this); + } } LocalPoolDataSetBase::LocalPoolDataSetBase(sid_t sid, @@ -26,8 +33,9 @@ LocalPoolDataSetBase::LocalPoolDataSetBase(sid_t sid, HasLocalDataPoolIF* hkOwner = objectManager->get( sid.objectId); if(hkOwner == nullptr) { - sif::error << "LocalDataSet::LocalDataSet: Owner can't be nullptr!" - << std::endl; + // Configuration error. + sif::error << "LocalPoolDataSetBase::LocalPoolDataSetBase: Owner " + << "invalid!" << std::endl; return; } hkManager = hkOwner->getHkManagerHandle(); @@ -111,8 +119,14 @@ ReturnValue_t LocalPoolDataSetBase::unlockDataPool() { } ReturnValue_t LocalPoolDataSetBase::serializeLocalPoolIds(uint8_t** buffer, - size_t* size, size_t maxSize, - SerializeIF::Endianness streamEndianness) const { + size_t* size, size_t maxSize,SerializeIF::Endianness streamEndianness, + bool serializeFillCount) const { + // Serialize as uint8_t + uint8_t fillCount = this->fillCount; + if(serializeFillCount) { + SerializeAdapter::serialize(&fillCount, buffer, size, maxSize, + streamEndianness); + } for (uint16_t count = 0; count < fillCount; count++) { lp_id_t currentPoolId = registeredVariables[count]->getDataPoolId(); auto result = SerializeAdapter::serialize(¤tPoolId, buffer, @@ -127,6 +141,16 @@ ReturnValue_t LocalPoolDataSetBase::serializeLocalPoolIds(uint8_t** buffer, } +uint8_t LocalPoolDataSetBase::getLocalPoolIdsSerializedSize( + bool serializeFillCount) const { + if(serializeFillCount) { + return fillCount * sizeof(lp_id_t) + sizeof(uint8_t); + } + else { + return fillCount * sizeof(lp_id_t); + } +} + size_t LocalPoolDataSetBase::getSerializedSize() const { if(withValidityBuffer) { uint8_t validityMaskSize = std::ceil(static_cast(fillCount)/8.0); @@ -175,6 +199,41 @@ void LocalPoolDataSetBase::bitSetter(uint8_t* byte, uint8_t position) const { *byte |= 1 << shiftNumber; } +void LocalPoolDataSetBase::setDiagnostic(bool isDiagnostics) { + this->diagnostic = isDiagnostics; +} + +bool LocalPoolDataSetBase::isDiagnostics() const { + return diagnostic; +} + +void LocalPoolDataSetBase::setReportingEnabled(bool reportingEnabled) { + this->reportingEnabled = reportingEnabled; +} + +bool LocalPoolDataSetBase::getReportingEnabled() const { + return reportingEnabled; +} + +void LocalPoolDataSetBase::initializePeriodicHelper( + float collectionInterval, dur_millis_t minimumPeriodicInterval, + bool isDiagnostics, uint8_t nonDiagIntervalFactor) { + periodicHelper->initialize(collectionInterval, minimumPeriodicInterval, + isDiagnostics, nonDiagIntervalFactor); +} + +void LocalPoolDataSetBase::setChanged(bool changed) { + this->changed = changed; +} + +bool LocalPoolDataSetBase::isChanged() const { + return changed; +} + +sid_t LocalPoolDataSetBase::getSid() const { + return sid; +} + bool LocalPoolDataSetBase::bitGetter(const uint8_t* byte, uint8_t position) const { if(position > 7) { @@ -190,4 +249,11 @@ bool LocalPoolDataSetBase::isValid() const { return this->valid; } - +void LocalPoolDataSetBase::setValidity(bool valid, bool setEntriesRecursively) { + if(setEntriesRecursively) { + for(size_t idx = 0; idx < this->getFillCount(); idx++) { + registeredVariables[idx] -> setValid(valid); + } + } + this->valid = valid; +} diff --git a/datapoollocal/LocalPoolDataSetBase.h b/datapoollocal/LocalPoolDataSetBase.h index bd127db49..d00af9920 100644 --- a/datapoollocal/LocalPoolDataSetBase.h +++ b/datapoollocal/LocalPoolDataSetBase.h @@ -1,27 +1,36 @@ -#ifndef FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLDATASETBASE_H_ -#define FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLDATASETBASE_H_ +#ifndef FSFW_DATAPOOLLOCAL_LOCALPOOLDATASETBASE_H_ +#define FSFW_DATAPOOLLOCAL_LOCALPOOLDATASETBASE_H_ + +#include "HasLocalDataPoolIF.h" #include "../datapool/DataSetIF.h" #include "../datapool/PoolDataSetBase.h" -#include "../datapoollocal/HasLocalDataPoolIF.h" #include "../serialize/SerializeIF.h" #include class LocalDataPoolManager; +class PeriodicHousekeepingHelper; /** * @brief The LocalDataSet class manages a set of locally checked out * variables for local data pools * @details + * Extends the PoolDataSetBase class for local data pools by introducing + * a validity state, a flag to mark the set as changed, and various other + * functions to make it usable by the LocalDataPoolManager class. + * * 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 local data pools, - * to ensure thread-safety. + * the commit call. The data set manages locking and freeing the local data + * pools, to ensure thread-safety. + * + * Pool variables can be added to the dataset by using the constructor + * argument of the pool variable or using the #registerVariable member function. * * An internal state manages usage of this class. Variables may only be - * registered before the read call is made, and the commit call only + * registered before any read call is made, and the commit call can only happen * after the read call. * * If pool variables are writable and not committed until destruction @@ -31,17 +40,21 @@ class LocalDataPoolManager; * @ingroup data_pool */ class LocalPoolDataSetBase: public PoolDataSetBase { + friend class LocalDataPoolManager; + friend class PeriodicHousekeepingHelper; public: /** * @brief Constructor for the creator of local pool data. + * @details + * This constructor also initializes the components required for + * periodic handling. */ LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner, uint32_t setId, PoolVariableIF** registeredVariablesArray, - const size_t maxNumberOfVariables); + const size_t maxNumberOfVariables, bool noPeriodicHandling = false); /** - * @brief Constructor for users of local pool data. The passed pool - * owner should implement the HasHkPoolParametersIF. + * @brief Constructor for users of local pool data. * @details * @param sid Unique identifier of dataset consisting of object ID and * set ID. @@ -63,6 +76,9 @@ public: void setValidityBufferGeneration(bool withValidityBuffer); + sid_t getSid() const; + + /** SerializeIF overrides */ ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize, SerializeIF::Endianness streamEndianness) const override; ReturnValue_t deSerialize(const uint8_t** buffer, size_t *size, @@ -73,7 +89,7 @@ public: * Special version of the serilization function which appends a * validity buffer at the end. Each bit of this validity buffer * denotes whether the container data set entries are valid from left - * to right, MSB first. + * to right, MSB first. (length = ceil(N/8), N = number of pool variables) * @param buffer * @param size * @param maxSize @@ -88,18 +104,58 @@ public: size_t *size, SerializeIF::Endianness streamEndianness); ReturnValue_t serializeLocalPoolIds(uint8_t** buffer, size_t* size, size_t maxSize, - SerializeIF::Endianness streamEndianness) const; + SerializeIF::Endianness streamEndianness, + bool serializeFillCount = true) const; + uint8_t getLocalPoolIdsSerializedSize(bool serializeFillCount = true) const; + /** + * Set the dataset valid or invalid + * @param setEntriesRecursively + * If this is true, all contained datasets will also be set recursively. + */ + void setValidity(bool valid, bool setEntriesRecursively); bool isValid() const override; + void setChanged(bool changed); + bool isChanged() const; + protected: sid_t sid; + + bool diagnostic = false; + void setDiagnostic(bool diagnostics); + bool isDiagnostics() const; + + /** + * Used for periodic generation. + */ + bool reportingEnabled = false; + void setReportingEnabled(bool enabled); + bool getReportingEnabled() const; + + void initializePeriodicHelper(float collectionInterval, + dur_millis_t minimumPeriodicInterval, + bool isDiagnostics, uint8_t nonDiagIntervalFactor = 5); + /** * If the valid state of a dataset is always relevant to the whole * data set we can use this flag. */ bool valid = false; + /** + * Can be used to mark the dataset as changed, which is used + * by the LocalDataPoolManager to send out update messages. + */ + bool changed = false; + + /** + * Specify whether the validity buffer is serialized too when serializing + * or deserializing the packet. Each bit of the validity buffer will + * contain the validity state of the pool variables from left to right. + * The size of validity buffer thus will be ceil(N / 8) with N = number of + * pool variables. + */ bool withValidityBuffer = true; /** @@ -125,9 +181,10 @@ protected: */ void bitSetter(uint8_t* byte, uint8_t position) const; bool bitGetter(const uint8_t* byte, uint8_t position) const; -private: + PeriodicHousekeepingHelper* periodicHelper = nullptr; }; -#endif /* FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLDATASETBASE_H_ */ + +#endif /* FSFW_DATAPOOLLOCAL_LOCALPOOLDATASETBASE_H_ */ diff --git a/datapoollocal/LocalPoolVariable.h b/datapoollocal/LocalPoolVariable.h index 7107bffe9..ec5c8cd19 100644 --- a/datapoollocal/LocalPoolVariable.h +++ b/datapoollocal/LocalPoolVariable.h @@ -1,12 +1,12 @@ -#ifndef FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLVARIABLE_H_ -#define FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLVARIABLE_H_ +#ifndef FSFW_DATAPOOLLOCAL_LOCALPOOLVARIABLE_H_ +#define FSFW_DATAPOOLLOCAL_LOCALPOOLVARIABLE_H_ + +#include "HasLocalDataPoolIF.h" +#include "LocalDataPoolManager.h" #include "../datapool/PoolVariableIF.h" #include "../datapool/DataSetIF.h" -#include "../datapoollocal/HasLocalDataPoolIF.h" -#include "../datapoollocal/LocalDataPoolManager.h" #include "../objectmanager/ObjectManagerIF.h" - #include "../serialize/SerializeAdapter.h" /** @@ -38,13 +38,13 @@ public: * @param poolId ID of the local pool entry. * @param hkOwner Pointer of the owner. This will generally be the calling * class itself which passes "this". - * @param setReadWriteMode Specify the read-write mode of the pool variable. * @param dataSet The data set in which the variable shall register itself. * If nullptr, the variable is not registered. + * @param setReadWriteMode Specify the read-write mode of the pool variable. */ LocalPoolVar(lp_id_t poolId, HasLocalDataPoolIF* hkOwner, - pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE, - DataSetIF* dataSet = nullptr); + DataSetIF* dataSet = nullptr, + pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE); /** * This constructor is used by data users like controllers to have @@ -58,13 +58,14 @@ public: * the pool variable in that dataset directly. * @param poolId ID of the local pool entry. * @param hkOwner object ID of the pool owner. - * @param setReadWriteMode Specify the read-write mode of the pool variable. * @param dataSet The data set in which the variable shall register itself. * If nullptr, the variable is not registered. + * @param setReadWriteMode Specify the read-write mode of the pool variable. + * */ LocalPoolVar(lp_id_t poolId, object_id_t poolOwner, - pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE, - DataSetIF* dataSet = nullptr); + DataSetIF* dataSet = nullptr, + pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE); virtual~ LocalPoolVar() {}; @@ -173,4 +174,4 @@ using lp_float_t = LocalPoolVar; using lp_double_t = LocalPoolVar; -#endif +#endif /* FSFW_DATAPOOLLOCAL_LOCALPOOLVARIABLE_H_ */ diff --git a/datapoollocal/LocalPoolVariable.tpp b/datapoollocal/LocalPoolVariable.tpp index 6e6f27aaa..b0bdd7b9e 100644 --- a/datapoollocal/LocalPoolVariable.tpp +++ b/datapoollocal/LocalPoolVariable.tpp @@ -1,44 +1,45 @@ -#ifndef FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLVARIABLE_TPP_ -#define FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLVARIABLE_TPP_ +#ifndef FSFW_DATAPOOLLOCAL_LOCALPOOLVARIABLE_TPP_ +#define FSFW_DATAPOOLLOCAL_LOCALPOOLVARIABLE_TPP_ -#ifndef FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLVARIABLE_H_ +#ifndef FSFW_DATAPOOLLOCAL_LOCALPOOLVARIABLE_H_ #error Include LocalPoolVariable.h before LocalPoolVariable.tpp! #endif template inline LocalPoolVar::LocalPoolVar(lp_id_t poolId, - HasLocalDataPoolIF* hkOwner, pool_rwm_t setReadWriteMode, - DataSetIF* dataSet): - localPoolId(poolId),readWriteMode(setReadWriteMode) { + HasLocalDataPoolIF* hkOwner, DataSetIF* dataSet, + pool_rwm_t setReadWriteMode): + localPoolId(poolId), readWriteMode(setReadWriteMode) { if(poolId == PoolVariableIF::NO_PARAMETER) { - sif::warning << "LocalPoolVector: 0 passed as pool ID, which is the " - "NO_PARAMETER value!" << std::endl; + sif::warning << "LocalPoolVar::LocalPoolVar: 0 passed as pool ID, " + << "which is the NO_PARAMETER value!" << std::endl; } if(hkOwner == nullptr) { - sif::error << "LocalPoolVariable: The supplied pool owner is a nullptr!" - << std::endl; + sif::error << "LocalPoolVar::LocalPoolVar: The supplied pool " + << "owner is a invalid!" << std::endl; return; } hkManager = hkOwner->getHkManagerHandle(); if(dataSet != nullptr) { - dataSet->registerVariable(this); + dataSet->registerVariable(this); } } template inline LocalPoolVar::LocalPoolVar(lp_id_t poolId, object_id_t poolOwner, - pool_rwm_t setReadWriteMode, DataSetIF *dataSet): - readWriteMode(setReadWriteMode) { - if(poolId == PoolVariableIF::NO_PARAMETER) { - sif::warning << "LocalPoolVector: 0 passed as pool ID, which is the " - "NO_PARAMETER value!" << std::endl; - } - HasLocalDataPoolIF* hkOwner = - objectManager->get(poolOwner); - if(hkOwner == nullptr) { - sif::error << "LocalPoolVariable: The supplied pool owner did not implement" - "the correct interface HasHkPoolParametersIF!" << std::endl; - return; + DataSetIF *dataSet, pool_rwm_t setReadWriteMode): + localPoolId(poolId), readWriteMode(setReadWriteMode) { + if(poolId == PoolVariableIF::NO_PARAMETER) { + sif::warning << "LocalPoolVar::LocalPoolVar: 0 passed as pool ID, " + << "which is the NO_PARAMETER value!" << std::endl; + } + HasLocalDataPoolIF* hkOwner = + objectManager->get(poolOwner); + if(hkOwner == nullptr) { + sif::error << "LocalPoolVariable: The supplied pool owner did not " + << "implement the correct interface " + << "HasLocalDataPoolIF!" << std::endl; + return; } hkManager = hkOwner->getHkManagerHandle(); if(dataSet != nullptr) { diff --git a/datapoollocal/LocalPoolVector.h b/datapoollocal/LocalPoolVector.h index 86705bb0d..57c4b90b4 100644 --- a/datapoollocal/LocalPoolVector.h +++ b/datapoollocal/LocalPoolVector.h @@ -47,8 +47,9 @@ public: * If nullptr, the variable is not registered. */ LocalPoolVector(lp_id_t poolId, HasLocalDataPoolIF* hkOwner, - pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE, - DataSetIF* dataSet = nullptr); + DataSetIF* dataSet = nullptr, + pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE + ); /** * This constructor is used by data users like controllers to have @@ -65,8 +66,9 @@ public: * If nullptr, the variable is not registered. */ LocalPoolVector(lp_id_t poolId, object_id_t poolOwner, - pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE, - DataSetIF* dataSet = nullptr); + DataSetIF* dataSet = nullptr, + pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE + ); /** * @brief This is the local copy of the data pool entry. @@ -192,7 +194,7 @@ private: }; -#include "../datapoollocal/LocalPoolVector.tpp" +#include "LocalPoolVector.tpp" template using lp_vec_t = LocalPoolVector; diff --git a/datapoollocal/LocalPoolVector.tpp b/datapoollocal/LocalPoolVector.tpp index 7c3d2c1ee..2aa6fbb5f 100644 --- a/datapoollocal/LocalPoolVector.tpp +++ b/datapoollocal/LocalPoolVector.tpp @@ -7,14 +7,14 @@ template inline LocalPoolVector::LocalPoolVector(lp_id_t poolId, - HasLocalDataPoolIF* hkOwner, pool_rwm_t setReadWriteMode, - DataSetIF* dataSet) : + HasLocalDataPoolIF* hkOwner, DataSetIF* dataSet, + pool_rwm_t setReadWriteMode): localPoolId(poolId), valid(false), readWriteMode(setReadWriteMode) { if(poolId == PoolVariableIF::NO_PARAMETER) { - sif::warning << "LocalPoolVector: 0 passed as pool ID, which is the " - "NO_PARAMETER value!" << std::endl; + sif::warning << "LocalPoolVector: PoolVariableIF::NO_PARAMETER passed " + << "as pool ID, which is the NO_PARAMETER value!" << std::endl; } - memset(this->value, 0, vectorSize * sizeof(T)); + std::memset(this->value, 0, vectorSize * sizeof(T)); hkManager = hkOwner->getHkManagerHandle(); if (dataSet != nullptr) { dataSet->registerVariable(this); @@ -23,17 +23,18 @@ inline LocalPoolVector::LocalPoolVector(lp_id_t poolId, template inline LocalPoolVector::LocalPoolVector(lp_id_t poolId, - object_id_t poolOwner, pool_rwm_t setReadWriteMode, DataSetIF *dataSet): - readWriteMode(readWriteMode) { + object_id_t poolOwner, DataSetIF *dataSet, pool_rwm_t setReadWriteMode): + readWriteMode(setReadWriteMode) { if(poolId == PoolVariableIF::NO_PARAMETER) { - sif::warning << "LocalPoolVector: 0 passed as pool ID, which is the " - "NO_PARAMETER value!" << std::endl; + sif::warning << "LocalPoolVector: PoolVariableIF::NO_PARAMETER passed " + << "as pool ID, which is the NO_PARAMETER value!" << std::endl; } HasLocalDataPoolIF* hkOwner = objectManager->get(poolOwner); if(hkOwner == nullptr) { - sif::error << "LocalPoolVariable: The supplied pool owner did not implement" - "the correct interface HasHkPoolParametersIF!" << std::endl; + sif::error << "LocalPoolVariable: The supplied pool owner did not " + << "implement the correct interface HasHkPoolParametersIF!" + << std::endl; return; } hkManager = hkOwner->getHkManagerHandle(); @@ -67,7 +68,7 @@ inline ReturnValue_t LocalPoolVector::readWithoutLock() { std::dec << " failed." << std::endl; return result; } - memcpy(this->value, poolEntry->address, poolEntry->getByteSize()); + std::memcpy(this->value, poolEntry->address, poolEntry->getByteSize()); this->valid = poolEntry->valid; return RETURN_OK; } @@ -96,7 +97,7 @@ inline ReturnValue_t LocalPoolVector::commitWithoutLock() { std::dec << " failed.\n" << std::flush; return result; } - memcpy(poolEntry->address, this->value, poolEntry->getByteSize()); + std::memcpy(poolEntry->address, this->value, poolEntry->getByteSize()); poolEntry->valid = this->valid; return RETURN_OK; } diff --git a/datapoollocal/SharedLocalDataSet.h b/datapoollocal/SharedLocalDataSet.h index f6748e4da..2e5a76fa9 100644 --- a/datapoollocal/SharedLocalDataSet.h +++ b/datapoollocal/SharedLocalDataSet.h @@ -1,17 +1,11 @@ -#ifndef FRAMEWORK_DATAPOOLLOCAL_SHAREDLOCALDATASET_H_ -#define FRAMEWORK_DATAPOOLLOCAL_SHAREDLOCALDATASET_H_ +#ifndef FSFW_DATAPOOLLOCAL_SHAREDLOCALDATASET_H_ +#define FSFW_DATAPOOLLOCAL_SHAREDLOCALDATASET_H_ + +#include "LocalPoolDataSetBase.h" #include "../datapool/SharedDataSetIF.h" -#include "../datapoollocal/LocalPoolDataSetBase.h" #include "../objectmanager/SystemObject.h" #include -/** - * Baseline question: If this dataset is shared, is there once instance - * shared among many objects or multiple instances? Maybe be flexible - * and provide both ways? Sharing one instance requires a mutex lock. - * If there are multiple instances, it is not shared anymore, to be fair.. - * Then a regular local data set is sufficient. - */ class SharedLocalDataSet: public SystemObject, public LocalPoolDataSetBase, public SharedDataSetIF { @@ -27,5 +21,4 @@ private: }; - -#endif /* FRAMEWORK_DATAPOOLLOCAL_SHAREDLOCALDATASET_H_ */ +#endif /* FSFW_DATAPOOLLOCAL_SHAREDLOCALDATASET_H_ */ diff --git a/datapoollocal/StaticLocalDataSet.h b/datapoollocal/StaticLocalDataSet.h index b3e8422c9..a637e360f 100644 --- a/datapoollocal/StaticLocalDataSet.h +++ b/datapoollocal/StaticLocalDataSet.h @@ -1,5 +1,6 @@ -#ifndef FRAMEWORK_DATAPOOLLOCAL_STATICLOCALDATASET_H_ -#define FRAMEWORK_DATAPOOLLOCAL_STATICLOCALDATASET_H_ +#ifndef FSFW_DATAPOOLLOCAL_STATICLOCALDATASET_H_ +#define FSFW_DATAPOOLLOCAL_STATICLOCALDATASET_H_ + #include "LocalPoolDataSetBase.h" #include "../objectmanager/SystemObjectIF.h" #include @@ -7,21 +8,43 @@ /** * @brief This local dataset type is created on the stack. * @details - * Size of data set specified as a constructor argument. It is recommended - * to use the default LocalDataSet of the dataset is constructed on the heap - * and the SharedLocalDataSet if it created on the heap and used by multiple - * other software objects. - * @tparam capacity + * This will is the primary data structure to organize pool variables into + * sets which can be accessed via the housekeeping service interface or + * which can be sent to other software objects. + * + * It is recommended to read the documentation of the LocalPoolDataSetBase + * class for more information on how this class works and how to use it. + * @tparam capacity Capacity of the static dataset, which is usually known + * beforehand. */ template class StaticLocalDataSet: public LocalPoolDataSetBase { public: - StaticLocalDataSet(sid_t sid): - LocalPoolDataSetBase(sid, poolVarList.data(), NUM_VARIABLES) { + /** + * Constructor used by data owner and creator like device handlers. + * This constructor also initialized the components required for + * periodic handling. + * @param hkOwner + * @param setId + */ + StaticLocalDataSet(HasLocalDataPoolIF* hkOwner, + uint32_t setId): LocalPoolDataSetBase(hkOwner, setId, nullptr, + NUM_VARIABLES) { + this->setContainer(poolVarList.data()); + } + + /** + * Constructor used by data users like controllers. + * @param hkOwner + * @param setId + */ + StaticLocalDataSet(sid_t sid): LocalPoolDataSetBase(sid, nullptr, + NUM_VARIABLES) { + this->setContainer(poolVarList.data()); } private: std::array poolVarList; }; -#endif /* FRAMEWORK_DATAPOOLLOCAL_STATICLOCALDATASET_H_ */ +#endif /* FSFW_DATAPOOLLOCAL_STATICLOCALDATASET_H_ */ diff --git a/devicehandlers/CommunicationMessage.cpp b/devicehandlers/CommunicationMessage.cpp index abdfd3a86..577742709 100644 --- a/devicehandlers/CommunicationMessage.cpp +++ b/devicehandlers/CommunicationMessage.cpp @@ -122,7 +122,7 @@ uint32_t CommunicationMessage::getUint32Data() const{ } void CommunicationMessage::setDataByte(uint8_t byte, uint8_t position) { - if(0 <= position && position <= 3) { + if(position <= 3) { memcpy(getData() + 3 * sizeof(uint32_t) + position * sizeof(uint8_t), &byte, sizeof(byte)); } else { @@ -131,7 +131,7 @@ void CommunicationMessage::setDataByte(uint8_t byte, uint8_t position) { } uint8_t CommunicationMessage::getDataByte(uint8_t position) const { - if(0 <= position && position <= 3) { + if(position <= 3) { uint8_t byte; memcpy(&byte, getData() + 3 * sizeof(uint32_t) + position * sizeof(uint8_t), sizeof(byte)); return byte; diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index ffb94359c..d67e47d8a 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -1,18 +1,18 @@ -#include "../devicehandlers/DeviceHandlerBase.h" +#include "DeviceHandlerBase.h" +#include "AcceptsDeviceResponsesIF.h" +#include "DeviceTmReportingWrapper.h" + +#include "../serviceinterface/ServiceInterfaceStream.h" +#include "../datapoolglob/GlobalDataSet.h" +#include "../datapoolglob/GlobalPoolVariable.h" #include "../objectmanager/ObjectManager.h" #include "../storagemanager/StorageManagerIF.h" #include "../thermal/ThermalComponentIF.h" -#include "../devicehandlers/AcceptsDeviceResponsesIF.h" - -#include "../datapoolglob/GlobalDataSet.h" -#include "../datapoolglob/GlobalPoolVariable.h" -#include "../devicehandlers/DeviceTmReportingWrapper.h" #include "../globalfunctions/CRC.h" #include "../housekeeping/HousekeepingMessage.h" #include "../ipc/MessageQueueMessage.h" -#include "../subsystem/SubsystemBase.h" #include "../ipc/QueueFactory.h" -#include "../serviceinterface/ServiceInterfaceStream.h" +#include "../subsystem/SubsystemBase.h" #include @@ -399,7 +399,7 @@ ReturnValue_t DeviceHandlerBase::isModeCombinationValid(Mode_t mode, ReturnValue_t DeviceHandlerBase::insertInCommandAndReplyMap( DeviceCommandId_t deviceCommand, uint16_t maxDelayCycles, - PoolDataSetIF* replyDataSet, size_t replyLen, bool periodic, + LocalPoolDataSetBase* replyDataSet, size_t replyLen, bool periodic, bool hasDifferentReplyId, DeviceCommandId_t replyId) { //No need to check, as we may try to insert multiple times. insertInCommandMap(deviceCommand); @@ -413,7 +413,7 @@ ReturnValue_t DeviceHandlerBase::insertInCommandAndReplyMap( } ReturnValue_t DeviceHandlerBase::insertInReplyMap(DeviceCommandId_t replyId, - uint16_t maxDelayCycles, PoolDataSetIF* dataSet, + uint16_t maxDelayCycles, LocalPoolDataSetBase* dataSet, size_t replyLen, bool periodic) { DeviceReplyInfo info; info.maxDelayCycles = maxDelayCycles; @@ -463,7 +463,7 @@ ReturnValue_t DeviceHandlerBase::updateReplyMapEntry(DeviceCommandId_t deviceRep ReturnValue_t DeviceHandlerBase::setReplyDataset(DeviceCommandId_t replyId, - PoolDataSetIF *dataSet) { + LocalPoolDataSetBase *dataSet) { auto replyIter = deviceReplyMap.find(replyId); if(replyIter == deviceReplyMap.end()) { return HasReturnvaluesIF::RETURN_FAILED; @@ -1286,10 +1286,14 @@ void DeviceHandlerBase::buildInternalCommand(void) { if (iter == deviceCommandMap.end()) { result = COMMAND_NOT_SUPPORTED; } else if (iter->second.isExecuting) { + //so we can track misconfigurations sif::debug << std::hex << getObjectId() << ": DHB::buildInternalCommand: Command " - << deviceCommandId << " isExecuting" << std::endl; //so we can track misconfigurations - return; //this is an internal command, no need to report a failure here, missed reply will track if a reply is too late, otherwise, it's ok + << deviceCommandId << " isExecuting" << std::dec + << std::endl; + // this is an internal command, no need to report a failure here, + // missed reply will track if a reply is too late, otherwise, it's ok + return; } else { iter->second.sendReplyTo = NO_COMMANDER; iter->second.isExecuting = true; @@ -1396,10 +1400,14 @@ ReturnValue_t DeviceHandlerBase::initializeAfterTaskCreation() { pstIntervalMs = executingTask->getPeriodMs(); } this->hkManager.initializeAfterTaskCreation(); + + if(setStartupImmediately) { + startTransition(MODE_ON, SUBMODE_NONE); + } return HasReturnvaluesIF::RETURN_OK; } -DataSetIF* DeviceHandlerBase::getDataSetHandle(sid_t sid) { +LocalPoolDataSetBase* DeviceHandlerBase::getDataSetHandle(sid_t sid) { auto iter = deviceReplyMap.find(sid.ownerSetId); if(iter != deviceReplyMap.end()) { return iter->second.dataSet; @@ -1413,6 +1421,10 @@ object_id_t DeviceHandlerBase::getObjectId() const { return SystemObject::getObjectId(); } +void DeviceHandlerBase::setStartUpImmediately() { + this->setStartupImmediately = true; +} + dur_millis_t DeviceHandlerBase::getPeriodicOperationFrequency() const { return pstIntervalMs; } diff --git a/devicehandlers/DeviceHandlerBase.h b/devicehandlers/DeviceHandlerBase.h index 8c4fb04ec..627a64238 100644 --- a/devicehandlers/DeviceHandlerBase.h +++ b/devicehandlers/DeviceHandlerBase.h @@ -1,25 +1,26 @@ -#ifndef FRAMEWORK_DEVICEHANDLERS_DEVICEHANDLERBASE_H_ -#define FRAMEWORK_DEVICEHANDLERS_DEVICEHANDLERBASE_H_ +#ifndef FSFW_DEVICEHANDLERS_DEVICEHANDLERBASE_H_ +#define FSFW_DEVICEHANDLERS_DEVICEHANDLERBASE_H_ + +#include "DeviceHandlerIF.h" +#include "DeviceCommunicationIF.h" +#include "DeviceHandlerFailureIsolation.h" #include "../objectmanager/SystemObject.h" #include "../tasks/ExecutableObjectIF.h" -#include "../devicehandlers/DeviceHandlerIF.h" #include "../returnvalues/HasReturnvaluesIF.h" #include "../action/HasActionsIF.h" #include "../datapool/PoolVariableIF.h" -#include "../devicehandlers/DeviceCommunicationIF.h" #include "../modes/HasModesIF.h" #include "../power/PowerSwitchIF.h" #include "../ipc/MessageQueueIF.h" #include "../tasks/PeriodicTaskIF.h" - #include "../action/ActionHelper.h" #include "../health/HealthHelper.h" #include "../parameters/ParameterHelper.h" #include "../datapool/HkSwitchHelper.h" #include "../datapoollocal/HasLocalDataPoolIF.h" #include "../datapoollocal/LocalDataPoolManager.h" -#include "../devicehandlers/DeviceHandlerFailureIsolation.h" + #include namespace Factory{ @@ -104,6 +105,18 @@ public: void setHkDestination(object_id_t hkDestination); void setThermalStateRequestPoolIds(uint32_t thermalStatePoolId, uint32_t thermalRequestPoolId); + /** + * @brief Helper function to ease device handler development. + * This will instruct the transition to MODE_ON immediately + * (leading to doStartUp() being called for the transition to the ON mode), + * so external mode commanding is not necessary anymore. + * + * This has to be called before the task is started! + * (e.g. in the task factory). This is only a helper function for + * development. Regular mode commanding should be performed by commanding + * the AssemblyBase or Subsystem objects resposible for the device handler. + */ + void setStartUpImmediately(); /** * @brief This function is the device handler base core component and is @@ -149,6 +162,14 @@ public: * @return */ virtual ReturnValue_t initialize(); + + /** + * @brief Intialization steps performed after all tasks have been created. + * This function will be called by the executing task. + * @return + */ + virtual ReturnValue_t initializeAfterTaskCreation() override; + /** Destructor. */ virtual ~DeviceHandlerBase(); @@ -370,7 +391,8 @@ protected: * - @c RETURN_FAILED else. */ ReturnValue_t insertInCommandAndReplyMap(DeviceCommandId_t deviceCommand, - uint16_t maxDelayCycles, PoolDataSetIF* replyDataSet = nullptr, + uint16_t maxDelayCycles, + LocalPoolDataSetBase* replyDataSet = nullptr, size_t replyLen = 0, bool periodic = false, bool hasDifferentReplyId = false, DeviceCommandId_t replyId = 0); @@ -385,7 +407,7 @@ protected: * - @c RETURN_FAILED else. */ ReturnValue_t insertInReplyMap(DeviceCommandId_t deviceCommand, - uint16_t maxDelayCycles, PoolDataSetIF* dataSet = nullptr, + uint16_t maxDelayCycles, LocalPoolDataSetBase* dataSet = nullptr, size_t replyLen = 0, bool periodic = false); /** @@ -415,7 +437,7 @@ protected: bool periodic = false); ReturnValue_t setReplyDataset(DeviceCommandId_t replyId, - PoolDataSetIF* dataset); + LocalPoolDataSetBase* dataset); /** * @brief Can be implemented by child handler to @@ -645,7 +667,7 @@ protected: //! The dataset used to access housekeeping data related to the //! respective device reply. Will point to a dataset held by //! the child handler (if one is specified) - PoolDataSetIF* dataSet = nullptr; + LocalPoolDataSetBase* dataSet; //! The command that expects this reply. DeviceCommandMap::iterator command; }; @@ -946,14 +968,17 @@ protected: virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, uint32_t *msToReachTheMode); - virtual void startTransition(Mode_t mode, Submode_t submode); - virtual void setToExternalControl(); - virtual void announceMode(bool recursive); + + /* HasModesIF overrides */ + virtual void startTransition(Mode_t mode, Submode_t submode) override; + virtual void setToExternalControl() override; + virtual void announceMode(bool recursive) override; virtual ReturnValue_t letChildHandleMessage(CommandMessage *message); /** - * Overwrites SystemObject::triggerEvent in order to inform FDIR"Helper" faster about executed events. + * Overwrites SystemObject::triggerEvent in order to inform FDIR"Helper" + * faster about executed events. * This is a bit sneaky, but improves responsiveness of the device FDIR. * @param event The event to be thrown * @param parameter1 Optional parameter 1 @@ -1045,6 +1070,8 @@ private: */ uint32_t timeoutStart = 0; + bool setStartupImmediately = false; + /** * Delay for the current mode transition, used for time out */ @@ -1163,7 +1190,6 @@ private: ReturnValue_t getStorageData(store_address_t storageAddress, uint8_t **data, uint32_t *len); - /** * @param modeTo either @c MODE_ON, MODE_NORMAL or MODE_RAW NOTHING ELSE!!! */ @@ -1174,28 +1200,14 @@ private: */ void callChildStatemachine(); - /** - * Switches the channel of the cookie used for the communication - * - * - * @param newChannel the object Id of the channel to switch to - * @return - * - @c RETURN_OK when cookie was changed - * - @c RETURN_FAILED when cookies could not be changed, - * e.g. because the newChannel is not enabled - * - @c returnvalues of RMAPChannelIF::isActive() - */ - ReturnValue_t switchCookieChannel(object_id_t newChannelId); - ReturnValue_t handleDeviceHandlerMessage(CommandMessage *message); - virtual ReturnValue_t initializeAfterTaskCreation() override; - virtual DataSetIF* getDataSetHandle(sid_t sid) override; - - void parseReply(const uint8_t* receivedData, - size_t receivedDataLen); + virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override; virtual dur_millis_t getPeriodicOperationFrequency() const override; + + void parseReply(const uint8_t* receivedData, + size_t receivedDataLen); }; -#endif /* FRAMEWORK_DEVICEHANDLERS_DEVICEHANDLERBASE_H_ */ +#endif /* FSFW_DEVICEHANDLERS_DEVICEHANDLERBASE_H_ */ diff --git a/devicehandlers/DeviceHandlerFailureIsolation.cpp b/devicehandlers/DeviceHandlerFailureIsolation.cpp index 9fbe71d85..24fe15a03 100644 --- a/devicehandlers/DeviceHandlerFailureIsolation.cpp +++ b/devicehandlers/DeviceHandlerFailureIsolation.cpp @@ -247,6 +247,14 @@ bool DeviceHandlerFailureIsolation::isFdirInActionOrAreWeFaulty( } return true; } + + if (owner == nullptr) { + // Configuration error. + sif::error << "DeviceHandlerFailureIsolation::" + << "isFdirInActionOrAreWeFaulty: Owner not set!" << std::endl; + return false; + } + if (owner->getHealth() == HasHealthIF::FAULTY || owner->getHealth() == HasHealthIF::PERMANENT_FAULTY) { //Ignore all events in case device is already faulty. diff --git a/devicehandlers/DeviceHandlerIF.h b/devicehandlers/DeviceHandlerIF.h index fcf501287..088c1b457 100644 --- a/devicehandlers/DeviceHandlerIF.h +++ b/devicehandlers/DeviceHandlerIF.h @@ -1,12 +1,19 @@ -#ifndef DEVICEHANDLERIF_H_ -#define DEVICEHANDLERIF_H_ +#ifndef FSFW_DEVICEHANDLERS_DEVICEHANDLERIF_H_ +#define FSFW_DEVICEHANDLERS_DEVICEHANDLERIF_H_ + +#include "DeviceHandlerMessage.h" #include "../action/HasActionsIF.h" -#include "../devicehandlers/DeviceHandlerMessage.h" #include "../events/Event.h" #include "../modes/HasModesIF.h" #include "../ipc/MessageQueueSenderIF.h" +/** + * This is used to uniquely identify commands that are sent to a device + * The values are defined in the device-specific implementations + */ +using DeviceCommandId_t = uint32_t; + /** * @brief This is the Interface used to communicate with a device handler. * @details Includes all expected return values, events and modes. @@ -15,6 +22,7 @@ class DeviceHandlerIF { public: + static const uint8_t TRANSITION_MODE_CHILD_ACTION_MASK = 0x20; static const uint8_t TRANSITION_MODE_BASE_ACTION_MASK = 0x10; @@ -153,4 +161,4 @@ public: }; -#endif /* DEVICEHANDLERIF_H_ */ +#endif /* FSFW_DEVICEHANDLERS_DEVICEHANDLERIF_H_ */ diff --git a/devicehandlers/DeviceHandlerMessage.cpp b/devicehandlers/DeviceHandlerMessage.cpp index b4963dbf7..cb9043db8 100644 --- a/devicehandlers/DeviceHandlerMessage.cpp +++ b/devicehandlers/DeviceHandlerMessage.cpp @@ -1,9 +1,5 @@ +#include "DeviceHandlerMessage.h" #include "../objectmanager/ObjectManagerIF.h" -#include "../devicehandlers/DeviceHandlerMessage.h" -#include "../objectmanager/ObjectManagerIF.h" - -DeviceHandlerMessage::DeviceHandlerMessage() { -} store_address_t DeviceHandlerMessage::getStoreAddress( const CommandMessage* message) { @@ -25,14 +21,6 @@ uint8_t DeviceHandlerMessage::getWiretappingMode( return message->getParameter(); } -//void DeviceHandlerMessage::setDeviceHandlerDirectCommandMessage( -// CommandMessage* message, DeviceCommandId_t deviceCommand, -// store_address_t commandParametersStoreId) { -// message->setCommand(CMD_DIRECT); -// message->setParameter(deviceCommand); -// message->setParameter2(commandParametersStoreId.raw); -//} - void DeviceHandlerMessage::setDeviceHandlerRawCommandMessage( CommandMessage* message, store_address_t rawPacketStoreId) { message->setCommand(CMD_RAW); @@ -79,13 +67,12 @@ void DeviceHandlerMessage::setDeviceHandlerDirectCommandReply( void DeviceHandlerMessage::clear(CommandMessage* message) { switch (message->getCommand()) { case CMD_RAW: -// case CMD_DIRECT: case REPLY_RAW_COMMAND: case REPLY_RAW_REPLY: case REPLY_DIRECT_COMMAND_DATA: { StorageManagerIF *ipcStore = objectManager->get( objects::IPC_STORE); - if (ipcStore != NULL) { + if (ipcStore != nullptr) { ipcStore->deleteData(getStoreAddress(message)); } } diff --git a/devicehandlers/DeviceHandlerMessage.h b/devicehandlers/DeviceHandlerMessage.h index 5f4583d2c..e5da01c8f 100644 --- a/devicehandlers/DeviceHandlerMessage.h +++ b/devicehandlers/DeviceHandlerMessage.h @@ -1,69 +1,56 @@ -#ifndef DEVICEHANDLERMESSAGE_H_ -#define DEVICEHANDLERMESSAGE_H_ +#ifndef FSFW_DEVICEHANDLERS_DEVICEHANDLERMESSAGE_H_ +#define FSFW_DEVICEHANDLERS_DEVICEHANDLERMESSAGE_H_ #include "../action/ActionMessage.h" #include "../ipc/CommandMessage.h" #include "../objectmanager/SystemObjectIF.h" #include "../storagemanager/StorageManagerIF.h" -//SHOULDDO: rework the static constructors to name the type of command they are building, maybe even hide setting the commandID. +// SHOULDDO: rework the static constructors to name the type of command +// they are building, maybe even hide setting the commandID. + /** - * This is used to uniquely identify commands that are sent to a device - * - * The values are defined in the device-specific implementations - */ -typedef uint32_t DeviceCommandId_t; - -/** - * The DeviceHandlerMessage is used to send Commands to a DeviceHandlerIF + * @brief The DeviceHandlerMessage is used to send commands to classes + * implementing DeviceHandlerIF */ class DeviceHandlerMessage { -private: - DeviceHandlerMessage(); public: + /** + * Instantiation forbidden. Instead, use static functions to operate + * on messages. + */ + DeviceHandlerMessage() = delete; + virtual ~DeviceHandlerMessage() {} /** * These are the commands that can be sent to a DeviceHandlerBase */ static const uint8_t MESSAGE_ID = messagetypes::DEVICE_HANDLER_COMMAND; - static const Command_t CMD_RAW = MAKE_COMMAND_ID( 1 ); //!< Sends a raw command, setParameter is a ::store_id_t containing the raw packet to send -// static const Command_t CMD_DIRECT = MAKE_COMMAND_ID( 2 ); //!< Sends a direct command, setParameter is a ::DeviceCommandId_t, setParameter2 is a ::store_id_t containing the data needed for the command - static const Command_t CMD_SWITCH_ADDRESS = MAKE_COMMAND_ID( 3 ); //!< Requests a IO-Board switch, setParameter() is the IO-Board identifier - static const Command_t CMD_WIRETAPPING = MAKE_COMMAND_ID( 4 ); //!< (De)Activates the monitoring of all raw traffic in DeviceHandlers, setParameter is 0 to deactivate, 1 to activate + //! Sends a raw command, setParameter is a storeId containing the + //! raw packet to send + static const Command_t CMD_RAW = MAKE_COMMAND_ID(1); + //! Requests a IO-Board switch, setParameter() is the IO-Board identifier + static const Command_t CMD_SWITCH_ADDRESS = MAKE_COMMAND_ID(3); + //! (De)Activates the monitoring of all raw traffic in DeviceHandlers, + //! setParameter is 0 to deactivate, 1 to activate + static const Command_t CMD_WIRETAPPING = MAKE_COMMAND_ID(4); - /*static const Command_t REPLY_SWITCHED_IOBOARD = MAKE_COMMAND_ID(1 );//!< Reply to a @c CMD_SWITCH_IOBOARD, indicates switch was successful, getParameter() contains the board switched to (0: nominal, 1: redundant) - static const Command_t REPLY_CANT_SWITCH_IOBOARD = MAKE_COMMAND_ID( 2); //!< Reply to a @c CMD_SWITCH_IOBOARD, indicating the switch could not be performed, getParameter() contains the error message - static const Command_t REPLY_WIRETAPPING = MAKE_COMMAND_ID( 3); //!< Reply to a @c CMD_WIRETAPPING, getParameter() is the current state, 1 enabled, 0 disabled - - static const Command_t REPLY_COMMAND_WAS_SENT = MAKE_COMMAND_ID(4 );//!< Reply to a @c CMD_RAW or @c CMD_DIRECT, indicates the command was successfully sent to the device, getParameter() contains the ::DeviceCommandId_t - static const Command_t REPLY_COMMAND_NOT_SUPPORTED = MAKE_COMMAND_ID(5 );//!< Reply to a @c CMD_DIRECT, the requested ::DeviceCommand_t is not supported, getParameter() contains the requested ::DeviceCommand_t, getParameter2() contains the ::DeviceCommandId_t - static const Command_t REPLY_COMMAND_WAS_NOT_SENT = MAKE_COMMAND_ID(6 );//!< Reply to a @c CMD_RAW or @c CMD_DIRECT, indicates the command was not sent, getParameter contains the RMAP Return code (@see rmap.h), getParameter2() contains the ::DeviceCommandId_t - - static const Command_t REPLY_COMMAND_ALREADY_SENT = MAKE_COMMAND_ID(7 );//!< Reply to a @c CMD_DIRECT, the requested ::DeviceCommand_t has already been sent to the device and not ye been answered - static const Command_t REPLY_WRONG_MODE_FOR_CMD = MAKE_COMMAND_ID(8 );//!< Reply to a @c CMD_RAW or @c CMD_DIRECT, indicates that the requested command can not be sent in the curent mode, getParameter() contains the DeviceHandlerCommand_t - static const Command_t REPLY_NO_DATA = MAKE_COMMAND_ID(9 ); //!< Reply to a CMD_RAW or @c CMD_DIRECT, indicates that the ::store_id_t was invalid, getParameter() contains the ::DeviceCommandId_t, getPrameter2() contains the error code - */ - static const Command_t REPLY_DIRECT_COMMAND_SENT = ActionMessage::STEP_SUCCESS; //!< Signals that a direct command was sent - static const Command_t REPLY_RAW_COMMAND = MAKE_COMMAND_ID(0x11 ); //!< Contains a raw command sent to the Device - static const Command_t REPLY_RAW_REPLY = MAKE_COMMAND_ID( 0x12); //!< Contains a raw reply from the Device, getParameter() is the ObjcetId of the sender, getParameter2() is a ::store_id_t containing the raw packet received + //! Signals that a direct command was sent + static const Command_t REPLY_DIRECT_COMMAND_SENT = ActionMessage::STEP_SUCCESS; + //! Contains a raw command sent to the Device + static const Command_t REPLY_RAW_COMMAND = MAKE_COMMAND_ID(0x11); + //! Contains a raw reply from the Device, getParameter() is the ObjcetId + //! of the sender, getParameter2() is a ::store_id_t containing the + //! raw packet received + static const Command_t REPLY_RAW_REPLY = MAKE_COMMAND_ID(0x12); static const Command_t REPLY_DIRECT_COMMAND_DATA = ActionMessage::DATA_REPLY; - /** - * Default Destructor - */ - virtual ~DeviceHandlerMessage() { - } - static store_address_t getStoreAddress(const CommandMessage* message); static uint32_t getDeviceCommandId(const CommandMessage* message); static object_id_t getDeviceObjectId(const CommandMessage *message); static object_id_t getIoBoardObjectId(const CommandMessage* message); static uint8_t getWiretappingMode(const CommandMessage* message); -// static void setDeviceHandlerDirectCommandMessage(CommandMessage* message, -// DeviceCommandId_t deviceCommand, -// store_address_t commandParametersStoreId); - static void setDeviceHandlerDirectCommandReply(CommandMessage* message, object_id_t deviceObjectid, store_address_t commandParametersStoreId); @@ -75,11 +62,6 @@ public: object_id_t deviceObjectid, store_address_t rawPacketStoreId, bool isCommand); -// static void setDeviceHandlerMessage(CommandMessage* message, -// Command_t command, DeviceCommandId_t deviceCommand, -// store_address_t commandParametersStoreId); -// static void setDeviceHandlerMessage(CommandMessage* message, -// Command_t command, store_address_t rawPacketStoreId); static void setDeviceHandlerWiretappingMessage(CommandMessage* message, uint8_t wiretappingMode); static void setDeviceHandlerSwitchIoBoardMessage(CommandMessage* message, @@ -88,4 +70,4 @@ public: static void clear(CommandMessage* message); }; -#endif /* DEVICEHANDLERMESSAGE_H_ */ +#endif /* FSFW_DEVICEHANDLERS_DEVICEHANDLERMESSAGE_H_ */ diff --git a/events/Event.cpp b/events/Event.cpp index ea3d46fe4..0f76b4386 100644 --- a/events/Event.cpp +++ b/events/Event.cpp @@ -1,4 +1,5 @@ #include "Event.h" + namespace EVENT { EventId_t getEventId(Event event) { return (event & 0xFFFF); @@ -8,7 +9,8 @@ EventSeverity_t getSeverity(Event event) { return ((event >> 16) & 0xFF); } -Event makeEvent(EventId_t eventId, EventSeverity_t eventSeverity) { - return (eventSeverity << 16) + (eventId & 0xFFFF); +Event makeEvent(uint8_t subsystemId, uint8_t uniqueEventId, + EventSeverity_t eventSeverity) { + return (eventSeverity << 16) + (subsystemId * 100) + uniqueEventId; } } diff --git a/events/Event.h b/events/Event.h index e22c9db16..f5434826b 100644 --- a/events/Event.h +++ b/events/Event.h @@ -4,7 +4,7 @@ #include #include "fwSubsystemIdRanges.h" //could be move to more suitable location -#include +#include typedef uint16_t EventId_t; typedef uint8_t EventSeverity_t; @@ -18,9 +18,10 @@ EventId_t getEventId(Event event); EventSeverity_t getSeverity(Event event); -Event makeEvent(EventId_t eventId, EventSeverity_t eventSeverity); - +Event makeEvent(uint8_t subsystemId, uint8_t uniqueEventId, + EventSeverity_t eventSeverity); } + namespace SEVERITY { static const EventSeverity_t INFO = 1; static const EventSeverity_t LOW = 2; diff --git a/events/EventManager.cpp b/events/EventManager.cpp index e71951e36..0971dadc8 100644 --- a/events/EventManager.cpp +++ b/events/EventManager.cpp @@ -109,13 +109,13 @@ ReturnValue_t EventManager::unsubscribeFromEventRange(MessageQueueId_t listener, return result; } -#ifdef DEBUG +#if FSFW_DEBUG_OUTPUT == 1 void EventManager::printEvent(EventMessage* message) { const char *string = 0; switch (message->getSeverity()) { case SEVERITY::INFO: -#ifdef DEBUG_INFO_EVENT +#if DEBUG_INFO_EVENT == 1 string = translateObject(message->getReporter()); sif::info << "EVENT: "; if (string != 0) { diff --git a/events/EventManager.h b/events/EventManager.h index 2602aeb23..f03c02415 100644 --- a/events/EventManager.h +++ b/events/EventManager.h @@ -8,9 +8,11 @@ #include "../tasks/ExecutableObjectIF.h" #include "../ipc/MessageQueueIF.h" #include "../ipc/MutexIF.h" +#include + #include -#ifdef DEBUG +#if FSFW_DEBUG_OUTPUT == 1 // forward declaration, should be implemented by mission extern const char* translateObject(object_id_t object); extern const char* translateEvents(Event event); @@ -55,7 +57,7 @@ protected: void notifyListeners(EventMessage *message); -#ifdef DEBUG +#if FSFW_DEBUG_OUTPUT == 1 void printEvent(EventMessage *message); #endif diff --git a/events/EventManagerIF.h b/events/EventManagerIF.h index f9ac420b3..253e6910c 100644 --- a/events/EventManagerIF.h +++ b/events/EventManagerIF.h @@ -1,10 +1,11 @@ #ifndef EVENTMANAGERIF_H_ #define EVENTMANAGERIF_H_ -#include "eventmatching/eventmatching.h" #include "EventMessage.h" +#include "eventmatching/eventmatching.h" #include "../objectmanager/ObjectManagerIF.h" #include "../ipc/MessageQueueSenderIF.h" +#include "../ipc/MessageQueueIF.h" class EventManagerIF { public: @@ -16,7 +17,8 @@ public: virtual MessageQueueId_t getEventReportQueue() = 0; - virtual ReturnValue_t registerListener(MessageQueueId_t listener, bool forwardAllButSelected = false) = 0; + virtual ReturnValue_t registerListener(MessageQueueId_t listener, + bool forwardAllButSelected = false) = 0; virtual ReturnValue_t subscribeToEvent(MessageQueueId_t listener, EventId_t event) = 0; virtual ReturnValue_t subscribeToAllEventsFrom(MessageQueueId_t listener, @@ -31,18 +33,22 @@ public: bool reporterInverted = false) = 0; static void triggerEvent(object_id_t reportingObject, Event event, - uint32_t parameter1 = 0, uint32_t parameter2 = 0, MessageQueueId_t sentFrom = 0) { + uint32_t parameter1 = 0, uint32_t parameter2 = 0, + MessageQueueId_t sentFrom = 0) { EventMessage message(event, reportingObject, parameter1, parameter2); triggerEvent(&message, sentFrom); } - static void triggerEvent(EventMessage* message, MessageQueueId_t sentFrom = 0) { - static MessageQueueId_t eventmanagerQueue = 0; - if (eventmanagerQueue == 0) { + + static void triggerEvent(EventMessage* message, + MessageQueueId_t sentFrom = 0) { + static MessageQueueId_t eventmanagerQueue = MessageQueueIF::NO_QUEUE; + if (eventmanagerQueue == MessageQueueIF::NO_QUEUE) { EventManagerIF *eventmanager = objectManager->get( objects::EVENT_MANAGER); - if (eventmanager != NULL) { - eventmanagerQueue = eventmanager->getEventReportQueue(); + if (eventmanager == nullptr) { + return; } + eventmanagerQueue = eventmanager->getEventReportQueue(); } MessageQueueSenderIF::sendMessage(eventmanagerQueue, message, sentFrom); } diff --git a/events/fwSubsystemIdRanges.h b/events/fwSubsystemIdRanges.h index a05652c22..8dc4def76 100644 --- a/events/fwSubsystemIdRanges.h +++ b/events/fwSubsystemIdRanges.h @@ -19,6 +19,8 @@ enum { SYSTEM_MANAGER_1 = 75, SYSTEM_1 = 79, PUS_SERVICE_1 = 80, + PUS_SERVICE_9 = 89, + PUS_SERVICE_17 = 97, FW_SUBSYSTEM_ID_RANGE }; } diff --git a/fdir/ConfirmsFailuresIF.h b/fdir/ConfirmsFailuresIF.h index 6cb2c47de..144114612 100644 --- a/fdir/ConfirmsFailuresIF.h +++ b/fdir/ConfirmsFailuresIF.h @@ -4,7 +4,6 @@ #include "../returnvalues/HasReturnvaluesIF.h" #include "../ipc/MessageQueueSenderIF.h" -// TODO: Documentation. class ConfirmsFailuresIF { public: static const uint8_t INTERFACE_ID = CLASS_ID::HANDLES_FAILURES_IF; diff --git a/fdir/EventCorrelation.cpp b/fdir/EventCorrelation.cpp index f98d22236..d60fc6ca3 100644 --- a/fdir/EventCorrelation.cpp +++ b/fdir/EventCorrelation.cpp @@ -1,4 +1,4 @@ -#include "../fdir/EventCorrelation.h" +#include "EventCorrelation.h" EventCorrelation::EventCorrelation(uint32_t timeout) : eventPending(false) { diff --git a/fdir/FailureIsolationBase.cpp b/fdir/FailureIsolationBase.cpp index ab462a97d..f3b34f0fb 100644 --- a/fdir/FailureIsolationBase.cpp +++ b/fdir/FailureIsolationBase.cpp @@ -1,5 +1,5 @@ #include "../events/EventManagerIF.h" -#include "../fdir/FailureIsolationBase.h" +#include "FailureIsolationBase.h" #include "../health/HasHealthIF.h" #include "../health/HealthMessage.h" #include "../ipc/QueueFactory.h" diff --git a/fdir/FailureIsolationBase.h b/fdir/FailureIsolationBase.h index f8a307b33..5b2c099ae 100644 --- a/fdir/FailureIsolationBase.h +++ b/fdir/FailureIsolationBase.h @@ -2,8 +2,8 @@ #define FRAMEWORK_FDIR_FAILUREISOLATIONBASE_H_ #include "../events/EventMessage.h" -#include "../fdir/ConfirmsFailuresIF.h" -#include "../fdir/FaultCounter.h" +#include "ConfirmsFailuresIF.h" +#include "FaultCounter.h" #include "../health/HealthMessage.h" #include "../parameters/HasParametersIF.h" #include "../returnvalues/HasReturnvaluesIF.h" diff --git a/fdir/FaultCounter.cpp b/fdir/FaultCounter.cpp index b75bd48fd..443adb52e 100644 --- a/fdir/FaultCounter.cpp +++ b/fdir/FaultCounter.cpp @@ -1,4 +1,4 @@ -#include "../fdir/FaultCounter.h" +#include "FaultCounter.h" FaultCounter::FaultCounter(uint32_t failureThreshold, uint32_t decrementAfterMs, uint8_t setParameterDomain) : diff --git a/fsfw.mk b/fsfw.mk index a548b6a88..c58475540 100644 --- a/fsfw.mk +++ b/fsfw.mk @@ -31,12 +31,25 @@ CXXSRC += $(wildcard $(FRAMEWORK_PATH)/osal/*.cpp) # select the OS ifeq ($(OS_FSFW),rtems) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/osal/rtems/*.cpp) + else ifeq ($(OS_FSFW),linux) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/osal/linux/*.cpp) + else ifeq ($(OS_FSFW),freeRTOS) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/osal/FreeRTOS/*.cpp) + else ifeq ($(OS_FSFW),host) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/osal/host/*.cpp) +ifeq ($(OS),Windows_NT) +CXXSRC += $(wildcard $(FRAMEWORK_PATH)/osal/windows/*.cpp) +else +# For now, the linux UDP bridge sources needs to be included manually by upper makefile +# for host OS because we can't be sure the OS is linux. +# Following lines can be used to do this: +# CXXSRC += $(FRAMEWORK_PATH)/osal/linux/TcUnixUdpPollingTask.cpp +# CXXSRC += $(FRAMEWORK_PATH)/osal/linux/TmTcUnixUdpBridge.cpp +endif + else $(error invalid OS_FSFW specified, valid OS_FSFW are rtems, linux, freeRTOS, host) endif diff --git a/globalfunctions/AsciiConverter.cpp b/globalfunctions/AsciiConverter.cpp index c57125e26..9eb3698fb 100644 --- a/globalfunctions/AsciiConverter.cpp +++ b/globalfunctions/AsciiConverter.cpp @@ -1,4 +1,4 @@ -#include "../globalfunctions/AsciiConverter.h" +#include "AsciiConverter.h" #include #include diff --git a/globalfunctions/CRC.cpp b/globalfunctions/CRC.cpp index 1258b6989..7bb568066 100644 --- a/globalfunctions/CRC.cpp +++ b/globalfunctions/CRC.cpp @@ -1,4 +1,4 @@ -#include "../globalfunctions/CRC.h" +#include "CRC.h" #include const uint16_t CRC::crc16ccitt_table[256] = { diff --git a/globalfunctions/DleEncoder.cpp b/globalfunctions/DleEncoder.cpp index 6bd402d7e..8520389d2 100644 --- a/globalfunctions/DleEncoder.cpp +++ b/globalfunctions/DleEncoder.cpp @@ -92,7 +92,7 @@ ReturnValue_t DleEncoder::decode(const uint8_t *sourceStream, else { /* The next byte is a STX, DTX or 0x0D character which * was escaped by a DLE character. The actual byte was - * also encoded by adding + 0x40 to preven having control chars, + * also encoded by adding + 0x40 to prevent having control chars, * in the stream at all, so we convert it back. */ if (nextByte == 0x42 or nextByte == 0x43 or nextByte == 0x4D) { destStream[decodedIndex] = nextByte - 0x40; diff --git a/globalfunctions/DleEncoder.h b/globalfunctions/DleEncoder.h index 3c535d1f3..6d073f9a2 100644 --- a/globalfunctions/DleEncoder.h +++ b/globalfunctions/DleEncoder.h @@ -15,12 +15,12 @@ * char based transmission systems. * The passed source strean is converted into a encoded stream by adding * a STX marker at the start of the stream and an ETX marker at the end of - * the stream. Any STX, ETX, DLE and CR occurences in the source stream are + * the stream. Any STX, ETX, DLE and CR occurrences in the source stream are * escaped by a DLE character. The encoder also replaces escaped control chars * by another char, so STX, ETX and CR should not appear anywhere in the actual * encoded data stream. * - * When using a strictly char based reception of packets enoded with DLE, + * When using a strictly char based reception of packets encoded with DLE, * STX can be used to notify a reader that actual data will start to arrive * while ETX can be used to notify the reader that the data has ended. */ @@ -38,7 +38,7 @@ public: static constexpr uint8_t STX_CHAR = 0x02; //! End Of Text character. Last character in encoded stream static constexpr uint8_t ETX_CHAR = 0x03; - //! Data Link Escape character. Used to escape STX, ETX and DLE occurences + //! Data Link Escape character. Used to escape STX, ETX and DLE occurrences //! in the source stream. static constexpr uint8_t DLE_CHAR = 0x10; static constexpr uint8_t CARRIAGE_RETURN = 0x0D; @@ -47,7 +47,7 @@ public: * Encodes the give data stream by preceding it with the STX marker * and ending it with an ETX marker. STX, ETX and DLE characters inside * the stream are escaped by DLE characters and also replaced by adding - * 0x40 (which is reverted in the decoing process). + * 0x40 (which is reverted in the decoding process). * @param sourceStream * @param sourceLen * @param destStream diff --git a/globalfunctions/PeriodicOperationDivider.cpp b/globalfunctions/PeriodicOperationDivider.cpp new file mode 100644 index 000000000..28e98feba --- /dev/null +++ b/globalfunctions/PeriodicOperationDivider.cpp @@ -0,0 +1,44 @@ +#include "PeriodicOperationDivider.h" + + +PeriodicOperationDivider::PeriodicOperationDivider(uint32_t divider, + bool resetAutomatically): resetAutomatically(resetAutomatically), + counter(divider), divider(divider) { +} + +bool PeriodicOperationDivider::checkAndIncrement() { + bool opNecessary = check(); + if(opNecessary) { + if(resetAutomatically) { + counter = 0; + } + return opNecessary; + } + counter ++; + return opNecessary; +} + +bool PeriodicOperationDivider::check() { + if(counter >= divider) { + return true; + } + return false; +} + + + +void PeriodicOperationDivider::resetCounter() { + counter = 0; +} + +void PeriodicOperationDivider::setDivider(uint32_t newDivider) { + divider = newDivider; +} + +uint32_t PeriodicOperationDivider::getCounter() const { + return counter; +} + +uint32_t PeriodicOperationDivider::getDivider() const { + return divider; +} diff --git a/globalfunctions/PeriodicOperationDivider.h b/globalfunctions/PeriodicOperationDivider.h new file mode 100644 index 000000000..7f7fb4697 --- /dev/null +++ b/globalfunctions/PeriodicOperationDivider.h @@ -0,0 +1,65 @@ +#ifndef FSFW_GLOBALFUNCTIONS_PERIODICOPERATIONDIVIDER_H_ +#define FSFW_GLOBALFUNCTIONS_PERIODICOPERATIONDIVIDER_H_ + +#include + +/** + * @brief Lightweight helper class to facilitate periodic operation with + * decreased frequencies. + * @details + * This class is useful to perform operations which have to be performed + * with a reduced frequency, like debugging printouts in high periodic tasks + * or low priority operations. + */ +class PeriodicOperationDivider { +public: + /** + * Initialize with the desired divider and specify whether the internal + * counter will be reset automatically. + * @param divider + * @param resetAutomatically + */ + PeriodicOperationDivider(uint32_t divider, bool resetAutomatically = true); + + + /** + * Check whether operation is necessary. + * If an operation is necessary and the class has been + * configured to be reset automatically, the counter will be reset. + * + * @return + * -@c true if the counter is larger or equal to the divider + * -@c false otherwise + */ + bool checkAndIncrement(); + + /** + * Checks whether an operation is necessary. + * This function will not increment the counter! + * @return + * -@c true if the counter is larger or equal to the divider + * -@c false otherwise + */ + bool check(); + + /** + * Can be used to reset the counter to 0 manually. + */ + void resetCounter(); + uint32_t getCounter() const; + + /** + * Can be used to set a new divider value. + * @param newDivider + */ + void setDivider(uint32_t newDivider); + uint32_t getDivider() const; +private: + bool resetAutomatically = true; + uint32_t counter = 0; + uint32_t divider = 0; +}; + + + +#endif /* FSFW_GLOBALFUNCTIONS_PERIODICOPERATIONDIVIDER_H_ */ diff --git a/globalfunctions/arrayprinter.cpp b/globalfunctions/arrayprinter.cpp index fa89c0dcd..b1e888c55 100644 --- a/globalfunctions/arrayprinter.cpp +++ b/globalfunctions/arrayprinter.cpp @@ -1,4 +1,4 @@ -#include "../globalfunctions/arrayprinter.h" +#include "arrayprinter.h" #include "../serviceinterface/ServiceInterfaceStream.h" #include @@ -27,7 +27,7 @@ void arrayprinter::printHex(const uint8_t *data, size_t size, if(i < size - 1){ sif::info << " , "; if(i > 0 and i % maxCharPerLine == 0) { - sif::info << "\r\n" << std::flush; + sif::info << std::endl; } } diff --git a/globalfunctions/matching/BinaryMatcher.h b/globalfunctions/matching/BinaryMatcher.h index 550439ab6..4f6db85d8 100644 --- a/globalfunctions/matching/BinaryMatcher.h +++ b/globalfunctions/matching/BinaryMatcher.h @@ -1,7 +1,7 @@ #ifndef BINARYMATCHER_H_ #define BINARYMATCHER_H_ -#include "../../globalfunctions/matching/MatcherIF.h" +#include "MatcherIF.h" template class BinaryMatcher: public MatcherIF { diff --git a/globalfunctions/matching/DecimalMatcher.h b/globalfunctions/matching/DecimalMatcher.h index 3c765cd7c..535050205 100644 --- a/globalfunctions/matching/DecimalMatcher.h +++ b/globalfunctions/matching/DecimalMatcher.h @@ -1,7 +1,7 @@ #ifndef DECIMALMATCHER_H_ #define DECIMALMATCHER_H_ -#include "../../globalfunctions/matching/MatcherIF.h" +#include "MatcherIF.h" template class DecimalMatcher: public MatcherIF { diff --git a/globalfunctions/matching/MatchTree.h b/globalfunctions/matching/MatchTree.h index 46245c25c..755687b28 100644 --- a/globalfunctions/matching/MatchTree.h +++ b/globalfunctions/matching/MatchTree.h @@ -2,7 +2,7 @@ #define FRAMEWORK_GLOBALFUNCTIONS_MATCHING_MATCHTREE_H_ #include "../../container/BinaryTree.h" -#include "../../globalfunctions/matching/SerializeableMatcherIF.h" +#include "SerializeableMatcherIF.h" #include "../../serialize/SerializeAdapter.h" template diff --git a/globalfunctions/matching/RangeMatcher.h b/globalfunctions/matching/RangeMatcher.h index 04c9c3fac..b64b9e30b 100644 --- a/globalfunctions/matching/RangeMatcher.h +++ b/globalfunctions/matching/RangeMatcher.h @@ -1,7 +1,7 @@ #ifndef RANGEMATCHER_H_ #define RANGEMATCHER_H_ -#include "../../globalfunctions/matching/SerializeableMatcherIF.h" +#include "SerializeableMatcherIF.h" #include "../../serialize/SerializeAdapter.h" template diff --git a/globalfunctions/matching/SerializeableMatcherIF.h b/globalfunctions/matching/SerializeableMatcherIF.h index f99c69642..067b0251a 100644 --- a/globalfunctions/matching/SerializeableMatcherIF.h +++ b/globalfunctions/matching/SerializeableMatcherIF.h @@ -1,7 +1,7 @@ #ifndef FRAMEWORK_GLOBALFUNCTIONS_MATCHING_SERIALIZEABLEMATCHERIF_H_ #define FRAMEWORK_GLOBALFUNCTIONS_MATCHING_SERIALIZEABLEMATCHERIF_H_ -#include "../../globalfunctions/matching/MatcherIF.h" +#include "MatcherIF.h" #include "../../serialize/SerializeIF.h" template diff --git a/globalfunctions/math/QuaternionOperations.cpp b/globalfunctions/math/QuaternionOperations.cpp index c6778de4a..c09426daa 100644 --- a/globalfunctions/math/QuaternionOperations.cpp +++ b/globalfunctions/math/QuaternionOperations.cpp @@ -1,5 +1,5 @@ #include "QuaternionOperations.h" -#include "../../globalfunctions/math/VectorOperations.h" +#include "VectorOperations.h" #include #include diff --git a/health/HasHealthIF.h b/health/HasHealthIF.h index ac4043008..86863ea8b 100644 --- a/health/HasHealthIF.h +++ b/health/HasHealthIF.h @@ -1,5 +1,5 @@ -#ifndef HASHEALTHIF_H_ -#define HASHEALTHIF_H_ +#ifndef FSFW_HEALTH_HASHEALTHIF_H_ +#define FSFW_HEALTH_HASHEALTHIF_H_ #include "../events/Event.h" #include "../returnvalues/HasReturnvaluesIF.h" @@ -8,9 +8,13 @@ class HasHealthIF { public: - typedef enum { - HEALTHY = 1, FAULTY = 0, EXTERNAL_CONTROL = 2, NEEDS_RECOVERY = 3, PERMANENT_FAULTY = 4 - } HealthState; + enum HealthState: uint8_t { + HEALTHY = 1, + FAULTY = 0, + EXTERNAL_CONTROL = 2, + NEEDS_RECOVERY = 3, + PERMANENT_FAULTY = 4 + }; static const uint8_t INTERFACE_ID = CLASS_ID::HAS_HEALTH_IF; static const ReturnValue_t OBJECT_NOT_HEALTHY = MAKE_RETURN_CODE(1); @@ -31,20 +35,17 @@ public: virtual MessageQueueId_t getCommandQueue() const = 0; /** - * set the Health State - * + * @brief Set the Health State * The parent will be informed, if the Health changes - * * @param health */ virtual ReturnValue_t setHealth(HealthState health) = 0; /** - * get Health State - * - * @return Health State of the object + * @brief Get Health State + * @return Health State of the object */ virtual HasHealthIF::HealthState getHealth() = 0; }; -#endif /* HASHEALTHIF_H_ */ +#endif /* FSFW_HEALTH_HASHEALTHIF_H_ */ diff --git a/health/HealthHelper.cpp b/health/HealthHelper.cpp index 61718f993..d574634d8 100644 --- a/health/HealthHelper.cpp +++ b/health/HealthHelper.cpp @@ -1,4 +1,4 @@ -#include "../health/HealthHelper.h" +#include "HealthHelper.h" #include "../serviceinterface/ServiceInterfaceStream.h" HealthHelper::HealthHelper(HasHealthIF* owner, object_id_t objectId) : @@ -71,7 +71,7 @@ void HealthHelper::setHealth(HasHealthIF::HealthState health) { void HealthHelper::informParent(HasHealthIF::HealthState health, HasHealthIF::HealthState oldHealth) { - if (parentQueue == MessageQueueMessageIF::NO_QUEUE) { + if (parentQueue == MessageQueueIF::NO_QUEUE) { return; } CommandMessage information; @@ -86,7 +86,7 @@ void HealthHelper::informParent(HasHealthIF::HealthState health, void HealthHelper::handleSetHealthCommand(CommandMessage* command) { ReturnValue_t result = owner->setHealth(HealthMessage::getHealth(command)); - if (command->getSender() == MessageQueueMessageIF::NO_QUEUE) { + if (command->getSender() == MessageQueueIF::NO_QUEUE) { return; } CommandMessage reply; diff --git a/health/HealthHelper.h b/health/HealthHelper.h index d8b81ca96..08889fba5 100644 --- a/health/HealthHelper.h +++ b/health/HealthHelper.h @@ -1,23 +1,26 @@ -#ifndef FRAMEWORK_HEALTH_HEALTHHELPER_H_ -#define FRAMEWORK_HEALTH_HEALTHHELPER_H_ +#ifndef FSFW_HEALTH_HEALTHHELPER_H_ +#define FSFW_HEALTH_HEALTHHELPER_H_ + +#include "HasHealthIF.h" +#include "HealthMessage.h" +#include "HealthTableIF.h" #include "../events/EventManagerIF.h" #include "../events/EventReportingProxyIF.h" -#include "../health/HasHealthIF.h" -#include "../health/HealthMessage.h" -#include "../health/HealthTableIF.h" #include "../ipc/MessageQueueIF.h" #include "../objectmanager/ObjectManagerIF.h" #include "../returnvalues/HasReturnvaluesIF.h" /** - * Helper class for Objects that implement HasHealthIF + * @brief Helper class for Objects that implement HasHealthIF + * @details + * It takes care of registering with the Health Table as well as handling + * health commands (including replying to the sender) and updating + * the Health Table. * - * It takes care of registering with the Health Table as well as handling health commands - * (including replying to the sender) and updating the Health Table. - * - * If a parent is set in the ctor, the parent will be informed with a @c HEALTH_INFO message - * about changes in the health state. Note that a @c HEALTH_INFO is only generated if the Health + * If a parent is set in the ctor, the parent will be informed with a + * @c HEALTH_INFO message about changes in the health state. + * Note that a @c HEALTH_INFO is only generated if the Health * changes, not for all @c HEALTH_SET commands received. * * It does NOT handle @c HEALTH_INFO messages @@ -26,10 +29,9 @@ class HealthHelper { public: /** - * ctor - * * @param owner - * @param objectId the object Id to use when communication with the HealthTable + * @param objectId The object Id to use when communication with + * the HealthTable */ HealthHelper(HasHealthIF* owner, object_id_t objectId); @@ -55,8 +57,9 @@ public: * * @param message * @return - * -@c RETURN_OK if the message was handled - * -@c RETURN_FAILED if the message could not be handled (ie it was not a @c HEALTH_SET or @c HEALTH_READ message) + * -@c RETURN_OK if the message was handled + * -@c RETURN_FAILED if the message could not be handled + * (ie it was not a @c HEALTH_SET or @c HEALTH_READ message) */ ReturnValue_t handleHealthCommand(CommandMessage *message); @@ -77,16 +80,19 @@ public: HasHealthIF::HealthState getHealth(); /** - * @param parentQueue the Queue id of the parent object. Set to 0 if no parent present + * @param parentQueue The queue ID of the parent object. + * Set to 0 if no parent present */ void setParentQueue(MessageQueueId_t parentQueue); /** * - * @param parentQueue the Queue id of the parent object. Set to 0 if no parent present + * @param parentQueue The queue ID of the parent object. + * Set to 0 if no parent present * @return - * -@c RETURN_OK if the Health Table was found and the object could be registered - * -@c RETURN_FAILED else + * -@c RETURN_OK if the Health Table was found and the object + * could be registered + * -@c RETURN_FAILED else */ ReturnValue_t initialize(MessageQueueId_t parentQueue ); @@ -109,13 +115,17 @@ private: HasHealthIF* owner; /** - * if the #parentQueue is not NULL, a @c HEALTH_INFO message will be sent to this queue - * @param health the health is passed as parameter so that the number of calls to the health table can be minimized + * if the #parentQueue is not NULL, a @c HEALTH_INFO message + * will be sent to this queue + * @param health + * The health is passed as parameter so that the number of + * calls to the health table can be minimized * @param oldHealth information of the previous health state. */ - void informParent(HasHealthIF::HealthState health, HasHealthIF::HealthState oldHealth); + void informParent(HasHealthIF::HealthState health, + HasHealthIF::HealthState oldHealth); void handleSetHealthCommand(CommandMessage *message); }; -#endif /* HEALTHHELPER_H_ */ +#endif /* FSFW_HEALTH_HEALTHHELPER_H_ */ diff --git a/health/HealthMessage.cpp b/health/HealthMessage.cpp index 39c53fb1c..52479c263 100644 --- a/health/HealthMessage.cpp +++ b/health/HealthMessage.cpp @@ -1,4 +1,4 @@ -#include "../health/HealthMessage.h" +#include "HealthMessage.h" void HealthMessage::setHealthMessage(CommandMessage* message, Command_t command, HasHealthIF::HealthState health, HasHealthIF::HealthState oldHealth) { @@ -7,11 +7,13 @@ void HealthMessage::setHealthMessage(CommandMessage* message, Command_t command, message->setParameter2(oldHealth); } -void HealthMessage::setHealthMessage(CommandMessage* message, Command_t command) { +void HealthMessage::setHealthMessage(CommandMessage* message, + Command_t command) { message->setCommand(command); } -HasHealthIF::HealthState HealthMessage::getHealth(const CommandMessage* message) { +HasHealthIF::HealthState HealthMessage::getHealth( + const CommandMessage* message) { return (HasHealthIF::HealthState) message->getParameter(); } diff --git a/health/HealthMessage.h b/health/HealthMessage.h index fa773d421..fb979c663 100644 --- a/health/HealthMessage.h +++ b/health/HealthMessage.h @@ -1,20 +1,26 @@ -#ifndef HEALTHMESSAGE_H_ -#define HEALTHMESSAGE_H_ +#ifndef FSFW_HEALTH_HEALTHMESSAGE_H_ +#define FSFW_HEALTH_HEALTHMESSAGE_H_ -#include "../health/HasHealthIF.h" +#include "HasHealthIF.h" #include "../ipc/CommandMessage.h" class HealthMessage { public: static const uint8_t MESSAGE_ID = messagetypes::HEALTH_COMMAND; - static const Command_t HEALTH_SET = MAKE_COMMAND_ID(1);//REPLY_COMMAND_OK/REPLY_REJECTED - static const Command_t HEALTH_ANNOUNCE = MAKE_COMMAND_ID(3); //NO REPLY! + + static const Command_t HEALTH_SET = MAKE_COMMAND_ID(1); + // No reply expected, health will be announced as event! + static const Command_t HEALTH_ANNOUNCE = MAKE_COMMAND_ID(2); + // Same as before, but all objects in health table will + // announce their health as events. + static const Command_t HEALTH_ANNOUNCE_ALL = MAKE_COMMAND_ID(3); + static const Command_t HEALTH_INFO = MAKE_COMMAND_ID(5); static const Command_t REPLY_HEALTH_SET = MAKE_COMMAND_ID(6); static void setHealthMessage(CommandMessage *message, Command_t command, - HasHealthIF::HealthState health, HasHealthIF::HealthState oldHealth = HasHealthIF::FAULTY); - + HasHealthIF::HealthState health, + HasHealthIF::HealthState oldHealth = HasHealthIF::FAULTY); static void setHealthMessage(CommandMessage *message, Command_t command); static HasHealthIF::HealthState getHealth(const CommandMessage *message); @@ -27,4 +33,4 @@ private: HealthMessage(); }; -#endif /* HEALTHMESSAGE_H_ */ +#endif /* FSFW_HEALTH_HEALTHMESSAGE_H_ */ diff --git a/health/HealthTable.cpp b/health/HealthTable.cpp index 1aa5a3ae6..6d6fe0172 100644 --- a/health/HealthTable.cpp +++ b/health/HealthTable.cpp @@ -1,6 +1,7 @@ -#include "../health/HealthTable.h" -#include "../serialize/SerializeAdapter.h" +#include "HealthTable.h" +#include "../ipc/MutexHelper.h" #include "../ipc/MutexFactory.h" +#include "../serialize/SerializeAdapter.h" HealthTable::HealthTable(object_id_t objectid) : SystemObject(objectid) { @@ -18,74 +19,64 @@ ReturnValue_t HealthTable::registerObject(object_id_t object, if (healthMap.count(object) != 0) { return HasReturnvaluesIF::RETURN_FAILED; } - healthMap.insert( - std::pair(object, - initilialState)); + healthMap.emplace(object, initilialState); return HasReturnvaluesIF::RETURN_OK; } void HealthTable::setHealth(object_id_t object, HasHealthIF::HealthState newState) { - mutex->lockMutex(MutexIF::BLOCKING); + MutexHelper(mutex, MutexIF::TimeoutType::WAITING, 20); HealthMap::iterator iter = healthMap.find(object); if (iter != healthMap.end()) { iter->second = newState; } - mutex->unlockMutex(); } HasHealthIF::HealthState HealthTable::getHealth(object_id_t object) { HasHealthIF::HealthState state = HasHealthIF::HEALTHY; - mutex->lockMutex(MutexIF::BLOCKING); + MutexHelper(mutex, MutexIF::TimeoutType::WAITING, 20); HealthMap::iterator iter = healthMap.find(object); if (iter != healthMap.end()) { state = iter->second; } - mutex->unlockMutex(); return state; } -uint32_t HealthTable::getPrintSize() { - mutex->lockMutex(MutexIF::BLOCKING); - uint32_t size = healthMap.size() * 5 + 2; - mutex->unlockMutex(); - return size; -} bool HealthTable::hasHealth(object_id_t object) { - bool exits = false; - mutex->lockMutex(MutexIF::BLOCKING); + MutexHelper(mutex, MutexIF::TimeoutType::WAITING, 20); HealthMap::iterator iter = healthMap.find(object); if (iter != healthMap.end()) { - exits = true; + return true; } - mutex->unlockMutex(); - return exits; + return false; +} + +size_t HealthTable::getPrintSize() { + MutexHelper(mutex, MutexIF::TimeoutType::WAITING, 20); + uint32_t size = healthMap.size() * sizeof(object_id_t) + + sizeof(HasHealthIF::HealthState) + sizeof(uint16_t); + return size; } void HealthTable::printAll(uint8_t* pointer, size_t maxSize) { - mutex->lockMutex(MutexIF::BLOCKING); + MutexHelper(mutex, MutexIF::TimeoutType::WAITING, 20); size_t size = 0; uint16_t count = healthMap.size(); - ReturnValue_t result = SerializeAdapter::serialize(&count, + SerializeAdapter::serialize(&count, &pointer, &size, maxSize, SerializeIF::Endianness::BIG); - HealthMap::iterator iter; - for (iter = healthMap.begin(); - iter != healthMap.end() && result == HasReturnvaluesIF::RETURN_OK; - ++iter) { - result = SerializeAdapter::serialize(&iter->first, + for (const auto& health: healthMap) { + SerializeAdapter::serialize(&health.first, &pointer, &size, maxSize, SerializeIF::Endianness::BIG); - uint8_t health = iter->second; - result = SerializeAdapter::serialize(&health, &pointer, &size, + uint8_t healthValue = health.second; + SerializeAdapter::serialize(&healthValue, &pointer, &size, maxSize, SerializeIF::Endianness::BIG); } - mutex->unlockMutex(); } -ReturnValue_t HealthTable::iterate( - std::pair *value, bool reset) { +ReturnValue_t HealthTable::iterate(HealthEntry *value, bool reset) { ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; - mutex->lockMutex(MutexIF::BLOCKING); + MutexHelper(mutex, MutexIF::TimeoutType::WAITING, 20); if (reset) { mapIterator = healthMap.begin(); } @@ -94,7 +85,5 @@ ReturnValue_t HealthTable::iterate( } *value = *mapIterator; mapIterator++; - mutex->unlockMutex(); - return result; } diff --git a/health/HealthTable.h b/health/HealthTable.h index 0f54a2641..945fb2e67 100644 --- a/health/HealthTable.h +++ b/health/HealthTable.h @@ -1,35 +1,42 @@ -#ifndef FRAMEWORK_HEALTH_HEALTHTABLE_H_ -#define FRAMEWORK_HEALTH_HEALTHTABLE_H_ +#ifndef FSFW_HEALTH_HEALTHTABLE_H_ +#define FSFW_HEALTH_HEALTHTABLE_H_ -#include "../health/HealthTableIF.h" +#include "HealthTableIF.h" #include "../objectmanager/SystemObject.h" #include "../ipc/MutexIF.h" #include -typedef std::map HealthMap; class HealthTable: public HealthTableIF, public SystemObject { public: HealthTable(object_id_t objectid); virtual ~HealthTable(); - virtual ReturnValue_t registerObject(object_id_t object, - HasHealthIF::HealthState initilialState = HasHealthIF::HEALTHY); + /** HealthTableIF overrides */ + virtual ReturnValue_t registerObject(object_id_t object, + HasHealthIF::HealthState initilialState = + HasHealthIF::HEALTHY) override; + virtual size_t getPrintSize() override; + virtual void printAll(uint8_t *pointer, size_t maxSize) override; - virtual bool hasHealth(object_id_t object); - virtual void setHealth(object_id_t object, HasHealthIF::HealthState newState); - virtual HasHealthIF::HealthState getHealth(object_id_t); - - virtual uint32_t getPrintSize(); - virtual void printAll(uint8_t *pointer, size_t maxSize); + /** ManagesHealthIF overrides */ + virtual bool hasHealth(object_id_t object) override; + virtual void setHealth(object_id_t object, + HasHealthIF::HealthState newState) override; + virtual HasHealthIF::HealthState getHealth(object_id_t) override; protected: + using HealthMap = std::map; + using HealthEntry = std::pair; + MutexIF* mutex; HealthMap healthMap; HealthMap::iterator mapIterator; - virtual ReturnValue_t iterate(std::pair *value, bool reset = false); + virtual ReturnValue_t iterate( + HealthEntry* value, + bool reset = false) override; }; -#endif /* HEALTHTABLE_H_ */ +#endif /* FSFW_HEALTH_HEALTHTABLE_H_ */ diff --git a/health/HealthTableIF.h b/health/HealthTableIF.h index f18f03155..d61e67616 100644 --- a/health/HealthTableIF.h +++ b/health/HealthTableIF.h @@ -1,28 +1,24 @@ -#ifndef FRAMEWORK_HEALTH_HEALTHTABLEIF_H_ -#define FRAMEWORK_HEALTH_HEALTHTABLEIF_H_ +#ifndef FSFW_HEALTH_HEALTHTABLEIF_H_ +#define FSFW_HEALTH_HEALTHTABLEIF_H_ -#include "../health/ManagesHealthIF.h" +#include "ManagesHealthIF.h" #include "../objectmanager/ObjectManagerIF.h" #include "../returnvalues/HasReturnvaluesIF.h" -#include - class HealthTableIF: public ManagesHealthIF { - // TODO: This is in the mission folder and not in the framework folder. - // delete it? - friend class HealthCommandingService; public: - virtual ~HealthTableIF() { - } + virtual ~HealthTableIF() {} virtual ReturnValue_t registerObject(object_id_t object, HasHealthIF::HealthState initilialState = HasHealthIF::HEALTHY) = 0; - virtual uint32_t getPrintSize() = 0; + virtual size_t getPrintSize() = 0; virtual void printAll(uint8_t *pointer, size_t maxSize) = 0; protected: - virtual ReturnValue_t iterate(std::pair *value, bool reset = false) = 0; + virtual ReturnValue_t iterate( + std::pair *value, + bool reset = false) = 0; }; #endif /* FRAMEWORK_HEALTH_HEALTHTABLEIF_H_ */ diff --git a/health/ManagesHealthIF.h b/health/ManagesHealthIF.h index 8ca170125..2edfcecad 100644 --- a/health/ManagesHealthIF.h +++ b/health/ManagesHealthIF.h @@ -1,8 +1,9 @@ -#ifndef FRAMEWORK_HEALTH_MANAGESHEALTHIF_H_ -#define FRAMEWORK_HEALTH_MANAGESHEALTHIF_H_ +#ifndef FSFW_HEALTH_MANAGESHEALTHIF_H_ +#define FSFW_HEALTH_MANAGESHEALTHIF_H_ -#include "../health/HasHealthIF.h" +#include "HasHealthIF.h" #include "../objectmanager/ObjectManagerIF.h" + class ManagesHealthIF { public: virtual ~ManagesHealthIF() { @@ -49,4 +50,4 @@ public: } }; -#endif /* FRAMEWORK_HEALTH_MANAGESHEALTHIF_H_ */ +#endif /* FSFW_HEALTH_MANAGESHEALTHIF_H_ */ diff --git a/housekeeping/HousekeepingMessage.cpp b/housekeeping/HousekeepingMessage.cpp index e354f8ffa..d2ab546b0 100644 --- a/housekeeping/HousekeepingMessage.cpp +++ b/housekeeping/HousekeepingMessage.cpp @@ -1,9 +1,10 @@ +#include #include "HousekeepingMessage.h" #include HousekeepingMessage::~HousekeepingMessage() {} -void HousekeepingMessage::setHkReportMessage(CommandMessage* message, sid_t sid, +void HousekeepingMessage::setHkReportReply(CommandMessage* message, sid_t sid, store_address_t storeId) { message->setCommand(HK_REPORT); message->setMessageSize(HK_MESSAGE_SIZE); @@ -11,7 +12,7 @@ void HousekeepingMessage::setHkReportMessage(CommandMessage* message, sid_t sid, message->setParameter3(storeId.raw); } -void HousekeepingMessage::setHkDiagnosticsMessage(CommandMessage* message, +void HousekeepingMessage::setHkDiagnosticsReply(CommandMessage* message, sid_t sid, store_address_t storeId) { message->setCommand(DIAGNOSTICS_REPORT); message->setMessageSize(HK_MESSAGE_SIZE); @@ -19,7 +20,7 @@ void HousekeepingMessage::setHkDiagnosticsMessage(CommandMessage* message, message->setParameter3(storeId.raw); } -sid_t HousekeepingMessage::getHkReportMessage(const CommandMessage *message, +sid_t HousekeepingMessage::getHkDataReply(const CommandMessage *message, store_address_t *storeIdToSet) { if(storeIdToSet != nullptr) { *storeIdToSet = message->getParameter3(); @@ -27,6 +28,96 @@ sid_t HousekeepingMessage::getHkReportMessage(const CommandMessage *message, return getSid(message); } +void HousekeepingMessage::setToggleReportingCommand(CommandMessage *message, + sid_t sid, bool enableReporting, bool isDiagnostics) { + if(isDiagnostics) { + if(enableReporting) { + message->setCommand(ENABLE_PERIODIC_DIAGNOSTICS_GENERATION); + } + else { + message->setCommand(DISABLE_PERIODIC_DIAGNOSTICS_GENERATION); + } + } + else { + if(enableReporting) { + message->setCommand(ENABLE_PERIODIC_HK_REPORT_GENERATION); + } + else { + message->setCommand(DISABLE_PERIODIC_HK_REPORT_GENERATION); + } + } + + setSid(message, sid); +} + +void HousekeepingMessage::setStructureReportingCommand(CommandMessage *command, + sid_t sid, bool isDiagnostics) { + if(isDiagnostics) { + command->setCommand(REPORT_DIAGNOSTICS_REPORT_STRUCTURES); + } + else { + command->setCommand(REPORT_HK_REPORT_STRUCTURES); + } + + setSid(command, sid); +} + +void HousekeepingMessage::setOneShotReportCommand(CommandMessage *command, + sid_t sid, bool isDiagnostics) { + if(isDiagnostics) { + command->setCommand(GENERATE_ONE_DIAGNOSTICS_REPORT); + } + else { + command->setCommand(GENERATE_ONE_PARAMETER_REPORT); + } + + setSid(command, sid); +} + +void HousekeepingMessage::setCollectionIntervalModificationCommand( + CommandMessage *command, sid_t sid, float collectionInterval, + bool isDiagnostics) { + if(isDiagnostics) { + command->setCommand(MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL); + } + else { + command->setCommand(MODIFY_PARAMETER_REPORT_COLLECTION_INTERVAL); + } + command->setParameter3(collectionInterval); + + setSid(command, sid); +} + +sid_t HousekeepingMessage::getCollectionIntervalModificationCommand( + const CommandMessage* command, float* newCollectionInterval) { + if(newCollectionInterval != nullptr) { + *newCollectionInterval = command->getParameter3(); + } + + return getSid(command); +} + +void HousekeepingMessage::setHkRequestSuccessReply(CommandMessage *reply, + sid_t sid) { + setSid(reply, sid); + reply->setCommand(HK_REQUEST_SUCCESS); +} + +void HousekeepingMessage::setHkRequestFailureReply(CommandMessage *reply, + sid_t sid, ReturnValue_t error) { + setSid(reply, sid); + reply->setCommand(HK_REQUEST_FAILURE); + reply->setParameter3(error); +} + +sid_t HousekeepingMessage::getHkRequestFailureReply(const CommandMessage *reply, + ReturnValue_t *error) { + if(error != nullptr) { + *error = reply->getParameter3(); + } + return getSid(reply); +} + sid_t HousekeepingMessage::getSid(const CommandMessage* message) { sid_t sid; std::memcpy(&sid.raw, message->getData(), sizeof(sid.raw)); @@ -37,3 +128,35 @@ void HousekeepingMessage::setSid(CommandMessage *message, sid_t sid) { std::memcpy(message->getData(), &sid.raw, sizeof(sid.raw)); } +void HousekeepingMessage::setHkStuctureReportReply(CommandMessage *reply, + sid_t sid, store_address_t storeId) { + reply->setCommand(HK_DEFINITIONS_REPORT); + setSid(reply, sid); + reply->setParameter3(storeId.raw); +} + +void HousekeepingMessage::setDiagnosticsStuctureReportReply( + CommandMessage *reply, sid_t sid, store_address_t storeId) { + reply->setCommand(DIAGNOSTICS_DEFINITION_REPORT); + setSid(reply, sid); + reply->setParameter3(storeId.raw); +} + +void HousekeepingMessage::clear(CommandMessage* message) { + switch(message->getCommand()) { + case(HK_REPORT): + case(DIAGNOSTICS_REPORT): + case(HK_DEFINITIONS_REPORT): + case(DIAGNOSTICS_DEFINITION_REPORT): + case(UPDATE_SNAPSHOT): { + store_address_t storeId; + getHkDataReply(message, &storeId); + StorageManagerIF *ipcStore = objectManager->get( + objects::IPC_STORE); + if (ipcStore != nullptr) { + ipcStore->deleteData(storeId); + } + } + } + message->setCommand(CommandMessage::CMD_NONE); +} diff --git a/housekeeping/HousekeepingMessage.h b/housekeeping/HousekeepingMessage.h index 75b315053..6dc95f542 100644 --- a/housekeeping/HousekeepingMessage.h +++ b/housekeeping/HousekeepingMessage.h @@ -1,16 +1,17 @@ -#ifndef FRAMEWORK_HK_HOUSEKEEPINGMESSAGE_H_ -#define FRAMEWORK_HK_HOUSEKEEPINGMESSAGE_H_ +#ifndef FSFW_HOUSEKEEPING_HOUSEKEEPINGMESSAGE_H_ +#define FSFW_HOUSEKEEPING_HOUSEKEEPINGMESSAGE_H_ #include "../ipc/CommandMessage.h" #include "../ipc/FwMessageTypes.h" +#include "../objectmanager/frameworkObjects.h" #include "../objectmanager/SystemObjectIF.h" #include "../storagemanager/StorageManagerIF.h" -#include union sid_t { - static constexpr uint64_t INVALID_ADDRESS = - std::numeric_limits::max(); - sid_t(): raw(INVALID_ADDRESS) {} + static constexpr uint64_t INVALID_SID = -1; + static constexpr uint32_t INVALID_SET_ID = -1; + static constexpr uint32_t INVALID_OBJECT_ID = objects::NO_OBJECT; + sid_t(): raw(INVALID_SID) {} sid_t(object_id_t objectId, uint32_t setId): objectId(objectId), @@ -31,7 +32,15 @@ union sid_t { uint64_t raw; bool notSet() const { - return raw == INVALID_ADDRESS; + return raw == INVALID_SID; + } + + bool operator==(const sid_t& other) const { + return raw == other.raw; + } + + bool operator!=(const sid_t& other) const { + return not (raw == other.raw); } }; @@ -49,25 +58,15 @@ public: sizeof(sid_t) + sizeof(uint32_t); /** - * The HK message is initialized with a pointer to a message which holds - * the message data, see CommandMessageIF and getInternalMessage(). - * @param message + * Concrete instance is not used, instead this class operates on + * command message instances. */ HousekeepingMessage() = delete; virtual ~HousekeepingMessage(); static constexpr uint8_t MESSAGE_ID = messagetypes::HOUSEKEEPING; - static constexpr Command_t ADD_HK_REPORT_STRUCT = - MAKE_COMMAND_ID(1); - static constexpr Command_t ADD_DIAGNOSTICS_REPORT_STRUCT = - MAKE_COMMAND_ID(2); - - static constexpr Command_t DELETE_HK_REPORT_STRUCT = MAKE_COMMAND_ID(3); - static constexpr Command_t DELETE_DIAGNOSTICS_REPORT_STRUCT = - MAKE_COMMAND_ID(4); - - static constexpr Command_t ENABLE_PERIODIC_HK_GENERATION = + static constexpr Command_t ENABLE_PERIODIC_HK_REPORT_GENERATION = MAKE_COMMAND_ID(5); static constexpr Command_t DISABLE_PERIODIC_HK_REPORT_GENERATION = MAKE_COMMAND_ID(6); @@ -92,31 +91,67 @@ public: static constexpr Command_t GENERATE_ONE_DIAGNOSTICS_REPORT = MAKE_COMMAND_ID(28); - static constexpr Command_t APPEND_PARAMETERS_TO_PARAMETER_REPORT_STRUCTURE = - MAKE_COMMAND_ID(29); - static constexpr Command_t APPEND_PARAMETERS_TO_DIAGNOSTICS_REPORT_STRUCTURE = - MAKE_COMMAND_ID(30); - static constexpr Command_t MODIFY_PARAMETER_REPORT_COLLECTION_INTERVAL = MAKE_COMMAND_ID(31); static constexpr Command_t MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL = MAKE_COMMAND_ID(32); + static constexpr Command_t HK_REQUEST_SUCCESS = + MAKE_COMMAND_ID(128); + static constexpr Command_t HK_REQUEST_FAILURE = + MAKE_COMMAND_ID(129); + + static constexpr Command_t UPDATE_NOTIFICATION = MAKE_COMMAND_ID(130); + static constexpr Command_t UPDATE_SNAPSHOT = MAKE_COMMAND_ID(131); + + static constexpr Command_t UPDATE_HK_REPORT = MAKE_COMMAND_ID(132); + static sid_t getSid(const CommandMessage* message); - static void setHkReportMessage(CommandMessage* message, sid_t sid, + /** Setter functions */ + static void setToggleReportingCommand(CommandMessage* command, sid_t sid, + bool enableReporting, bool isDiagnostics); + static void setStructureReportingCommand(CommandMessage* command, sid_t sid, + bool isDiagnostics); + static void setOneShotReportCommand(CommandMessage* command, sid_t sid, + bool isDiagnostics); + static void setCollectionIntervalModificationCommand( + CommandMessage* command, sid_t sid, float collectionInterval, + bool isDiagnostics); + + static void setHkReportReply(CommandMessage* reply, sid_t sid, store_address_t storeId); - static void setHkDiagnosticsMessage(CommandMessage* message, sid_t sid, + static void setHkDiagnosticsReply(CommandMessage* reply, sid_t sid, store_address_t storeId); - //! Get the respective SID and store ID. Command ID can be used beforehand - //! to distinguish between diagnostics and regular HK packets - static sid_t getHkReportMessage(const CommandMessage* message, + static void setHkRequestSuccessReply(CommandMessage* reply, sid_t sid); + static void setHkRequestFailureReply(CommandMessage* reply, sid_t sid, + ReturnValue_t error); + + static void setHkStuctureReportReply(CommandMessage* reply, + sid_t sid, store_address_t storeId); + static void setDiagnosticsStuctureReportReply(CommandMessage* reply, + sid_t sid, store_address_t storeId); + + static sid_t getHkRequestFailureReply(const CommandMessage* reply, + ReturnValue_t* error); + + /** + * @brief Generic getter function for housekeeping data replies + * @details + * Command ID can be used beforehand to distinguish between diagnostics and + * regular HK packets. This getter function should be used for the + * command IDs 10, 12, 25 and 26. + */ + static sid_t getHkDataReply(const CommandMessage* message, store_address_t * storeIdToSet); + static sid_t getCollectionIntervalModificationCommand( + const CommandMessage* command, float* newCollectionInterval); + static void clear(CommandMessage* message); private: static void setSid(CommandMessage* message, sid_t sid); }; -#endif /* FRAMEWORK_HK_HOUSEKEEPINGMESSAGE_H_ */ +#endif /* FSFW_HOUSEKEEPING_HOUSEKEEPINGMESSAGE_H_ */ diff --git a/housekeeping/HousekeepingPacketDownlink.h b/housekeeping/HousekeepingPacketDownlink.h index bee0bac10..ae0cc988d 100644 --- a/housekeeping/HousekeepingPacketDownlink.h +++ b/housekeeping/HousekeepingPacketDownlink.h @@ -1,8 +1,7 @@ -#ifndef FRAMEWORK_HOUSEKEEPING_HOUSEKEEPINGPACKETDOWNLINK_H_ -#define FRAMEWORK_HOUSEKEEPING_HOUSEKEEPINGPACKETDOWNLINK_H_ +#ifndef FSFW_HOUSEKEEPING_HOUSEKEEPINGPACKETDOWNLINK_H_ +#define FSFW_HOUSEKEEPING_HOUSEKEEPINGPACKETDOWNLINK_H_ #include "../datapoollocal/LocalPoolDataSetBase.h" -#include "../housekeeping/HousekeepingMessage.h" #include "../serialize/SerialLinkedListAdapter.h" #include "../storagemanager/StorageManagerIF.h" @@ -15,67 +14,21 @@ */ class HousekeepingPacketDownlink: public SerialLinkedListAdapter { public: - HousekeepingPacketDownlink(sid_t sid, float collectionInterval, uint8_t - numberOfParameters, LocalPoolDataSetBase* dataSetPtr): - sourceId(sid.objectId), setId(sid.ownerSetId), - collectionInterval(collectionInterval), - numberOfParameters(numberOfParameters), hkData(dataSetPtr) { + HousekeepingPacketDownlink(sid_t sid, LocalPoolDataSetBase* dataSetPtr): + sourceId(sid.objectId), setId(sid.ownerSetId), hkData(dataSetPtr) { setLinks(); } - /** - * Helper functions which can be used to move HK data from the IPC store - * to the telemetry store. TODO: maybe not needed. - * @param formerStore - * @param storeId - * @param newStore - * @param newStoreId [out] - * @return - */ - virtual ReturnValue_t moveToOtherStore(StorageManagerIF* formerStore, - store_address_t storeId, StorageManagerIF* newStore, - store_address_t* newStoreId) { - const uint8_t* dataPtr = nullptr; - size_t hkDataSize = 0; - ReturnValue_t result = formerStore->getData(storeId, &dataPtr, - &hkDataSize); - if(result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - - return newStore->addData(newStoreId, dataPtr, hkDataSize); - } - private: void setLinks() { setStart(&sourceId); sourceId.setNext(&setId); - setId.setNext(&collectionInterval); - collectionInterval.setNext(&numberOfParameters); - numberOfParameters.setNext(&hkData); + setId.setNext(&hkData); } SerializeElement sourceId; SerializeElement setId; - SerializeElement collectionInterval; - SerializeElement numberOfParameters; LinkedElement hkData; }; #endif /* FRAMEWORK_HOUSEKEEPING_HOUSEKEEPINGPACKETDOWNLINK_H_ */ - - - -// virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, -// size_t maxSize, Endianness streamEndianness) const override { -// ReturnValue_t result = SerialLinkedListAdapter::serialize(buffer, size, -// maxSize, streamEndianness); -// if(result != HasReturnvaluesIF::RETURN_OK) { -// return result; -// } -// return dataSetPtr->serialize(buffer, size, maxSize, streamEndianness); -// } -// -// virtual size_t getSerializedSize() const override { -// -// } diff --git a/housekeeping/HousekeepingPacketUpdate.h b/housekeeping/HousekeepingPacketUpdate.h index e7b644f58..eebdc11cc 100644 --- a/housekeeping/HousekeepingPacketUpdate.h +++ b/housekeeping/HousekeepingPacketUpdate.h @@ -1,9 +1,9 @@ #ifndef FRAMEWORK_HOUSEKEEPING_HOUSEKEEPINGPACKETUPDATE_H_ #define FRAMEWORK_HOUSEKEEPING_HOUSEKEEPINGPACKETUPDATE_H_ -#include -#include -#include +#include "../serialize/SerialBufferAdapter.h" +#include "../serialize/SerialLinkedListAdapter.h" +#include "../datapoollocal/LocalPoolDataSetBase.h" /** * @brief This helper class will be used to serialize and deserialize diff --git a/housekeeping/HousekeepingSetPacket.h b/housekeeping/HousekeepingSetPacket.h new file mode 100644 index 000000000..f94720d4c --- /dev/null +++ b/housekeeping/HousekeepingSetPacket.h @@ -0,0 +1,59 @@ +#ifndef FSFW_HOUSEKEEPING_HOUSEKEEPINGSETPACKET_H_ +#define FSFW_HOUSEKEEPING_HOUSEKEEPINGSETPACKET_H_ + +#include "../housekeeping/HousekeepingMessage.h" +#include "../serialize/SerialLinkedListAdapter.h" +#include "../datapoollocal/LocalPoolDataSetBase.h" + +class HousekeepingSetPacket: public SerialLinkedListAdapter { +public: + HousekeepingSetPacket(sid_t sid, bool reportingEnabled, bool valid, + float collectionInterval, LocalPoolDataSetBase* dataSetPtr): + objectId(sid.objectId), setId(sid.ownerSetId), + reportingEnabled(reportingEnabled), valid(valid), + collectionIntervalSeconds(collectionInterval), dataSet(dataSetPtr) { + setLinks(); + } + + ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const override { + ReturnValue_t result = SerialLinkedListAdapter::serialize(buffer, size, + maxSize, streamEndianness); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + return dataSet->serializeLocalPoolIds(buffer, size ,maxSize, + streamEndianness); + } + + size_t getSerializedSize() const override { + size_t linkedSize = SerialLinkedListAdapter::getSerializedSize(); + linkedSize += dataSet->getLocalPoolIdsSerializedSize(); + return linkedSize; + } + + ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) override { + return HasReturnvaluesIF::RETURN_OK; + } + +private: + + void setLinks() { + setStart(&objectId); + objectId.setNext(&setId); + setId.setNext(&reportingEnabled); + reportingEnabled.setNext(&valid); + valid.setNext(&collectionIntervalSeconds); + collectionIntervalSeconds.setEnd(); + } + + SerializeElement objectId; + SerializeElement setId; + SerializeElement reportingEnabled; + SerializeElement valid; + SerializeElement collectionIntervalSeconds; + LocalPoolDataSetBase* dataSet; +}; + +#endif /* FSFW_HOUSEKEEPING_HOUSEKEEPINGSETPACKET_H_ */ diff --git a/housekeeping/PeriodicHousekeepingHelper.cpp b/housekeeping/PeriodicHousekeepingHelper.cpp new file mode 100644 index 000000000..37349f815 --- /dev/null +++ b/housekeeping/PeriodicHousekeepingHelper.cpp @@ -0,0 +1,48 @@ +#include "../datapoollocal/LocalPoolDataSetBase.h" +#include "PeriodicHousekeepingHelper.h" +#include + +PeriodicHousekeepingHelper::PeriodicHousekeepingHelper( + LocalPoolDataSetBase* owner): owner(owner) {} + + +void PeriodicHousekeepingHelper::initialize(float collectionInterval, + dur_millis_t minimumPeriodicInterval, bool isDiagnostics, + uint8_t nonDiagIntervalFactor) { + this->minimumPeriodicInterval = minimumPeriodicInterval; + if(not isDiagnostics) { + this->minimumPeriodicInterval = this->minimumPeriodicInterval * + nonDiagIntervalFactor; + } + collectionIntervalTicks = intervalSecondsToInterval(collectionInterval); +} + +float PeriodicHousekeepingHelper::getCollectionIntervalInSeconds() { + return intervalToIntervalSeconds(collectionIntervalTicks); +} + +bool PeriodicHousekeepingHelper::checkOpNecessary() { + if(internalTickCounter >= collectionIntervalTicks) { + internalTickCounter = 1; + return true; + } + internalTickCounter++; + return false; +} + +uint32_t PeriodicHousekeepingHelper::intervalSecondsToInterval( + float collectionIntervalSeconds) { + return std::ceil(collectionIntervalSeconds * 1000 + / minimumPeriodicInterval); +} + +float PeriodicHousekeepingHelper::intervalToIntervalSeconds( + uint32_t collectionInterval) { + return static_cast(collectionInterval * + minimumPeriodicInterval); +} + +void PeriodicHousekeepingHelper::changeCollectionInterval( + float newIntervalSeconds) { + collectionIntervalTicks = intervalSecondsToInterval(newIntervalSeconds); +} diff --git a/housekeeping/PeriodicHousekeepingHelper.h b/housekeeping/PeriodicHousekeepingHelper.h new file mode 100644 index 000000000..d96eae1d4 --- /dev/null +++ b/housekeeping/PeriodicHousekeepingHelper.h @@ -0,0 +1,32 @@ +#ifndef FSFW_HOUSEKEEPING_PERIODICHOUSEKEEPINGHELPER_H_ +#define FSFW_HOUSEKEEPING_PERIODICHOUSEKEEPINGHELPER_H_ + +#include "../timemanager/Clock.h" +#include + +class LocalPoolDataSetBase; + +class PeriodicHousekeepingHelper { +public: + PeriodicHousekeepingHelper(LocalPoolDataSetBase* owner); + + void initialize(float collectionInterval, + dur_millis_t minimumPeriodicInterval, bool isDiagnostics, + uint8_t nonDiagIntervalFactor); + + void changeCollectionInterval(float newInterval); + float getCollectionIntervalInSeconds(); + bool checkOpNecessary(); +private: + LocalPoolDataSetBase* owner = nullptr; + + uint32_t intervalSecondsToInterval(float collectionIntervalSeconds); + float intervalToIntervalSeconds(uint32_t collectionInterval); + + dur_millis_t minimumPeriodicInterval = 0; + uint32_t internalTickCounter = 1; + uint32_t collectionIntervalTicks = 0; + +}; + +#endif /* FSFW_HOUSEKEEPING_PERIODICHOUSEKEEPINGHELPER_H_ */ diff --git a/internalError/InternalErrorDataset.h b/internalError/InternalErrorDataset.h new file mode 100644 index 000000000..52a4b6324 --- /dev/null +++ b/internalError/InternalErrorDataset.h @@ -0,0 +1,34 @@ +#ifndef FSFW_INTERNALERROR_INTERNALERRORDATASET_H_ +#define FSFW_INTERNALERROR_INTERNALERRORDATASET_H_ + +#include +#include + +enum errorPoolIds { + TM_HITS, + QUEUE_HITS, + STORE_HITS +}; + + +class InternalErrorDataset: public StaticLocalDataSet<3 * sizeof(uint32_t)> { +public: + static constexpr uint8_t ERROR_SET_ID = 0; + + InternalErrorDataset(HasLocalDataPoolIF* owner): + StaticLocalDataSet(owner, ERROR_SET_ID) {} + + InternalErrorDataset(object_id_t objectId): + StaticLocalDataSet(sid_t(objectId , ERROR_SET_ID)) {} + + lp_var_t tmHits = lp_var_t(TM_HITS, + hkManager->getOwner(), this); + lp_var_t queueHits = lp_var_t(QUEUE_HITS, + hkManager->getOwner(), this); + lp_var_t storeHits = lp_var_t(STORE_HITS, + hkManager->getOwner(), this); +}; + + + +#endif /* FSFW_INTERNALERROR_INTERNALERRORDATASET_H_ */ diff --git a/internalError/InternalErrorReporter.cpp b/internalError/InternalErrorReporter.cpp index 3424266bd..22e2c38ce 100644 --- a/internalError/InternalErrorReporter.cpp +++ b/internalError/InternalErrorReporter.cpp @@ -1,16 +1,19 @@ -#include "../datapoolglob/GlobalDataSet.h" #include "InternalErrorReporter.h" +#include "../ipc/QueueFactory.h" +#include "../datapoolglob/GlobalDataSet.h" #include "../datapoolglob/GlobalPoolVariable.h" #include "../ipc/MutexFactory.h" - #include "../serviceinterface/ServiceInterfaceStream.h" InternalErrorReporter::InternalErrorReporter(object_id_t setObjectId, - uint32_t queuePoolId, uint32_t tmPoolId, uint32_t storePoolId) : - SystemObject(setObjectId), mutex(NULL), queuePoolId(queuePoolId), - tmPoolId(tmPoolId),storePoolId(storePoolId), queueHits(0), tmHits(0), - storeHits(0) { + uint32_t messageQueueDepth) : + SystemObject(setObjectId), + commandQueue(QueueFactory::instance()-> + createMessageQueue(messageQueueDepth)), + poolManager(this, commandQueue), + internalErrorSid(setObjectId, InternalErrorDataset::ERROR_SET_ID), + internalErrorDataset(this) { mutex = MutexFactory::instance()->createMutex(); } @@ -18,28 +21,42 @@ InternalErrorReporter::~InternalErrorReporter() { MutexFactory::instance()->deleteMutex(mutex); } +void InternalErrorReporter::setDiagnosticPrintout(bool enable) { + this->diagnosticPrintout = enable; +} + ReturnValue_t InternalErrorReporter::performOperation(uint8_t opCode) { - - GlobDataSet mySet; - gp_uint32_t queueHitsInPool(queuePoolId, &mySet, - PoolVariableIF::VAR_READ_WRITE); - gp_uint32_t tmHitsInPool(tmPoolId, &mySet, - PoolVariableIF::VAR_READ_WRITE); - - gp_uint32_t storeHitsInPool(storePoolId, &mySet, - PoolVariableIF::VAR_READ_WRITE); - mySet.read(); + internalErrorDataset.read(INTERNAL_ERROR_MUTEX_TIMEOUT); uint32_t newQueueHits = getAndResetQueueHits(); uint32_t newTmHits = getAndResetTmHits(); uint32_t newStoreHits = getAndResetStoreHits(); - queueHitsInPool.value += newQueueHits; - tmHitsInPool.value += newTmHits; - storeHitsInPool.value += newStoreHits; +#ifdef DEBUG + if(diagnosticPrintout) { + if((newQueueHits > 0) or (newTmHits > 0) or (newStoreHits > 0)) { + sif::debug << "InternalErrorReporter::performOperation: Errors " + << "occured!" << std::endl; + sif::debug << "Queue errors: " << newQueueHits << std::endl; + sif::debug << "TM errors: " << newTmHits << std::endl; + sif::debug << "Store errors: " << newStoreHits << std::endl; + } + } +#endif - mySet.commit(PoolVariableIF::VALID); + internalErrorDataset.queueHits.value += newQueueHits; + internalErrorDataset.storeHits.value += newStoreHits; + internalErrorDataset.tmHits.value += newTmHits; + internalErrorDataset.commit(INTERNAL_ERROR_MUTEX_TIMEOUT); + + poolManager.performHkOperation(); + + CommandMessage message; + ReturnValue_t result = commandQueue->receiveMessage(&message); + if(result != MessageQueueIF::EMPTY) { + poolManager.handleHousekeepingMessage(&message); + } return HasReturnvaluesIF::RETURN_OK; } @@ -53,7 +70,7 @@ void InternalErrorReporter::lostTm() { uint32_t InternalErrorReporter::getAndResetQueueHits() { uint32_t value; - mutex->lockMutex(MutexIF::BLOCKING); + mutex->lockMutex(MutexIF::WAITING, INTERNAL_ERROR_MUTEX_TIMEOUT); value = queueHits; queueHits = 0; mutex->unlockMutex(); @@ -62,21 +79,21 @@ uint32_t InternalErrorReporter::getAndResetQueueHits() { uint32_t InternalErrorReporter::getQueueHits() { uint32_t value; - mutex->lockMutex(MutexIF::BLOCKING); + mutex->lockMutex(MutexIF::WAITING, INTERNAL_ERROR_MUTEX_TIMEOUT); value = queueHits; mutex->unlockMutex(); return value; } void InternalErrorReporter::incrementQueueHits() { - mutex->lockMutex(MutexIF::BLOCKING); + mutex->lockMutex(MutexIF::WAITING, INTERNAL_ERROR_MUTEX_TIMEOUT); queueHits++; mutex->unlockMutex(); } uint32_t InternalErrorReporter::getAndResetTmHits() { uint32_t value; - mutex->lockMutex(MutexIF::BLOCKING); + mutex->lockMutex(MutexIF::WAITING, INTERNAL_ERROR_MUTEX_TIMEOUT); value = tmHits; tmHits = 0; mutex->unlockMutex(); @@ -85,14 +102,14 @@ uint32_t InternalErrorReporter::getAndResetTmHits() { uint32_t InternalErrorReporter::getTmHits() { uint32_t value; - mutex->lockMutex(MutexIF::BLOCKING); + mutex->lockMutex(MutexIF::WAITING, INTERNAL_ERROR_MUTEX_TIMEOUT); value = tmHits; mutex->unlockMutex(); return value; } void InternalErrorReporter::incrementTmHits() { - mutex->lockMutex(MutexIF::BLOCKING); + mutex->lockMutex(MutexIF::WAITING, INTERNAL_ERROR_MUTEX_TIMEOUT); tmHits++; mutex->unlockMutex(); } @@ -103,7 +120,7 @@ void InternalErrorReporter::storeFull() { uint32_t InternalErrorReporter::getAndResetStoreHits() { uint32_t value; - mutex->lockMutex(MutexIF::BLOCKING); + mutex->lockMutex(MutexIF::WAITING, INTERNAL_ERROR_MUTEX_TIMEOUT); value = storeHits; storeHits = 0; mutex->unlockMutex(); @@ -112,14 +129,65 @@ uint32_t InternalErrorReporter::getAndResetStoreHits() { uint32_t InternalErrorReporter::getStoreHits() { uint32_t value; - mutex->lockMutex(MutexIF::BLOCKING); + mutex->lockMutex(MutexIF::WAITING, INTERNAL_ERROR_MUTEX_TIMEOUT); value = storeHits; mutex->unlockMutex(); return value; } void InternalErrorReporter::incrementStoreHits() { - mutex->lockMutex(MutexIF::BLOCKING); + mutex->lockMutex(MutexIF::WAITING, INTERNAL_ERROR_MUTEX_TIMEOUT); storeHits++; mutex->unlockMutex(); } + +object_id_t InternalErrorReporter::getObjectId() const { + return SystemObject::getObjectId(); +} + +MessageQueueId_t InternalErrorReporter::getCommandQueue() const { + return this->commandQueue->getId(); +} + +ReturnValue_t InternalErrorReporter::initializeLocalDataPool( + LocalDataPool &localDataPoolMap, LocalDataPoolManager &poolManager) { + localDataPoolMap.emplace(errorPoolIds::TM_HITS, + new PoolEntry()); + localDataPoolMap.emplace(errorPoolIds::QUEUE_HITS, + new PoolEntry()); + localDataPoolMap.emplace(errorPoolIds::STORE_HITS, + new PoolEntry()); + poolManager.subscribeForPeriodicPacket(internalErrorSid, false, + getPeriodicOperationFrequency(), true); + internalErrorDataset.setValidity(true, true); + return HasReturnvaluesIF::RETURN_OK; +} + +LocalDataPoolManager* InternalErrorReporter::getHkManagerHandle() { + return &poolManager; +} + +dur_millis_t InternalErrorReporter::getPeriodicOperationFrequency() const { + return this->executingTask->getPeriodMs(); +} + +LocalPoolDataSetBase* InternalErrorReporter::getDataSetHandle(sid_t sid) { + return &internalErrorDataset; +} + +void InternalErrorReporter::setTaskIF(PeriodicTaskIF *task) { + this->executingTask = task; +} + +ReturnValue_t InternalErrorReporter::initialize() { + ReturnValue_t result = poolManager.initialize(commandQueue); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + return SystemObject::initialize(); +} + +ReturnValue_t InternalErrorReporter::initializeAfterTaskCreation() { + return poolManager.initializeAfterTaskCreation(); +} + diff --git a/internalError/InternalErrorReporter.h b/internalError/InternalErrorReporter.h index 9aa24a0fa..8d33c06e2 100644 --- a/internalError/InternalErrorReporter.h +++ b/internalError/InternalErrorReporter.h @@ -1,37 +1,75 @@ -#ifndef INTERNALERRORREPORTER_H_ -#define INTERNALERRORREPORTER_H_ +#ifndef FSFW_INTERNALERROR_INTERNALERRORREPORTER_H_ +#define FSFW_INTERNALERROR_INTERNALERRORREPORTER_H_ #include "InternalErrorReporterIF.h" +#include "../tasks/PeriodicTaskIF.h" +#include "../internalError/InternalErrorDataset.h" +#include "../datapoollocal/LocalDataPoolManager.h" #include "../tasks/ExecutableObjectIF.h" #include "../objectmanager/SystemObject.h" #include "../ipc/MutexIF.h" +/** + * @brief This class is used to track internal errors like lost telemetry, + * failed message sending or a full store. + * @details + * All functions were kept virtual so this class can be extended easily + * to store custom internal errors (e.g. communication interface errors). + */ class InternalErrorReporter: public SystemObject, public ExecutableObjectIF, - public InternalErrorReporterIF { + public InternalErrorReporterIF, + public HasLocalDataPoolIF { public: - InternalErrorReporter(object_id_t setObjectId, uint32_t queuePoolId, - uint32_t tmPoolId, uint32_t storePoolId); + static constexpr uint8_t INTERNAL_ERROR_MUTEX_TIMEOUT = 20; + + InternalErrorReporter(object_id_t setObjectId, + uint32_t messageQueueDepth = 5); + + /** + * Enable diagnostic printout. Please note that this feature will + * only work if DEBUG has been supplied to the build defines. + * @param enable + */ + void setDiagnosticPrintout(bool enable); + virtual ~InternalErrorReporter(); - virtual ReturnValue_t performOperation(uint8_t opCode); + virtual object_id_t getObjectId() const override; + virtual MessageQueueId_t getCommandQueue() const override; + virtual ReturnValue_t initializeLocalDataPool( + LocalDataPool& localDataPoolMap, + LocalDataPoolManager& poolManager) override; + virtual LocalDataPoolManager* getHkManagerHandle() override; + virtual dur_millis_t getPeriodicOperationFrequency() const override; + virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override; + + virtual ReturnValue_t initialize() override; + virtual ReturnValue_t initializeAfterTaskCreation() override; + virtual ReturnValue_t performOperation(uint8_t opCode) override; virtual void queueMessageNotSent(); virtual void lostTm(); virtual void storeFull(); + + virtual void setTaskIF(PeriodicTaskIF* task) override; protected: - MutexIF* mutex; + MessageQueueIF* commandQueue; + LocalDataPoolManager poolManager; - uint32_t queuePoolId; - uint32_t tmPoolId; - uint32_t storePoolId; + PeriodicTaskIF* executingTask = nullptr; + MutexIF* mutex = nullptr; + sid_t internalErrorSid; + InternalErrorDataset internalErrorDataset; - uint32_t queueHits; - uint32_t tmHits; - uint32_t storeHits; + bool diagnosticPrintout = true; + + uint32_t queueHits = 0; + uint32_t tmHits = 0; + uint32_t storeHits = 0; uint32_t getAndResetQueueHits(); uint32_t getQueueHits(); @@ -47,4 +85,4 @@ protected: }; -#endif /* INTERNALERRORREPORTER_H_ */ +#endif /* FSFW_INTERNALERROR_INTERNALERRORREPORTER_H_ */ diff --git a/ipc/CommandMessage.h b/ipc/CommandMessage.h index ca7b817f1..8f5daa044 100644 --- a/ipc/CommandMessage.h +++ b/ipc/CommandMessage.h @@ -8,7 +8,7 @@ /** * @brief Default command message used to pass command messages between tasks. * Primary message type for IPC. Contains sender, 2-byte command ID - * field, and 2 4-byte parameters. + * field, and 3 4-byte parameter * @details * It operates on an external memory which is contained inside a * class implementing MessageQueueMessageIF by taking its address. @@ -23,10 +23,11 @@ class CommandMessage: public MessageQueueMessage, public CommandMessageIF { public: /** - * Default size can accomodate 2 4-byte parameters. + * Default size can accomodate 3 4-byte parameters. */ static constexpr size_t DEFAULT_COMMAND_MESSAGE_SIZE = - CommandMessageIF::MINIMUM_COMMAND_MESSAGE_SIZE + sizeof(uint32_t); + CommandMessageIF::MINIMUM_COMMAND_MESSAGE_SIZE + + 3 * sizeof(uint32_t); /** * @brief Default Constructor, does not initialize anything. diff --git a/ipc/CommandMessageCleaner.cpp b/ipc/CommandMessageCleaner.cpp index 6a99b4d2d..fa03a9a38 100644 --- a/ipc/CommandMessageCleaner.cpp +++ b/ipc/CommandMessageCleaner.cpp @@ -1,4 +1,4 @@ -#include "../ipc/CommandMessageCleaner.h" +#include "CommandMessageCleaner.h" #include "../devicehandlers/DeviceHandlerMessage.h" #include "../health/HealthMessage.h" @@ -7,6 +7,7 @@ #include "../monitoring/MonitoringMessage.h" #include "../subsystem/modes/ModeSequenceMessage.h" #include "../tmstorage/TmStoreMessage.h" +#include "../housekeeping/HousekeepingMessage.h" #include "../parameters/ParameterMessage.h" void CommandMessageCleaner::clearCommandMessage(CommandMessage* message) { @@ -38,6 +39,9 @@ void CommandMessageCleaner::clearCommandMessage(CommandMessage* message) { case messagetypes::PARAMETER: ParameterMessage::clear(message); break; + case messagetypes::HOUSEKEEPING: + HousekeepingMessage::clear(message); + break; default: messagetypes::clearMissionMessage(message); break; diff --git a/ipc/MessageQueueIF.h b/ipc/MessageQueueIF.h index 96bd379f9..44b6f4c00 100644 --- a/ipc/MessageQueueIF.h +++ b/ipc/MessageQueueIF.h @@ -1,21 +1,23 @@ #ifndef FSFW_IPC_MESSAGEQUEUEIF_H_ #define FSFW_IPC_MESSAGEQUEUEIF_H_ +#include +#include "MessageQueueMessageIF.h" +#include "../returnvalues/HasReturnvaluesIF.h" + +#include + + // COULDDO: We could support blocking calls // semaphores are being implemented, which makes this idea even more iteresting. - /** * @defgroup message_queue Message Queue * @brief Message Queue related software components */ - -#include "../ipc/MessageQueueMessage.h" -#include "../ipc/MessageQueueSenderIF.h" -#include "../returnvalues/HasReturnvaluesIF.h" class MessageQueueIF { public: - static const MessageQueueId_t NO_QUEUE = MessageQueueMessageIF::NO_QUEUE; //!< Ugly hack. + static const MessageQueueId_t NO_QUEUE = 0; static const uint8_t INTERFACE_ID = CLASS_ID::MESSAGE_QUEUE_IF; //! No new messages on the queue diff --git a/ipc/MessageQueueMessage.h b/ipc/MessageQueueMessage.h index f68e9b9f9..5234f64ff 100644 --- a/ipc/MessageQueueMessage.h +++ b/ipc/MessageQueueMessage.h @@ -2,7 +2,6 @@ #define FSFW_IPC_MESSAGEQUEUEMESSAGE_H_ #include "../ipc/MessageQueueMessageIF.h" -#include "../ipc/MessageQueueSenderIF.h" #include /** diff --git a/ipc/MessageQueueMessageIF.h b/ipc/MessageQueueMessageIF.h index 91753ced9..b5a30c086 100644 --- a/ipc/MessageQueueMessageIF.h +++ b/ipc/MessageQueueMessageIF.h @@ -1,24 +1,13 @@ #ifndef FRAMEWORK_IPC_MESSAGEQUEUEMESSAGEIF_H_ #define FRAMEWORK_IPC_MESSAGEQUEUEMESSAGEIF_H_ + +#include #include #include -/* - * TODO: Actually, the definition of this ID to be a uint32_t is not ideal and - * breaks layering. However, it is difficult to keep layering, as the ID is - * stored in many places and sent around in MessageQueueMessage. - * Ideally, one would use the (current) object_id_t only, however, doing a - * lookup of queueIDs for every call does not sound ideal. - * In a first step, I'll circumvent the issue by not touching it, - * maybe in a second step. This also influences Interface design - * (getCommandQueue) and some other issues.. - */ - -typedef uint32_t MessageQueueId_t; - class MessageQueueMessageIF { public: - static const MessageQueueId_t NO_QUEUE = -1; + /** * @brief This constants defines the size of the header, * which is added to every message. diff --git a/ipc/MessageQueueSenderIF.h b/ipc/MessageQueueSenderIF.h index b967bbdf5..42d4078fe 100644 --- a/ipc/MessageQueueSenderIF.h +++ b/ipc/MessageQueueSenderIF.h @@ -1,6 +1,7 @@ -#ifndef FRAMEWORK_IPC_MESSAGEQUEUESENDERIF_H_ -#define FRAMEWORK_IPC_MESSAGEQUEUESENDERIF_H_ +#ifndef FSFW_IPC_MESSAGEQUEUESENDERIF_H_ +#define FSFW_IPC_MESSAGEQUEUESENDERIF_H_ +#include "../ipc/MessageQueueIF.h" #include "../ipc/MessageQueueMessageIF.h" #include "../objectmanager/ObjectManagerIF.h" @@ -15,11 +16,11 @@ public: */ static ReturnValue_t sendMessage(MessageQueueId_t sendTo, MessageQueueMessageIF* message, - MessageQueueId_t sentFrom = MessageQueueMessageIF::NO_QUEUE, + MessageQueueId_t sentFrom = MessageQueueIF::NO_QUEUE, bool ignoreFault = false); private: MessageQueueSenderIF() {} }; -#endif /* FRAMEWORK_IPC_MESSAGEQUEUESENDERIF_H_ */ +#endif /* FSFW_IPC_MESSAGEQUEUESENDERIF_H_ */ diff --git a/ipc/QueueFactory.h b/ipc/QueueFactory.h index be5544061..9853d2562 100644 --- a/ipc/QueueFactory.h +++ b/ipc/QueueFactory.h @@ -1,8 +1,10 @@ -#ifndef FRAMEWORK_IPC_QUEUEFACTORY_H_ -#define FRAMEWORK_IPC_QUEUEFACTORY_H_ +#ifndef FSFW_IPC_QUEUEFACTORY_H_ +#define FSFW_IPC_QUEUEFACTORY_H_ #include "MessageQueueIF.h" +#include "MessageQueueMessage.h" #include + /** * Creates message queues. * This class is a "singleton" interface, i.e. it provides an @@ -30,4 +32,4 @@ private: static QueueFactory* factoryInstance; }; -#endif /* FRAMEWORK_IPC_QUEUEFACTORY_H_ */ +#endif /* FSFW_IPC_QUEUEFACTORY_H_ */ diff --git a/ipc/messageQueueDefinitions.h b/ipc/messageQueueDefinitions.h new file mode 100644 index 000000000..d250da8a3 --- /dev/null +++ b/ipc/messageQueueDefinitions.h @@ -0,0 +1,18 @@ +#ifndef FSFW_IPC_MESSAGEQUEUEDEFINITIONS_H_ +#define FSFW_IPC_MESSAGEQUEUEDEFINITIONS_H_ + +#include + +/* + * TODO: Actually, the definition of this ID to be a uint32_t is not ideal and + * breaks layering. However, it is difficult to keep layering, as the ID is + * stored in many places and sent around in MessageQueueMessage. + * Ideally, one would use the (current) object_id_t only, however, doing a + * lookup of queueIDs for every call does not sound ideal. + * In a first step, I'll circumvent the issue by not touching it, + * maybe in a second step. This also influences Interface design + * (getCommandQueue) and some other issues.. + */ +using MessageQueueId_t = uint32_t; + +#endif /* FSFW_IPC_MESSAGEQUEUEDEFINITIONS_H_ */ diff --git a/memory/AcceptsMemoryMessagesIF.h b/memory/AcceptsMemoryMessagesIF.h index 4c222dece..7491f47d4 100644 --- a/memory/AcceptsMemoryMessagesIF.h +++ b/memory/AcceptsMemoryMessagesIF.h @@ -1,15 +1,8 @@ -/** - * @file AcceptsMemoryMessagesIF.h - * @brief This file defines the AcceptsMemoryMessagesIF class. - * @date 11.07.2013 - * @author baetz - */ +#ifndef FSFW_MEMORY_ACCEPTSMEMORYMESSAGESIF_H_ +#define FSFW_MEMORY_ACCEPTSMEMORYMESSAGESIF_H_ -#ifndef ACCEPTSMEMORYMESSAGESIF_H_ -#define ACCEPTSMEMORYMESSAGESIF_H_ - -#include "../memory/HasMemoryIF.h" -#include "../memory/MemoryMessage.h" +#include "HasMemoryIF.h" +#include "MemoryMessage.h" #include "../ipc/MessageQueueSenderIF.h" class AcceptsMemoryMessagesIF : public HasMemoryIF { @@ -18,4 +11,4 @@ public: }; -#endif /* ACCEPTSMEMORYMESSAGESIF_H_ */ +#endif /* FSFW_MEMORY_ACCEPTSMEMORYMESSAGESIF_H_ */ diff --git a/memory/FileSystemMessage.cpp b/memory/FileSystemMessage.cpp deleted file mode 100644 index 30437a623..000000000 --- a/memory/FileSystemMessage.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/* - * FileSystemMessage.cpp - * - * Created on: 19.01.2020 - * Author: Jakob Meier - */ - -#include "FileSystemMessage.h" -#include "../objectmanager/ObjectManagerIF.h" - -ReturnValue_t FileSystemMessage::setWriteToFileCommand(CommandMessage* message, - MessageQueueId_t replyQueueId, store_address_t storageID) { - message->setCommand(WRITE_TO_FILE); - message->setParameter(replyQueueId); - message->setParameter2(storageID.raw); - return HasReturnvaluesIF::RETURN_OK; -} - -store_address_t FileSystemMessage::getStoreID(const CommandMessage* message) { - store_address_t temp; - temp.raw = message->getParameter2(); - return temp; -} - -MessageQueueId_t FileSystemMessage::getReplyQueueId(const CommandMessage* message){ - return message->getParameter(); -} - diff --git a/memory/FileSystemMessage.h b/memory/FileSystemMessage.h deleted file mode 100644 index da5b3181e..000000000 --- a/memory/FileSystemMessage.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * FileSystemMessage.h - * - * Created on: 19.01.2020 - * Author: Jakob Meier - */ - -#ifndef FRAMEWORK_MEMORY_FILESYSTEMMESSAGE_H_ -#define FRAMEWORK_MEMORY_FILESYSTEMMESSAGE_H_ - -#include "../ipc/CommandMessage.h" -#include "../storagemanager/StorageManagerIF.h" -#include "../objectmanager/SystemObject.h" - -class FileSystemMessage { -private: - FileSystemMessage(); //A private ctor inhibits instantiation -public: - static const uint8_t MESSAGE_ID = messagetypes::FILE_SYSTEM_MESSAGE; - static const Command_t CREATE_FILE = MAKE_COMMAND_ID( 0x01 ); - static const Command_t DELETE_FILE = MAKE_COMMAND_ID( 0x02 ); - static const Command_t WRITE_TO_FILE = MAKE_COMMAND_ID( 0x80 ); - - static ReturnValue_t setWriteToFileCommand(CommandMessage* message, MessageQueueId_t replyToQueue, store_address_t storageID ); - static store_address_t getStoreID( const CommandMessage* message ); - static MessageQueueId_t getReplyQueueId(const CommandMessage* message); - -}; - -#endif /* FRAMEWORK_MEMORY_FILESYSTEMMESSAGE_H_ */ diff --git a/memory/HasFileSystemIF.h b/memory/HasFileSystemIF.h index b6d439811..7ab4cc4ef 100644 --- a/memory/HasFileSystemIF.h +++ b/memory/HasFileSystemIF.h @@ -1,17 +1,27 @@ -/* - * HasFileSystemIF.h - * - * Created on: 19.01.2020 - * Author: Jakob Meier - */ - -#ifndef FRAMEWORK_MEMORY_HASFILESYSTEMIF_H_ -#define FRAMEWORK_MEMORY_HASFILESYSTEMIF_H_ +#ifndef FSFW_MEMORY_HASFILESYSTEMIF_H_ +#define FSFW_MEMORY_HASFILESYSTEMIF_H_ #include "../returnvalues/HasReturnvaluesIF.h" +#include "../returnvalues/FwClassIds.h" +#include "../ipc/messageQueueDefinitions.h" +#include + +/** + * @author Jakob Meier + */ class HasFileSystemIF { public: + static constexpr uint8_t INTERFACE_ID = CLASS_ID::FILE_SYSTEM; + + static constexpr ReturnValue_t FILE_DOES_NOT_EXIST = MAKE_RETURN_CODE(0x00); + static constexpr ReturnValue_t FILE_ALREADY_EXISTS = MAKE_RETURN_CODE(0x01); + + static constexpr ReturnValue_t DIRECTORY_DOES_NOT_EXIST = MAKE_RETURN_CODE(0x02); + static constexpr ReturnValue_t DIRECTORY_ALREADY_EXISTS = MAKE_RETURN_CODE(0x03); + static constexpr ReturnValue_t DIRECTORY_NOT_EMPTY = MAKE_RETURN_CODE(0x04); + + static constexpr ReturnValue_t SEQUENCE_PACKET_MISSING = MAKE_RETURN_CODE(0x05); virtual ~HasFileSystemIF() {} /** @@ -19,18 +29,47 @@ public: * @return MessageQueueId_t of the object */ virtual MessageQueueId_t getCommandQueue() const = 0; + /** - * Function to write to a file + * Generic function to append to file. * @param dirname Directory of the file * @param filename The filename of the file * @param data The data to write to the file * @param size The size of the data to write - * @param packetNumber Counts the number of packets. For large files the write procedure must be split in multiple calls to writeToFile + * @param packetNumber Current packet number. Can be used to verify that + * there are no missing packets. + * @param args Any other arguments which an implementation might require. + * @param bytesWritten Actual bytes written to file + * For large files the write procedure must be split in multiple calls + * to writeToFile */ - virtual ReturnValue_t writeToFile(const char* dirname, char* filename, const uint8_t* data, uint32_t size, uint16_t packetNumber) = 0; - virtual ReturnValue_t createFile(const char* dirname, const char* filename, const uint8_t* data, uint32_t size) = 0; - virtual ReturnValue_t deleteFile(const char* dirname, const char* filename) = 0; + virtual ReturnValue_t appendToFile(const char* repositoryPath, + const char* filename, const uint8_t* data, size_t size, + uint16_t packetNumber, void* args = nullptr) = 0; + + /** + * Generic function to create a new file. + * @param repositoryPath + * @param filename + * @param data + * @param size + * @param args Any other arguments which an implementation might require. + * @return + */ + virtual ReturnValue_t createFile(const char* repositoryPath, + const char* filename, const uint8_t* data = nullptr, + size_t size = 0, void* args = nullptr) = 0; + + /** + * Generic function to delete a file. + * @param repositoryPath + * @param filename + * @param args + * @return + */ + virtual ReturnValue_t deleteFile(const char* repositoryPath, + const char* filename, void* args = nullptr) = 0; }; -#endif /* FRAMEWORK_MEMORY_HASFILESYSTEMIF_H_ */ +#endif /* FSFW_MEMORY_HASFILESYSTEMIF_H_ */ diff --git a/memory/MemoryHelper.cpp b/memory/MemoryHelper.cpp index 2daddf634..6b11882f3 100644 --- a/memory/MemoryHelper.cpp +++ b/memory/MemoryHelper.cpp @@ -1,14 +1,15 @@ +#include "MemoryHelper.h" +#include "MemoryMessage.h" + #include "../globalfunctions/CRC.h" -#include "../memory/MemoryHelper.h" -#include "../memory/MemoryMessage.h" #include "../objectmanager/ObjectManagerIF.h" #include "../serialize/EndianConverter.h" #include "../serviceinterface/ServiceInterfaceStream.h" MemoryHelper::MemoryHelper(HasMemoryIF* workOnThis, MessageQueueIF* useThisQueue): - workOnThis(workOnThis), queueToUse(useThisQueue), ipcStore(nullptr), - ipcAddress(), lastCommand(CommandMessage::CMD_NONE), busy(false) { + workOnThis(workOnThis), queueToUse(useThisQueue), ipcAddress(), + lastCommand(CommandMessage::CMD_NONE), busy(false) { } ReturnValue_t MemoryHelper::handleMemoryCommand(CommandMessage* message) { @@ -34,7 +35,7 @@ ReturnValue_t MemoryHelper::handleMemoryCommand(CommandMessage* message) { } void MemoryHelper::completeLoad(ReturnValue_t errorCode, - const uint8_t* dataToCopy, const uint32_t size, uint8_t* copyHere) { + const uint8_t* dataToCopy, const size_t size, uint8_t* copyHere) { busy = false; switch (errorCode) { case HasMemoryIF::DO_IT_MYSELF: @@ -64,7 +65,7 @@ void MemoryHelper::completeLoad(ReturnValue_t errorCode, } void MemoryHelper::completeDump(ReturnValue_t errorCode, - const uint8_t* dataToCopy, const uint32_t size) { + const uint8_t* dataToCopy, const size_t size) { busy = false; CommandMessage reply; MemoryMessage::setMemoryReplyFailed(&reply, errorCode, lastCommand); @@ -121,7 +122,7 @@ void MemoryHelper::completeDump(ReturnValue_t errorCode, } void MemoryHelper::swapMatrixCopy(uint8_t* out, const uint8_t *in, - uint32_t totalSize, uint8_t datatypeSize) { + size_t totalSize, uint8_t datatypeSize) { if (totalSize % datatypeSize != 0){ return; } diff --git a/memory/MemoryHelper.h b/memory/MemoryHelper.h index 418cf50d3..a651861cb 100644 --- a/memory/MemoryHelper.h +++ b/memory/MemoryHelper.h @@ -1,11 +1,16 @@ -#ifndef FRAMEWORK_MEMORY_MEMORYHELPER_H_ -#define FRAMEWORK_MEMORY_MEMORYHELPER_H_ +#ifndef FSFW_MEMORY_MEMORYHELPER_H_ +#define FSFW_MEMORY_MEMORYHELPER_H_ + +#include "AcceptsMemoryMessagesIF.h" + #include "../ipc/CommandMessage.h" -#include "../memory/AcceptsMemoryMessagesIF.h" #include "../returnvalues/HasReturnvaluesIF.h" #include "../storagemanager/StorageManagerIF.h" #include "../ipc/MessageQueueIF.h" +/** + * @brief TODO: documentation. + */ class MemoryHelper : public HasReturnvaluesIF { public: static const uint8_t INTERFACE_ID = CLASS_ID::MEMORY_HELPER; @@ -13,6 +18,20 @@ public: static const ReturnValue_t INVALID_ADDRESS = MAKE_RETURN_CODE(0xE1); static const ReturnValue_t INVALID_SIZE = MAKE_RETURN_CODE(0xE2); static const ReturnValue_t STATE_MISMATCH = MAKE_RETURN_CODE(0xE3); + + MemoryHelper(HasMemoryIF* workOnThis, MessageQueueIF* useThisQueue); + ~MemoryHelper(); + + ReturnValue_t handleMemoryCommand(CommandMessage* message); + void completeLoad(ReturnValue_t errorCode, + const uint8_t* dataToCopy = nullptr, const size_t size = 0, + uint8_t* copyHere = nullptr); + void completeDump(ReturnValue_t errorCode, + const uint8_t* dataToCopy = nullptr, const size_t size = 0); + void swapMatrixCopy(uint8_t *out, const uint8_t *in, size_t totalSize, + uint8_t datatypeSize); + ReturnValue_t initialize(MessageQueueIF* queueToUse_); + private: HasMemoryIF* workOnThis; MessageQueueIF* queueToUse; @@ -25,13 +44,6 @@ private: void handleMemoryLoad(CommandMessage* message); void handleMemoryCheckOrDump(CommandMessage* message); ReturnValue_t initialize(); -public: - ReturnValue_t handleMemoryCommand(CommandMessage* message); - void completeLoad( ReturnValue_t errorCode, const uint8_t* dataToCopy = NULL, const uint32_t size = 0, uint8_t* copyHere = NULL ); - void completeDump( ReturnValue_t errorCode, const uint8_t* dataToCopy = NULL, const uint32_t size = 0); - void swapMatrixCopy( uint8_t *out, const uint8_t *in, uint32_t totalSize, uint8_t datatypeSize); - ReturnValue_t initialize(MessageQueueIF* queueToUse_); - MemoryHelper( HasMemoryIF* workOnThis, MessageQueueIF* useThisQueue ); - ~MemoryHelper(); + }; -#endif /* MEMORYHELPER_H_ */ +#endif /* FSFW_MEMORY_MEMORYHELPER_H_ */ diff --git a/memory/MemoryMessage.cpp b/memory/MemoryMessage.cpp index 4e077dee8..94fa46917 100644 --- a/memory/MemoryMessage.cpp +++ b/memory/MemoryMessage.cpp @@ -1,7 +1,6 @@ -#include "../memory/MemoryMessage.h" +#include "MemoryMessage.h" + #include "../objectmanager/ObjectManagerIF.h" -MemoryMessage::MemoryMessage() { -} uint32_t MemoryMessage::getAddress(const CommandMessage* message) { return message->getParameter(); @@ -17,18 +16,17 @@ uint32_t MemoryMessage::getLength(const CommandMessage* message) { return message->getParameter2(); } -ReturnValue_t MemoryMessage::setMemoryDumpCommand(CommandMessage* message, +void MemoryMessage::setMemoryDumpCommand(CommandMessage* message, uint32_t address, uint32_t length) { message->setCommand(CMD_MEMORY_DUMP); message->setParameter( address ); message->setParameter2( length ); - return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t MemoryMessage::setMemoryDumpReply(CommandMessage* message, store_address_t storageID) { +void MemoryMessage::setMemoryDumpReply(CommandMessage* message, + store_address_t storageID) { message->setCommand(REPLY_MEMORY_DUMP); message->setParameter2( storageID.raw ); - return HasReturnvaluesIF::RETURN_OK; } void MemoryMessage::setMemoryLoadCommand(CommandMessage* message, @@ -64,22 +62,21 @@ void MemoryMessage::clear(CommandMessage* message) { } } -ReturnValue_t MemoryMessage::setMemoryCheckCommand(CommandMessage* message, +void MemoryMessage::setMemoryCheckCommand(CommandMessage* message, uint32_t address, uint32_t length) { message->setCommand(CMD_MEMORY_CHECK); message->setParameter( address ); message->setParameter2( length ); - return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t MemoryMessage::setMemoryCheckReply(CommandMessage* message, +void MemoryMessage::setMemoryCheckReply(CommandMessage* message, uint16_t crc) { message->setCommand(REPLY_MEMORY_CHECK); message->setParameter( crc ); - return HasReturnvaluesIF::RETURN_OK; } -void MemoryMessage::setCrcReturnValue(CommandMessage* message, ReturnValue_t returnValue){ +void MemoryMessage::setCrcReturnValue(CommandMessage* message, + ReturnValue_t returnValue){ message->setParameter(returnValue<<16); }; @@ -95,18 +92,16 @@ Command_t MemoryMessage::getInitialCommand(const CommandMessage* message) { return message->getParameter2(); } -ReturnValue_t MemoryMessage::setMemoryReplyFailed(CommandMessage* message, +void MemoryMessage::setMemoryReplyFailed(CommandMessage* message, ReturnValue_t errorCode, Command_t initialCommand) { message->setCommand(REPLY_MEMORY_FAILED); message->setParameter(errorCode); message->setParameter2(initialCommand); - return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t MemoryMessage::setMemoryCopyEnd(CommandMessage* message) { +void MemoryMessage::setMemoryCopyEnd(CommandMessage* message) { message->setCommand(END_OF_MEMORY_COPY); message->setParameter(0); message->setParameter2(0); - return HasReturnvaluesIF::RETURN_OK; } diff --git a/memory/MemoryMessage.h b/memory/MemoryMessage.h index a366eb9a3..05b9926de 100644 --- a/memory/MemoryMessage.h +++ b/memory/MemoryMessage.h @@ -1,14 +1,15 @@ -#ifndef MEMORYMESSAGE_H_ -#define MEMORYMESSAGE_H_ +#ifndef FSFW_MEMORY_MEMORYMESSAGE_H_ +#define FSFW_MEMORY_MEMORYMESSAGE_H_ #include "../ipc/CommandMessage.h" #include "../storagemanager/StorageManagerIF.h" class MemoryMessage { -private: - MemoryMessage(); //A private ctor inhibits instantiation public: + // Instantiation forbidden. + MemoryMessage() = delete; + static const uint8_t MESSAGE_ID = messagetypes::MEMORY; static const Command_t CMD_MEMORY_LOAD = MAKE_COMMAND_ID( 0x01 ); static const Command_t CMD_MEMORY_DUMP = MAKE_COMMAND_ID( 0x02 ); @@ -19,21 +20,29 @@ public: static const Command_t END_OF_MEMORY_COPY = MAKE_COMMAND_ID(0xF0); static uint32_t getAddress( const CommandMessage* message ); - static store_address_t getStoreID( const CommandMessage* message ); + static store_address_t getStoreID(const CommandMessage* message); static uint32_t getLength( const CommandMessage* message ); - static ReturnValue_t getErrorCode( const CommandMessage* message ); - static ReturnValue_t setMemoryDumpCommand( CommandMessage* message, uint32_t address, uint32_t length ); - static ReturnValue_t setMemoryDumpReply( CommandMessage* message, store_address_t storageID ); - static void setMemoryLoadCommand( CommandMessage* message, uint32_t address, store_address_t storageID ); - static ReturnValue_t setMemoryCheckCommand( CommandMessage* message, uint32_t address, uint32_t length ); - static ReturnValue_t setMemoryCheckReply( CommandMessage* message, uint16_t crc ); - static ReturnValue_t setMemoryReplyFailed( CommandMessage* message, ReturnValue_t errorCode, Command_t initialCommand ); - static ReturnValue_t setMemoryCopyEnd( CommandMessage* message); + static ReturnValue_t getErrorCode(const CommandMessage* message); + static uint16_t getCrc(const CommandMessage* message ); + static ReturnValue_t getCrcReturnValue(const CommandMessage* message); + static Command_t getInitialCommand(const CommandMessage* message); + + static void setMemoryDumpCommand(CommandMessage* message, + uint32_t address, uint32_t length ); + static void setMemoryDumpReply(CommandMessage* message, + store_address_t storageID); + static void setMemoryLoadCommand(CommandMessage* message, + uint32_t address, store_address_t storageID ); + static void setMemoryCheckCommand(CommandMessage* message, + uint32_t address, uint32_t length); + static void setMemoryCheckReply(CommandMessage* message, + uint16_t crc); + static void setMemoryReplyFailed(CommandMessage* message, + ReturnValue_t errorCode, Command_t initialCommand); + static void setMemoryCopyEnd(CommandMessage* message); static void setCrcReturnValue(CommandMessage*, ReturnValue_t returnValue); - static uint16_t getCrc( const CommandMessage* message ); - static ReturnValue_t getCrcReturnValue(const CommandMessage* message); - static Command_t getInitialCommand( const CommandMessage* message ); + static void clear(CommandMessage* message); }; -#endif /* MEMORYMESSAGE_H_ */ +#endif /* FSFW_MEMORY_MEMORYMESSAGE_H_ */ diff --git a/modes/HasModesIF.h b/modes/HasModesIF.h index c3abaaaff..34a159375 100644 --- a/modes/HasModesIF.h +++ b/modes/HasModesIF.h @@ -1,18 +1,11 @@ -/** - * @file HasModesIF.h - * @brief This file defines the HasModesIF class. - * @date 20.06.2013 - * @author baetz - */ - -#ifndef HASMODESIF_H_ -#define HASMODESIF_H_ +#ifndef FSFW_MODES_HASMODESIF_H_ +#define FSFW_MODES_HASMODESIF_H_ +#include "ModeHelper.h" +#include "ModeMessage.h" #include "../events/Event.h" -#include "../modes/ModeHelper.h" -#include "../modes/ModeMessage.h" #include "../returnvalues/HasReturnvaluesIF.h" -#include +#include class HasModesIF { @@ -37,21 +30,22 @@ public: static const Mode_t MODE_ON = 1; //!< The device is powered and ready to perform operations. In this mode, no commands are sent by the device handler itself, but direct commands van be commanded and will be interpreted static const Mode_t MODE_OFF = 0; //!< The device is powered off. The only command accepted in this mode is a mode change to on. static const Submode_t SUBMODE_NONE = 0; //!< To avoid checks against magic number "0". - virtual ~HasModesIF() { - } + + virtual ~HasModesIF() {} virtual MessageQueueId_t getCommandQueue() const = 0; virtual void getMode(Mode_t *mode, Submode_t *submode) = 0; + protected: virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, uint32_t *msToReachTheMode) { return HasReturnvaluesIF::RETURN_FAILED; } - virtual void startTransition(Mode_t mode, Submode_t submode) { - } - virtual void setToExternalControl() { - } - virtual void announceMode(bool recursive) { - } + + virtual void startTransition(Mode_t mode, Submode_t submode) {} + + virtual void setToExternalControl() {} + + virtual void announceMode(bool recursive) {} }; -#endif /* HASMODESIF_H_ */ +#endif /*FSFW_MODES_HASMODESIF_H_ */ diff --git a/modes/ModeHelper.cpp b/modes/ModeHelper.cpp index e7fc0bcb4..6be4f776d 100644 --- a/modes/ModeHelper.cpp +++ b/modes/ModeHelper.cpp @@ -1,5 +1,7 @@ -#include "../modes/HasModesIF.h" -#include "../modes/ModeHelper.h" +#include "HasModesIF.h" +#include "ModeHelper.h" + +#include "../ipc/MessageQueueSenderIF.h" #include "../serviceinterface/ServiceInterfaceStream.h" ModeHelper::ModeHelper(HasModesIF *owner) : @@ -25,7 +27,7 @@ ReturnValue_t ModeHelper::handleModeCommand(CommandMessage* command) { uint32_t timeout; ReturnValue_t result = owner->checkModeCommand(mode, submode, &timeout); if (result != HasReturnvaluesIF::RETURN_OK) { - ModeMessage::cantReachMode(&reply, result); + ModeMessage::setCantReachMode(&reply, result); MessageQueueSenderIF::sendMessage(command->getSender(), &reply, owner->getCommandQueue()); break; @@ -35,7 +37,7 @@ ReturnValue_t ModeHelper::handleModeCommand(CommandMessage* command) { commandedMode = mode; commandedSubmode = submode; - if ((parentQueueId != MessageQueueMessageIF::NO_QUEUE) + if ((parentQueueId != MessageQueueIF::NO_QUEUE) && (theOneWhoCommandedAMode != parentQueueId)) { owner->setToExternalControl(); } @@ -73,13 +75,13 @@ void ModeHelper::modeChanged(Mode_t ownerMode, Submode_t ownerSubmode) { forced = false; sendModeReplyMessage(ownerMode, ownerSubmode); sendModeInfoMessage(ownerMode, ownerSubmode); - theOneWhoCommandedAMode = MessageQueueMessageIF::NO_QUEUE; + theOneWhoCommandedAMode = MessageQueueIF::NO_QUEUE; } void ModeHelper::sendModeReplyMessage(Mode_t ownerMode, Submode_t ownerSubmode) { CommandMessage reply; - if (theOneWhoCommandedAMode != MessageQueueMessageIF::NO_QUEUE) + if (theOneWhoCommandedAMode != MessageQueueIF::NO_QUEUE) { if (ownerMode != commandedMode or ownerSubmode != commandedSubmode) { @@ -101,7 +103,7 @@ void ModeHelper::sendModeInfoMessage(Mode_t ownerMode, Submode_t ownerSubmode) { CommandMessage reply; if (theOneWhoCommandedAMode != parentQueueId - and parentQueueId != MessageQueueMessageIF::NO_QUEUE) + and parentQueueId != MessageQueueIF::NO_QUEUE) { ModeMessage::setModeMessage(&reply, ModeMessage::REPLY_MODE_INFO, ownerMode, ownerSubmode); diff --git a/modes/ModeHelper.h b/modes/ModeHelper.h index 02cf5799b..c2f089ec4 100644 --- a/modes/ModeHelper.h +++ b/modes/ModeHelper.h @@ -1,8 +1,8 @@ -#ifndef MODEHELPER_H_ -#define MODEHELPER_H_ +#ifndef FSFW_MODES_MODEHELPER_H_ +#define FSFW_MODES_MODEHELPER_H_ +#include "ModeMessage.h" #include "../ipc/MessageQueueIF.h" -#include "../modes/ModeMessage.h" #include "../returnvalues/HasReturnvaluesIF.h" #include "../timemanager/Countdown.h" @@ -20,14 +20,14 @@ public: ReturnValue_t handleModeCommand(CommandMessage *message); /** - * - * @param parentQueue the Queue id of the parent object. Set to 0 if no parent present + * @param parentQueue the Queue id of the parent object. + * Set to 0 if no parent present */ void setParentQueue(MessageQueueId_t parentQueueId); ReturnValue_t initialize(MessageQueueId_t parentQueueId); - ReturnValue_t initialize(void); //void is there to stop eclipse CODAN from falsely reporting an error + ReturnValue_t initialize(void); void modeChanged(Mode_t mode, Submode_t submode); @@ -50,4 +50,4 @@ private: void sendModeInfoMessage(Mode_t ownerMode, Submode_t ownerSubmode); }; -#endif /* MODEHELPER_H_ */ +#endif /* FSFW_MODES_MODEHELPER_H_ */ diff --git a/modes/ModeMessage.cpp b/modes/ModeMessage.cpp index 7ad7d06fd..b33bba60b 100644 --- a/modes/ModeMessage.cpp +++ b/modes/ModeMessage.cpp @@ -1,4 +1,4 @@ -#include "../modes/ModeMessage.h" +#include "ModeMessage.h" Mode_t ModeMessage::getMode(const CommandMessage* message) { return message->getParameter(); @@ -8,12 +8,11 @@ Submode_t ModeMessage::getSubmode(const CommandMessage* message) { return message->getParameter2(); } -ReturnValue_t ModeMessage::setModeMessage(CommandMessage* message, Command_t command, - Mode_t mode, Submode_t submode) { +void ModeMessage::setModeMessage(CommandMessage* message, + Command_t command, Mode_t mode, Submode_t submode) { message->setCommand( command ); message->setParameter( mode ); message->setParameter2( submode ); - return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t ModeMessage::getCantReachModeReason(const CommandMessage* message) { @@ -24,7 +23,8 @@ void ModeMessage::clear(CommandMessage* message) { message->setCommand(CommandMessage::CMD_NONE); } -void ModeMessage::cantReachMode(CommandMessage* message, ReturnValue_t reason) { +void ModeMessage::setCantReachMode(CommandMessage* message, + ReturnValue_t reason) { message->setCommand(REPLY_CANT_REACH_MODE); message->setParameter(reason); message->setParameter2(0); diff --git a/modes/ModeMessage.h b/modes/ModeMessage.h index 925f3fc16..856996cf6 100644 --- a/modes/ModeMessage.h +++ b/modes/ModeMessage.h @@ -1,12 +1,5 @@ -/** - * @file ModeMessage.h - * @brief This file defines the ModeMessage class. - * @date 17.07.2013 - * @author baetz - */ - -#ifndef MODEMESSAGE_H_ -#define MODEMESSAGE_H_ +#ifndef FSFW_MODES_MODEMESSAGE_H_ +#define FSFW_MODES_MODEMESSAGE_H_ #include "../ipc/CommandMessage.h" @@ -30,11 +23,12 @@ public: static Mode_t getMode(const CommandMessage* message); static Submode_t getSubmode(const CommandMessage* message); - static ReturnValue_t setModeMessage(CommandMessage* message, + static ReturnValue_t getCantReachModeReason(const CommandMessage* message); + + static void setModeMessage(CommandMessage* message, Command_t command, Mode_t mode, Submode_t submode); - static void cantReachMode(CommandMessage* message, ReturnValue_t reason); - static ReturnValue_t getCantReachModeReason(const CommandMessage* message); + static void setCantReachMode(CommandMessage* message, ReturnValue_t reason); static void clear(CommandMessage* message); }; -#endif /* MODEMESSAGE_H_ */ +#endif /* FSFW_MODES_MODEMESSAGE_H_ */ diff --git a/monitoring/AbsLimitMonitor.h b/monitoring/AbsLimitMonitor.h index c32c63ef0..c9c33c74b 100644 --- a/monitoring/AbsLimitMonitor.h +++ b/monitoring/AbsLimitMonitor.h @@ -1,15 +1,20 @@ -#ifndef FRAMEWORK_MONITORING_ABSLIMITMONITOR_H_ -#define FRAMEWORK_MONITORING_ABSLIMITMONITOR_H_ +#ifndef FSFW_MONITORING_ABSLIMITMONITOR_H_ +#define FSFW_MONITORING_ABSLIMITMONITOR_H_ -#include "../monitoring/MonitorBase.h" +#include "MonitorBase.h" #include template class AbsLimitMonitor: public MonitorBase { public: - AbsLimitMonitor(object_id_t reporterId, uint8_t monitorId, uint32_t parameterId, - uint16_t confirmationLimit, T limit, Event violationEvent = MonitoringIF::VALUE_OUT_OF_RANGE, bool aboveIsViolation = true) : - MonitorBase(reporterId, monitorId, parameterId, confirmationLimit), limit(limit), violationEvent(violationEvent), aboveIsViolation(aboveIsViolation) { + AbsLimitMonitor(object_id_t reporterId, uint8_t monitorId, + uint32_t parameterId, uint16_t confirmationLimit, T limit, + Event violationEvent = MonitoringIF::VALUE_OUT_OF_RANGE, + bool aboveIsViolation = true) : + MonitorBase(reporterId, monitorId, parameterId, + confirmationLimit), + limit(limit), violationEvent(violationEvent), + aboveIsViolation(aboveIsViolation) { } virtual ~AbsLimitMonitor() { } @@ -32,7 +37,8 @@ public: const ParameterWrapper *newValues, uint16_t startAtIndex) { ReturnValue_t result = this->MonitorBase::getParameter(domainId, parameterId, parameterWrapper, newValues, startAtIndex); - //We'll reuse the DOMAIN_ID of MonitorReporter, as we know the parameterIds used there. + // We'll reuse the DOMAIN_ID of MonitorReporter, + // as we know the parameterIds used there. if (result != this->INVALID_MATRIX_ID) { return result; } @@ -59,7 +65,8 @@ protected: void sendTransitionEvent(T currentValue, ReturnValue_t state) { switch (state) { case MonitoringIF::OUT_OF_RANGE: - EventManagerIF::triggerEvent(this->reportingId, violationEvent, this->parameterId); + EventManagerIF::triggerEvent(this->reportingId, + violationEvent, this->parameterId); break; default: break; @@ -70,4 +77,4 @@ protected: const bool aboveIsViolation; }; -#endif /* FRAMEWORK_MONITORING_ABSLIMITMONITOR_H_ */ +#endif /* FSFW_MONITORING_ABSLIMITMONITOR_H_ */ diff --git a/monitoring/HasMonitorsIF.h b/monitoring/HasMonitorsIF.h index 85d92b6b9..04f634374 100644 --- a/monitoring/HasMonitorsIF.h +++ b/monitoring/HasMonitorsIF.h @@ -1,11 +1,5 @@ -/** - * @file HasMonitorsIF.h - * @brief This file defines the HasMonitorsIF class. - * @date 28.07.2014 - * @author baetz - */ -#ifndef HASMONITORSIF_H_ -#define HASMONITORSIF_H_ +#ifndef FSFW_MONITORING_HASMONITORSIF_H_ +#define FSFW_MONITORING_HASMONITORSIF_H_ #include "../events/EventReportingProxyIF.h" #include "../objectmanager/ObjectManagerIF.h" @@ -27,4 +21,4 @@ public: } }; -#endif /* HASMONITORSIF_H_ */ +#endif /* FSFW_MONITORING_HASMONITORSIF_H_ */ diff --git a/monitoring/LimitMonitor.h b/monitoring/LimitMonitor.h index 4aec86695..66e6725e8 100644 --- a/monitoring/LimitMonitor.h +++ b/monitoring/LimitMonitor.h @@ -1,7 +1,7 @@ #ifndef FRAMEWORK_MONITORING_LIMITMONITOR_H_ #define FRAMEWORK_MONITORING_LIMITMONITOR_H_ -#include "../monitoring/MonitorBase.h" +#include "MonitorBase.h" /** * Variant of a limit checking class. @@ -16,13 +16,12 @@ public: uint16_t confirmationLimit, T lowerLimit, T upperLimit, Event belowLowEvent = MonitoringIF::VALUE_BELOW_LOW_LIMIT, Event aboveHighEvent = MonitoringIF::VALUE_ABOVE_HIGH_LIMIT) : - MonitorBase(reporterId, monitorId, parameterId, confirmationLimit), - lowerLimit(lowerLimit), upperLimit(upperLimit), belowLowEvent(belowLowEvent), - aboveHighEvent(aboveHighEvent) { + MonitorBase(reporterId, monitorId, parameterId, confirmationLimit), lowerLimit( + lowerLimit), upperLimit(upperLimit), belowLowEvent( + belowLowEvent), aboveHighEvent(aboveHighEvent) { + } + virtual ~LimitMonitor() { } - - virtual ~LimitMonitor() {} - virtual ReturnValue_t checkSample(T sample, T* crossedLimit) { *crossedLimit = 0.0; if (sample > upperLimit) { diff --git a/monitoring/LimitViolationReporter.cpp b/monitoring/LimitViolationReporter.cpp index 87278f4e1..c531a6e69 100644 --- a/monitoring/LimitViolationReporter.cpp +++ b/monitoring/LimitViolationReporter.cpp @@ -4,9 +4,9 @@ * @date 17.07.2014 * @author baetz */ -#include "../monitoring/LimitViolationReporter.h" -#include "../monitoring/MonitoringIF.h" -#include "../monitoring/ReceivesMonitoringReportsIF.h" +#include "LimitViolationReporter.h" +#include "MonitoringIF.h" +#include "ReceivesMonitoringReportsIF.h" #include "../objectmanager/ObjectManagerIF.h" #include "../serialize/SerializeAdapter.h" diff --git a/monitoring/MonitorBase.h b/monitoring/MonitorBase.h index 5173c4798..5f9a2cafa 100644 --- a/monitoring/MonitorBase.h +++ b/monitoring/MonitorBase.h @@ -1,35 +1,42 @@ -#ifndef MONITORBASE_H_ -#define MONITORBASE_H_ +#ifndef FSFW_MONITORING_MONITORBASE_H_ +#define FSFW_MONITORING_MONITORBASE_H_ + +#include "LimitViolationReporter.h" +#include "MonitoringIF.h" +#include "MonitoringMessageContent.h" +#include "MonitorReporter.h" #include "../datapoolglob/GlobalDataSet.h" #include "../datapoolglob/PIDReader.h" -#include "../monitoring/LimitViolationReporter.h" -#include "../monitoring/MonitoringIF.h" -#include "../monitoring/MonitoringMessageContent.h" -#include "../monitoring/MonitorReporter.h" /** - * Base class for monitoring of parameters. - * Can be used anywhere, specializations need to implement checkSample and should override sendTransitionEvent. - * Manages state handling, enabling and disabling of events/reports and forwarding of transition - * reports via MonitorReporter. In addition, it provides default implementations for fetching the parameter sample from - * the data pool and a simple confirmation counter. + * @brief Base class for monitoring of parameters. + * @details + * Can be used anywhere, specializations need to implement checkSample and + * should override sendTransitionEvent. + * Manages state handling, enabling and disabling of events/reports and + * forwarding of transition reports via MonitorReporter. + * + * In addition, it provides default implementations for fetching the + * parameter sample from the data pool and a simple confirmation counter. */ template class MonitorBase: public MonitorReporter { public: MonitorBase(object_id_t reporterId, uint8_t monitorId, uint32_t parameterId, uint16_t confirmationLimit) : - MonitorReporter(reporterId, monitorId, parameterId, confirmationLimit) { + MonitorReporter(reporterId, monitorId, parameterId, + confirmationLimit) { } virtual ~MonitorBase() { } virtual ReturnValue_t check() { - //1. Fetch sample of type T, return validity. + // 1. Fetch sample of type T, return validity. T sample = 0; ReturnValue_t validity = fetchSample(&sample); - //2. If returning from fetch != OK, parameter is invalid. Report (if oldState is != invalidity). + // 2. If returning from fetch != OK, parameter is invalid. + // Report (if oldState is != invalidity). if (validity != HasReturnvaluesIF::RETURN_OK) { this->monitorStateIs(validity, sample, 0); //3. Otherwise, check sample. @@ -43,7 +50,8 @@ public: ReturnValue_t currentState = checkSample(sample, &crossedLimit); return this->monitorStateIs(currentState,sample, crossedLimit); } - //Abstract or default. + + // Abstract or default. virtual ReturnValue_t checkSample(T sample, T* crossedLimit) = 0; protected: @@ -59,4 +67,4 @@ protected: } }; -#endif /* MONITORBASE_H_ */ +#endif /* FSFW_MONITORING_MONITORBASE_H_ */ diff --git a/monitoring/MonitorReporter.h b/monitoring/MonitorReporter.h index 9823cde01..88fa6ede5 100644 --- a/monitoring/MonitorReporter.h +++ b/monitoring/MonitorReporter.h @@ -1,10 +1,11 @@ -#ifndef FRAMEWORK_MONITORING_MONITORREPORTER_H_ -#define FRAMEWORK_MONITORING_MONITORREPORTER_H_ +#ifndef FSFW_MONITORING_MONITORREPORTER_H_ +#define FSFW_MONITORING_MONITORREPORTER_H_ + +#include "LimitViolationReporter.h" +#include "MonitoringIF.h" +#include "MonitoringMessageContent.h" #include "../events/EventManagerIF.h" -#include "../monitoring/LimitViolationReporter.h" -#include "../monitoring/MonitoringIF.h" -#include "../monitoring/MonitoringMessageContent.h" #include "../parameters/HasParametersIF.h" template @@ -14,11 +15,12 @@ public: static const uint8_t ENABLED = 1; static const uint8_t DISABLED = 0; - MonitorReporter(object_id_t reportingId, uint8_t monitorId, uint32_t parameterId, uint16_t confirmationLimit) : - monitorId(monitorId), parameterId(parameterId), reportingId( - reportingId), oldState(MonitoringIF::UNCHECKED), reportingEnabled( - ENABLED), eventEnabled(ENABLED), currentCounter(0), confirmationLimit( - confirmationLimit) { + MonitorReporter(object_id_t reportingId, uint8_t monitorId, + uint32_t parameterId, uint16_t confirmationLimit) : + monitorId(monitorId), parameterId(parameterId), + reportingId(reportingId), oldState(MonitoringIF::UNCHECKED), + reportingEnabled(ENABLED), eventEnabled(ENABLED), currentCounter(0), + confirmationLimit(confirmationLimit) { } virtual ~MonitorReporter() { @@ -148,7 +150,8 @@ protected: case HasReturnvaluesIF::RETURN_OK: break; default: - EventManagerIF::triggerEvent(reportingId, MonitoringIF::MONITOR_CHANGED_STATE, state); + EventManagerIF::triggerEvent(reportingId, + MonitoringIF::MONITOR_CHANGED_STATE, state); break; } } @@ -159,7 +162,8 @@ protected: * @param crossedLimit The limit crossed (if applicable). * @param state Current state the monitor is in. */ - virtual void sendTransitionReport(T parameterValue, T crossedLimit, ReturnValue_t state) { + virtual void sendTransitionReport(T parameterValue, T crossedLimit, + ReturnValue_t state) { MonitoringReportContent report(parameterId, parameterValue, crossedLimit, oldState, state); LimitViolationReporter::sendLimitViolationReport(&report); @@ -175,4 +179,4 @@ protected: } }; -#endif /* FRAMEWORK_MONITORING_MONITORREPORTER_H_ */ +#endif /* FSFW_MONITORING_MONITORREPORTER_H_ */ diff --git a/monitoring/MonitoringIF.h b/monitoring/MonitoringIF.h index d9ea339f4..aa266f337 100644 --- a/monitoring/MonitoringIF.h +++ b/monitoring/MonitoringIF.h @@ -1,8 +1,8 @@ -#ifndef MONITORINGIF_H_ -#define MONITORINGIF_H_ +#ifndef FSFW_MONITORING_MONITORINGIF_H_ +#define FSFW_MONITORING_MONITORINGIF_H_ +#include "MonitoringMessage.h" #include "../memory/HasMemoryIF.h" -#include "../monitoring/MonitoringMessage.h" #include "../serialize/SerializeIF.h" class MonitoringIF : public SerializeIF { @@ -64,4 +64,4 @@ public: -#endif /* MONITORINGIF_H_ */ +#endif /* FSFW_MONITORING_MONITORINGIF_H_ */ diff --git a/monitoring/MonitoringMessage.cpp b/monitoring/MonitoringMessage.cpp index 2cfe1ecee..8caa27aee 100644 --- a/monitoring/MonitoringMessage.cpp +++ b/monitoring/MonitoringMessage.cpp @@ -1,4 +1,4 @@ -#include "../monitoring/MonitoringMessage.h" +#include "MonitoringMessage.h" #include "../objectmanager/ObjectManagerIF.h" MonitoringMessage::~MonitoringMessage() { diff --git a/monitoring/MonitoringMessageContent.h b/monitoring/MonitoringMessageContent.h index ea52962b2..c82506f3a 100644 --- a/monitoring/MonitoringMessageContent.h +++ b/monitoring/MonitoringMessageContent.h @@ -1,8 +1,8 @@ #ifndef MONITORINGMESSAGECONTENT_H_ #define MONITORINGMESSAGECONTENT_H_ -#include "../monitoring/HasMonitorsIF.h" -#include "../monitoring/MonitoringIF.h" +#include "HasMonitorsIF.h" +#include "MonitoringIF.h" #include "../objectmanager/ObjectManagerIF.h" #include "../serialize/SerialBufferAdapter.h" #include "../serialize/SerialFixedArrayListAdapter.h" diff --git a/monitoring/TwoValueLimitMonitor.h b/monitoring/TwoValueLimitMonitor.h index 74934828e..e690cdae2 100644 --- a/monitoring/TwoValueLimitMonitor.h +++ b/monitoring/TwoValueLimitMonitor.h @@ -1,7 +1,7 @@ #ifndef FRAMEWORK_MONITORING_TWOVALUELIMITMONITOR_H_ #define FRAMEWORK_MONITORING_TWOVALUELIMITMONITOR_H_ -#include "../monitoring/LimitMonitor.h" +#include "LimitMonitor.h" template class TwoValueLimitMonitor: public LimitMonitor { diff --git a/objectmanager/ObjectManager.cpp b/objectmanager/ObjectManager.cpp index a8c844159..5871bfcdf 100644 --- a/objectmanager/ObjectManager.cpp +++ b/objectmanager/ObjectManager.cpp @@ -1,4 +1,4 @@ -#include "../objectmanager/ObjectManager.h" +#include "ObjectManager.h" #include "../serviceinterface/ServiceInterfaceStream.h" #include #include diff --git a/objectmanager/ObjectManager.h b/objectmanager/ObjectManager.h index e582584cd..69a74f73e 100644 --- a/objectmanager/ObjectManager.h +++ b/objectmanager/ObjectManager.h @@ -1,15 +1,8 @@ -/** - * @file ObjectManager.h - * @brief This file contains the implementation of the ObjectManager class - * @date 18.09.2012 - * @author Bastian Baetz - */ +#ifndef FSFW_OBJECTMANAGER_OBJECTMANAGER_H_ +#define FSFW_OBJECTMANAGER_OBJECTMANAGER_H_ -#ifndef OBJECTMANAGER_H_ -#define OBJECTMANAGER_H_ - -#include "../objectmanager/ObjectManagerIF.h" -#include "../objectmanager/SystemObjectIF.h" +#include "ObjectManagerIF.h" +#include "SystemObjectIF.h" #include /** @@ -22,14 +15,15 @@ * most of the system initialization. * As the system is static after initialization, no new objects are * created or inserted into the list after startup. - * \ingroup system_objects + * @ingroup system_objects + * @author Bastian Baetz */ class ObjectManager : public ObjectManagerIF { private: //comparison? /** - * \brief This is the map of all initialized objects in the manager. - * \details Objects in the List must inherit the SystemObjectIF. + * @brief This is the map of all initialized objects in the manager. + * @details Objects in the List must inherit the SystemObjectIF. */ std::map objectList; protected: @@ -54,7 +48,8 @@ public: /** * @brief In the class's destructor, all objects in the list are deleted. */ - //SHOULDDO: If, for some reason, deleting an ObjectManager instance is required, check if this works. + // SHOULDDO: If, for some reason, deleting an ObjectManager instance is + // required, check if this works. virtual ~ObjectManager( void ); ReturnValue_t insert( object_id_t id, SystemObjectIF* object ); ReturnValue_t remove( object_id_t id ); @@ -64,4 +59,4 @@ public: -#endif /* OBJECTMANAGER_H_ */ +#endif /* FSFW_OBJECTMANAGER_OBJECTMANAGER_H_ */ diff --git a/objectmanager/ObjectManagerIF.h b/objectmanager/ObjectManagerIF.h index 16619e23a..4bd1d915a 100644 --- a/objectmanager/ObjectManagerIF.h +++ b/objectmanager/ObjectManagerIF.h @@ -1,8 +1,8 @@ -#ifndef FRAMEWORK_OBJECTMANAGER_OBJECTMANAGERIF_H_ -#define FRAMEWORK_OBJECTMANAGER_OBJECTMANAGERIF_H_ +#ifndef FSFW_OBJECTMANAGER_OBJECTMANAGERIF_H_ +#define FSFW_OBJECTMANAGER_OBJECTMANAGERIF_H_ -#include "../objectmanager/frameworkObjects.h" -#include "../objectmanager/SystemObjectIF.h" +#include "frameworkObjects.h" +#include "SystemObjectIF.h" #include "../returnvalues/HasReturnvaluesIF.h" #include "../serviceinterface/ServiceInterfaceStream.h" @@ -21,7 +21,7 @@ public: static constexpr uint8_t INTERFACE_ID = CLASS_ID::OBJECT_MANAGER_IF; static constexpr ReturnValue_t INSERTION_FAILED = MAKE_RETURN_CODE( 1 ); static constexpr ReturnValue_t NOT_FOUND = MAKE_RETURN_CODE( 2 ); - static constexpr ReturnValue_t CHILD_INIT_FAILED = MAKE_RETURN_CODE( 3 ); + static constexpr ReturnValue_t CHILD_INIT_FAILED = MAKE_RETURN_CODE( 3 ); //!< Can be used if the initialization of a SystemObject failed. static constexpr ReturnValue_t INTERNAL_ERR_REPORTER_UNINIT = MAKE_RETURN_CODE( 4 ); protected: @@ -79,6 +79,7 @@ public: /** * @brief This is the forward declaration of the global objectManager instance. */ +// SHOULDDO: maybe put this in the glob namespace to explicitely mark it global? extern ObjectManagerIF *objectManager; /*Documentation can be found in the class method declaration above.*/ diff --git a/objectmanager/SystemObject.cpp b/objectmanager/SystemObject.cpp index 61eaf90af..64330fbc9 100644 --- a/objectmanager/SystemObject.cpp +++ b/objectmanager/SystemObject.cpp @@ -1,6 +1,6 @@ +#include "ObjectManager.h" +#include "SystemObject.h" #include "../events/EventManagerIF.h" -#include "../objectmanager/ObjectManager.h" -#include "../objectmanager/SystemObject.h" SystemObject::SystemObject(object_id_t setObjectId, bool doRegister) : objectId(setObjectId), registered(doRegister) { diff --git a/objectmanager/SystemObject.h b/objectmanager/SystemObject.h index ae4b13897..d9c4236d0 100644 --- a/objectmanager/SystemObject.h +++ b/objectmanager/SystemObject.h @@ -1,9 +1,9 @@ -#ifndef SYSTEMOBJECT_H_ -#define SYSTEMOBJECT_H_ +#ifndef FSFW_OBJECTMANAGER_SYSTEMOBJECT_H_ +#define FSFW_OBJECTMANAGER_SYSTEMOBJECT_H_ +#include "SystemObjectIF.h" #include "../events/Event.h" #include "../events/EventReportingProxyIF.h" -#include "../objectmanager/SystemObjectIF.h" #include "../timemanager/Clock.h" /** @@ -13,7 +13,8 @@ * class that is announced to ObjectManager. It automatically includes * itself (and therefore the inheriting class) in the object manager's * list. - * \ingroup system_objects + * @author Ulrich Mohr + * @ingroup system_objects */ class SystemObject: public SystemObjectIF { private: @@ -30,14 +31,16 @@ public: * @param parameter1 * @param parameter2 */ - virtual void triggerEvent(Event event, uint32_t parameter1 = 0, uint32_t parameter2 = 0); + virtual void triggerEvent(Event event, uint32_t parameter1 = 0, + uint32_t parameter2 = 0); /** * @brief The class's constructor. * @details In the constructor, the object id is set and the class is * inserted in the object manager. * @param setObjectId The id the object shall have. - * @param doRegister Determines if the object is registered in the global object manager. + * @param doRegister Determines if the object is registered in + * the global object manager. */ SystemObject(object_id_t setObjectId, bool doRegister = true); /** @@ -48,7 +51,8 @@ public: virtual ReturnValue_t initialize() override; virtual ReturnValue_t checkObjectConnections(); - virtual void forwardEvent(Event event, uint32_t parameter1 = 0, uint32_t parameter2 = 0) const; + virtual void forwardEvent(Event event, uint32_t parameter1 = 0, + uint32_t parameter2 = 0) const; }; -#endif /* SYSTEMOBJECT_H_ */ +#endif /* FSFW_OBJECTMANAGER_SYSTEMOBJECT_H_ */ diff --git a/objectmanager/SystemObjectIF.h b/objectmanager/SystemObjectIF.h index 108717af5..315fde9b3 100644 --- a/objectmanager/SystemObjectIF.h +++ b/objectmanager/SystemObjectIF.h @@ -1,5 +1,5 @@ -#ifndef FRAMEWORK_OBJECTMANAGER_SYSTEMOBJECTIF_H_ -#define FRAMEWORK_OBJECTMANAGER_SYSTEMOBJECTIF_H_ +#ifndef FSFW_OBJECTMANAGER_SYSTEMOBJECTIF_H_ +#define FSFW_OBJECTMANAGER_SYSTEMOBJECTIF_H_ #include "../events/EventReportingProxyIF.h" #include "../returnvalues/HasReturnvaluesIF.h" @@ -59,4 +59,4 @@ public: virtual ReturnValue_t checkObjectConnections() = 0; }; -#endif /* FRAMEWORK_OBJECTMANAGER_SYSTEMOBJECTIF_H_ */ +#endif /* #ifndef FSFW_OBJECTMANAGER_SYSTEMOBJECTIF_H_ */ diff --git a/objectmanager/frameworkObjects.h b/objectmanager/frameworkObjects.h index 46d5feea2..57783286a 100644 --- a/objectmanager/frameworkObjects.h +++ b/objectmanager/frameworkObjects.h @@ -1,10 +1,17 @@ -#ifndef FRAMEWORK_OBJECTMANAGER_FRAMEWORKOBJECTS_H_ -#define FRAMEWORK_OBJECTMANAGER_FRAMEWORKOBJECTS_H_ +#ifndef FSFW_OBJECTMANAGER_FRAMEWORKOBJECTS_H_ +#define FSFW_OBJECTMANAGER_FRAMEWORKOBJECTS_H_ namespace objects { enum framework_objects { // Default verification reporter. - PUS_SERVICE_1 = 0x53000000, + PUS_SERVICE_1_VERIFICATION = 0x53000001, + PUS_SERVICE_2_DEVICE_ACCESS = 0x53000002, + PUS_SERVICE_3_HOUSEKEEPING = 0x53000003, + PUS_SERVICE_5_EVENT_REPORTING = 0x53000005, + PUS_SERVICE_8_FUNCTION_MGMT = 0x53000008, + PUS_SERVICE_9_TIME_MGMT = 0x53000009, + PUS_SERVICE_17_TEST = 0x53000017, + PUS_SERVICE_200_MODE_MGMT = 0x53000200, //Generic IDs for IPC, modes, health, events HEALTH_TABLE = 0x53010000, @@ -22,4 +29,4 @@ enum framework_objects { -#endif /* FRAMEWORK_OBJECTMANAGER_FRAMEWORKOBJECTS_H_ */ +#endif /* FSFW_OBJECTMANAGER_FRAMEWORKOBJECTS_H_ */ diff --git a/osal/FreeRTOS/BinSemaphUsingTask.cpp b/osal/FreeRTOS/BinSemaphUsingTask.cpp index dd1e48ca9..9c29948e9 100644 --- a/osal/FreeRTOS/BinSemaphUsingTask.cpp +++ b/osal/FreeRTOS/BinSemaphUsingTask.cpp @@ -1,5 +1,5 @@ -#include "../../osal/FreeRTOS/BinSemaphUsingTask.h" -#include "../../osal/FreeRTOS/TaskManagement.h" +#include "BinSemaphUsingTask.h" +#include "TaskManagement.h" #include "../../serviceinterface/ServiceInterfaceStream.h" BinarySemaphoreUsingTask::BinarySemaphoreUsingTask() { @@ -16,6 +16,10 @@ BinarySemaphoreUsingTask::~BinarySemaphoreUsingTask() { xTaskNotifyAndQuery(handle, 0, eSetValueWithOverwrite, nullptr); } +void BinarySemaphoreUsingTask::refreshTaskHandle() { + handle = TaskManagement::getCurrentTaskHandle(); +} + ReturnValue_t BinarySemaphoreUsingTask::acquire(TimeoutType timeoutType, uint32_t timeoutMs) { TickType_t timeout = 0; diff --git a/osal/FreeRTOS/BinSemaphUsingTask.h b/osal/FreeRTOS/BinSemaphUsingTask.h index 4317e0b23..65a091a3f 100644 --- a/osal/FreeRTOS/BinSemaphUsingTask.h +++ b/osal/FreeRTOS/BinSemaphUsingTask.h @@ -1,5 +1,5 @@ -#ifndef FRAMEWORK_OSAL_FREERTOS_BINSEMAPHUSINGTASK_H_ -#define FRAMEWORK_OSAL_FREERTOS_BINSEMAPHUSINGTASK_H_ +#ifndef FSFW_OSAL_FREERTOS_BINSEMAPHUSINGTASK_H_ +#define FSFW_OSAL_FREERTOS_BINSEMAPHUSINGTASK_H_ #include "../../returnvalues/HasReturnvaluesIF.h" #include "../../tasks/SemaphoreIF.h" @@ -7,16 +7,20 @@ #include #include +// todo: does not work for older FreeRTOS version, so we should +// actually check whether tskKERNEL_VERSION_MAJOR is larger than.. 7 or 8 ? + /** * @brief Binary Semaphore implementation using the task notification value. * The notification value should therefore not be used - * for other purposes. + * for other purposes! * @details * Additional information: https://www.freertos.org/RTOS-task-notifications.html * and general semaphore documentation. * This semaphore is bound to the task it is created in! - * Take care of calling this function with the correct executing task, - * (for example in the initializeAfterTaskCreation() function). + * Take care of building this class with the correct executing task, + * (for example in the initializeAfterTaskCreation() function) or + * by calling refreshTaskHandle() with the correct executing task. */ class BinarySemaphoreUsingTask: public SemaphoreIF, public HasReturnvaluesIF { @@ -28,6 +32,16 @@ public: //! @brief Default dtor virtual~ BinarySemaphoreUsingTask(); + /** + * This function can be used to get the correct task handle from the + * currently executing task. + * + * This is required because the task notification value will be used + * as a binary semaphore, and the semaphore might be created by another + * task. + */ + void refreshTaskHandle(); + ReturnValue_t acquire(TimeoutType timeoutType = TimeoutType::BLOCKING, uint32_t timeoutMs = portMAX_DELAY) override; ReturnValue_t release() override; @@ -70,10 +84,10 @@ public: * - @c RETURN_FAILED on failure */ static ReturnValue_t releaseFromISR(TaskHandle_t taskToNotify, - BaseType_t * higherPriorityTaskWoken); + BaseType_t* higherPriorityTaskWoken); protected: TaskHandle_t handle; }; -#endif /* FRAMEWORK_OSAL_FREERTOS_BINSEMAPHUSINGTASK_H_ */ +#endif /* FSFW_OSAL_FREERTOS_BINSEMAPHUSINGTASK_H_ */ diff --git a/osal/FreeRTOS/Clock.cpp b/osal/FreeRTOS/Clock.cpp index d556444c4..42f060b45 100644 --- a/osal/FreeRTOS/Clock.cpp +++ b/osal/FreeRTOS/Clock.cpp @@ -67,6 +67,13 @@ ReturnValue_t Clock::getUptime(uint32_t* uptimeMs) { return HasReturnvaluesIF::RETURN_OK; } + +uint32_t Clock::getUptimeSeconds() { + timeval uptime = getUptime(); + return uptime.tv_sec; +} + + ReturnValue_t Clock::getClock_usecs(uint64_t* time) { timeval time_timeval; ReturnValue_t result = getClock_timeval(&time_timeval); diff --git a/osal/FreeRTOS/FixedTimeslotTask.cpp b/osal/FreeRTOS/FixedTimeslotTask.cpp index 309574eb7..062686e2b 100644 --- a/osal/FreeRTOS/FixedTimeslotTask.cpp +++ b/osal/FreeRTOS/FixedTimeslotTask.cpp @@ -150,15 +150,6 @@ void FixedTimeslotTask::handleMissedDeadline() { if(deadlineMissedFunc != nullptr) { this->deadlineMissedFunc(); } - -#ifdef DEBUG - object_id_t handlerId = pst.current->handlerId; - sif::warning << "FixedTimeslotTask: " << pcTaskGetName(NULL) << " with" - << " object ID 0x" << std::setfill('0') << std::setw(8) << std::hex - << handlerId << " missed deadline!" << std::setfill(' ') - << std::dec << std::endl; -#endif - } ReturnValue_t FixedTimeslotTask::sleepFor(uint32_t ms) { diff --git a/osal/FreeRTOS/FixedTimeslotTask.h b/osal/FreeRTOS/FixedTimeslotTask.h index c46de5b7b..7d2cdb703 100644 --- a/osal/FreeRTOS/FixedTimeslotTask.h +++ b/osal/FreeRTOS/FixedTimeslotTask.h @@ -1,7 +1,7 @@ -#ifndef FRAMEWORK_OSAL_FREERTOS_FIXEDTIMESLOTTASK_H_ -#define FRAMEWORK_OSAL_FREERTOS_FIXEDTIMESLOTTASK_H_ +#ifndef FSFW_OSAL_FREERTOS_FIXEDTIMESLOTTASK_H_ +#define FSFW_OSAL_FREERTOS_FIXEDTIMESLOTTASK_H_ -#include "../../osal/FreeRTOS/FreeRTOSTaskIF.h" +#include "FreeRTOSTaskIF.h" #include "../../tasks/FixedSlotSequence.h" #include "../../tasks/FixedTimeslotTaskIF.h" #include "../../tasks/Typedef.h" @@ -98,4 +98,4 @@ protected: void handleMissedDeadline(); }; -#endif /* POLLINGTASK_H_ */ +#endif /* FSFW_OSAL_FREERTOS_FIXEDTIMESLOTTASK_H_ */ diff --git a/osal/FreeRTOS/MessageQueue.cpp b/osal/FreeRTOS/MessageQueue.cpp index e3e0ef1c1..fdadf8b7d 100644 --- a/osal/FreeRTOS/MessageQueue.cpp +++ b/osal/FreeRTOS/MessageQueue.cpp @@ -1,5 +1,5 @@ #include "MessageQueue.h" - +#include "../../objectmanager/ObjectManagerIF.h" #include "../../serviceinterface/ServiceInterfaceStream.h" // TODO I guess we should have a way of checking if we are in an ISR and then @@ -11,7 +11,12 @@ MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize): maxMessageSize(maxMessageSize) { handle = xQueueCreate(messageDepth, maxMessageSize); if (handle == nullptr) { - sif::error << "MessageQueue::MessageQueue Creation failed" << std::endl; + sif::error << "MessageQueue::MessageQueue:" + << " Creation failed." << std::endl; + sif::error << "Specified Message Depth: " << messageDepth + << std::endl; + sif::error << "Specified Maximum Message Size: " + << maxMessageSize << std::endl; } } @@ -40,7 +45,7 @@ ReturnValue_t MessageQueue::sendToDefaultFrom(MessageQueueMessageIF* message, } ReturnValue_t MessageQueue::reply(MessageQueueMessageIF* message) { - if (this->lastPartner != MessageQueueMessageIF::NO_QUEUE) { + if (this->lastPartner != MessageQueueIF::NO_QUEUE) { return sendMessageFrom(this->lastPartner, message, this->getId()); } else { return NO_REPLY_PARTNER; @@ -58,8 +63,8 @@ ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo, ReturnValue_t MessageQueue::handleSendResult(BaseType_t result, bool ignoreFault) { if (result != pdPASS) { if (not ignoreFault) { - InternalErrorReporterIF* internalErrorReporter = - objectManager->get( + InternalErrorReporterIF* internalErrorReporter = objectManager-> + get( objects::INTERNAL_ERROR_REPORTER); if (internalErrorReporter != nullptr) { internalErrorReporter->queueMessageNotSent(); diff --git a/osal/FreeRTOS/MessageQueue.h b/osal/FreeRTOS/MessageQueue.h index e953ec34b..b99bf7c8d 100644 --- a/osal/FreeRTOS/MessageQueue.h +++ b/osal/FreeRTOS/MessageQueue.h @@ -8,6 +8,7 @@ #include #include +#include // TODO: this class assumes that MessageQueueId_t is the same size as void* // (the FreeRTOS handle type), compiler will catch this but it might be nice @@ -139,8 +140,8 @@ protected: private: bool defaultDestinationSet = false; QueueHandle_t handle; - MessageQueueId_t defaultDestination = 0; - MessageQueueId_t lastPartner = 0; + MessageQueueId_t defaultDestination = MessageQueueIF::NO_QUEUE; + MessageQueueId_t lastPartner = MessageQueueIF::NO_QUEUE; const size_t maxMessageSize; //! Stores the current system context CallContext callContext = CallContext::TASK; diff --git a/osal/FreeRTOS/PeriodicTask.cpp b/osal/FreeRTOS/PeriodicTask.cpp index 990d38d67..5c0a840da 100644 --- a/osal/FreeRTOS/PeriodicTask.cpp +++ b/osal/FreeRTOS/PeriodicTask.cpp @@ -133,10 +133,6 @@ TaskHandle_t PeriodicTask::getTaskHandle() { } void PeriodicTask::handleMissedDeadline() { -#ifdef DEBUG - sif::warning << "PeriodicTask: " << pcTaskGetName(NULL) << - " missed deadline!\n" << std::flush; -#endif if(deadlineMissedFunc != nullptr) { this->deadlineMissedFunc(); } diff --git a/osal/FreeRTOS/QueueFactory.cpp b/osal/FreeRTOS/QueueFactory.cpp index cd99afd98..5b3c73dca 100644 --- a/osal/FreeRTOS/QueueFactory.cpp +++ b/osal/FreeRTOS/QueueFactory.cpp @@ -1,3 +1,4 @@ +#include "../../ipc/MessageQueueSenderIF.h" #include "../../ipc/QueueFactory.h" #include "../../osal/FreeRTOS/MessageQueue.h" diff --git a/osal/host/Clock.cpp b/osal/host/Clock.cpp index 41321eeb5..17d98ba88 100644 --- a/osal/host/Clock.cpp +++ b/osal/host/Clock.cpp @@ -106,6 +106,11 @@ ReturnValue_t Clock::getUptime(uint32_t* uptimeMs) { return HasReturnvaluesIF::RETURN_OK; } +uint32_t Clock::getUptimeSeconds() { + timeval uptime = getUptime(); + return uptime.tv_sec; +} + ReturnValue_t Clock::getDateAndTime(TimeOfDay_t* time) { // do some magic with chrono (C++20!) diff --git a/osal/host/FixedTimeslotTask.cpp b/osal/host/FixedTimeslotTask.cpp index 1139badbd..3c31eb760 100644 --- a/osal/host/FixedTimeslotTask.cpp +++ b/osal/host/FixedTimeslotTask.cpp @@ -1,9 +1,7 @@ -#include "../../osal/host/FixedTimeslotTask.h" +#include "FixedTimeslotTask.h" +#include "Mutex.h" #include "../../ipc/MutexFactory.h" -#include "../../osal/host/Mutex.h" -#include "../../osal/host/FixedTimeslotTask.h" - #include "../../serviceinterface/ServiceInterfaceStream.h" #include "../../tasks/ExecutableObjectIF.h" @@ -35,15 +33,15 @@ FixedTimeslotTask::FixedTimeslotTask(const char *name, TaskPriority setPriority, reinterpret_cast(mainThread.native_handle()), ABOVE_NORMAL_PRIORITY_CLASS); if(result != 0) { - sif::error << "FixedTimeslotTask: Windows SetPriorityClass failed with code " - << GetLastError() << std::endl; + sif::error << "FixedTimeslotTask: Windows SetPriorityClass failed with " + << "code " << GetLastError() << std::endl; } result = SetThreadPriority( reinterpret_cast(mainThread.native_handle()), THREAD_PRIORITY_NORMAL); if(result != 0) { - sif::error << "FixedTimeslotTask: Windows SetPriorityClass failed with code " - << GetLastError() << std::endl; + sif::error << "FixedTimeslotTask: Windows SetPriorityClass failed with " + "code " << GetLastError() << std::endl; } #elif defined(LINUX) // we can just copy and paste the code from linux here. @@ -60,7 +58,8 @@ FixedTimeslotTask::~FixedTimeslotTask(void) { } void FixedTimeslotTask::taskEntryPoint(void* argument) { - FixedTimeslotTask *originalTask(reinterpret_cast(argument)); + FixedTimeslotTask *originalTask( + reinterpret_cast(argument)); if (not originalTask->started) { // we have to suspend/block here until the task is started. @@ -90,9 +89,12 @@ ReturnValue_t FixedTimeslotTask::sleepFor(uint32_t ms) { } void FixedTimeslotTask::taskFunctionality() { + pollingSeqTable.intializeSequenceAfterTaskCreation(); + // A local iterator for the Polling Sequence Table is created to // find the start time for the first entry. - FixedSlotSequence::SlotListIter slotListIter = pollingSeqTable.current; + auto slotListIter = pollingSeqTable.current; + // Get start time for first entry. chron_ms interval(slotListIter->pollingTimeMs); auto currentStartTime { @@ -122,8 +124,11 @@ void FixedTimeslotTask::taskFunctionality() { ReturnValue_t FixedTimeslotTask::addSlot(object_id_t componentId, uint32_t slotTimeMs, int8_t executionStep) { - if (objectManager->get(componentId) != nullptr) { - pollingSeqTable.addSlot(componentId, slotTimeMs, executionStep, this); + ExecutableObjectIF* executableObject = objectManager-> + get(componentId); + if (executableObject != nullptr) { + pollingSeqTable.addSlot(componentId, slotTimeMs, executionStep, + executableObject, this); return HasReturnvaluesIF::RETURN_OK; } @@ -132,7 +137,7 @@ ReturnValue_t FixedTimeslotTask::addSlot(object_id_t componentId, return HasReturnvaluesIF::RETURN_FAILED; } -ReturnValue_t FixedTimeslotTask::checkAndInitializeSequence() const { +ReturnValue_t FixedTimeslotTask::checkSequence() const { return pollingSeqTable.checkSequence(); } diff --git a/osal/host/FixedTimeslotTask.h b/osal/host/FixedTimeslotTask.h index 3ea97b977..9985e2ee6 100644 --- a/osal/host/FixedTimeslotTask.h +++ b/osal/host/FixedTimeslotTask.h @@ -61,7 +61,7 @@ public: ReturnValue_t addSlot(object_id_t componentId, uint32_t slotTimeMs, int8_t executionStep); - ReturnValue_t checkAndInitializeSequence() const; + ReturnValue_t checkSequence() const override; uint32_t getPeriodMs() const; diff --git a/osal/host/MessageQueue.cpp b/osal/host/MessageQueue.cpp index 8a34282c9..bced37139 100644 --- a/osal/host/MessageQueue.cpp +++ b/osal/host/MessageQueue.cpp @@ -1,6 +1,7 @@ -#include "../../osal/host/MessageQueue.h" +#include "MessageQueue.h" +#include "QueueMapManager.h" + #include "../../serviceinterface/ServiceInterfaceStream.h" -#include "../../osal/host/QueueMapManager.h" #include "../../ipc/MutexFactory.h" #include "../../ipc/MutexHelper.h" @@ -9,7 +10,8 @@ MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize): queueLock = MutexFactory::instance()->createMutex(); auto result = QueueMapManager::instance()->addMessageQueue(this, &mqId); if(result != HasReturnvaluesIF::RETURN_OK) { - sif::error << "MessageQueue: Could not be created" << std::endl; + sif::error << "MessageQueue::MessageQueue:" + << " Could not be created" << std::endl; } } @@ -61,7 +63,7 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) { } // not sure this will work.. //*message = std::move(messageQueue.front()); - MutexHelper mutexLock(queueLock, 20); + MutexHelper mutexLock(queueLock, MutexIF::TimeoutType::WAITING, 20); MessageQueueMessage* currentMessage = &messageQueue.front(); std::copy(currentMessage->getBuffer(), currentMessage->getBuffer() + messageSize, message->getBuffer()); @@ -126,7 +128,8 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, } if(targetQueue->messageQueue.size() < targetQueue->messageDepth) { - MutexHelper mutexLock(targetQueue->queueLock, 20); + MutexHelper mutexLock(targetQueue->queueLock, + MutexIF::TimeoutType::WAITING, 20); // not ideal, works for now though. MessageQueueMessage* mqmMessage = dynamic_cast(message); @@ -146,8 +149,9 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t MessageQueue::lockQueue(dur_millis_t lockTimeout) { - return queueLock->lockMutex(lockTimeout); +ReturnValue_t MessageQueue::lockQueue(MutexIF::TimeoutType timeoutType, + dur_millis_t lockTimeout) { + return queueLock->lockMutex(timeoutType, lockTimeout); } ReturnValue_t MessageQueue::unlockQueue() { diff --git a/osal/host/MessageQueue.h b/osal/host/MessageQueue.h index 21a016630..97a9e4915 100644 --- a/osal/host/MessageQueue.h +++ b/osal/host/MessageQueue.h @@ -182,7 +182,8 @@ public: bool isDefaultDestinationSet() const override; - ReturnValue_t lockQueue(dur_millis_t lockTimeout); + ReturnValue_t lockQueue(MutexIF::TimeoutType timeoutType, + dur_millis_t lockTimeout); ReturnValue_t unlockQueue(); protected: /** diff --git a/osal/host/Mutex.cpp b/osal/host/Mutex.cpp index 2718f2b99..8471cab80 100644 --- a/osal/host/Mutex.cpp +++ b/osal/host/Mutex.cpp @@ -1,10 +1,9 @@ -#include "../../osal/host/Mutex.h" +#include "Mutex.h" #include "../../serviceinterface/ServiceInterfaceStream.h" -const uint32_t MutexIF::POLLING = 0; -const uint32_t MutexIF::BLOCKING = 0xffffffff; +Mutex::Mutex() {} -ReturnValue_t Mutex::lockMutex(uint32_t timeoutMs) { +ReturnValue_t Mutex::lockMutex(TimeoutType timeoutType, uint32_t timeoutMs) { if(timeoutMs == MutexIF::BLOCKING) { mutex.lock(); locked = true; diff --git a/osal/host/Mutex.h b/osal/host/Mutex.h index 4461e5f2f..af56b8f79 100644 --- a/osal/host/Mutex.h +++ b/osal/host/Mutex.h @@ -1,5 +1,5 @@ -#ifndef FRAMEWORK_OSAL_FREERTOS_MUTEX_H_ -#define FRAMEWORK_OSAL_FREERTOS_MUTEX_H_ +#ifndef FSFW_OSAL_HOST_MUTEX_H_ +#define FSFW_OSAL_HOST_MUTEX_H_ #include "../../ipc/MutexIF.h" @@ -15,8 +15,9 @@ */ class Mutex : public MutexIF { public: - Mutex() = default; - ReturnValue_t lockMutex(uint32_t timeoutMs = MutexIF::BLOCKING) override; + Mutex(); + ReturnValue_t lockMutex(TimeoutType timeoutType = + TimeoutType::BLOCKING, uint32_t timeoutMs = 0) override; ReturnValue_t unlockMutex() override; std::timed_mutex* getMutexHandle(); @@ -25,4 +26,4 @@ private: std::timed_mutex mutex; }; -#endif /* FRAMEWORK_FREERTOS_MUTEX_H_ */ +#endif /* FSFW_OSAL_HOST_MUTEX_H_ */ diff --git a/osal/host/PeriodicTask.cpp b/osal/host/PeriodicTask.cpp index 0b5f8bbe0..f7807a171 100644 --- a/osal/host/PeriodicTask.cpp +++ b/osal/host/PeriodicTask.cpp @@ -1,7 +1,7 @@ -#include "../../ipc/MutexFactory.h" -#include "../../osal/host/Mutex.h" -#include "../../osal/host/PeriodicTask.h" +#include "Mutex.h" +#include "PeriodicTask.h" +#include "../../ipc/MutexFactory.h" #include "../../serviceinterface/ServiceInterfaceStream.h" #include "../../tasks/ExecutableObjectIF.h" @@ -96,18 +96,23 @@ void PeriodicTask::taskFunctionality() { }; auto nextStartTime{ currentStartTime }; + for (const auto& object: objectList) { + object->initializeAfterTaskCreation(); + } + /* Enter the loop that defines the task behavior. */ for (;;) { if(terminateThread.load()) { break; } - for (ObjectList::iterator it = objectList.begin(); - it != objectList.end(); ++it) { - (*it)->performOperation(); + for (const auto& object: objectList) { + object->performOperation(); } if(not delayForInterval(¤tStartTime, periodChrono)) { +#ifdef DEBUG sif::warning << "PeriodicTask: " << taskName << " missed deadline!\n" << std::flush; +#endif if(deadlineMissedFunc != nullptr) { this->deadlineMissedFunc(); } @@ -121,6 +126,7 @@ ReturnValue_t PeriodicTask::addComponent(object_id_t object) { if (newObject == nullptr) { return HasReturnvaluesIF::RETURN_FAILED; } + newObject->setTaskIF(this); objectList.push_back(newObject); return HasReturnvaluesIF::RETURN_OK; } diff --git a/osal/host/QueueFactory.cpp b/osal/host/QueueFactory.cpp index da3fea55a..7feb1ad67 100644 --- a/osal/host/QueueFactory.cpp +++ b/osal/host/QueueFactory.cpp @@ -1,5 +1,6 @@ +#include "MessageQueue.h" #include "../../ipc/QueueFactory.h" -#include "../../osal/host/MessageQueue.h" +#include "../../ipc/MessageQueueSenderIF.h" #include "../../serviceinterface/ServiceInterfaceStream.h" #include diff --git a/osal/host/QueueMapManager.cpp b/osal/host/QueueMapManager.cpp index 47687bc1a..c3d945848 100644 --- a/osal/host/QueueMapManager.cpp +++ b/osal/host/QueueMapManager.cpp @@ -1,6 +1,7 @@ +#include "QueueMapManager.h" + #include "../../ipc/MutexFactory.h" #include "../../ipc/MutexHelper.h" -#include "../../osal/host/QueueMapManager.h" QueueMapManager* QueueMapManager::mqManagerInstance = nullptr; @@ -37,15 +38,23 @@ ReturnValue_t QueueMapManager::addMessageQueue( MessageQueueIF* QueueMapManager::getMessageQueue( MessageQueueId_t messageQueueId) const { - MutexHelper(mapLock, 50); + MutexHelper(mapLock, MutexIF::TimeoutType::WAITING, 50); auto queueIter = queueMap.find(messageQueueId); if(queueIter != queueMap.end()) { return queueIter->second; } else { - sif::warning << "QueueMapManager::getQueueHandle: The ID" << - messageQueueId << " does not exists in the map" << std::endl; - return nullptr; + if(messageQueueId == MessageQueueIF::NO_QUEUE) { + sif::error << "QueueMapManager::getQueueHandle: Configuration" + << " error, NO_QUEUE was passed to this function!" + << std::endl; + } + else { + sif::warning << "QueueMapManager::getQueueHandle: The ID " + << messageQueueId << " does not exists in the map." + << std::endl; + } + return nullptr; } } diff --git a/osal/host/QueueMapManager.h b/osal/host/QueueMapManager.h index 823fd4c2b..d7d5c9154 100644 --- a/osal/host/QueueMapManager.h +++ b/osal/host/QueueMapManager.h @@ -1,5 +1,5 @@ -#ifndef FRAMEWORK_OSAL_HOST_QUEUEMAP_H_ -#define FRAMEWORK_OSAL_HOST_QUEUEMAP_H_ +#ifndef FSFW_OSAL_HOST_QUEUEMAPMANAGER_H_ +#define FSFW_OSAL_HOST_QUEUEMAPMANAGER_H_ #include "../../ipc/MessageQueueSenderIF.h" #include "../../osal/host/MessageQueue.h" @@ -44,4 +44,4 @@ private: -#endif /* FRAMEWORK_OSAL_HOST_QUEUEMAP_H_ */ +#endif /* FSFW_OSAL_HOST_QUEUEMAPMANAGER_H_ */ diff --git a/osal/host/SemaphoreFactory.cpp b/osal/host/SemaphoreFactory.cpp index c354c47cf..b19b2c75a 100644 --- a/osal/host/SemaphoreFactory.cpp +++ b/osal/host/SemaphoreFactory.cpp @@ -3,9 +3,6 @@ #include "../../osal/linux/CountingSemaphore.h" #include "../../serviceinterface/ServiceInterfaceStream.h" -const uint32_t SemaphoreIF::POLLING = 0; -const uint32_t SemaphoreIF::BLOCKING = 0xFFFFFFFF; - SemaphoreFactory* SemaphoreFactory::factoryInstance = nullptr; SemaphoreFactory::SemaphoreFactory() { diff --git a/osal/host/TaskFactory.cpp b/osal/host/TaskFactory.cpp index 37df981a3..bc65504c8 100644 --- a/osal/host/TaskFactory.cpp +++ b/osal/host/TaskFactory.cpp @@ -25,8 +25,6 @@ PeriodicTaskIF* TaskFactory::createPeriodicTask(TaskName name_, TaskPriority taskPriority_,TaskStackSize stackSize_, TaskPeriod periodInSeconds_, TaskDeadlineMissedFunction deadLineMissedFunction_) { - // This is going to be interesting. Time now learn the C++ threading library - // :-) return new PeriodicTask(name_, taskPriority_, stackSize_, periodInSeconds_, deadLineMissedFunction_); } @@ -35,8 +33,6 @@ FixedTimeslotTaskIF* TaskFactory::createFixedTimeslotTask(TaskName name_, TaskPriority taskPriority_,TaskStackSize stackSize_, TaskPeriod periodInSeconds_, TaskDeadlineMissedFunction deadLineMissedFunction_) { - // This is going to be interesting. Time now learn the C++ threading library - // :-) return new FixedTimeslotTask(name_, taskPriority_, stackSize_, periodInSeconds_, deadLineMissedFunction_); } diff --git a/osal/linux/Clock.cpp b/osal/linux/Clock.cpp index 5f764a6fc..468fcb80f 100644 --- a/osal/linux/Clock.cpp +++ b/osal/linux/Clock.cpp @@ -1,3 +1,4 @@ +#include #include "../../serviceinterface/ServiceInterfaceStream.h" #include "../../timemanager/Clock.h" @@ -6,8 +7,8 @@ #include #include #include +#include -//#include uint16_t Clock::leapSeconds = 0; MutexIF* Clock::timeMutex = NULL; @@ -75,24 +76,24 @@ timeval Clock::getUptime() { } ReturnValue_t Clock::getUptime(timeval* uptime) { + //TODO This is not posix compatible and delivers only seconds precision + // Linux specific file read but more precise. + double uptimeSeconds; + if(std::ifstream("/proc/uptime",std::ios::in) >> uptimeSeconds){ + uptime->tv_sec = uptimeSeconds; + uptime->tv_usec = uptimeSeconds *(double) 1e6 - (uptime->tv_sec *1e6); + } + return HasReturnvaluesIF::RETURN_OK; +} + +uint32_t Clock::getUptimeSeconds() { //TODO This is not posix compatible and delivers only seconds precision struct sysinfo sysInfo; int result = sysinfo(&sysInfo); if(result != 0){ return HasReturnvaluesIF::RETURN_FAILED; } - uptime->tv_sec = sysInfo.uptime; - uptime->tv_usec = 0; - - - //Linux specific file read but more precise -// double uptimeSeconds; -// if(std::ifstream("/proc/uptime",std::ios::in) >> uptimeSeconds){ -// uptime->tv_sec = uptimeSeconds; -// uptime->tv_usec = uptimeSeconds *(double) 1e6 - (uptime->tv_sec *1e6); -// } - - return HasReturnvaluesIF::RETURN_OK; + return sysInfo.uptime; } ReturnValue_t Clock::getUptime(uint32_t* uptimeMs) { diff --git a/osal/linux/FixedTimeslotTask.cpp b/osal/linux/FixedTimeslotTask.cpp index b634b4cf7..247a34ed8 100644 --- a/osal/linux/FixedTimeslotTask.cpp +++ b/osal/linux/FixedTimeslotTask.cpp @@ -1,5 +1,5 @@ +#include "FixedTimeslotTask.h" #include "../../serviceinterface/ServiceInterfaceStream.h" -#include "../../osal/linux/FixedTimeslotTask.h" #include @@ -63,6 +63,7 @@ void FixedTimeslotTask::taskFunctionality() { } pst.intializeSequenceAfterTaskCreation(); + //The start time for the first entry is read. uint64_t lastWakeTime = getCurrentMonotonicTimeMs(); uint64_t interval = pst.getIntervalToNextSlotMs(); diff --git a/osal/linux/FixedTimeslotTask.h b/osal/linux/FixedTimeslotTask.h index 0148922dd..5c5c18148 100644 --- a/osal/linux/FixedTimeslotTask.h +++ b/osal/linux/FixedTimeslotTask.h @@ -1,9 +1,9 @@ -#ifndef FRAMEWORK_OSAL_LINUX_FIXEDTIMESLOTTASK_H_ -#define FRAMEWORK_OSAL_LINUX_FIXEDTIMESLOTTASK_H_ +#ifndef FSFW_OSAL_LINUX_FIXEDTIMESLOTTASK_H_ +#define FSFW_OSAL_LINUX_FIXEDTIMESLOTTASK_H_ +#include "PosixThread.h" #include "../../tasks/FixedTimeslotTaskIF.h" #include "../../tasks/FixedSlotSequence.h" -#include "../../osal/linux/PosixThread.h" #include class FixedTimeslotTask: public FixedTimeslotTaskIF, public PosixThread { @@ -74,4 +74,4 @@ private: bool started; }; -#endif /* FRAMEWORK_OSAL_LINUX_FIXEDTIMESLOTTASK_H_ */ +#endif /* FSFW_OSAL_LINUX_FIXEDTIMESLOTTASK_H_ */ diff --git a/osal/linux/MessageQueue.cpp b/osal/linux/MessageQueue.cpp index 872517241..cfadb7931 100644 --- a/osal/linux/MessageQueue.cpp +++ b/osal/linux/MessageQueue.cpp @@ -1,5 +1,6 @@ +#include "MessageQueue.h" #include "../../serviceinterface/ServiceInterfaceStream.h" -#include "../../osal/linux/MessageQueue.h" +#include "../../objectmanager/ObjectManagerIF.h" #include @@ -9,6 +10,7 @@ #include + MessageQueue::MessageQueue(uint32_t messageDepth, size_t maxMessageSize): id(MessageQueueIF::NO_QUEUE),lastPartner(MessageQueueIF::NO_QUEUE), defaultDestination(MessageQueueIF::NO_QUEUE), diff --git a/osal/linux/MessageQueue.h b/osal/linux/MessageQueue.h index c0b770192..239bbbdb5 100644 --- a/osal/linux/MessageQueue.h +++ b/osal/linux/MessageQueue.h @@ -1,5 +1,5 @@ -#ifndef MESSAGEQUEUE_H_ -#define MESSAGEQUEUE_H_ +#ifndef FSFW_OSAL_LINUX_MESSAGEQUEUE_H_ +#define FSFW_OSAL_LINUX_MESSAGEQUEUE_H_ #include "../../internalError/InternalErrorReporterIF.h" #include "../../ipc/MessageQueueIF.h" @@ -184,4 +184,4 @@ private: ReturnValue_t handleError(mq_attr* attributes, uint32_t messageDepth); }; -#endif /* MESSAGEQUEUE_H_ */ +#endif /* FSFW_OSAL_LINUX_MESSAGEQUEUE_H_ */ diff --git a/osal/linux/PeriodicPosixTask.cpp b/osal/linux/PeriodicPosixTask.cpp index bbf33b01d..3c1df6bb1 100644 --- a/osal/linux/PeriodicPosixTask.cpp +++ b/osal/linux/PeriodicPosixTask.cpp @@ -1,8 +1,7 @@ #include "../../tasks/ExecutableObjectIF.h" #include "../../serviceinterface/ServiceInterfaceStream.h" -#include "../../osal/linux/PeriodicPosixTask.h" - #include +#include "PeriodicPosixTask.h" PeriodicPosixTask::PeriodicPosixTask(const char* name_, int priority_, size_t stackSize_, uint32_t period_, void(deadlineMissedFunc_)()): @@ -26,14 +25,14 @@ ReturnValue_t PeriodicPosixTask::addComponent(object_id_t object) { ExecutableObjectIF* newObject = objectManager->get( object); if (newObject == nullptr) { - sif::error << "PeriodicTask::addComponent: Invalid object. Make sure" - "it implements ExecutableObjectIF" << std::endl; + sif::error << "PeriodicTask::addComponent: Invalid object. Make sure" + << " it implements ExecutableObjectIF!" << std::endl; return HasReturnvaluesIF::RETURN_FAILED; } objectList.push_back(newObject); newObject->setTaskIF(this); - return newObject->initializeAfterTaskCreation(); + return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t PeriodicPosixTask::sleepFor(uint32_t ms) { @@ -49,27 +48,31 @@ ReturnValue_t PeriodicPosixTask::startTask(void) { } void PeriodicPosixTask::taskFunctionality(void) { - if(!started){ + if(not started) { suspend(); } + for (auto const &object: objectList) { + object->initializeAfterTaskCreation(); + } + uint64_t lastWakeTime = getCurrentMonotonicTimeMs(); //The task's "infinite" inner loop is entered. while (1) { - for (ObjectList::iterator it = objectList.begin(); - it != objectList.end(); ++it) { - (*it)->performOperation(); + for (auto const &object: objectList) { + object->performOperation(); } - if(!PosixThread::delayUntil(&lastWakeTime,periodMs)){ + + if(not PosixThread::delayUntil(&lastWakeTime, periodMs)){ char name[20] = {0}; - int status = pthread_getname_np(pthread_self(),name,sizeof(name)); - if(status == 0){ - //sif::error << "PeriodicPosixTask " << name << ": Deadline " - // "missed." << std::endl; + int status = pthread_getname_np(pthread_self(), name, sizeof(name)); + if(status == 0) { + sif::error << "PeriodicPosixTask " << name << ": Deadline " + "missed." << std::endl; } else { - //sif::error << "PeriodicPosixTask X: Deadline missed. " << - // status << std::endl; + sif::error << "PeriodicPosixTask X: Deadline missed. " << + status << std::endl; } if (this->deadlineMissedFunc != nullptr) { this->deadlineMissedFunc(); diff --git a/osal/linux/PeriodicPosixTask.h b/osal/linux/PeriodicPosixTask.h index 38825bbf3..ffee236bc 100644 --- a/osal/linux/PeriodicPosixTask.h +++ b/osal/linux/PeriodicPosixTask.h @@ -3,7 +3,7 @@ #include "../../tasks/PeriodicTaskIF.h" #include "../../objectmanager/ObjectManagerIF.h" -#include "../../osal/linux/PosixThread.h" +#include "PosixThread.h" #include "../../tasks/ExecutableObjectIF.h" #include @@ -32,7 +32,7 @@ public: * The address of the task object is passed as an argument * to the system call. */ - ReturnValue_t startTask(void) override; + ReturnValue_t startTask() override; /** * Adds an object to the list of objects to be executed. * The objects are executed in the order added. diff --git a/osal/linux/QueueFactory.cpp b/osal/linux/QueueFactory.cpp index fb8f6df7d..44def48a5 100644 --- a/osal/linux/QueueFactory.cpp +++ b/osal/linux/QueueFactory.cpp @@ -1,8 +1,14 @@ #include "../../ipc/QueueFactory.h" +#include "MessageQueue.h" + +#include "../../ipc/messageQueueDefinitions.h" +#include "../../ipc/MessageQueueSenderIF.h" +#include "../../serviceinterface/ServiceInterfaceStream.h" + #include #include -#include "../../osal/linux/MessageQueue.h" -#include "../../serviceinterface/ServiceInterfaceStream.h" + + #include QueueFactory* QueueFactory::factoryInstance = nullptr; diff --git a/osal/linux/TcUnixUdpPollingTask.cpp b/osal/linux/TcUnixUdpPollingTask.cpp index d8a398699..670ba8044 100644 --- a/osal/linux/TcUnixUdpPollingTask.cpp +++ b/osal/linux/TcUnixUdpPollingTask.cpp @@ -1,4 +1,4 @@ -#include "../../osal/linux/TcUnixUdpPollingTask.h" +#include "TcUnixUdpPollingTask.h" #include "../../globalfunctions/arrayprinter.h" TcUnixUdpPollingTask::TcUnixUdpPollingTask(object_id_t objectId, @@ -120,6 +120,7 @@ void TcUnixUdpPollingTask::setTimeout(double timeoutSeconds) { } } +// TODO: sleep after error detection to prevent spam void TcUnixUdpPollingTask::handleReadError() { switch(errno) { case(EAGAIN): { diff --git a/osal/linux/TmTcUnixUdpBridge.cpp b/osal/linux/TmTcUnixUdpBridge.cpp index 3e9674f3e..b55291b3d 100644 --- a/osal/linux/TmTcUnixUdpBridge.cpp +++ b/osal/linux/TmTcUnixUdpBridge.cpp @@ -1,10 +1,11 @@ -#include "../../osal/linux/TmTcUnixUdpBridge.h" +#include "TmTcUnixUdpBridge.h" #include "../../serviceinterface/ServiceInterfaceStream.h" #include "../../ipc/MutexHelper.h" #include #include + TmTcUnixUdpBridge::TmTcUnixUdpBridge(object_id_t objectId, object_id_t tcDestination, object_id_t tmStoreId, object_id_t tcStoreId, uint16_t serverPort, uint16_t clientPort): @@ -24,7 +25,7 @@ TmTcUnixUdpBridge::TmTcUnixUdpBridge(object_id_t objectId, // Set up UDP socket: https://man7.org/linux/man-pages/man7/ip.7.html //clientSocket = socket(AF_INET, SOCK_DGRAM, 0); serverSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if(socket < 0) { + if(serverSocket < 0) { sif::error << "TmTcUnixUdpBridge::TmTcUnixUdpBridge: Could not open" " UDP socket!" << std::endl; handleSocketError(); @@ -100,8 +101,8 @@ void TmTcUnixUdpBridge::checkAndSetClientAddress(sockaddr_in newAddress) { } } -void TmTcUnixUdpBridge::handleSocketError() { +void TmTcUnixUdpBridge::handleSocketError() { // See: https://man7.org/linux/man-pages/man2/socket.2.html switch(errno) { case(EACCES): @@ -162,7 +163,8 @@ void TmTcUnixUdpBridge::handleBindError() { void TmTcUnixUdpBridge::handleSendError() { switch(errno) { default: - sif::error << "Error: " << strerror(errno) << std::endl; + sif::error << "TmTcUnixBridge::handleSendError: " + << strerror(errno) << std::endl; } } diff --git a/osal/windows/TcWinUdpPollingTask.cpp b/osal/windows/TcWinUdpPollingTask.cpp new file mode 100644 index 000000000..7b54bb2cf --- /dev/null +++ b/osal/windows/TcWinUdpPollingTask.cpp @@ -0,0 +1,148 @@ +#include "TcWinUdpPollingTask.h" +#include "../../globalfunctions/arrayprinter.h" +#include "../../serviceinterface/ServiceInterfaceStream.h" + +#include +#include + +TcWinUdpPollingTask::TcWinUdpPollingTask(object_id_t objectId, + object_id_t tmtcUnixUdpBridge, size_t frameSize, + double timeoutSeconds): SystemObject(objectId), + tmtcBridgeId(tmtcUnixUdpBridge) { + if(frameSize > 0) { + this->frameSize = frameSize; + } + else { + this->frameSize = DEFAULT_MAX_FRAME_SIZE; + } + + // Set up reception buffer with specified frame size. + // For now, it is assumed that only one frame is held in the buffer! + receptionBuffer.reserve(this->frameSize); + receptionBuffer.resize(this->frameSize); + + if(timeoutSeconds == -1) { + receptionTimeout = DEFAULT_TIMEOUT; + } + else { + receptionTimeout = timevalOperations::toTimeval(timeoutSeconds); + } +} + +TcWinUdpPollingTask::~TcWinUdpPollingTask() {} + +ReturnValue_t TcWinUdpPollingTask::performOperation(uint8_t opCode) { + // Poll for new UDP datagrams in permanent loop. + while(true) { + //! Sender Address is cached here. + struct sockaddr_in senderAddress; + int senderAddressSize = sizeof(senderAddress); + ssize_t bytesReceived = recvfrom(serverUdpSocket, + reinterpret_cast(receptionBuffer.data()), frameSize, + receptionFlags, reinterpret_cast(&senderAddress), + &senderAddressSize); + if(bytesReceived == SOCKET_ERROR) { + // handle error + sif::error << "TcWinUdpPollingTask::performOperation: Reception" + " error." << std::endl; + handleReadError(); + continue; + } + //sif::debug << "TcWinUdpPollingTask::performOperation: " << bytesReceived + // << " bytes received" << std::endl; + + ReturnValue_t result = handleSuccessfullTcRead(bytesReceived); + if(result != HasReturnvaluesIF::RETURN_FAILED) { + + } + tmtcBridge->registerCommConnect(); + tmtcBridge->checkAndSetClientAddress(senderAddress); + } + return HasReturnvaluesIF::RETURN_OK; +} + + +ReturnValue_t TcWinUdpPollingTask::handleSuccessfullTcRead(size_t bytesRead) { + store_address_t storeId; + ReturnValue_t result = tcStore->addData(&storeId, + receptionBuffer.data(), bytesRead); + // arrayprinter::print(receptionBuffer.data(), bytesRead); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "TcSerialPollingTask::transferPusToSoftwareBus: Data " + "storage failed" << std::endl; + sif::error << "Packet size: " << bytesRead << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + + TmTcMessage message(storeId); + + result = MessageQueueSenderIF::sendMessage(targetTcDestination, &message); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Serial Polling: Sending message to queue failed" + << std::endl; + tcStore->deleteData(storeId); + } + return result; +} + +ReturnValue_t TcWinUdpPollingTask::initialize() { + tcStore = objectManager->get(objects::TC_STORE); + if (tcStore == nullptr) { + sif::error << "TcSerialPollingTask::initialize: TC Store uninitialized!" + << std::endl; + return ObjectManagerIF::CHILD_INIT_FAILED; + } + + tmtcBridge = objectManager->get(tmtcBridgeId); + if(tmtcBridge == nullptr) { + sif::error << "TcSocketPollingTask::TcSocketPollingTask: Invalid" + " TMTC bridge object!" << std::endl; + return ObjectManagerIF::CHILD_INIT_FAILED; + } + + serverUdpSocket = tmtcBridge->serverSocket; + //sif::info << "TcWinUdpPollingTask::initialize: Server UDP socket " + // << serverUdpSocket << std::endl; + + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t TcWinUdpPollingTask::initializeAfterTaskCreation() { + // Initialize the destination after task creation. This ensures + // that the destination has already been set in the TMTC bridge. + targetTcDestination = tmtcBridge->getRequestQueue(); + return HasReturnvaluesIF::RETURN_OK; +} + +void TcWinUdpPollingTask::setTimeout(double timeoutSeconds) { + DWORD timeoutMs = timeoutSeconds * 1000.0; + int result = setsockopt(serverUdpSocket, SOL_SOCKET, SO_RCVTIMEO, + reinterpret_cast(&timeoutMs), sizeof(DWORD)); + if(result == -1) { + sif::error << "TcSocketPollingTask::TcSocketPollingTask: Setting " + "receive timeout failed with " << strerror(errno) << std::endl; + } +} + +void TcWinUdpPollingTask::handleReadError() { + int error = WSAGetLastError(); + switch(error) { + case(WSANOTINITIALISED): { + sif::info << "TmTcWinUdpBridge::handleReadError: WSANOTINITIALISED: " + << "WSAStartup(...) call " << "necessary" << std::endl; + break; + } + case(WSAEFAULT): { + sif::info << "TmTcWinUdpBridge::handleReadError: WSADEFAULT: " + << "Bad address " << std::endl; + break; + } + default: { + sif::info << "TmTcWinUdpBridge::handleReadError: Error code: " + << error << std::endl; + break; + } + } + // to prevent spam. + Sleep(1000); +} diff --git a/osal/windows/TcWinUdpPollingTask.h b/osal/windows/TcWinUdpPollingTask.h new file mode 100644 index 000000000..50d39d25f --- /dev/null +++ b/osal/windows/TcWinUdpPollingTask.h @@ -0,0 +1,67 @@ +#ifndef FSFW_OSAL_WINDOWS_TCSOCKETPOLLINGTASK_H_ +#define FSFW_OSAL_WINDOWS_TCSOCKETPOLLINGTASK_H_ + +#include "TmTcWinUdpBridge.h" +#include "../../objectmanager/SystemObject.h" +#include "../../tasks/ExecutableObjectIF.h" +#include "../../storagemanager/StorageManagerIF.h" + +#include + +/** + * @brief This class can be used to implement the polling of a Unix socket, + * using UDP for now. + * @details + * The task will be blocked while the specified number of bytes has not been + * received, so TC reception is handled inside a separate task. + * This class caches the IP address of the sender. It is assumed there + * is only one sender for now. + */ +class TcWinUdpPollingTask: public SystemObject, + public ExecutableObjectIF { + friend class TmTcWinUdpBridge; +public: + static constexpr size_t DEFAULT_MAX_FRAME_SIZE = 2048; + //! 0.5 default milliseconds timeout for now. + static constexpr timeval DEFAULT_TIMEOUT = {.tv_sec = 0, .tv_usec = 500}; + + TcWinUdpPollingTask(object_id_t objectId, object_id_t tmtcUnixUdpBridge, + size_t frameSize = 0, double timeoutSeconds = -1); + virtual~ TcWinUdpPollingTask(); + + /** + * Turn on optional timeout for UDP polling. In the default mode, + * the receive function will block until a packet is received. + * @param timeoutSeconds + */ + void setTimeout(double timeoutSeconds); + + virtual ReturnValue_t performOperation(uint8_t opCode) override; + virtual ReturnValue_t initialize() override; + virtual ReturnValue_t initializeAfterTaskCreation() override; + +protected: + StorageManagerIF* tcStore = nullptr; + +private: + //! TMTC bridge is cached. + object_id_t tmtcBridgeId = objects::NO_OBJECT; + TmTcWinUdpBridge* tmtcBridge = nullptr; + MessageQueueId_t targetTcDestination = MessageQueueIF::NO_QUEUE; + //! Reception flags: https://linux.die.net/man/2/recvfrom. + int receptionFlags = 0; + + //! Server socket, which is member of TMTC bridge and is assigned in + //! constructor + SOCKET serverUdpSocket = 0; + + std::vector receptionBuffer; + + size_t frameSize = 0; + timeval receptionTimeout; + + ReturnValue_t handleSuccessfullTcRead(size_t bytesRead); + void handleReadError(); +}; + +#endif /* FRAMEWORK_OSAL_LINUX_TCSOCKETPOLLINGTASK_H_ */ diff --git a/osal/windows/TmTcWinUdpBridge.cpp b/osal/windows/TmTcWinUdpBridge.cpp new file mode 100644 index 000000000..7e283c2a7 --- /dev/null +++ b/osal/windows/TmTcWinUdpBridge.cpp @@ -0,0 +1,176 @@ +#include +#include "TmTcWinUdpBridge.h" + +TmTcWinUdpBridge::TmTcWinUdpBridge(object_id_t objectId, + object_id_t tcDestination, object_id_t tmStoreId, object_id_t tcStoreId, + uint16_t serverPort, uint16_t clientPort): + TmTcBridge(objectId, tcDestination, tmStoreId, tcStoreId) { + mutex = MutexFactory::instance()->createMutex(); + + // Initiates Winsock DLL. + WSAData wsaData; + WORD wVersionRequested = MAKEWORD(2, 2); + int err = WSAStartup(wVersionRequested, &wsaData); + if (err != 0) { + /* Tell the user that we could not find a usable */ + /* Winsock DLL. */ + sif::error << "TmTcWinUdpBridge::TmTcWinUdpBridge:" + "WSAStartup failed with error: " << err << std::endl; + return; + } + + uint16_t setServerPort = DEFAULT_UDP_SERVER_PORT; + if(serverPort != 0xFFFF) { + setServerPort = serverPort; + } + + uint16_t setClientPort = DEFAULT_UDP_CLIENT_PORT; + if(clientPort != 0xFFFF) { + setClientPort = clientPort; + } + + // Set up UDP socket: https://man7.org/linux/man-pages/man7/ip.7.html + //clientSocket = socket(AF_INET, SOCK_DGRAM, 0); + serverSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if(serverSocket == INVALID_SOCKET) { + sif::error << "TmTcWinUdpBridge::TmTcWinUdpBridge: Could not open" + " UDP socket!" << std::endl; + handleSocketError(); + return; + } + + serverAddress.sin_family = AF_INET; + + // Accept packets from any interface. (potentially insecure). + serverAddress.sin_addr.s_addr = htonl(INADDR_ANY); + serverAddress.sin_port = htons(setServerPort); + serverAddressLen = sizeof(serverAddress); + setsockopt(serverSocket, SOL_SOCKET, SO_REUSEADDR, + reinterpret_cast(&serverSocketOptions), + sizeof(serverSocketOptions)); + + clientAddress.sin_family = AF_INET; + clientAddress.sin_addr.s_addr = htonl(INADDR_ANY); + clientAddress.sin_port = htons(setClientPort); + clientAddressLen = sizeof(clientAddress); + + int result = bind(serverSocket, + reinterpret_cast(&serverAddress), + serverAddressLen); + if(result != 0) { + sif::error << "TmTcWinUdpBridge::TmTcWinUdpBridge: Could not bind " + "local port " << setServerPort << " to server socket!" + << std::endl; + handleBindError(); + } +} + +TmTcWinUdpBridge::~TmTcWinUdpBridge() { + WSACleanup(); +} + +ReturnValue_t TmTcWinUdpBridge::sendTm(const uint8_t *data, size_t dataLen) { + int flags = 0; + + //clientAddress.sin_addr.s_addr = htons(INADDR_ANY); + //clientAddressLen = sizeof(serverAddress); + +// char ipAddress [15]; +// sif::debug << "IP Address Sender: "<< inet_ntop(AF_INET, +// &clientAddress.sin_addr.s_addr, ipAddress, 15) << std::endl; + + ssize_t bytesSent = sendto(serverSocket, + reinterpret_cast(data), dataLen, flags, + reinterpret_cast(&clientAddress), clientAddressLen); + if(bytesSent == SOCKET_ERROR) { + sif::error << "TmTcWinUdpBridge::sendTm: Send operation failed." + << std::endl; + handleSendError(); + } +// sif::debug << "TmTcUnixUdpBridge::sendTm: " << bytesSent << " bytes were" +// " sent." << std::endl; + return HasReturnvaluesIF::RETURN_OK; + return HasReturnvaluesIF::RETURN_OK; +} + +void TmTcWinUdpBridge::checkAndSetClientAddress(sockaddr_in newAddress) { + MutexHelper lock(mutex, MutexIF::TimeoutType::WAITING, 10); + +// char ipAddress [15]; +// sif::debug << "IP Address Sender: "<< inet_ntop(AF_INET, +// &newAddress.sin_addr.s_addr, ipAddress, 15) << std::endl; +// sif::debug << "IP Address Old: " << inet_ntop(AF_INET, +// &clientAddress.sin_addr.s_addr, ipAddress, 15) << std::endl; + + // Set new IP address if it has changed. + if(clientAddress.sin_addr.s_addr != newAddress.sin_addr.s_addr) { + clientAddress.sin_addr.s_addr = newAddress.sin_addr.s_addr; + clientAddressLen = sizeof(clientAddress); + } +} + +void TmTcWinUdpBridge::handleSocketError() { + int errCode = WSAGetLastError(); + switch(errCode) { + case(WSANOTINITIALISED): { + sif::info << "TmTcWinUdpBridge::handleSocketError: WSANOTINITIALISED: " + << "WSAStartup(...) call " << "necessary" << std::endl; + break; + } + default: { + /* + https://docs.microsoft.com/en-us/windows/win32/winsock/ + windows-sockets-error-codes-2 + */ + sif::info << "TmTcWinUdpBridge::handleSocketError: Error code: " + << errCode << std::endl; + break; + } + } +} + +void TmTcWinUdpBridge::handleBindError() { + int errCode = WSAGetLastError(); + switch(errCode) { + case(WSANOTINITIALISED): { + sif::info << "TmTcWinUdpBridge::handleBindError: WSANOTINITIALISED: " + << "WSAStartup(...) call " << "necessary" << std::endl; + break; + } + default: { + /* + https://docs.microsoft.com/en-us/windows/win32/winsock/ + windows-sockets-error-codes-2 + */ + sif::info << "TmTcWinUdpBridge::handleBindError: Error code: " + << errCode << std::endl; + break; + } + } +} + +void TmTcWinUdpBridge::handleSendError() { + int errCode = WSAGetLastError(); + switch(errCode) { + case(WSANOTINITIALISED): { + sif::info << "TmTcWinUdpBridge::handleSendError: WSANOTINITIALISED: " + << "WSAStartup(...) call " << "necessary" << std::endl; + break; + } + case(WSAEADDRNOTAVAIL): { + sif::info << "TmTcWinUdpBridge::handleReadError: WSAEADDRNOTAVAIL: " + << "Check target address. " << std::endl; + break; + } + default: { + /* + https://docs.microsoft.com/en-us/windows/win32/winsock/ + windows-sockets-error-codes-2 + */ + sif::info << "TmTcWinUdpBridge::handleSendError: Error code: " + << errCode << std::endl; + break; + } + } +} + diff --git a/osal/windows/TmTcWinUdpBridge.h b/osal/windows/TmTcWinUdpBridge.h new file mode 100644 index 000000000..8188039c0 --- /dev/null +++ b/osal/windows/TmTcWinUdpBridge.h @@ -0,0 +1,49 @@ +#ifndef FSFW_OSAL_WINDOWS_TMTCWINUDPBRIDGE_H_ +#define FSFW_OSAL_WINDOWS_TMTCWINUDPBRIDGE_H_ + +#include "../../tmtcservices/TmTcBridge.h" + +#include +#include + +class TmTcWinUdpBridge: public TmTcBridge { + friend class TcWinUdpPollingTask; +public: + // The ports chosen here should not be used by any other process. + static constexpr uint16_t DEFAULT_UDP_SERVER_PORT = 7301; + static constexpr uint16_t DEFAULT_UDP_CLIENT_PORT = 7302; + + TmTcWinUdpBridge(object_id_t objectId, object_id_t tcDestination, + object_id_t tmStoreId, object_id_t tcStoreId, + uint16_t serverPort = 0xFFFF,uint16_t clientPort = 0xFFFF); + virtual~ TmTcWinUdpBridge(); + + void checkAndSetClientAddress(sockaddr_in clientAddress); + +protected: + virtual ReturnValue_t sendTm(const uint8_t * data, size_t dataLen) override; + +private: + SOCKET serverSocket = 0; + + const int serverSocketOptions = 0; + + struct sockaddr_in clientAddress; + int clientAddressLen = 0; + + struct sockaddr_in serverAddress; + int serverAddressLen = 0; + + //! Access to the client address is mutex protected as it is set + //! by another task. + MutexIF* mutex; + + void handleSocketError(); + void handleBindError(); + void handleSendError(); +}; + + + +#endif /* FSFW_OSAL_HOST_TMTCWINUDPBRIDGE_H_ */ + diff --git a/power/Fuse.cpp b/power/Fuse.cpp index 3ea0b18cc..ace625bfe 100644 --- a/power/Fuse.cpp +++ b/power/Fuse.cpp @@ -1,7 +1,8 @@ +#include "Fuse.h" + #include "../monitoring/LimitViolationReporter.h" #include "../monitoring/MonitoringMessageContent.h" #include "../objectmanager/ObjectManagerIF.h" -#include "../power/Fuse.h" #include "../serialize/SerialFixedArrayListAdapter.h" #include "../ipc/QueueFactory.h" @@ -10,13 +11,16 @@ object_id_t Fuse::powerSwitchId = 0; Fuse::Fuse(object_id_t fuseObjectId, uint8_t fuseId, VariableIds ids, float maxCurrent, uint16_t confirmationCount) : SystemObject(fuseObjectId), oldFuseState(0), fuseId(fuseId), powerIF( - NULL), currentLimit(fuseObjectId, 1, ids.pidCurrent, confirmationCount, - maxCurrent, FUSE_CURRENT_HIGH), powerMonitor(fuseObjectId, 2, - GlobalDataPool::poolIdAndPositionToPid(ids.poolIdPower, 0), - confirmationCount), set(), voltage(ids.pidVoltage, &set), current( - ids.pidCurrent, &set), state(ids.pidState, &set), power( - ids.poolIdPower, &set, PoolVariableIF::VAR_READ_WRITE), commandQueue( - NULL), parameterHelper(this), healthHelper(this, fuseObjectId) { + NULL), + currentLimit(fuseObjectId, 1, ids.pidCurrent, confirmationCount, + maxCurrent, FUSE_CURRENT_HIGH), + powerMonitor(fuseObjectId, 2, + GlobalDataPool::poolIdAndPositionToPid(ids.poolIdPower, 0), + confirmationCount), + set(), voltage(ids.pidVoltage, &set), current(ids.pidCurrent, &set), + state(ids.pidState, &set), + power(ids.poolIdPower, &set, PoolVariableIF::VAR_READ_WRITE), + parameterHelper(this), healthHelper(this, fuseObjectId) { commandQueue = QueueFactory::instance()->createMessageQueue(); } diff --git a/power/Fuse.h b/power/Fuse.h index dd8759f47..13a0eb7c3 100644 --- a/power/Fuse.h +++ b/power/Fuse.h @@ -1,13 +1,14 @@ -#ifndef FUSE_H_ -#define FUSE_H_ +#ifndef FSFW_POWER_FUSE_H_ +#define FSFW_POWER_FUSE_H_ + +#include "PowerComponentIF.h" +#include "PowerSwitchIF.h" #include "../datapoolglob/GlobalDataSet.h" #include "../datapoolglob/GlobalPoolVariable.h" #include "../datapoolglob/PIDReader.h" #include "../devicehandlers/HealthDevice.h" #include "../monitoring/AbsLimitMonitor.h" -#include "../power/PowerComponentIF.h" -#include "../power/PowerSwitchIF.h" #include "../returnvalues/HasReturnvaluesIF.h" #include "../parameters/ParameterHelper.h" #include @@ -90,7 +91,7 @@ private: PIDReader current; PIDReader state; gp_float_t power; - MessageQueueIF* commandQueue; + MessageQueueIF* commandQueue = nullptr; ParameterHelper parameterHelper; HealthHelper healthHelper; static object_id_t powerSwitchId; @@ -103,4 +104,4 @@ private: bool areSwitchesOfComponentOn(DeviceList::iterator iter); }; -#endif /* FUSE_H_ */ +#endif /* FSFW_POWER_FUSE_H_ */ diff --git a/power/PowerComponent.cpp b/power/PowerComponent.cpp index a37970553..4af7c96b5 100644 --- a/power/PowerComponent.cpp +++ b/power/PowerComponent.cpp @@ -1,20 +1,14 @@ -/** - * @file PowerComponent.cpp - * @brief This file defines the PowerComponent class. - * @date 28.08.2014 - * @author baetz - */ +#include "PowerComponent.h" -#include "../power/PowerComponent.h" - -PowerComponent::PowerComponent() : - deviceObjectId(0), switchId1(0xFF), switchId2(0xFF), doIHaveTwoSwitches( - false), min(0.0), max(0.0), moduleId(0) { +PowerComponent::PowerComponent(): switchId1(0xFF), switchId2(0xFF), + doIHaveTwoSwitches(false) { } -PowerComponent::PowerComponent(object_id_t setId, uint8_t moduleId, float min, float max, - uint8_t switchId1, bool twoSwitches, uint8_t switchId2) : - deviceObjectId(setId), switchId1(switchId1), switchId2(switchId2), doIHaveTwoSwitches( - twoSwitches), min(min), max(max), moduleId(moduleId) { + +PowerComponent::PowerComponent(object_id_t setId, uint8_t moduleId, float min, + float max, uint8_t switchId1, bool twoSwitches, uint8_t switchId2) : + deviceObjectId(setId), switchId1(switchId1), switchId2(switchId2), + doIHaveTwoSwitches(twoSwitches), min(min), max(max), + moduleId(moduleId) { } ReturnValue_t PowerComponent::serialize(uint8_t** buffer, size_t* size, diff --git a/power/PowerComponent.h b/power/PowerComponent.h index dc5217be1..c1add3b91 100644 --- a/power/PowerComponent.h +++ b/power/PowerComponent.h @@ -1,13 +1,17 @@ -#ifndef POWERCOMPONENT_H_ -#define POWERCOMPONENT_H_ +#ifndef FSFW_POWER_POWERCOMPONENT_H_ +#define FSFW_POWER_POWERCOMPONENT_H_ +#include "PowerComponentIF.h" + +#include "../objectmanager/frameworkObjects.h" #include "../objectmanager/SystemObjectIF.h" -#include "../power/PowerComponentIF.h" + class PowerComponent: public PowerComponentIF { public: - PowerComponent(object_id_t setId, uint8_t moduleId, float min, float max, uint8_t switchId1, - bool twoSwitches = false, uint8_t switchId2 = 0xFF); + PowerComponent(object_id_t setId, uint8_t moduleId, float min, float max, + uint8_t switchId1, bool twoSwitches = false, + uint8_t switchId2 = 0xFF); virtual object_id_t getDeviceObjectId(); @@ -31,18 +35,18 @@ public: ParameterWrapper *parameterWrapper, const ParameterWrapper *newValues, uint16_t startAtIndex); private: - const object_id_t deviceObjectId; + const object_id_t deviceObjectId = objects::NO_OBJECT; const uint8_t switchId1; const uint8_t switchId2; const bool doIHaveTwoSwitches; - float min; - float max; + float min = 0.0; + float max = 0.0; - uint8_t moduleId; + uint8_t moduleId = 0; PowerComponent(); }; -#endif /* POWERCOMPONENT_H_ */ +#endif /* FSFW_POWER_POWERCOMPONENT_H_ */ diff --git a/power/PowerComponentIF.h b/power/PowerComponentIF.h index c2e3a6a56..f35b4d1d3 100644 --- a/power/PowerComponentIF.h +++ b/power/PowerComponentIF.h @@ -1,24 +1,23 @@ -#ifndef POWERCOMPONENTIF_H_ -#define POWERCOMPONENTIF_H_ +#ifndef FSFW_POWER_POWERCOMPONENTIF_H_ +#define FSFW_POWER_POWERCOMPONENTIF_H_ #include "../serialize/SerializeIF.h" #include "../parameters/HasParametersIF.h" +#include "../objectmanager/SystemObjectIF.h" class PowerComponentIF : public SerializeIF, public HasParametersIF { public: - virtual ~PowerComponentIF() { + virtual ~PowerComponentIF() {} - } + virtual object_id_t getDeviceObjectId() = 0; - virtual object_id_t getDeviceObjectId()=0; - - virtual uint8_t getSwitchId1()=0; - virtual uint8_t getSwitchId2()=0; - virtual bool hasTwoSwitches()=0; + virtual uint8_t getSwitchId1() = 0; + virtual uint8_t getSwitchId2() = 0; + virtual bool hasTwoSwitches() = 0; virtual float getMin() = 0; virtual float getMax() = 0; }; -#endif /* POWERCOMPONENTIF_H_ */ +#endif /* FSFW_POWER_POWERCOMPONENTIF_H_ */ diff --git a/power/PowerSensor.cpp b/power/PowerSensor.cpp index df26fb8e3..739d02f26 100644 --- a/power/PowerSensor.cpp +++ b/power/PowerSensor.cpp @@ -1,14 +1,16 @@ -#include "../power/PowerSensor.h" +#include "PowerSensor.h" + #include "../ipc/QueueFactory.h" PowerSensor::PowerSensor(object_id_t setId, VariableIds ids, DefaultLimits limits, SensorEvents events, uint16_t confirmationCount) : - SystemObject(setId), commandQueue(NULL), parameterHelper(this), healthHelper(this, setId), set(), current( - ids.pidCurrent, &set), voltage(ids.pidVoltage, &set), power( - ids.poolIdPower, &set, PoolVariableIF::VAR_WRITE), currentLimit( - setId, MODULE_ID_CURRENT, ids.pidCurrent, confirmationCount, + SystemObject(setId), parameterHelper(this), healthHelper(this, setId), + set(), current(ids.pidCurrent, &set), voltage(ids.pidVoltage, &set), + power(ids.poolIdPower, &set, PoolVariableIF::VAR_WRITE), + currentLimit(setId, MODULE_ID_CURRENT, ids.pidCurrent, confirmationCount, limits.currentMin, limits.currentMax, events.currentLow, - events.currentHigh), voltageLimit(setId, MODULE_ID_VOLTAGE, + events.currentHigh), + voltageLimit(setId, MODULE_ID_VOLTAGE, ids.pidVoltage, confirmationCount, limits.voltageMin, limits.voltageMax, events.voltageLow, events.voltageHigh) { commandQueue = QueueFactory::instance()->createMessageQueue(); diff --git a/power/PowerSensor.h b/power/PowerSensor.h index da0bd8c73..20ebff397 100644 --- a/power/PowerSensor.h +++ b/power/PowerSensor.h @@ -1,5 +1,5 @@ -#ifndef POWERSENSOR_H_ -#define POWERSENSOR_H_ +#ifndef FSFW_POWER_POWERSENSOR_H_ +#define FSFW_POWER_POWERSENSOR_H_ #include "../datapoolglob/GlobalDataSet.h" #include "../datapoolglob/GlobalPoolVariable.h" @@ -50,7 +50,7 @@ public: ParameterWrapper *parameterWrapper, const ParameterWrapper *newValues, uint16_t startAtIndex); private: - MessageQueueIF* commandQueue; + MessageQueueIF* commandQueue = nullptr; ParameterHelper parameterHelper; HealthHelper healthHelper; GlobDataSet set; @@ -68,4 +68,4 @@ protected: LimitMonitor voltageLimit; }; -#endif /* POWERSENSOR_H_ */ +#endif /* FSFW_POWER_POWERSENSOR_H_ */ diff --git a/power/PowerSwitchIF.h b/power/PowerSwitchIF.h index 876a82c59..1422baebc 100644 --- a/power/PowerSwitchIF.h +++ b/power/PowerSwitchIF.h @@ -1,22 +1,15 @@ -/** - * @file PowerSwitchIF.h - * @brief This file defines the PowerSwitchIF class. - * @date 20.03.2013 - * @author baetz - */ - -#ifndef POWERSWITCHIF_H_ -#define POWERSWITCHIF_H_ +#ifndef FSFW_POWER_POWERSWITCHIF_H_ +#define FSFW_POWER_POWERSWITCHIF_H_ #include "../events/Event.h" #include "../returnvalues/HasReturnvaluesIF.h" /** * - * @brief This interface defines a connection to a device that is capable of turning on and off - * switches of devices identified by a switch ID. - * @details The virtual functions of this interface do not allow to make any assignments - * because they can be called asynchronosuly (const ending). - * + * @brief This interface defines a connection to a device that is capable of + * turning on and off switches of devices identified by a switch ID. + * @details + * The virtual functions of this interface do not allow to make any assignments + * because they can be called asynchronosuly (const ending). * @ingroup interfaces */ class PowerSwitchIF : public HasReturnvaluesIF { @@ -77,4 +70,4 @@ public: }; -#endif /* POWERSWITCHIF_H_ */ +#endif /* FSFW_POWER_POWERSWITCHIF_H_ */ diff --git a/power/PowerSwitcher.cpp b/power/PowerSwitcher.cpp index 1844a11af..ed37998ec 100644 --- a/power/PowerSwitcher.cpp +++ b/power/PowerSwitcher.cpp @@ -1,15 +1,17 @@ +#include "PowerSwitcher.h" + #include "../objectmanager/ObjectManagerIF.h" -#include "../power/PowerSwitcher.h" #include "../serviceinterface/ServiceInterfaceStream.h" PowerSwitcher::PowerSwitcher(uint8_t setSwitch1, uint8_t setSwitch2, - PowerSwitcher::State_t setStartState) : - state(setStartState), firstSwitch(setSwitch1), secondSwitch(setSwitch2), power(NULL) { + PowerSwitcher::State_t setStartState): + state(setStartState), firstSwitch(setSwitch1), + secondSwitch(setSwitch2) { } ReturnValue_t PowerSwitcher::initialize(object_id_t powerSwitchId) { power = objectManager->get(powerSwitchId); - if (power == NULL) { + if (power == nullptr) { return HasReturnvaluesIF::RETURN_FAILED; } return HasReturnvaluesIF::RETURN_OK; @@ -17,19 +19,25 @@ ReturnValue_t PowerSwitcher::initialize(object_id_t powerSwitchId) { ReturnValue_t PowerSwitcher::getStateOfSwitches() { SwitchReturn_t result = howManySwitches(); + switch (result) { case ONE_SWITCH: return power->getSwitchState(firstSwitch); - case TWO_SWITCHES: - if ((power->getSwitchState(firstSwitch) == PowerSwitchIF::SWITCH_ON) - && (power->getSwitchState(secondSwitch) == PowerSwitchIF::SWITCH_ON)) { + case TWO_SWITCHES: { + ReturnValue_t firstSwitchState = power->getSwitchState(firstSwitch); + ReturnValue_t secondSwitchState = power->getSwitchState(firstSwitch); + if ((firstSwitchState == PowerSwitchIF::SWITCH_ON) + && (secondSwitchState == PowerSwitchIF::SWITCH_ON)) { return PowerSwitchIF::SWITCH_ON; - } else if ((power->getSwitchState(firstSwitch) == PowerSwitchIF::SWITCH_OFF) - && (power->getSwitchState(secondSwitch) == PowerSwitchIF::SWITCH_OFF)) { + } + else if ((firstSwitchState == PowerSwitchIF::SWITCH_OFF) + && (secondSwitchState == PowerSwitchIF::SWITCH_OFF)) { return PowerSwitchIF::SWITCH_OFF; - } else { + } + else { return HasReturnvaluesIF::RETURN_FAILED; } + } default: return HasReturnvaluesIF::RETURN_FAILED; } diff --git a/power/PowerSwitcher.h b/power/PowerSwitcher.h index 515ce0428..f4e2138d4 100644 --- a/power/PowerSwitcher.h +++ b/power/PowerSwitcher.h @@ -1,10 +1,13 @@ -#ifndef POWERSWITCHER_H_ -#define POWERSWITCHER_H_ -#include "../power/PowerSwitchIF.h" +#ifndef FSFW_POWER_POWERSWITCHER_H_ +#define FSFW_POWER_POWERSWITCHER_H_ + +#include "PowerSwitchIF.h" + +#include "../objectmanager/SystemObjectIF.h" #include "../returnvalues/HasReturnvaluesIF.h" #include "../timemanager/Countdown.h" -class PowerSwitcher : public HasReturnvaluesIF { +class PowerSwitcher: public HasReturnvaluesIF { public: enum State_t { WAIT_OFF, @@ -16,7 +19,8 @@ public: static const uint8_t INTERFACE_ID = CLASS_ID::POWER_SWITCHER; static const ReturnValue_t IN_POWER_TRANSITION = MAKE_RETURN_CODE(1); static const ReturnValue_t SWITCH_STATE_MISMATCH = MAKE_RETURN_CODE(2); - PowerSwitcher( uint8_t setSwitch1, uint8_t setSwitch2 = NO_SWITCH, State_t setStartState = SWITCH_IS_OFF ); + PowerSwitcher( uint8_t setSwitch1, uint8_t setSwitch2 = NO_SWITCH, + State_t setStartState = SWITCH_IS_OFF ); ReturnValue_t initialize(object_id_t powerSwitchId); void turnOn(); void turnOff(); @@ -29,7 +33,8 @@ public: private: uint8_t firstSwitch; uint8_t secondSwitch; - PowerSwitchIF* power; + PowerSwitchIF* power = nullptr; + static const uint8_t NO_SWITCH = 0xFF; enum SwitchReturn_t { ONE_SWITCH = 1, @@ -42,4 +47,4 @@ private: -#endif /* POWERSWITCHER_H_ */ +#endif /* FSFW_POWER_POWERSWITCHER_H_ */ diff --git a/pus/CService200ModeCommanding.cpp b/pus/CService200ModeCommanding.cpp index dda58e038..c4e99359b 100644 --- a/pus/CService200ModeCommanding.cpp +++ b/pus/CService200ModeCommanding.cpp @@ -1,5 +1,5 @@ -#include "../pus/CService200ModeCommanding.h" -#include "../pus/servicepackets/Service200Packets.h" +#include "CService200ModeCommanding.h" +#include "servicepackets/Service200Packets.h" #include "../modes/HasModesIF.h" #include "../serviceinterface/ServiceInterfaceStream.h" @@ -7,9 +7,10 @@ #include "../modes/ModeMessage.h" CService200ModeCommanding::CService200ModeCommanding(object_id_t objectId, - uint16_t apid, uint8_t serviceId): + uint16_t apid, uint8_t serviceId, uint8_t numParallelCommands, + uint16_t commandTimeoutSeconds): CommandingServiceBase(objectId, apid, serviceId, - NUMBER_OF_PARALLEL_COMMANDS,COMMAND_TIMEOUT_SECONDS) {} + numParallelCommands, commandTimeoutSeconds) {} CService200ModeCommanding::~CService200ModeCommanding() {} @@ -107,13 +108,23 @@ ReturnValue_t CService200ModeCommanding::prepareWrongModeReply( const CommandMessage *reply, object_id_t objectId) { ModePacket wrongModeReply(objectId, ModeMessage::getMode(reply), ModeMessage::getSubmode(reply)); - return sendTmPacket(Subservice::REPLY_WRONG_MODE_REPLY, &wrongModeReply); + ReturnValue_t result = sendTmPacket(Subservice::REPLY_WRONG_MODE_REPLY, &wrongModeReply); + if(result == RETURN_OK){ + // We want to produce an error here in any case because the mode was not correct + return RETURN_FAILED; + } + return result; } ReturnValue_t CService200ModeCommanding::prepareCantReachModeReply( const CommandMessage *reply, object_id_t objectId) { CantReachModePacket cantReachModePacket(objectId, ModeMessage::getCantReachModeReason(reply)); - return sendTmPacket(Subservice::REPLY_CANT_REACH_MODE, + ReturnValue_t result = sendTmPacket(Subservice::REPLY_CANT_REACH_MODE, &cantReachModePacket); + if(result == RETURN_OK){ + // We want to produce an error here in any case because the mode was not reached + return RETURN_FAILED; + } + return result; } diff --git a/pus/CService200ModeCommanding.h b/pus/CService200ModeCommanding.h index 89347dbd8..840402120 100644 --- a/pus/CService200ModeCommanding.h +++ b/pus/CService200ModeCommanding.h @@ -1,5 +1,5 @@ -#ifndef FRAMEWORK_PUS_CSERVICE200MODECOMMANDING_H_ -#define FRAMEWORK_PUS_CSERVICE200MODECOMMANDING_H_ +#ifndef FSFW_PUS_CSERVICE200MODECOMMANDING_H_ +#define FSFW_PUS_CSERVICE200MODECOMMANDING_H_ #include "../tmtcservices/CommandingServiceBase.h" @@ -15,11 +15,10 @@ */ class CService200ModeCommanding: public CommandingServiceBase { public: - static constexpr uint8_t NUMBER_OF_PARALLEL_COMMANDS = 4; - static constexpr uint16_t COMMAND_TIMEOUT_SECONDS = 60; CService200ModeCommanding(object_id_t objectId, - uint16_t apid, uint8_t serviceId); + uint16_t apid, uint8_t serviceId, uint8_t numParallelCommands = 4, + uint16_t commandTimeoutSeconds = 60); virtual~ CService200ModeCommanding(); protected: @@ -82,4 +81,4 @@ private: }; }; -#endif /* FRAMEWORK_PUS_CSERVICE200MODECOMMANDING_H_ */ +#endif /* FSFW_PUS_CSERVICE200MODECOMMANDING_H_ */ diff --git a/pus/CService201HealthCommanding.cpp b/pus/CService201HealthCommanding.cpp index cc5dd640c..db43db898 100644 --- a/pus/CService201HealthCommanding.cpp +++ b/pus/CService201HealthCommanding.cpp @@ -6,9 +6,10 @@ #include "servicepackets/Service201Packets.h" CService201HealthCommanding::CService201HealthCommanding(object_id_t objectId, - uint16_t apid, uint8_t serviceId): - CommandingServiceBase(objectId, apid, serviceId, - NUMBER_OF_PARALLEL_COMMANDS,COMMAND_TIMEOUT_SECONDS) { + uint16_t apid, uint8_t serviceId, uint8_t numParallelCommands, + uint16_t commandTimeoutSeconds): + CommandingServiceBase(objectId, apid, serviceId, + numParallelCommands, commandTimeoutSeconds) { } CService201HealthCommanding::~CService201HealthCommanding() { @@ -17,6 +18,8 @@ CService201HealthCommanding::~CService201HealthCommanding() { ReturnValue_t CService201HealthCommanding::isValidSubservice(uint8_t subservice) { switch(subservice) { case(Subservice::COMMAND_SET_HEALTH): + case(Subservice::COMMAND_ANNOUNCE_HEALTH): + case(Subservice::COMMAND_ANNOUNCE_HEALTH_ALL): return RETURN_OK; default: sif::error << "Invalid Subservice" << std::endl; @@ -47,19 +50,34 @@ ReturnValue_t CService201HealthCommanding::checkInterfaceAndAcquireMessageQueue( return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t CService201HealthCommanding::prepareCommand - (CommandMessage* message, uint8_t subservice, const uint8_t *tcData, +ReturnValue_t CService201HealthCommanding::prepareCommand( + CommandMessage* message, uint8_t subservice, const uint8_t *tcData, size_t tcDataLen, uint32_t *state, object_id_t objectId) { - HealthCommand healthCommand; - ReturnValue_t result = healthCommand.deSerialize(&tcData, &tcDataLen, - SerializeIF::Endianness::BIG); - if (result != RETURN_OK) { - return result; - } else { - HealthMessage::setHealthMessage(dynamic_cast(message), - HealthMessage::HEALTH_SET, healthCommand.getHealth()); - return result; - } + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + switch(subservice) { + case(Subservice::COMMAND_SET_HEALTH): { + HealthSetCommand healthCommand; + result = healthCommand.deSerialize(&tcData, &tcDataLen, + SerializeIF::Endianness::BIG); + if (result != RETURN_OK) { + break; + } + HealthMessage::setHealthMessage(message, HealthMessage::HEALTH_SET, + healthCommand.getHealth()); + break; + } + case(Subservice::COMMAND_ANNOUNCE_HEALTH): { + HealthMessage::setHealthMessage(message, + HealthMessage::HEALTH_ANNOUNCE); + break; + } + case(Subservice::COMMAND_ANNOUNCE_HEALTH_ALL): { + HealthMessage::setHealthMessage(message, + HealthMessage::HEALTH_ANNOUNCE_ALL); + break; + } + } + return result; } ReturnValue_t CService201HealthCommanding::handleReply @@ -68,17 +86,17 @@ ReturnValue_t CService201HealthCommanding::handleReply object_id_t objectId, bool *isStep) { Command_t replyId = reply->getCommand(); if (replyId == HealthMessage::REPLY_HEALTH_SET) { - prepareHealthSetReply(reply); + return prepareHealthSetReply(reply); } - return RETURN_OK; + return CommandingServiceBase::INVALID_REPLY; } -void CService201HealthCommanding::prepareHealthSetReply( +ReturnValue_t CService201HealthCommanding::prepareHealthSetReply( const CommandMessage* reply) { prepareHealthSetReply(reply); uint8_t health = static_cast(HealthMessage::getHealth(reply)); uint8_t oldHealth = static_cast(HealthMessage::getOldHealth(reply)); HealthSetReply healthSetReply(health, oldHealth); - sendTmPacket(Subservice::REPLY_HEALTH_SET,&healthSetReply); + return sendTmPacket(Subservice::REPLY_HEALTH_SET, &healthSetReply); } diff --git a/pus/CService201HealthCommanding.h b/pus/CService201HealthCommanding.h index 100f675e2..124e2ac79 100644 --- a/pus/CService201HealthCommanding.h +++ b/pus/CService201HealthCommanding.h @@ -19,11 +19,10 @@ */ class CService201HealthCommanding: public CommandingServiceBase { public: - static const uint8_t NUMBER_OF_PARALLEL_COMMANDS = 4; - static const uint16_t COMMAND_TIMEOUT_SECONDS = 60; CService201HealthCommanding(object_id_t objectId, uint16_t apid, - uint8_t serviceId); + uint8_t serviceId, uint8_t numParallelCommands = 4, + uint16_t commandTimeoutSeconds = 60); virtual~ CService201HealthCommanding(); protected: /* CSB abstract function implementations */ @@ -47,11 +46,17 @@ private: ReturnValue_t checkInterfaceAndAcquireMessageQueue( MessageQueueId_t* MessageQueueToSet, object_id_t* objectId); - void prepareHealthSetReply(const CommandMessage *reply); + ReturnValue_t prepareHealthSetReply(const CommandMessage *reply); enum Subservice { - COMMAND_SET_HEALTH = 1, //!< [EXPORT] : [TC] Set health of target object - REPLY_HEALTH_SET = 2 //!< [EXPORT] : [TM] Reply to health set command which also provides old health + //! [EXPORT] : [TC] Set health of target object + COMMAND_SET_HEALTH = 1, + //! [EXPORT] : [TM] Reply to health set command which also provides old health + REPLY_HEALTH_SET = 2, + //! [EXPORT] : [TC] Commands object to announce their health as an event + COMMAND_ANNOUNCE_HEALTH = 3, + //! [EXPORT] : [TC] Commands all objects in the health map to announce their health + COMMAND_ANNOUNCE_HEALTH_ALL = 4 }; }; diff --git a/pus/Service17Test.h b/pus/Service17Test.h index 8d6a43770..e26818659 100644 --- a/pus/Service17Test.h +++ b/pus/Service17Test.h @@ -1,5 +1,5 @@ -#ifndef MISSION_PUS_SERVICE17TEST_H_ -#define MISSION_PUS_SERVICE17TEST_H_ +#ifndef FSFW_PUS_SERVICE17TEST_H_ +#define FSFW_PUS_SERVICE17TEST_H_ #include "../tmtcservices/PusServiceBase.h" #include "../objectmanager/SystemObject.h" @@ -41,4 +41,4 @@ protected: uint16_t packetSubCounter = 0; }; -#endif /* MISSION_PUS_SERVICE17TEST_H_ */ +#endif /* FSFW_PUS_SERVICE17TEST_H_ */ diff --git a/pus/Service1TelecommandVerification.cpp b/pus/Service1TelecommandVerification.cpp index 9b17eba58..86b0dcded 100644 --- a/pus/Service1TelecommandVerification.cpp +++ b/pus/Service1TelecommandVerification.cpp @@ -1,20 +1,18 @@ -#include "../pus/Service1TelecommandVerification.h" -#include "../pus/servicepackets/Service1Packets.h" +#include "Service1TelecommandVerification.h" +#include "servicepackets/Service1Packets.h" #include "../ipc/QueueFactory.h" #include "../tmtcservices/PusVerificationReport.h" #include "../tmtcpacket/pus/TmPacketStored.h" #include "../serviceinterface/ServiceInterfaceStream.h" #include "../tmtcservices/AcceptsTelemetryIF.h" -#include "../serviceinterface/ServiceInterfaceStream.h" - Service1TelecommandVerification::Service1TelecommandVerification( object_id_t objectId, uint16_t apid, uint8_t serviceId, - object_id_t targetDestination): + object_id_t targetDestination, uint16_t messageQueueDepth): SystemObject(objectId), apid(apid), serviceId(serviceId), targetDestination(targetDestination) { - tmQueue = QueueFactory::instance()->createMessageQueue(); + tmQueue = QueueFactory::instance()->createMessageQueue(messageQueueDepth); } Service1TelecommandVerification::~Service1TelecommandVerification() {} diff --git a/pus/Service1TelecommandVerification.h b/pus/Service1TelecommandVerification.h index 37562d1c9..3d68a4e06 100644 --- a/pus/Service1TelecommandVerification.h +++ b/pus/Service1TelecommandVerification.h @@ -1,5 +1,5 @@ -#ifndef MISSION_PUS_SERVICE1TELECOMMANDVERIFICATION_H_ -#define MISSION_PUS_SERVICE1TELECOMMANDVERIFICATION_H_ +#ifndef FSFW_PUS_SERVICE1TELECOMMANDVERIFICATION_H_ +#define FSFW_PUS_SERVICE1TELECOMMANDVERIFICATION_H_ #include "../objectmanager/SystemObject.h" #include "../returnvalues/HasReturnvaluesIF.h" @@ -44,14 +44,15 @@ public: static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PUS_SERVICE_1; Service1TelecommandVerification(object_id_t objectId, - uint16_t apid, uint8_t serviceId, object_id_t targetDestination); + uint16_t apid, uint8_t serviceId, object_id_t targetDestination, + uint16_t messageQueueDepth); virtual ~Service1TelecommandVerification(); /** * * @return ID of Verification Queue */ - virtual MessageQueueId_t getVerificationQueue(); + virtual MessageQueueId_t getVerificationQueue() override; /** * Performs the service periodically as specified in init_mission(). @@ -91,4 +92,4 @@ private: }; }; -#endif /* MISSION_PUS_SERVICE1TELECOMMANDVERIFICATION_H_ */ +#endif /* FSFW_PUS_SERVICE1TELECOMMANDVERIFICATION_H_ */ diff --git a/pus/Service2DeviceAccess.cpp b/pus/Service2DeviceAccess.cpp index 9529c675e..3648b7eb6 100644 --- a/pus/Service2DeviceAccess.cpp +++ b/pus/Service2DeviceAccess.cpp @@ -1,5 +1,5 @@ -#include "../pus/Service2DeviceAccess.h" -#include "../pus/servicepackets/Service2Packets.h" +#include "Service2DeviceAccess.h" +#include "servicepackets/Service2Packets.h" #include "../devicehandlers/DeviceHandlerIF.h" #include "../storagemanager/StorageManagerIF.h" @@ -21,8 +21,8 @@ Service2DeviceAccess::~Service2DeviceAccess() {} ReturnValue_t Service2DeviceAccess::isValidSubservice(uint8_t subservice) { switch(static_cast(subservice)){ - case Subservice::RAW_COMMANDING: - case Subservice::TOGGLE_WIRETAPPING: + case Subservice::COMMAND_RAW_COMMANDING: + case Subservice::COMMAND_TOGGLE_WIRETAPPING: return HasReturnvaluesIF::RETURN_OK; default: sif::error << "Invalid Subservice" << std::endl; @@ -39,8 +39,7 @@ ReturnValue_t Service2DeviceAccess::getMessageQueueAndObject( SerializeAdapter::deSerialize(objectId, &tcData, &tcDataLen, SerializeIF::Endianness::BIG); - ReturnValue_t result = checkInterfaceAndAcquireMessageQueue(id,objectId); - return result; + return checkInterfaceAndAcquireMessageQueue(id,objectId); } ReturnValue_t Service2DeviceAccess::checkInterfaceAndAcquireMessageQueue( @@ -59,11 +58,11 @@ ReturnValue_t Service2DeviceAccess::prepareCommand(CommandMessage* message, uint8_t subservice, const uint8_t* tcData, size_t tcDataLen, uint32_t* state, object_id_t objectId) { switch(static_cast(subservice)){ - case Subservice::RAW_COMMANDING: { + case Subservice::COMMAND_RAW_COMMANDING: { return prepareRawCommand(message, tcData, tcDataLen); } break; - case Subservice::TOGGLE_WIRETAPPING: { + case Subservice::COMMAND_TOGGLE_WIRETAPPING: { return prepareWiretappingCommand(message, tcData, tcDataLen); } break; @@ -119,11 +118,11 @@ void Service2DeviceAccess::handleUnrequestedReply(CommandMessage* reply) { switch(reply->getCommand()) { case DeviceHandlerMessage::REPLY_RAW_COMMAND: sendWiretappingTm(reply, - static_cast(Subservice::WIRETAPPING_RAW_TC)); + static_cast(Subservice::REPLY_WIRETAPPING_RAW_TC)); break; case DeviceHandlerMessage::REPLY_RAW_REPLY: sendWiretappingTm(reply, - static_cast(Subservice::RAW_REPLY)); + static_cast(Subservice::REPLY_RAW)); break; default: sif::error << "Unknown message in Service2DeviceAccess::" diff --git a/pus/Service2DeviceAccess.h b/pus/Service2DeviceAccess.h index f6aa8b521..b62e6854a 100644 --- a/pus/Service2DeviceAccess.h +++ b/pus/Service2DeviceAccess.h @@ -1,5 +1,5 @@ -#ifndef FRAMEWORK_PUS_SERVICE2DEVICEACCESS_H_ -#define FRAMEWORK_PUS_SERVICE2DEVICEACCESS_H_ +#ifndef FSFW_PUS_SERVICE2DEVICEACCESS_H_ +#define FSFW_PUS_SERVICE2DEVICEACCESS_H_ #include "../objectmanager/SystemObjectIF.h" #include "../devicehandlers/AcceptsDeviceResponsesIF.h" @@ -81,12 +81,16 @@ private: const uint8_t* tcData, size_t tcDataLen); enum class Subservice { - RAW_COMMANDING = 128, //!< [EXPORT] : [COMMAND] Command in device native protocol - TOGGLE_WIRETAPPING = 129, //!< [EXPORT] : [COMMAND] Toggle wiretapping of raw communication - RAW_REPLY = 130, //!< [EXPORT] : [REPLY] Includes wiretapping TM and normal TM raw replies from device - WIRETAPPING_RAW_TC = 131 //!< [EXPORT] : [REPLY] Wiretapping packets of commands built by device handler + //!< [EXPORT] : [COMMAND] Command in device native protocol + COMMAND_RAW_COMMANDING = 128, + //!< [EXPORT] : [COMMAND] Toggle wiretapping of raw communication + COMMAND_TOGGLE_WIRETAPPING = 129, + //!< [EXPORT] : [REPLY] Includes wiretapping TM and normal TM raw replies from device + REPLY_RAW = 130, + //!< [EXPORT] : [REPLY] Wiretapping packets of commands built by device handler + REPLY_WIRETAPPING_RAW_TC = 131 }; }; -#endif /* MISSION_PUS_DEVICE2DEVICECOMMANDING_H_ */ +#endif /* FSFW_PUS_DEVICE2DEVICECOMMANDING_H_ */ diff --git a/pus/Service3Housekeeping.cpp b/pus/Service3Housekeeping.cpp new file mode 100644 index 000000000..3f41f541f --- /dev/null +++ b/pus/Service3Housekeeping.cpp @@ -0,0 +1,294 @@ +#include "Service3Housekeeping.h" +#include "servicepackets/Service3Packets.h" +#include "../datapoollocal/HasLocalDataPoolIF.h" + + +Service3Housekeeping::Service3Housekeeping(object_id_t objectId, uint16_t apid, + uint8_t serviceId): + CommandingServiceBase(objectId, apid, serviceId, + NUM_OF_PARALLEL_COMMANDS, COMMAND_TIMEOUT_SECONDS) {} + +Service3Housekeeping::~Service3Housekeeping() {} + +ReturnValue_t Service3Housekeeping::isValidSubservice(uint8_t subservice) { + switch(static_cast(subservice)) { + case Subservice::ENABLE_PERIODIC_HK_REPORT_GENERATION: + case Subservice::DISABLE_PERIODIC_HK_REPORT_GENERATION: + case Subservice::ENABLE_PERIODIC_DIAGNOSTICS_REPORT_GENERATION: + case Subservice::DISABLE_PERIODIC_DIAGNOSTICS_REPORT_GENERATION: + case Subservice::REPORT_HK_REPORT_STRUCTURES: + case Subservice::REPORT_DIAGNOSTICS_REPORT_STRUCTURES : + case Subservice::GENERATE_ONE_PARAMETER_REPORT: + case Subservice::GENERATE_ONE_DIAGNOSTICS_REPORT: + case Subservice::MODIFY_PARAMETER_REPORT_COLLECTION_INTERVAL: + case Subservice::MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL: + return HasReturnvaluesIF::RETURN_OK; + // Telemetry or invalid subservice. + case Subservice::HK_DEFINITIONS_REPORT: + case Subservice::DIAGNOSTICS_DEFINITION_REPORT: + case Subservice::HK_REPORT: + case Subservice::DIAGNOSTICS_REPORT: + default: + return AcceptsTelecommandsIF::INVALID_SUBSERVICE; + } +} + +ReturnValue_t Service3Housekeeping::getMessageQueueAndObject(uint8_t subservice, + const uint8_t *tcData, size_t tcDataLen, + MessageQueueId_t *id, object_id_t *objectId) { + ReturnValue_t result = checkAndAcquireTargetID(objectId,tcData,tcDataLen); + if(result != RETURN_OK) { + return result; + } + return checkInterfaceAndAcquireMessageQueue(id,objectId); +} + +ReturnValue_t Service3Housekeeping::checkAndAcquireTargetID( + object_id_t* objectIdToSet, const uint8_t* tcData, size_t tcDataLen) { + if(SerializeAdapter::deSerialize(objectIdToSet, &tcData, &tcDataLen, + SerializeIF::Endianness::BIG) != HasReturnvaluesIF::RETURN_OK) { + return CommandingServiceBase::INVALID_TC; + } + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t Service3Housekeeping::checkInterfaceAndAcquireMessageQueue( + MessageQueueId_t* messageQueueToSet, object_id_t* objectId) { + // check HasLocalDataPoolIF property of target + HasLocalDataPoolIF* possibleTarget = + objectManager->get(*objectId); + if(possibleTarget == nullptr){ + return CommandingServiceBase::INVALID_OBJECT; + } + *messageQueueToSet = possibleTarget->getCommandQueue(); + return HasReturnvaluesIF::RETURN_OK; +} + + +ReturnValue_t Service3Housekeeping::prepareCommand(CommandMessage* message, + uint8_t subservice, const uint8_t *tcData, size_t tcDataLen, + uint32_t *state, object_id_t objectId) { + switch(static_cast(subservice)) { + case Subservice::ENABLE_PERIODIC_HK_REPORT_GENERATION: + return prepareReportingTogglingCommand(message, objectId, true, false, + tcData, tcDataLen); + case Subservice::DISABLE_PERIODIC_HK_REPORT_GENERATION: + return prepareReportingTogglingCommand(message, objectId, false, false, + tcData, tcDataLen); + case Subservice::ENABLE_PERIODIC_DIAGNOSTICS_REPORT_GENERATION: + return prepareReportingTogglingCommand(message, objectId, true, true, + tcData, tcDataLen); + case Subservice::DISABLE_PERIODIC_DIAGNOSTICS_REPORT_GENERATION: + return prepareReportingTogglingCommand(message, objectId, false, true, + tcData, tcDataLen); + case Subservice::REPORT_HK_REPORT_STRUCTURES: + return prepareStructureReportingCommand(message, objectId, false, tcData, + tcDataLen); + case Subservice::REPORT_DIAGNOSTICS_REPORT_STRUCTURES: + return prepareStructureReportingCommand(message, objectId, true, tcData, + tcDataLen); + case Subservice::GENERATE_ONE_PARAMETER_REPORT: + return prepareOneShotReportCommand(message, objectId, false, + tcData, tcDataLen); + case Subservice::GENERATE_ONE_DIAGNOSTICS_REPORT: + return prepareOneShotReportCommand(message, objectId, true, + tcData, tcDataLen); + case Subservice::MODIFY_PARAMETER_REPORT_COLLECTION_INTERVAL: + return prepareCollectionIntervalModificationCommand(message, objectId, + false, tcData, tcDataLen); + case Subservice::MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL: + return prepareCollectionIntervalModificationCommand(message, objectId, + true, tcData, tcDataLen); + case Subservice::HK_DEFINITIONS_REPORT: + case Subservice::DIAGNOSTICS_DEFINITION_REPORT: + case Subservice::HK_REPORT: + case Subservice::DIAGNOSTICS_REPORT: + // Those are telemetry packets. + return CommandingServiceBase::INVALID_TC; + default: + // should never happen, subservice was already checked. + return HasReturnvaluesIF::RETURN_FAILED; + } + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t Service3Housekeeping::prepareReportingTogglingCommand( + CommandMessage *command, object_id_t objectId, + bool enableReporting, bool isDiagnostics, + const uint8_t* tcData, size_t tcDataLen) { + if(tcDataLen < sizeof(sid_t)) { + // TC data should consist of object ID and set ID. + return CommandingServiceBase::INVALID_TC; + } + + sid_t targetSid = buildSid(objectId, &tcData, &tcDataLen); + HousekeepingMessage::setToggleReportingCommand(command, targetSid, + enableReporting, isDiagnostics); + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t Service3Housekeeping::prepareStructureReportingCommand( + CommandMessage *command, object_id_t objectId, bool isDiagnostics, + const uint8_t* tcData, size_t tcDataLen) { + if(tcDataLen < sizeof(sid_t)) { + // TC data should consist of object ID and set ID. + return CommandingServiceBase::INVALID_TC; + } + + sid_t targetSid = buildSid(objectId, &tcData, &tcDataLen); + HousekeepingMessage::setStructureReportingCommand(command, targetSid, + isDiagnostics); + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t Service3Housekeeping::prepareOneShotReportCommand( + CommandMessage *command, object_id_t objectId, bool isDiagnostics, + const uint8_t *tcData, size_t tcDataLen) { + if(tcDataLen < sizeof(sid_t)) { + // TC data should consist of object ID and set ID. + return CommandingServiceBase::INVALID_TC; + } + + sid_t targetSid = buildSid(objectId, &tcData, &tcDataLen); + HousekeepingMessage::setOneShotReportCommand(command, targetSid, + isDiagnostics); + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t Service3Housekeeping::prepareCollectionIntervalModificationCommand( + CommandMessage *command, object_id_t objectId, bool isDiagnostics, + const uint8_t *tcData, size_t tcDataLen) { + if(tcDataLen < sizeof(sid_t) + sizeof(float)) { + // SID plus the size of the new collection intervL. + return CommandingServiceBase::INVALID_TC; + } + + sid_t targetSid = buildSid(objectId, &tcData, &tcDataLen); + float newCollectionInterval = 0; + SerializeAdapter::deSerialize(&newCollectionInterval, &tcData, &tcDataLen, + SerializeIF::Endianness::BIG); + HousekeepingMessage::setCollectionIntervalModificationCommand(command, + targetSid, newCollectionInterval, isDiagnostics); + return HasReturnvaluesIF::RETURN_OK; +} + + +ReturnValue_t Service3Housekeeping::handleReply(const CommandMessage* reply, + Command_t previousCommand, uint32_t *state, + CommandMessage* optionalNextCommand, object_id_t objectId, + bool *isStep) { + Command_t command = reply->getCommand(); + switch(command) { + + case(HousekeepingMessage::HK_REPORT): { + ReturnValue_t result = generateHkReply(reply, + static_cast(Subservice::HK_REPORT)); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + return CommandingServiceBase::EXECUTION_COMPLETE; + } + + case(HousekeepingMessage::DIAGNOSTICS_REPORT): { + ReturnValue_t result = generateHkReply(reply, + static_cast(Subservice::DIAGNOSTICS_REPORT)); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + return CommandingServiceBase::EXECUTION_COMPLETE; + } + + case(HousekeepingMessage::HK_DEFINITIONS_REPORT): { + return generateHkReply(reply, static_cast( + Subservice::HK_DEFINITIONS_REPORT)); + break; + } + case(HousekeepingMessage::DIAGNOSTICS_DEFINITION_REPORT): { + return generateHkReply(reply, static_cast( + Subservice::DIAGNOSTICS_DEFINITION_REPORT)); + break; + } + + case(HousekeepingMessage::HK_REQUEST_SUCCESS): { + return CommandingServiceBase::EXECUTION_COMPLETE; + } + + case(HousekeepingMessage::HK_REQUEST_FAILURE): { + failureParameter1 = objectId; + ReturnValue_t error = HasReturnvaluesIF::RETURN_FAILED; + HousekeepingMessage::getHkRequestFailureReply(reply,&error); + failureParameter2 = error; + return CommandingServiceBase::EXECUTION_COMPLETE; + } + + default: + sif::error << "Service3Housekeeping::handleReply: Invalid reply with " + << "reply command " << command << "!" << std::endl; + return CommandingServiceBase::INVALID_REPLY; + } + return HasReturnvaluesIF::RETURN_OK; +} + +void Service3Housekeeping::handleUnrequestedReply( + CommandMessage* reply) { + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + Command_t command = reply->getCommand(); + + switch(command) { + + case(HousekeepingMessage::DIAGNOSTICS_REPORT): { + result = generateHkReply(reply, + static_cast(Subservice::DIAGNOSTICS_REPORT)); + break; + } + + case(HousekeepingMessage::HK_REPORT): { + result = generateHkReply(reply, + static_cast(Subservice::HK_REPORT)); + break; + } + + default: + sif::error << "Service3Housekeeping::handleReply: Invalid reply with " + << "reply command " << command << "!" << std::endl; + return; + } + + if(result != HasReturnvaluesIF::RETURN_OK) { + // Configuration error + sif::debug << "Service3Housekeeping::handleUnrequestedReply:" + << "Could not generate reply!" << std::endl; + } +} + +MessageQueueId_t Service3Housekeeping::getHkQueue() const { + return commandQueue->getId(); +} + +ReturnValue_t Service3Housekeeping::generateHkReply( + const CommandMessage* hkMessage, uint8_t subserviceId) { + store_address_t storeId; + + sid_t sid = HousekeepingMessage::getHkDataReply(hkMessage, &storeId); + auto resultPair = IPCStore->getData(storeId); + if(resultPair.first != HasReturnvaluesIF::RETURN_OK) { + return resultPair.first; + } + + HkPacket hkPacket(sid, resultPair.second.data(), resultPair.second.size()); + return sendTmPacket(static_cast(subserviceId), + hkPacket.hkData, hkPacket.hkSize, nullptr, 0); +} + +sid_t Service3Housekeeping::buildSid(object_id_t objectId, + const uint8_t** tcData, size_t* tcDataLen) { + sid_t targetSid; + targetSid.objectId = objectId; + // skip deserialization of object ID, was already done. + *tcData += sizeof(object_id_t); + *tcDataLen -= sizeof(object_id_t); + // size check is expected to be performed beforehand! + SerializeAdapter::deSerialize(&targetSid.ownerSetId, tcData, tcDataLen, + SerializeIF::Endianness::BIG); + return targetSid; +} diff --git a/pus/Service3Housekeeping.h b/pus/Service3Housekeeping.h new file mode 100644 index 000000000..269710ef3 --- /dev/null +++ b/pus/Service3Housekeeping.h @@ -0,0 +1,105 @@ +#ifndef FSFW_PUS_SERVICE3HOUSEKEEPINGSERVICE_H_ +#define FSFW_PUS_SERVICE3HOUSEKEEPINGSERVICE_H_ + +#include "../housekeeping/AcceptsHkPacketsIF.h" +#include "../housekeeping/HousekeepingMessage.h" +#include "../tmtcservices/CommandingServiceBase.h" + +/** + * @brief Manges spacecraft housekeeping reports and + * sends pool variables (temperature, GPS data ...) to ground. + * + * @details Full Documentation: ECSS-E70-41A or ECSS-E-ST-70-41C. + * Implementation based on PUS-C + * + * The housekeeping service type provides means to control and adapt the + * spacecraft reporting plan according to the mission phases. + * The housekeeping service type provides the visibility of any + * on-board parameters assembled in housekeeping parameter report structures + * or diagnostic parameter report structures as required for the mission. + * The parameter report structures used by the housekeeping service can + * be predefined on-board or created when needed. + * + * @author R. Mueller + * @ingroup pus_services + */ +class Service3Housekeeping: public CommandingServiceBase, + public AcceptsHkPacketsIF { +public: + static constexpr uint8_t NUM_OF_PARALLEL_COMMANDS = 4; + static constexpr uint16_t COMMAND_TIMEOUT_SECONDS = 60; + + Service3Housekeeping(object_id_t objectId, uint16_t apid, uint8_t serviceId); + virtual~ Service3Housekeeping(); +protected: + /* CSB abstract functions implementation . See CSB documentation. */ + ReturnValue_t isValidSubservice(uint8_t subservice) override; + ReturnValue_t getMessageQueueAndObject(uint8_t subservice, + const uint8_t *tcData, size_t tcDataLen, MessageQueueId_t *id, + object_id_t *objectId) override; + ReturnValue_t prepareCommand(CommandMessage* message, + uint8_t subservice, const uint8_t *tcData, size_t tcDataLen, + uint32_t *state, object_id_t objectId) override; + ReturnValue_t handleReply(const CommandMessage* reply, + Command_t previousCommand, uint32_t *state, + CommandMessage* optionalNextCommand, object_id_t objectId, + bool *isStep) override; + + virtual MessageQueueId_t getHkQueue() const; +private: + enum class Subservice { + ENABLE_PERIODIC_HK_REPORT_GENERATION = 5, //!< [EXPORT] : [TC] + DISABLE_PERIODIC_HK_REPORT_GENERATION = 6, //!< [EXPORT] : [TC] + + ENABLE_PERIODIC_DIAGNOSTICS_REPORT_GENERATION = 7, //!< [EXPORT] : [TC] + DISABLE_PERIODIC_DIAGNOSTICS_REPORT_GENERATION = 8, //!< [EXPORT] : [TC] + + //! [EXPORT] : [TC] Report HK structure by supplying SID + REPORT_HK_REPORT_STRUCTURES = 9, + //! [EXPORT] : [TC] Report Diagnostics structure by supplying SID + REPORT_DIAGNOSTICS_REPORT_STRUCTURES = 11, + + //! [EXPORT] : [TM] Report corresponding to Subservice 9 TC + HK_DEFINITIONS_REPORT = 10, + //! [EXPORT] : [TM] Report corresponding to Subservice 11 TC + DIAGNOSTICS_DEFINITION_REPORT = 12, + + //! [EXPORT] : [TM] Core packet. Contains Housekeeping data + HK_REPORT = 25, + //! [EXPORT] : [TM] Core packet. Contains diagnostics data + DIAGNOSTICS_REPORT = 26, + + /* PUS-C */ + GENERATE_ONE_PARAMETER_REPORT = 27, //!< [EXPORT] : [TC] + GENERATE_ONE_DIAGNOSTICS_REPORT = 28, //!< [EXPORT] : [TC] + + MODIFY_PARAMETER_REPORT_COLLECTION_INTERVAL = 31, //!< [EXPORT] : [TC] + MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL = 32, //!< [EXPORT] : [TC] + }; + + ReturnValue_t checkAndAcquireTargetID(object_id_t* objectIdToSet, + const uint8_t* tcData, size_t tcDataLen); + ReturnValue_t checkInterfaceAndAcquireMessageQueue( + MessageQueueId_t* messageQueueToSet, object_id_t* objectId); + + ReturnValue_t generateHkReply(const CommandMessage* hkMessage, + uint8_t subserviceId); + ReturnValue_t prepareReportingTogglingCommand(CommandMessage* command, + object_id_t objectId, bool enableReporting, bool isDiagnostics, + const uint8_t* tcData, size_t tcDataLen); + ReturnValue_t prepareStructureReportingCommand(CommandMessage* command, + object_id_t objectId, bool isDiagnostics, const uint8_t* tcData, + size_t tcDataLen); + ReturnValue_t prepareOneShotReportCommand(CommandMessage* command, + object_id_t objectId, bool isDiagnostics, const uint8_t* tcData, + size_t tcDataLen); + ReturnValue_t prepareCollectionIntervalModificationCommand( + CommandMessage* command, object_id_t objectId, bool isDiagnostics, + const uint8_t* tcData, size_t tcDataLen); + + void handleUnrequestedReply(CommandMessage* reply) override; + sid_t buildSid(object_id_t objectId, const uint8_t** tcData, + size_t* tcDataLen); +}; + +#endif /* FSFW_PUS_SERVICE3HOUSEKEEPINGSERVICE_H_ */ diff --git a/pus/Service5EventReporting.cpp b/pus/Service5EventReporting.cpp index 02031df4b..829d04bde 100644 --- a/pus/Service5EventReporting.cpp +++ b/pus/Service5EventReporting.cpp @@ -1,5 +1,5 @@ -#include "../pus/Service5EventReporting.h" -#include "../pus/servicepackets/Service5Packets.h" +#include "Service5EventReporting.h" +#include "servicepackets/Service5Packets.h" #include "../serviceinterface/ServiceInterfaceStream.h" #include "../events/EventManagerIF.h" diff --git a/pus/Service5EventReporting.h b/pus/Service5EventReporting.h index 0b6ee9a8c..78c18bf30 100644 --- a/pus/Service5EventReporting.h +++ b/pus/Service5EventReporting.h @@ -1,5 +1,5 @@ -#ifndef FRAMEWORK_PUS_SERVICE5EVENTREPORTING_H_ -#define FRAMEWORK_PUS_SERVICE5EVENTREPORTING_H_ +#ifndef FSFW_PUS_SERVICE5EVENTREPORTING_H_ +#define FSFW_PUS_SERVICE5EVENTREPORTING_H_ #include "../tmtcservices/PusServiceBase.h" #include "../events/EventMessage.h" @@ -83,4 +83,4 @@ private: ReturnValue_t generateEventReport(EventMessage message); }; -#endif /* MISSION_PUS_SERVICE5EVENTREPORTING_H_ */ +#endif /* FSFW_PUS_SERVICE5EVENTREPORTING_H_ */ diff --git a/pus/Service8FunctionManagement.cpp b/pus/Service8FunctionManagement.cpp index 3c94071d0..d710c56e1 100644 --- a/pus/Service8FunctionManagement.cpp +++ b/pus/Service8FunctionManagement.cpp @@ -1,5 +1,5 @@ -#include "../pus/Service8FunctionManagement.h" -#include "../pus/servicepackets/Service8Packets.h" +#include "Service8FunctionManagement.h" +#include "servicepackets/Service8Packets.h" #include "../objectmanager/SystemObjectIF.h" #include "../action/HasActionsIF.h" @@ -7,10 +7,10 @@ #include "../serialize/SerializeAdapter.h" #include "../serviceinterface/ServiceInterfaceStream.h" -Service8FunctionManagement::Service8FunctionManagement(object_id_t object_id, +Service8FunctionManagement::Service8FunctionManagement(object_id_t objectId, uint16_t apid, uint8_t serviceId, uint8_t numParallelCommands, uint16_t commandTimeoutSeconds): - CommandingServiceBase(object_id, apid, serviceId, numParallelCommands, + CommandingServiceBase(objectId, apid, serviceId, numParallelCommands, commandTimeoutSeconds) {} Service8FunctionManagement::~Service8FunctionManagement() {} @@ -19,7 +19,7 @@ Service8FunctionManagement::~Service8FunctionManagement() {} ReturnValue_t Service8FunctionManagement::isValidSubservice( uint8_t subservice) { switch(static_cast(subservice)) { - case Subservice::DIRECT_COMMANDING: + case Subservice::COMMAND_DIRECT_COMMANDING: return HasReturnvaluesIF::RETURN_OK; default: return AcceptsTelecommandsIF::INVALID_SUBSERVICE; @@ -131,7 +131,7 @@ ReturnValue_t Service8FunctionManagement::handleDataReply( } DataReply dataReply(objectId, actionId, buffer, size); result = sendTmPacket(static_cast( - Subservice::DIRECT_COMMANDING_DATA_REPLY), &dataReply); + Subservice::REPLY_DIRECT_COMMANDING_DATA), &dataReply); auto deletionResult = IPCStore->deleteData(storeId); if(deletionResult != HasReturnvaluesIF::RETURN_OK) { diff --git a/pus/Service8FunctionManagement.h b/pus/Service8FunctionManagement.h index b5ebcda8b..00153cfb0 100644 --- a/pus/Service8FunctionManagement.h +++ b/pus/Service8FunctionManagement.h @@ -1,5 +1,5 @@ -#ifndef FRAMEWORK_PUS_SERVICE8FUNCTIONMANAGEMENT_H_ -#define FRAMEWORK_PUS_SERVICE8FUNCTIONMANAGEMENT_H_ +#ifndef FSFW_PUS_SERVICE8FUNCTIONMANAGEMENT_H_ +#define FSFW_PUS_SERVICE8FUNCTIONMANAGEMENT_H_ #include "../action/ActionMessage.h" #include "../tmtcservices/CommandingServiceBase.h" @@ -52,8 +52,10 @@ protected: private: enum class Subservice { - DIRECT_COMMANDING = 128, //!< [EXPORT] : [COMMAND] Functional commanding - DIRECT_COMMANDING_DATA_REPLY = 130, //!< [EXPORT] : [REPLY] Data reply + //!< [EXPORT] : [COMMAND] Functional commanding + COMMAND_DIRECT_COMMANDING = 128, + //!< [EXPORT] : [REPLY] Data reply + REPLY_DIRECT_COMMANDING_DATA = 130, }; ReturnValue_t checkInterfaceAndAcquireMessageQueue( @@ -64,4 +66,4 @@ private: object_id_t objectId, ActionId_t actionId); }; -#endif /* FRAMEWORK_PUS_SERVICE8FUNCTIONMANAGEMENT_H_ */ +#endif /* FSFW_PUS_SERVICE8FUNCTIONMANAGEMENT_H_ */ diff --git a/pus/Service9TimeManagement.h b/pus/Service9TimeManagement.h index 4ad6be6e3..4802cdecc 100644 --- a/pus/Service9TimeManagement.h +++ b/pus/Service9TimeManagement.h @@ -1,7 +1,7 @@ #ifndef FSFW_PUS_SERVICE9TIMEMANAGEMENT_H_ #define FSFW_PUS_SERVICE9TIMEMANAGEMENT_H_ -#include +#include "../tmtcservices/PusServiceBase.h" class Service9TimeManagement: public PusServiceBase { public: @@ -34,7 +34,6 @@ private: SET_TIME = 128 //!< [EXPORT] : [COMMAND] Time command in ASCII, CUC or CDS format }; - void setIsisClock(Clock::TimeOfDay_t& timeOfDay); }; diff --git a/pus/servicepackets/Service1Packets.h b/pus/servicepackets/Service1Packets.h index 8c5cb005f..ecb62693c 100644 --- a/pus/servicepackets/Service1Packets.h +++ b/pus/servicepackets/Service1Packets.h @@ -1,8 +1,5 @@ -#ifndef MISSION_PUS_SERVICEPACKETS_SERVICE1PACKETS_H_ -#define MISSION_PUS_SERVICEPACKETS_SERVICE1PACKETS_H_ - -#include "../../serialize/SerializeAdapter.h" -#include "../../tmtcservices/VerificationCodes.h" +#ifndef FSFW_PUS_SERVICEPACKETS_SERVICE1PACKETS_H_ +#define FSFW_PUS_SERVICEPACKETS_SERVICE1PACKETS_H_ /** * @defgroup spacepackets PUS Packet Definitions @@ -11,12 +8,15 @@ * packet structures in Mission Information Base (MIB). */ +#include "../../serialize/SerializeAdapter.h" +#include "../../tmtcservices/VerificationCodes.h" + /** * @brief FailureReport class to serialize a failure report * @brief Subservice 1, 3, 5, 7 * @ingroup spacepackets */ -class FailureReport: public SerializeIF { //!< [EXPORT] : [SUBSERVICE] 2, 4, 6, 8 +class FailureReport: public SerializeIF { //!< [EXPORT] : [SUBSERVICE] 1, 3, 5, 7 public: FailureReport(uint8_t failureSubtype_, uint16_t packetId_, uint16_t packetSequenceControl_, uint8_t stepNumber_, @@ -111,7 +111,7 @@ private: * @brief Subservices 2, 4, 6, 8 * @ingroup spacepackets */ -class SuccessReport: public SerializeIF { //!< [EXPORT] : [SUBSERVICE] 1, 3, 5, 7 +class SuccessReport: public SerializeIF { //!< [EXPORT] : [SUBSERVICE] 2, 4, 6, 8 public: SuccessReport(uint8_t subtype_, uint16_t packetId_, uint16_t packetSequenceControl_,uint8_t stepNumber_) : diff --git a/pus/servicepackets/Service200Packets.h b/pus/servicepackets/Service200Packets.h index efcf65fcf..cb9ad4a70 100644 --- a/pus/servicepackets/Service200Packets.h +++ b/pus/servicepackets/Service200Packets.h @@ -1,5 +1,5 @@ -#ifndef FRAMEWORK_PUS_SERVICEPACKETS_SERVICE200PACKETS_H_ -#define FRAMEWORK_PUS_SERVICEPACKETS_SERVICE200PACKETS_H_ +#ifndef FSFW_PUS_SERVICEPACKETS_SERVICE200PACKETS_H_ +#define FSFW_PUS_SERVICEPACKETS_SERVICE200PACKETS_H_ #include "../../serialize/SerialLinkedListAdapter.h" #include "../../modes/ModeMessage.h" @@ -60,4 +60,4 @@ public: SerializeElement reason; //!< [EXPORT] : [COMMENT] Reason the mode could not be reached }; -#endif /* FRAMEWORK_PUS_SERVICEPACKETS_SERVICE200PACKETS_H_ */ +#endif /* FSFW_PUS_SERVICEPACKETS_SERVICE200PACKETS_H_ */ diff --git a/pus/servicepackets/Service201Packets.h b/pus/servicepackets/Service201Packets.h index 8dce88e5b..aed821f98 100644 --- a/pus/servicepackets/Service201Packets.h +++ b/pus/servicepackets/Service201Packets.h @@ -5,10 +5,10 @@ #include "../../serialize/SerializeIF.h" #include "../../health/HasHealthIF.h" -class HealthCommand: public SerialLinkedListAdapter { //!< [EXPORT] : [SUBSERVICE] 1 +class HealthSetCommand: public SerialLinkedListAdapter { //!< [EXPORT] : [SUBSERVICE] 1 public: - HealthCommand() { + HealthSetCommand() { setLinks(); } diff --git a/pus/servicepackets/Service2Packets.h b/pus/servicepackets/Service2Packets.h index d4f3fb170..285a8f9f1 100644 --- a/pus/servicepackets/Service2Packets.h +++ b/pus/servicepackets/Service2Packets.h @@ -1,5 +1,5 @@ -#ifndef FRAMEWORK_PUS_SERVICEPACKETS_SERVICE2PACKETS_H_ -#define FRAMEWORK_PUS_SERVICEPACKETS_SERVICE2PACKETS_H_ +#ifndef FSFW_PUS_SERVICEPACKETS_SERVICE2PACKETS_H_ +#define FSFW_PUS_SERVICEPACKETS_SERVICE2PACKETS_H_ #include "../../action/ActionMessage.h" #include "../../objectmanager/SystemObjectIF.h" @@ -73,4 +73,4 @@ public: } }; -#endif /* FRAMEWORK_PUS_SERVICEPACKETS_SERVICE2PACKETS_H_ */ +#endif /* FSFW_PUS_SERVICEPACKETS_SERVICE2PACKETS_H_ */ diff --git a/pus/servicepackets/Service3Packets.h b/pus/servicepackets/Service3Packets.h new file mode 100644 index 000000000..05732e11b --- /dev/null +++ b/pus/servicepackets/Service3Packets.h @@ -0,0 +1,21 @@ +#ifndef FSFW_PUS_SERVICEPACKETS_SERVICE3PACKETS_H_ +#define FSFW_PUS_SERVICEPACKETS_SERVICE3PACKETS_H_ + +#include +#include + +/** + * @brief Subservices 25 and 26: TM packets + * @ingroup spacepackets + */ +class HkPacket { //!< [EXPORT] : [SUBSERVICE] 25, 26 +public: + sid_t sid; //!< [EXPORT] : [COMMENT] Structure ID (SID) of housekeeping data. + const uint8_t* hkData; //!< [EXPORT] : [MAXSIZE] Deduced size + size_t hkSize; //!< [EXPORT] : [IGNORE] + + HkPacket(sid_t sid, const uint8_t* data, size_t size): + sid(sid), hkData(data), hkSize(size) {} +}; + +#endif /* FSFW_PUS_SERVICEPACKETS_SERVICE3PACKETS_H_ */ diff --git a/pus/servicepackets/Service5Packets.h b/pus/servicepackets/Service5Packets.h index 9655608aa..f903d6a26 100644 --- a/pus/servicepackets/Service5Packets.h +++ b/pus/servicepackets/Service5Packets.h @@ -1,5 +1,5 @@ -#ifndef MISSION_PUS_SERVICEPACKETS_SERVICE5PACKETS_H_ -#define MISSION_PUS_SERVICEPACKETS_SERVICE5PACKETS_H_ +#ifndef FSFW_PUS_SERVICEPACKETS_SERVICE5PACKETS_H_ +#define FSFW_PUS_SERVICEPACKETS_SERVICE5PACKETS_H_ #include "../../serialize/SerializeAdapter.h" #include "../../tmtcservices/VerificationCodes.h" @@ -73,4 +73,4 @@ private: }; -#endif /* MISSION_PUS_SERVICEPACKETS_SERVICE5PACKETS_H_ */ +#endif /* FSFW_PUS_SERVICEPACKETS_SERVICE5PACKETS_H_ */ diff --git a/pus/servicepackets/Service8Packets.h b/pus/servicepackets/Service8Packets.h index 14f8b6e6e..b026edf52 100644 --- a/pus/servicepackets/Service8Packets.h +++ b/pus/servicepackets/Service8Packets.h @@ -1,5 +1,5 @@ -#ifndef FRAMEWORK_PUS_SERVICEPACKETS_SERVICE8PACKETS_H_ -#define FRAMEWORK_PUS_SERVICEPACKETS_SERVICE8PACKETS_H_ +#ifndef FSFW_PUS_SERVICEPACKETS_SERVICE8PACKETS_H_ +#define FSFW_PUS_SERVICEPACKETS_SERVICE8PACKETS_H_ #include "../../action/ActionMessage.h" #include "../../objectmanager/SystemObjectIF.h" @@ -118,4 +118,4 @@ private: }; -#endif /* FRAMEWORK_PUS_SERVICEPACKETS_SERVICE8PACKETS_H_ */ +#endif /* FSFW_PUS_SERVICEPACKETS_SERVICE8PACKETS_H_ */ diff --git a/returnvalues/FwClassIds.h b/returnvalues/FwClassIds.h index 12877b404..120d1e2e7 100644 --- a/returnvalues/FwClassIds.h +++ b/returnvalues/FwClassIds.h @@ -65,9 +65,9 @@ enum { POOL_VARIABLE_IF, //PVA 59 HOUSEKEEPING_MANAGER, //HKM 60 DLE_ENCODER, //DLEE 61 - PUS_PARSER, //PUSP 62 - SERIAL_ANALYZER, //SERA 63 - PUS_SERVICE_9, + SERIAL_ANALYZER, //SERA 62 + PUS_SERVICE_9, //PUS9 63 + FILE_SYSTEM, //FLSY 64 FW_CLASS_ID_COUNT //is actually count + 1 ! }; diff --git a/serialize/EndianConverter.h b/serialize/EndianConverter.h index f981751d0..c888a905a 100644 --- a/serialize/EndianConverter.h +++ b/serialize/EndianConverter.h @@ -1,5 +1,5 @@ -#ifndef ENDIANSWAPPER_H_ -#define ENDIANSWAPPER_H_ +#ifndef FSFW_SERIALIZE_ENDIANCONVERTER_H_ +#define FSFW_SERIALIZE_ENDIANCONVERTER_H_ #include "../osal/Endiness.h" #include @@ -121,4 +121,4 @@ public: } }; -#endif /* ENDIANSWAPPER_H_ */ +#endif /* FSFW_SERIALIZE_ENDIANCONVERTER_H_ */ diff --git a/serialize/SerialArrayListAdapter.h b/serialize/SerialArrayListAdapter.h index 69afdd4af..daa3fe7f1 100644 --- a/serialize/SerialArrayListAdapter.h +++ b/serialize/SerialArrayListAdapter.h @@ -1,18 +1,13 @@ -/** - * @file SerialArrayListAdapter.h - * @brief This file defines the SerialArrayListAdapter class. - * @date 22.07.2014 - * @author baetz - */ -#ifndef SERIALARRAYLISTADAPTER_H_ -#define SERIALARRAYLISTADAPTER_H_ +#ifndef FSFW_SERIALIZE_SERIALARRAYLISTADAPTER_H_ +#define FSFW_SERIALIZE_SERIALARRAYLISTADAPTER_H_ +#include "SerializeIF.h" #include "../container/ArrayList.h" -#include "../serialize/SerializeIF.h" #include /** * Also serializes length field ! + * @author baetz * @ingroup serialize */ template @@ -26,8 +21,9 @@ public: return serialize(adaptee, buffer, size, maxSize, streamEndianness); } - static ReturnValue_t serialize(const ArrayList* list, uint8_t** buffer, size_t* size, - size_t maxSize, Endianness streamEndianness) { + static ReturnValue_t serialize(const ArrayList* list, + uint8_t** buffer, size_t* size, size_t maxSize, + Endianness streamEndianness) { ReturnValue_t result = SerializeAdapter::serialize(&list->size, buffer, size, maxSize, streamEndianness); count_t i = 0; @@ -59,14 +55,19 @@ public: return deSerialize(adaptee, buffer, size, streamEndianness); } - static ReturnValue_t deSerialize(ArrayList* list, const uint8_t** buffer, size_t* size, + static ReturnValue_t deSerialize(ArrayList* list, + const uint8_t** buffer, size_t* size, Endianness streamEndianness) { count_t tempSize = 0; ReturnValue_t result = SerializeAdapter::deSerialize(&tempSize, buffer, size, streamEndianness); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } if (tempSize > list->maxSize()) { return SerializeIF::TOO_MANY_ELEMENTS; } + list->size = tempSize; count_t i = 0; while ((result == HasReturnvaluesIF::RETURN_OK) && (i < list->size)) { @@ -78,14 +79,8 @@ public: return result; } - - static void swapArrayListEndianness(ArrayList* list) { - list->swapArrayListEndianness(); - } private: ArrayList *adaptee; }; - - -#endif /* SERIALARRAYLISTADAPTER_H_ */ +#endif /* FSFW_SERIALIZE_SERIALARRAYLISTADAPTER_H_ */ diff --git a/serialize/SerialFixedArrayListAdapter.h b/serialize/SerialFixedArrayListAdapter.h index c866df868..70ca987ac 100644 --- a/serialize/SerialFixedArrayListAdapter.h +++ b/serialize/SerialFixedArrayListAdapter.h @@ -1,8 +1,8 @@ -#ifndef SERIALFIXEDARRAYLISTADAPTER_H_ -#define SERIALFIXEDARRAYLISTADAPTER_H_ +#ifndef FSFW_SERIALIZE_SERIALFIXEDARRAYLISTADAPTER_H_ +#define FSFW_SERIALIZE_SERIALFIXEDARRAYLISTADAPTER_H_ +#include "SerialArrayListAdapter.h" #include "../container/FixedArrayList.h" -#include "../serialize/SerialArrayListAdapter.h" /** * @brief This adapter provides an interface for SerializeIF to serialize and @@ -13,18 +13,11 @@ * The sequence of objects is defined in the constructor by * using the setStart and setNext functions. * - * - Buffers with a size header inside that class can be declared with - * @code - * SerialFixedArrayListAdapter mySerialFixedArrayList(...). - * @endcode - * - * - MAX_SIZE: specifies the maximum allowed number of elements - * in FixedArrayList. - * - BUFFER_TYPE: specifies the data type of the buffer - * - count_t: specifies the type/size of the length field - * which defaults to one byte. - * + * @tparam BUFFER_TYPE: Specifies the data type of the buffer + * @tparam MAX_SIZE: Specifies the maximum allowed number of elements + * (not bytes!) + * @tparam count_t: specifies the type/size of the length field which defaults + * to one byte. * @ingroup serialize */ template @@ -33,7 +26,7 @@ class SerialFixedArrayListAdapter : public SerializeIF { public: /** - * Constructor Arguments are forwarded to FixedArrayList constructor. + * Constructor arguments are forwarded to FixedArrayList constructor. * Refer to the fixed array list constructors for different options. * @param args */ @@ -49,7 +42,8 @@ public: } size_t getSerializedSize() const { - return SerialArrayListAdapter::getSerializedSize(this); + return SerialArrayListAdapter:: + getSerializedSize(this); } ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, @@ -60,4 +54,4 @@ public: }; -#endif /* SERIALFIXEDARRAYLISTADAPTER_H_ */ +#endif /* FSFW_SERIALIZE_SERIALFIXEDARRAYLISTADAPTER_H_ */ diff --git a/serialize/SerialLinkedListAdapter.h b/serialize/SerialLinkedListAdapter.h index 987fa70ea..430a21ac2 100644 --- a/serialize/SerialLinkedListAdapter.h +++ b/serialize/SerialLinkedListAdapter.h @@ -1,17 +1,10 @@ -/** - * @file SerialLinkedListAdapter.h - * @brief This file defines the SerialLinkedListAdapter class. - * @date 22.07.2014 - * @author baetz - */ -#ifndef SERIALLINKEDLISTADAPTER_H_ -#define SERIALLINKEDLISTADAPTER_H_ +#ifndef FSFW_SERIALIZE_SERIALLINKEDLISTADAPTER_H_ +#define FSFW_SERIALIZE_SERIALLINKEDLISTADAPTER_H_ #include "../container/SinglyLinkedList.h" -#include "../serialize/SerializeAdapter.h" -#include "../serialize/SerializeElement.h" -#include "../serialize/SerializeIF.h" -//This is where we need the SerializeAdapter! +#include "SerializeAdapter.h" +#include "SerializeElement.h" +#include "SerializeIF.h" /** * @brief Implement the conversion of object data to data streams @@ -22,7 +15,7 @@ * SerializeElement members inside the class * implementing this adapter. * - The element type can also be a SerialBufferAdapter to - * de-/serialize buffers with a known size + * de-/serialize buffers. * - The element type can also be a SerialFixedArrayListAdapter to * de-/serialize buffers with a size header, which is scanned automatically. * @@ -37,21 +30,12 @@ * supplying a buffer with the data which is converted into an object. * The size of data to serialize can be supplied and is * decremented in the function. Range checking is done internally. - * + * @author baetz * @ingroup serialize */ template class SerialLinkedListAdapter: public SinglyLinkedList, public SerializeIF { public: - /** - * Copying is forbidden by deleting the copy constructor and the copy - * assignment operator because of the pointers to the linked list members. - * Unless the child class implements an own copy constructor or - * copy assignment operator, these operation will throw a compiler error. - * @param - */ - SerialLinkedListAdapter(const SerialLinkedListAdapter &) = delete; - SerialLinkedListAdapter& operator=(const SerialLinkedListAdapter&) = delete; SerialLinkedListAdapter(typename LinkedElement::Iterator start, bool printCount = false) : @@ -85,7 +69,7 @@ public: uint8_t** buffer, size_t* size, size_t maxSize, Endianness streamEndianness) { ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; - while ((result == HasReturnvaluesIF::RETURN_OK) && (element != NULL)) { + while ((result == HasReturnvaluesIF::RETURN_OK) and (element != nullptr)) { result = element->value->serialize(buffer, size, maxSize, streamEndianness); element = element->getNext(); @@ -104,7 +88,7 @@ public: static size_t getSerializedSize(const LinkedElement *element) { size_t size = 0; - while (element != NULL) { + while (element != nullptr) { size += element->value->getSerializedSize(); element = element->getNext(); } @@ -114,20 +98,31 @@ public: virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, Endianness streamEndianness) override { - return deSerialize(SinglyLinkedList::start, buffer, size, streamEndianness); + return deSerialize(SinglyLinkedList::start, buffer, size, + streamEndianness); } static ReturnValue_t deSerialize(LinkedElement* element, const uint8_t** buffer, size_t* size, Endianness streamEndianness) { ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; - while ((result == HasReturnvaluesIF::RETURN_OK) && (element != NULL)) { + while ((result == HasReturnvaluesIF::RETURN_OK) and (element != nullptr)) { result = element->value->deSerialize(buffer, size, streamEndianness); element = element->getNext(); } return result; } + /** + * Copying is forbidden by deleting the copy constructor and the copy + * assignment operator because of the pointers to the linked list members. + * Unless the child class implements an own copy constructor or + * copy assignment operator, these operation will throw a compiler error. + * @param + */ + SerialLinkedListAdapter(const SerialLinkedListAdapter &) = delete; + SerialLinkedListAdapter& operator=(const SerialLinkedListAdapter&) = delete; + bool printCount; }; -#endif /* SERIALLINKEDLISTADAPTER_H_ */ +#endif /* FSFW_SERIALIZE_SERIALLINKEDLISTADAPTER_H_ */ diff --git a/serialize/SerializeAdapter.h b/serialize/SerializeAdapter.h index 3e84bdf95..e6cd247e1 100644 --- a/serialize/SerializeAdapter.h +++ b/serialize/SerializeAdapter.h @@ -1,10 +1,10 @@ -#ifndef SERIALIZEADAPTER_H_ -#define SERIALIZEADAPTER_H_ +#ifndef _FSFW_SERIALIZE_SERIALIZEADAPTER_H_ +#define _FSFW_SERIALIZE_SERIALIZEADAPTER_H_ -#include "../container/IsDerivedFrom.h" #include "../returnvalues/HasReturnvaluesIF.h" -#include "../serialize/EndianConverter.h" -#include "../serialize/SerializeIF.h" +#include "EndianConverter.h" +#include "SerializeIF.h" +#include #include /** @@ -13,88 +13,102 @@ * serialization of classes with different multiple different data types * into buffers and vice-versa. * @details - * - * A report class is converted into a TM buffer. The report class implements a - * serialize functions and calls the AutoSerializeAdapter::serialize function - * repeatedly on all object data fields. The getSerializedSize function is - * implemented by calling the AutoSerializeAdapter::getSerializedSize function - * repeatedly on all data fields. - * - * The AutoSerializeAdapter functions can also be used as an alternative to - * memcpy to retrieve data out of a buffer directly into a class variable - * with data type T while being able to specify endianness. The boolean - * bigEndian specifies whether an endian swap is performed on the data before - * serialization or deserialization. - * - * There are three ways to retrieve data out of a buffer to be used in the FSFW - * to use regular aligned (big endian) data. Examples: - * - * 1. Use the AutoSerializeAdapter::deSerialize function - * The pointer *buffer will be incremented automatically by the typeSize - * of the object, so this function can be called on &buffer repeatedly - * without adjusting pointer position. Set bigEndian parameter to true - * to perform endian swapping, if necessary - * @code - * uint16_t data; - * int32_t dataLen = sizeof(data); - * ReturnValue_t result = - * AutoSerializeAdapter::deSerialize(&data,&buffer,&dataLen,true); - * @endcode - * - * 2. Perform a bitshift operation. Watch for for endianness: - * @code - * uint16_t data; - * data = buffer[targetByte1] << 8 | buffer[targetByte2]; - * data = EndianSwapper::swap(data); //optional, or swap order above - * @endcode - * - * 3. memcpy or std::copy can also be used, but watch out if system - * endianness is different from required data endianness. - * Perform endian-swapping if necessary. - * @code - * uint16_t data; - * memcpy(&data,buffer + positionOfTargetByte1,sizeof(data)); - * data = EndianSwapper::swap(data); //optional - * @endcode - * - * When serializing for downlink, the packets are generally serialized assuming - * big endian data format like seen in TmPacketStored.cpp for example. + * The correct serialization or deserialization function is chosen at + * compile time with template type deduction. * * @ingroup serialize */ - class SerializeAdapter { public: + /*** + * This function can be used to serialize a trivial copy-able type or a + * child of SerializeIF. + * The right template to be called is determined in the function itself. + * For objects of non trivial copy-able type this function is almost never + * called by the user directly. Instead helpers for specific types like + * SerialArrayListAdapter or SerialLinkedListAdapter is the right choice here. + * + * @param[in] object Object to serialize, the used type is deduced from this pointer + * @param[in/out] buffer Buffer to serialize into. Will be moved by the function. + * @param[in/out] size Size of current written buffer. Will be incremented by the function. + * @param[in] maxSize Max size of Buffer + * @param[in] streamEndianness Endianness of serialized element as in according to SerializeIF::Endianness + * @return + * - @c BUFFER_TOO_SHORT The given buffer in is too short + * - @c RETURN_FAILED Generic Error + * - @c RETURN_OK Successful serialization + */ template static ReturnValue_t serialize(const T *object, uint8_t **buffer, - size_t *size, size_t maxSize, SerializeIF::Endianness streamEndianness) { - InternalSerializeAdapter::Is> adapter; + size_t *size, size_t maxSize, + SerializeIF::Endianness streamEndianness) { + InternalSerializeAdapter::value> adapter; return adapter.serialize(object, buffer, size, maxSize, streamEndianness); } + /** + * Function to return the serialized size of the object in the pointer. + * May be a trivially copy-able object or a Child of SerializeIF + * + * @param object Pointer to Object + * @return Serialized size of object + */ template - static uint32_t getSerializedSize(const T *object) { - InternalSerializeAdapter::Is> adapter; + static size_t getSerializedSize(const T *object){ + InternalSerializeAdapter::value> adapter; return adapter.getSerializedSize(object); } + /** + * @brief + * Deserializes a object from a given buffer of given size. + * Object Must be trivially copy-able or a child of SerializeIF. + * + * @details + * Buffer will be moved to the current read location. Size will be decreased by the function. + * + * @param[in/out] buffer Buffer to deSerialize from. Will be moved by the function. + * @param[in/out] size Remaining size of the buffer to read from. Will be decreased by function. + * @param[in] streamEndianness Endianness as in according to SerializeIF::Endianness + * @return + * - @c STREAM_TOO_SHORT The input stream is too short to deSerialize the object + * - @c TOO_MANY_ELEMENTS The buffer has more inputs than expected + * - @c RETURN_FAILED Generic Error + * - @c RETURN_OK Successful deserialization + */ template static ReturnValue_t deSerialize(T *object, const uint8_t **buffer, size_t *size, SerializeIF::Endianness streamEndianness) { - InternalSerializeAdapter::Is> adapter; + InternalSerializeAdapter::value> adapter; return adapter.deSerialize(object, buffer, size, streamEndianness); } private: - template - class InternalSerializeAdapter { + /** + * Internal template to deduce the right function calls at compile time + */ + template class InternalSerializeAdapter; + + /** + * Template to be used if T is not a child of SerializeIF + * + * @tparam T T must be trivially_copyable + */ + template + class InternalSerializeAdapter { + static_assert (std::is_trivially_copyable::value, + "If a type needs to be serialized it must be a child of " + "SerializeIF or trivially copy-able"); public: static ReturnValue_t serialize(const T *object, uint8_t **buffer, - size_t *size, size_t max_size, SerializeIF::Endianness streamEndianness) { + size_t *size, size_t max_size, + SerializeIF::Endianness streamEndianness) { size_t ignoredSize = 0; - if (size == NULL) { + if (size == nullptr) { size = &ignoredSize; } - //TODO check integer overflow of *size - if (sizeof(T) + *size <= max_size) { + // Check remaining size is large enough and check integer + // overflow of *size + size_t newSize = sizeof(T) + *size; + if ((newSize <= max_size) and (newSize > *size)) { T tmp; switch (streamEndianness) { case SerializeIF::Endianness::BIG: @@ -108,7 +122,7 @@ private: tmp = *object; break; } - memcpy(*buffer, &tmp, sizeof(T)); + std::memcpy(*buffer, &tmp, sizeof(T)); *size += sizeof(T); (*buffer) += sizeof(T); return HasReturnvaluesIF::RETURN_OK; @@ -122,7 +136,7 @@ private: T tmp; if (*size >= sizeof(T)) { *size -= sizeof(T); - memcpy(&tmp, *buffer, sizeof(T)); + std::memcpy(&tmp, *buffer, sizeof(T)); switch (streamEndianness) { case SerializeIF::Endianness::BIG: *object = EndianConverter::convertBigEndian(tmp); @@ -146,22 +160,26 @@ private: uint32_t getSerializedSize(const T *object) { return sizeof(T); } - }; + /** + * Template for objects that inherit from SerializeIF + * + * @tparam T A child of SerializeIF + */ template - class InternalSerializeAdapter { + class InternalSerializeAdapter { public: - ReturnValue_t serialize(const T *object, uint8_t **buffer, - size_t *size, size_t max_size, + ReturnValue_t serialize(const T *object, uint8_t **buffer, size_t *size, + size_t max_size, SerializeIF::Endianness streamEndianness) const { size_t ignoredSize = 0; - if (size == NULL) { + if (size == nullptr) { size = &ignoredSize; } return object->serialize(buffer, size, max_size, streamEndianness); } - uint32_t getSerializedSize(const T *object) const { + size_t getSerializedSize(const T *object) const { return object->getSerializedSize(); } @@ -172,4 +190,4 @@ private: }; }; -#endif /* SERIALIZEADAPTER_H_ */ +#endif /* _FSFW_SERIALIZE_SERIALIZEADAPTER_H_ */ diff --git a/serialize/SerializeElement.h b/serialize/SerializeElement.h index 8c3472b2c..470802927 100644 --- a/serialize/SerializeElement.h +++ b/serialize/SerializeElement.h @@ -1,8 +1,8 @@ -#ifndef SERIALIZEELEMENT_H_ -#define SERIALIZEELEMENT_H_ +#ifndef FSFW_SERIALIZE_SERIALIZEELEMENT_H_ +#define FSFW_SERIALIZE_SERIALIZEELEMENT_H_ +#include "SerializeAdapter.h" #include "../container/SinglyLinkedList.h" -#include "../serialize/SerializeAdapter.h" #include /** @@ -12,7 +12,7 @@ * Used by declaring any arbitrary datatype with SerializeElement myVariable, * inside a SerialLinkedListAdapter implementation and setting the sequence * of objects with setNext() and setStart(). - * Serilization and Deserialization is then performed automatically in + * Serialization and Deserialization is then performed automatically in * specified sequence order. * @ingroup serialize */ @@ -27,7 +27,7 @@ public: SerializeElement() : LinkedElement(this) { } - T entry; + ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize, Endianness streamEndianness) const override { return SerializeAdapter::serialize(&entry, buffer, size, maxSize, @@ -52,9 +52,12 @@ public: entry = newValue; return *this; } + T* operator->() { return &entry; } + + T entry; }; -#endif /* SERIALIZEELEMENT_H_ */ +#endif /* FSFW_SERIALIZE_SERIALIZEELEMENT_H_ */ diff --git a/serialize/SerializeIF.h b/serialize/SerializeIF.h index 6d5a0dda4..d72218f0a 100644 --- a/serialize/SerializeIF.h +++ b/serialize/SerializeIF.h @@ -1,34 +1,19 @@ -#ifndef SERIALIZEIF_H_ -#define SERIALIZEIF_H_ +#ifndef FSFW_SERIALIZE_SERIALIZEIF_H_ +#define FSFW_SERIALIZE_SERIALIZEIF_H_ #include "../returnvalues/HasReturnvaluesIF.h" #include /** * @defgroup serialize Serialization - * Contains serialisation services. + * Contains serialization services. */ /** - * @brief An interface for alle classes which require - * translation of objects data into data streams and vice-versa. + * @brief Translation of objects into data streams and from data streams. * @details - * If the target architecture is little endian (e.g. ARM), any data types - * created might have the wrong endianess if they are to be used for the FSFW. - * Depending on the system architecture, endian correctness must be assured, - * This is important for incoming and outgoing data. The internal handling - * of data should be performed in the native system endianness. - * There are three ways to copy data (with different options to ensure - * endian correctness): - * - * 1. Use the @c AutoSerializeAdapter::deSerialize function (with - * the endian flag) - * 2. Perform a bitshift operation (with correct order) - * 3. @c memcpy (with @c EndianSwapper if necessary) - * - * When serializing for downlink, the packets are generally serialized - * assuming big endian data format like seen in TmPacketStored.cpp for example. - * + * Also provides options to convert from/to data with different endianness. + * variables. * @ingroup serialize */ class SerializeIF { @@ -38,21 +23,65 @@ public: }; static const uint8_t INTERFACE_ID = CLASS_ID::SERIALIZE_IF; - static const ReturnValue_t BUFFER_TOO_SHORT = MAKE_RETURN_CODE(1); - static const ReturnValue_t STREAM_TOO_SHORT = MAKE_RETURN_CODE(2); - static const ReturnValue_t TOO_MANY_ELEMENTS = MAKE_RETURN_CODE(3); + static const ReturnValue_t BUFFER_TOO_SHORT = MAKE_RETURN_CODE(1); // !< The given buffer in serialize is too short + static const ReturnValue_t STREAM_TOO_SHORT = MAKE_RETURN_CODE(2); // !< The input stream in deserialize is too short + static const ReturnValue_t TOO_MANY_ELEMENTS = MAKE_RETURN_CODE(3);// !< There are too many elements to be deserialized virtual ~SerializeIF() { } - + /** + * @brief + * Function to serialize the object into a buffer with maxSize. Size represents the written amount. + * If a part of the buffer has been used already, size must be set to the used amount of bytes. + * + * @details + * Implementations of this function must increase the size variable and move the buffer pointer. + * MaxSize must be checked by implementations of this function + * and BUFFER_TOO_SHORT has to be returned if size would be larger than maxSize. + * + * Custom implementations might use additional return values. + * + * @param[in/out] buffer Buffer to serialize into, will be set to the current write location + * @param[in/out] size Size that has been used in the buffer already, will be increased by the function + * @param[in] maxSize The size of the buffer that is allowed to be used for serialize. + * @param[in] streamEndianness Endianness of the serialized data according to SerializeIF::Endianness + * @return + * - @c BUFFER_TOO_SHORT The given buffer in is too short + * - @c RETURN_FAILED Generic error + * - @c RETURN_OK Successful serialization + */ virtual ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize, Endianness streamEndianness) const = 0; + /** + * Gets the size of a object if it would be serialized in a buffer + * @return Size of serialized object + */ virtual size_t getSerializedSize() const = 0; + /** + * @brief + * Deserializes a object from a given buffer of given size. + * + * @details + * Buffer must be moved to the current read location by the implementation + * of this function. Size must be decreased by the implementation. + * Implementations are not allowed to alter the buffer as indicated by const pointer. + * + * Custom implementations might use additional return values. + * + * @param[in/out] buffer Buffer to deSerialize from. Will be moved by the function. + * @param[in/out] size Remaining size of the buffer to read from. Will be decreased by function. + * @param[in] streamEndianness Endianness as in according to SerializeIF::Endianness + * @return + * - @c STREAM_TOO_SHORT The input stream is too short to deSerialize the object + * - @c TOO_MANY_ELEMENTS The buffer has more inputs than expected + * - @c RETURN_FAILED Generic Error + * - @c RETURN_OK Successful deserialization + */ virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size, Endianness streamEndianness) = 0; }; -#endif /* SERIALIZEIF_H_ */ +#endif /* FSFW_SERIALIZE_SERIALIZEIF_H_ */ diff --git a/serviceinterface/ServiceInterfaceBuffer.cpp b/serviceinterface/ServiceInterfaceBuffer.cpp index 880f51e12..68fc4dec3 100644 --- a/serviceinterface/ServiceInterfaceBuffer.cpp +++ b/serviceinterface/ServiceInterfaceBuffer.cpp @@ -1,5 +1,5 @@ #include "../timemanager/Clock.h" -#include "../serviceinterface/ServiceInterfaceBuffer.h" +#include "ServiceInterfaceBuffer.h" #include #include diff --git a/serviceinterface/ServiceInterfaceStream.cpp b/serviceinterface/ServiceInterfaceStream.cpp index 8a3589991..5b7b9f004 100644 --- a/serviceinterface/ServiceInterfaceStream.cpp +++ b/serviceinterface/ServiceInterfaceStream.cpp @@ -1,4 +1,4 @@ -#include "../serviceinterface/ServiceInterfaceStream.h" +#include "ServiceInterfaceStream.h" ServiceInterfaceStream::ServiceInterfaceStream(std::string setMessage, bool addCrToPreamble, bool buffered, bool errStream, uint16_t port) : diff --git a/serviceinterface/ServiceInterfaceStream.h b/serviceinterface/ServiceInterfaceStream.h index 051500f5b..76fa1bf23 100644 --- a/serviceinterface/ServiceInterfaceStream.h +++ b/serviceinterface/ServiceInterfaceStream.h @@ -1,7 +1,7 @@ #ifndef FRAMEWORK_SERVICEINTERFACE_SERVICEINTERFACESTREAM_H_ #define FRAMEWORK_SERVICEINTERFACE_SERVICEINTERFACESTREAM_H_ -#include "../serviceinterface/ServiceInterfaceBuffer.h" +#include "ServiceInterfaceBuffer.h" #include #include diff --git a/storagemanager/ConstStorageAccessor.cpp b/storagemanager/ConstStorageAccessor.cpp index 4ada7f801..842f1ce88 100644 --- a/storagemanager/ConstStorageAccessor.cpp +++ b/storagemanager/ConstStorageAccessor.cpp @@ -1,6 +1,7 @@ +#include "ConstStorageAccessor.h" +#include "StorageManagerIF.h" + #include "../serviceinterface/ServiceInterfaceStream.h" -#include "../storagemanager/ConstStorageAccessor.h" -#include "../storagemanager/StorageManagerIF.h" #include "../globalfunctions/arrayprinter.h" ConstStorageAccessor::ConstStorageAccessor(store_address_t storeId): @@ -14,7 +15,6 @@ ConstStorageAccessor::ConstStorageAccessor(store_address_t storeId, ConstStorageAccessor::~ConstStorageAccessor() { if(deleteData and store != nullptr) { - sif::debug << "deleting store data" << std::endl; store->deleteData(storeId); } } @@ -58,7 +58,8 @@ ReturnValue_t ConstStorageAccessor::getDataCopy(uint8_t *pointer, return HasReturnvaluesIF::RETURN_FAILED; } if(size_ > maxSize) { - sif::error << "StorageAccessor: Supplied buffer not large enough" << std::endl; + sif::error << "StorageAccessor: Supplied buffer not large enough" + << std::endl; return HasReturnvaluesIF::RETURN_FAILED; } std::copy(constDataPointer, constDataPointer + size_, pointer); diff --git a/storagemanager/ConstStorageAccessor.h b/storagemanager/ConstStorageAccessor.h index 573892da5..96d2dca2c 100644 --- a/storagemanager/ConstStorageAccessor.h +++ b/storagemanager/ConstStorageAccessor.h @@ -1,7 +1,7 @@ -#ifndef FRAMEWORK_STORAGEMANAGER_CONSTSTORAGEACCESSOR_H_ -#define FRAMEWORK_STORAGEMANAGER_CONSTSTORAGEACCESSOR_H_ +#ifndef FSFW_STORAGEMANAGER_CONSTSTORAGEACCESSOR_H_ +#define FSFW_STORAGEMANAGER_CONSTSTORAGEACCESSOR_H_ -#include "../storagemanager/storeAddress.h" +#include "storeAddress.h" #include "../returnvalues/HasReturnvaluesIF.h" #include @@ -113,4 +113,4 @@ protected: }; -#endif /* FRAMEWORK_STORAGEMANAGER_CONSTSTORAGEACCESSOR_H_ */ +#endif /* FSFW_STORAGEMANAGER_CONSTSTORAGEACCESSOR_H_ */ diff --git a/storagemanager/LocalPool.h b/storagemanager/LocalPool.h index 2a526b6a3..3a94c03db 100644 --- a/storagemanager/LocalPool.h +++ b/storagemanager/LocalPool.h @@ -1,14 +1,15 @@ -#ifndef FRAMEWORK_STORAGEMANAGER_LOCALPOOL_H_ -#define FRAMEWORK_STORAGEMANAGER_LOCALPOOL_H_ +#ifndef FSFW_STORAGEMANAGER_LOCALPOOL_H_ +#define FSFW_STORAGEMANAGER_LOCALPOOL_H_ +#include "StorageManagerIF.h" #include "../objectmanager/SystemObject.h" -#include "../serviceinterface/ServiceInterfaceStream.h" -#include "../storagemanager/StorageManagerIF.h" #include "../objectmanager/ObjectManagerIF.h" +#include "../serviceinterface/ServiceInterfaceStream.h" #include "../internalError/InternalErrorReporterIF.h" #include "../storagemanager/StorageAccessor.h" #include + /** * @brief The LocalPool class provides an intermediate data storage with * a fixed pool size policy. @@ -184,6 +185,6 @@ private: ReturnValue_t findEmpty(uint16_t pool_index, uint16_t* element); }; -#include "../storagemanager/LocalPool.tpp" +#include "LocalPool.tpp" -#endif /* FRAMEWORK_STORAGEMANAGER_LOCALPOOL_H_ */ +#endif /* FSFW_STORAGEMANAGER_LOCALPOOL_H_ */ diff --git a/storagemanager/LocalPool.tpp b/storagemanager/LocalPool.tpp index 764bd7be4..5e61efe45 100644 --- a/storagemanager/LocalPool.tpp +++ b/storagemanager/LocalPool.tpp @@ -1,7 +1,7 @@ -#ifndef FRAMEWORK_STORAGEMANAGER_LOCALPOOL_TPP_ -#define FRAMEWORK_STORAGEMANAGER_LOCALPOOL_TPP_ +#ifndef FSFW_STORAGEMANAGER_LOCALPOOL_TPP_ +#define FSFW_STORAGEMANAGER_LOCALPOOL_TPP_ -#ifndef FRAMEWORK_STORAGEMANAGER_LOCALPOOL_H_ +#ifndef FSFW_STORAGEMANAGER_LOCALPOOL_H_ #error Include LocalPool.h before LocalPool.tpp! #endif @@ -125,9 +125,10 @@ inline LocalPool::~LocalPool(void) { } } -template inline -ReturnValue_t LocalPool::addData(store_address_t* storageId, - const uint8_t* data, size_t size, bool ignoreFault) { +template +inline ReturnValue_t LocalPool::addData( + store_address_t* storageId, const uint8_t* data, size_t size, + bool ignoreFault) { ReturnValue_t status = reserveSpace(size, storageId, ignoreFault); if (status == RETURN_OK) { write(*storageId, data, size); @@ -171,7 +172,7 @@ inline ReturnValue_t LocalPool::getData(store_address_t storeId template inline ReturnValue_t LocalPool::getData( store_address_t packet_id, const uint8_t** packet_ptr, size_t* size) { - uint8_t* tempData = NULL; + uint8_t* tempData = nullptr; ReturnValue_t status = modifyData(packet_id, &tempData, size); *packet_ptr = tempData; return status; @@ -301,4 +302,4 @@ inline ReturnValue_t LocalPool::initialize() { return RETURN_OK; } -#endif +#endif /* FSFW_STORAGEMANAGER_LOCALPOOL_TPP_ */ diff --git a/storagemanager/PoolManager.h b/storagemanager/PoolManager.h index 76bddb8ff..8cc6c0654 100644 --- a/storagemanager/PoolManager.h +++ b/storagemanager/PoolManager.h @@ -1,9 +1,10 @@ -#ifndef FRAMEWORK_STORAGEMANAGER_POOLMANAGER_H_ -#define FRAMEWORK_STORAGEMANAGER_POOLMANAGER_H_ +#ifndef FSFW_STORAGEMANAGER_POOLMANAGER_H_ +#define FSFW_STORAGEMANAGER_POOLMANAGER_H_ -#include "../storagemanager/LocalPool.h" +#include "LocalPool.h" +#include "StorageAccessor.h" #include "../ipc/MutexHelper.h" -#include "../storagemanager/StorageAccessor.h" + /** * @brief The PoolManager class provides an intermediate data storage with @@ -19,18 +20,24 @@ public: const uint16_t element_sizes[NUMBER_OF_POOLS], const uint16_t n_elements[NUMBER_OF_POOLS]); - //! @brief In the PoolManager's destructor all allocated memory is freed. + /** + * @brief In the PoolManager's destructor all allocated memory + * is freed. + */ virtual ~PoolManager(); - //! @brief LocalPool overrides for thread-safety. Decorator function which - //! wraps LocalPool calls with a mutex protection. + /** + * @brief LocalPool overrides for thread-safety. Decorator function + * which wraps LocalPool calls with a mutex protection. + */ ReturnValue_t deleteData(store_address_t) override; ReturnValue_t deleteData(uint8_t* buffer, size_t size, store_address_t* storeId = nullptr) override; + void setMutexTimeout(uint32_t mutexTimeoutMs); protected: //! Default mutex timeout value to prevent permanent blocking. - static constexpr uint32_t mutexTimeout = 50; + uint32_t mutexTimeoutMs = 20; ReturnValue_t reserveSpace(const uint32_t size, store_address_t* address, bool ignoreFault) override; @@ -46,4 +53,4 @@ protected: #include "PoolManager.tpp" -#endif /* POOLMANAGER_H_ */ +#endif /* FSFW_STORAGEMANAGER_POOLMANAGER_H_ */ diff --git a/storagemanager/PoolManager.tpp b/storagemanager/PoolManager.tpp index 0656e9675..2be44ece2 100644 --- a/storagemanager/PoolManager.tpp +++ b/storagemanager/PoolManager.tpp @@ -1,7 +1,7 @@ #ifndef FRAMEWORK_STORAGEMANAGER_POOLMANAGER_TPP_ #define FRAMEWORK_STORAGEMANAGER_POOLMANAGER_TPP_ -#ifndef FRAMEWORK_STORAGEMANAGER_POOLMANAGER_H_ +#ifndef FSFW_STORAGEMANAGER_POOLMANAGER_H_ #error Include PoolManager.h before PoolManager.tpp! #endif @@ -21,8 +21,7 @@ inline PoolManager::~PoolManager(void) { template inline ReturnValue_t PoolManager::reserveSpace( const uint32_t size, store_address_t* address, bool ignoreFault) { - MutexHelper mutexHelper(mutex, MutexIF::TimeoutType::WAITING, - mutexTimeout); + MutexHelper mutexHelper(mutex,MutexIF::WAITING, mutexTimeoutMs); ReturnValue_t status = LocalPool::reserveSpace(size, address,ignoreFault); return status; @@ -34,8 +33,7 @@ inline ReturnValue_t PoolManager::deleteData( // debug << "PoolManager( " << translateObject(getObjectId()) << // " )::deleteData from store " << packet_id.pool_index << // ". id is "<< packet_id.packet_index << std::endl; - MutexHelper mutexHelper(mutex, MutexIF::TimeoutType::WAITING, - mutexTimeout); + MutexHelper mutexHelper(mutex,MutexIF::WAITING, mutexTimeoutMs); ReturnValue_t status = LocalPool::deleteData(packet_id); return status; } @@ -43,11 +41,16 @@ inline ReturnValue_t PoolManager::deleteData( template inline ReturnValue_t PoolManager::deleteData(uint8_t* buffer, size_t size, store_address_t* storeId) { - MutexHelper mutexHelper(mutex, MutexIF::TimeoutType::WAITING, - mutexTimeout); + MutexHelper mutexHelper(mutex,MutexIF::WAITING, mutexTimeoutMs); ReturnValue_t status = LocalPool::deleteData(buffer, size, storeId); return status; } -#endif +template +inline void PoolManager::setMutexTimeout( + uint32_t mutexTimeoutMs) { + this->mutexTimeout = mutexTimeoutMs; +} + +#endif /* FRAMEWORK_STORAGEMANAGER_POOLMANAGER_TPP_ */ diff --git a/storagemanager/StorageAccessor.cpp b/storagemanager/StorageAccessor.cpp index 60bd41304..9c2f936a5 100644 --- a/storagemanager/StorageAccessor.cpp +++ b/storagemanager/StorageAccessor.cpp @@ -1,5 +1,5 @@ -#include "../storagemanager/StorageAccessor.h" -#include "../storagemanager/StorageManagerIF.h" +#include "StorageAccessor.h" +#include "StorageManagerIF.h" #include "../serviceinterface/ServiceInterfaceStream.h" StorageAccessor::StorageAccessor(store_address_t storeId): diff --git a/storagemanager/StorageAccessor.h b/storagemanager/StorageAccessor.h index a65427b8b..5cf15d509 100644 --- a/storagemanager/StorageAccessor.h +++ b/storagemanager/StorageAccessor.h @@ -1,7 +1,7 @@ -#ifndef FRAMEWORK_STORAGEMANAGER_STORAGEACCESSOR_H_ -#define FRAMEWORK_STORAGEMANAGER_STORAGEACCESSOR_H_ +#ifndef FSFW_STORAGEMANAGER_STORAGEACCESSOR_H_ +#define FSFW_STORAGEMANAGER_STORAGEACCESSOR_H_ -#include "../storagemanager/ConstStorageAccessor.h" +#include "ConstStorageAccessor.h" class StorageManagerIF; @@ -42,4 +42,4 @@ private: void assignConstPointer(); }; -#endif /* TEST_PROTOTYPES_STORAGEACCESSOR_H_ */ +#endif /* FSFW_STORAGEMANAGER_STORAGEACCESSOR_H_ */ diff --git a/storagemanager/StorageManagerIF.h b/storagemanager/StorageManagerIF.h index 2229cdf89..834e75637 100644 --- a/storagemanager/StorageManagerIF.h +++ b/storagemanager/StorageManagerIF.h @@ -1,10 +1,12 @@ -#ifndef STORAGEMANAGERIF_H_H -#define STORAGEMANAGERIF_H_H +#ifndef FSFW_STORAGEMANAGER_STORAGEMANAGERIF_H_ +#define FSFW_STORAGEMANAGER_STORAGEMANAGERIF_H_ + +#include "StorageAccessor.h" +#include "storeAddress.h" #include "../events/Event.h" #include "../returnvalues/HasReturnvaluesIF.h" -#include "../storagemanager/StorageAccessor.h" -#include "../storagemanager/storeAddress.h" + #include #include @@ -164,4 +166,4 @@ public: virtual void clearStore() = 0; }; -#endif /* STORAGEMANAGERIF_H_ */ +#endif /* FSFW_STORAGEMANAGER_STORAGEMANAGERIF_H_ */ diff --git a/storagemanager/storeAddress.h b/storagemanager/storeAddress.h index 5dd785a3e..044c07908 100644 --- a/storagemanager/storeAddress.h +++ b/storagemanager/storeAddress.h @@ -1,5 +1,6 @@ -#ifndef FRAMEWORK_STORAGEMANAGER_STOREADDRESS_H_ -#define FRAMEWORK_STORAGEMANAGER_STOREADDRESS_H_ +#ifndef FSFW_STORAGEMANAGER_STOREADDRESS_H_ +#define FSFW_STORAGEMANAGER_STOREADDRESS_H_ + #include /** @@ -51,4 +52,4 @@ union store_address_t { } }; -#endif /* FRAMEWORK_STORAGEMANAGER_STOREADDRESS_H_ */ +#endif /* FSFW_STORAGEMANAGER_STOREADDRESS_H_ */ diff --git a/subsystem/Subsystem.cpp b/subsystem/Subsystem.cpp index 400ecc830..9712d7d42 100644 --- a/subsystem/Subsystem.cpp +++ b/subsystem/Subsystem.cpp @@ -12,13 +12,10 @@ Subsystem::Subsystem(object_id_t setObjectId, object_id_t parent, uint32_t maxNumberOfSequences, uint32_t maxNumberOfTables) : SubsystemBase(setObjectId, parent, 0), isInTransition(false), childrenChangedHealth(false), currentTargetTable(), - targetMode(0), targetSubmode(SUBMODE_NONE), initialMode(0), - currentSequenceIterator(), modeTables(maxNumberOfTables), - modeSequences(maxNumberOfSequences) {} + targetSubmode(SUBMODE_NONE), currentSequenceIterator(), + modeTables(maxNumberOfTables), modeSequences(maxNumberOfSequences) {} -Subsystem::~Subsystem() { - //Auto-generated destructor stub -} +Subsystem::~Subsystem() {} ReturnValue_t Subsystem::checkSequence(HybridIterator iter, Mode_t fallbackSequence) { @@ -344,7 +341,8 @@ ReturnValue_t Subsystem::addSequence(ArrayList *sequence, ReturnValue_t result; - //Before initialize() is called, tables must not be checked as the children are not added yet. + //Before initialize() is called, tables must not be checked as the + //children are not added yet. //Sequences added before are checked by initialize() if (!preInit) { result = checkSequence( @@ -390,8 +388,8 @@ ReturnValue_t Subsystem::addTable(ArrayList *table, Mode_t id, ReturnValue_t result; - //Before initialize() is called, tables must not be checked as the children are not added yet. - //Tables added before are checked by initialize() + //Before initialize() is called, tables must not be checked as the children + //are not added yet. Tables added before are checked by initialize() if (!preInit) { result = checkTable( HybridIterator(table->front(), table->back())); @@ -545,7 +543,7 @@ Mode_t Subsystem::getFallbackSequence(Mode_t sequence) { for (FixedMap::Iterator iter = modeSequences.begin(); iter != modeSequences.end(); ++iter) { if (iter.value->first == sequence) { - return iter->fallbackSequence; + return iter->second.fallbackSequence; } } return -1; @@ -554,7 +552,7 @@ Mode_t Subsystem::getFallbackSequence(Mode_t sequence) { bool Subsystem::isFallbackSequence(Mode_t SequenceId) { for (FixedMap::Iterator iter = modeSequences.begin(); iter != modeSequences.end(); iter++) { - if (iter->fallbackSequence == SequenceId) { + if (iter->second.fallbackSequence == SequenceId) { return true; } } @@ -582,12 +580,14 @@ void Subsystem::transitionFailed(ReturnValue_t failureCode, triggerEvent(MODE_TRANSITION_FAILED, failureCode, parameter); if (mode == targetMode) { //already tried going back to the current mode - //go into fallback mode, also set current mode to fallback mode, so we come here at the next fail + //go into fallback mode, also set current mode to fallback mode, + //so we come here at the next fail modeHelper.setForced(true); ReturnValue_t result; if ((result = checkSequence(getFallbackSequence(mode))) != RETURN_OK) { triggerEvent(FALLBACK_FAILED, result, getFallbackSequence(mode)); - isInTransition = false; //keep still and allow arbitrary mode commands to recover + //keep still and allow arbitrary mode commands to recover + isInTransition = false; return; } mode = getFallbackSequence(mode); @@ -651,8 +651,10 @@ void Subsystem::cantKeepMode() { modeHelper.setForced(true); - //already set the mode, so that we do not try to go back in our old mode when the transition fails + //already set the mode, so that we do not try to go back in our old mode + //when the transition fails mode = getFallbackSequence(mode); - //SHOULDDO: We should store submodes for fallback sequence as well, otherwise we should get rid of submodes completely. + //SHOULDDO: We should store submodes for fallback sequence as well, + //otherwise we should get rid of submodes completely. startTransition(mode, SUBMODE_NONE); } diff --git a/subsystem/Subsystem.h b/subsystem/Subsystem.h index 2b501574f..9a3fcdfe6 100644 --- a/subsystem/Subsystem.h +++ b/subsystem/Subsystem.h @@ -1,13 +1,14 @@ -#ifndef SUBSYSTEM_H_ -#define SUBSYSTEM_H_ +#ifndef FSFW_SUBSYSTEM_SUBSYSTEM_H_ +#define FSFW_SUBSYSTEM_SUBSYSTEM_H_ + +#include "SubsystemBase.h" +#include "modes/ModeDefinitions.h" #include "../container/FixedArrayList.h" #include "../container/FixedMap.h" #include "../container/HybridIterator.h" #include "../container/SinglyLinkedList.h" #include "../serialize/SerialArrayListAdapter.h" -#include "../subsystem/modes/ModeDefinitions.h" -#include "../subsystem/SubsystemBase.h" class Subsystem: public SubsystemBase, public HasModeSequenceIF { public: @@ -44,11 +45,11 @@ public: void setInitialMode(Mode_t mode); - virtual ReturnValue_t initialize(); + virtual ReturnValue_t initialize() override; - virtual ReturnValue_t checkObjectConnections(); + virtual ReturnValue_t checkObjectConnections() override; - virtual MessageQueueId_t getSequenceCommandQueue() const; + virtual MessageQueueId_t getSequenceCommandQueue() const override; /** * @@ -96,11 +97,11 @@ protected: HybridIterator currentTargetTable; - Mode_t targetMode; + Mode_t targetMode = 0; Submode_t targetSubmode; - Mode_t initialMode; + Mode_t initialMode = 0; HybridIterator currentSequenceIterator; @@ -153,7 +154,8 @@ protected: virtual void startTransition(Mode_t mode, Submode_t submode); - void sendSerializablesAsCommandMessage(Command_t command, SerializeIF **elements, uint8_t count); + void sendSerializablesAsCommandMessage(Command_t command, + SerializeIF **elements, uint8_t count); void transitionFailed(ReturnValue_t failureCode, uint32_t parameter); @@ -161,4 +163,4 @@ protected: }; -#endif /* SUBSYSTEM_H_ */ +#endif /* FSFW_SUBSYSTEM_SUBSYSTEM_H_ */ diff --git a/subsystem/SubsystemBase.cpp b/subsystem/SubsystemBase.cpp index 17599808f..f60c88478 100644 --- a/subsystem/SubsystemBase.cpp +++ b/subsystem/SubsystemBase.cpp @@ -6,10 +6,10 @@ SubsystemBase::SubsystemBase(object_id_t setObjectId, object_id_t parent, Mode_t initialMode, uint16_t commandQueueDepth) : SystemObject(setObjectId), mode(initialMode), submode(SUBMODE_NONE), - childrenChangedMode(false), commandsOutstanding(0), commandQueue(NULL), + childrenChangedMode(false), + commandQueue(QueueFactory::instance()->createMessageQueue( + commandQueueDepth, CommandMessage::MAX_MESSAGE_SIZE)), healthHelper(this, setObjectId), modeHelper(this), parentId(parent) { - commandQueue = QueueFactory::instance()->createMessageQueue(commandQueueDepth, - MessageQueueMessage::MAX_MESSAGE_SIZE); } SubsystemBase::~SubsystemBase() { @@ -21,7 +21,8 @@ ReturnValue_t SubsystemBase::registerChild(object_id_t objectId) { ChildInfo info; HasModesIF *child = objectManager->get(objectId); - //This is a rather ugly hack to have the changedHealth info for all children available. (needed for FOGs). + // This is a rather ugly hack to have the changedHealth info for all + // children available. HasHealthIF* healthChild = objectManager->get(objectId); if (child == nullptr) { if (healthChild == nullptr) { @@ -38,14 +39,11 @@ ReturnValue_t SubsystemBase::registerChild(object_id_t objectId) { info.submode = SUBMODE_NONE; info.healthChanged = false; - std::pair::iterator, bool> returnValue = - childrenMap.insert( - std::pair(objectId, info)); - if (!(returnValue.second)) { + auto resultPair = childrenMap.emplace(objectId, info); + if (not resultPair.second) { return COULD_NOT_INSERT_CHILD; - } else { - return RETURN_OK; } + return RETURN_OK; } ReturnValue_t SubsystemBase::checkStateAgainstTable( diff --git a/subsystem/SubsystemBase.h b/subsystem/SubsystemBase.h index 2d949b56c..b8e4f9029 100644 --- a/subsystem/SubsystemBase.h +++ b/subsystem/SubsystemBase.h @@ -1,5 +1,7 @@ -#ifndef SUBSYSTEMBASE_H_ -#define SUBSYSTEMBASE_H_ +#ifndef FSFW_SUBSYSTEM_SUBSYSTEMBASE_H_ +#define FSFW_SUBSYSTEM_SUBSYSTEMBASE_H_ + +#include "modes/HasModeSequenceIF.h" #include "../container/HybridIterator.h" #include "../health/HasHealthIF.h" @@ -7,7 +9,6 @@ #include "../modes/HasModesIF.h" #include "../objectmanager/SystemObject.h" #include "../returnvalues/HasReturnvaluesIF.h" -#include "../subsystem/modes/HasModeSequenceIF.h" #include "../tasks/ExecutableObjectIF.h" #include "../ipc/MessageQueueIF.h" #include @@ -34,17 +35,17 @@ public: Mode_t initialMode = 0, uint16_t commandQueueDepth = 8); virtual ~SubsystemBase(); - virtual MessageQueueId_t getCommandQueue() const; + virtual MessageQueueId_t getCommandQueue() const override; ReturnValue_t registerChild(object_id_t objectId); - virtual ReturnValue_t initialize(); + virtual ReturnValue_t initialize() 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; protected: struct ChildInfo { @@ -62,9 +63,9 @@ protected: /** * Always check this against <=0, so you are robust against too many replies */ - int32_t commandsOutstanding; + int32_t commandsOutstanding = 0; - MessageQueueIF* commandQueue; + MessageQueueIF* commandQueue = nullptr; HealthHelper healthHelper; @@ -126,4 +127,4 @@ protected: virtual void modeChanged(); }; -#endif /* SUBSYSTEMBASE_H_ */ +#endif /* FSFW_SUBSYSTEM_SUBSYSTEMBASE_H_ */ diff --git a/subsystem/modes/HasModeSequenceIF.h b/subsystem/modes/HasModeSequenceIF.h index 06bde2aae..70b1667e9 100644 --- a/subsystem/modes/HasModeSequenceIF.h +++ b/subsystem/modes/HasModeSequenceIF.h @@ -1,9 +1,9 @@ #ifndef HASMODESEQUENCEIF_H_ #define HASMODESEQUENCEIF_H_ -#include "../../subsystem/modes/ModeDefinitions.h" -#include "../../subsystem/modes/ModeSequenceMessage.h" -#include "../../subsystem/modes/ModeStoreIF.h" +#include "ModeDefinitions.h" +#include "ModeSequenceMessage.h" +#include "ModeStoreIF.h" class HasModeSequenceIF { diff --git a/subsystem/modes/ModeDefinitions.h b/subsystem/modes/ModeDefinitions.h index a865ab0cf..13a780ee0 100644 --- a/subsystem/modes/ModeDefinitions.h +++ b/subsystem/modes/ModeDefinitions.h @@ -1,22 +1,19 @@ -#ifndef MODEDEFINITIONS_H_ -#define MODEDEFINITIONS_H_ +#ifndef FSFW_SUBSYSTEM_MODES_MODEDEFINITIONS_H_ +#define FSFW_SUBSYSTEM_MODES_MODEDEFINITIONS_H_ #include "../../modes/HasModesIF.h" #include "../../objectmanager/SystemObjectIF.h" #include "../../serialize/SerializeIF.h" #include "../../serialize/SerialLinkedListAdapter.h" + class ModeListEntry: public SerializeIF, public LinkedElement { public: - ModeListEntry() : - LinkedElement(this), value1(0), value2(0), value3(0), value4( - 0) { + ModeListEntry(): LinkedElement(this) {} - } - - uint32_t value1; - uint32_t value2; - uint8_t value3; - uint8_t value4; + uint32_t value1 = 0; + uint32_t value2 = 0; + uint8_t value3 = 0; + uint8_t value4 = 0; virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize, Endianness streamEndianness) const { @@ -149,4 +146,4 @@ public: } }; -#endif //MODEDEFINITIONS_H_ +#endif /* FSFW_SUBSYSTEM_MODES_MODEDEFINITIONS_H_ */ diff --git a/subsystem/modes/ModeSequenceMessage.cpp b/subsystem/modes/ModeSequenceMessage.cpp index e092380ef..7733098e3 100644 --- a/subsystem/modes/ModeSequenceMessage.cpp +++ b/subsystem/modes/ModeSequenceMessage.cpp @@ -1,8 +1,7 @@ -#include "../../objectmanager/ObjectManagerIF.h" -#include "../../objectmanager/ObjectManagerIF.h" +#include "ModeSequenceMessage.h" + #include "../../objectmanager/ObjectManagerIF.h" #include "../../storagemanager/StorageManagerIF.h" -#include "../../subsystem/modes/ModeSequenceMessage.h" void ModeSequenceMessage::setModeSequenceMessage(CommandMessage* message, Command_t command, Mode_t sequence, store_address_t storeAddress) { @@ -11,25 +10,12 @@ void ModeSequenceMessage::setModeSequenceMessage(CommandMessage* message, message->setParameter2(sequence); } -//void ModeSequenceMessage::setModeSequenceMessage(CommandMessage* message, -// Command_t command, ModeTableId_t table, store_address_t storeAddress) { -// message->setCommand(command); -// message->setParameter(storeAddress.raw); -// message->setParameter2(table); -//} - void ModeSequenceMessage::setModeSequenceMessage(CommandMessage* message, Command_t command, Mode_t sequence) { message->setCommand(command); message->setParameter2(sequence); } -//void ModeSequenceMessage::setModeSequenceMessage(CommandMessage* message, -// Command_t command, ModeTableId_t table) { -// message->setCommand(command); -// message->setParameter2(table); -//} - void ModeSequenceMessage::setModeSequenceMessage(CommandMessage* message, Command_t command, store_address_t storeAddress) { message->setCommand(command); @@ -63,9 +49,10 @@ void ModeSequenceMessage::clear(CommandMessage *message) { case SEQUENCE_LIST: case TABLE_LIST: case TABLE: - case SEQUENCE:{ - StorageManagerIF *ipcStore = objectManager->get(objects::IPC_STORE); - if (ipcStore != NULL){ + case SEQUENCE: { + StorageManagerIF *ipcStore = objectManager->get( + objects::IPC_STORE); + if (ipcStore != nullptr){ ipcStore->deleteData(ModeSequenceMessage::getStoreAddress(message)); } } diff --git a/subsystem/modes/ModeSequenceMessage.h b/subsystem/modes/ModeSequenceMessage.h index 61ba30f31..9be4586e2 100644 --- a/subsystem/modes/ModeSequenceMessage.h +++ b/subsystem/modes/ModeSequenceMessage.h @@ -1,9 +1,10 @@ -#ifndef MODESEQUENCEMESSAGE_H_ -#define MODESEQUENCEMESSAGE_H_ +#ifndef FSFW_SUBSYSTEM_MODES_MODESEQUENCEMESSAGE_H_ +#define FSFW_SUBSYSTEM_MODES_MODESEQUENCEMESSAGE_H_ +#include "ModeDefinitions.h" #include "../../ipc/CommandMessage.h" #include "../../storagemanager/StorageManagerIF.h" -#include "../../subsystem/modes/ModeDefinitions.h" + class ModeSequenceMessage { public: @@ -45,4 +46,4 @@ private: ModeSequenceMessage(); }; -#endif /* MODESEQUENCEMESSAGE_H_ */ +#endif /* FSFW_SUBSYSTEM_MODES_MODESEQUENCEMESSAGE_H_ */ diff --git a/subsystem/modes/ModeStore.cpp b/subsystem/modes/ModeStore.cpp index dce2931c1..260e5ab21 100644 --- a/subsystem/modes/ModeStore.cpp +++ b/subsystem/modes/ModeStore.cpp @@ -1,5 +1,7 @@ #include "../../subsystem/modes/ModeStore.h" +// todo: I think some parts are deprecated. If this is used, the define +// USE_MODESTORE could be part of the new FSFWConfig.h file. #ifdef USE_MODESTORE ModeStore::ModeStore(object_id_t objectId, uint32_t slots) : diff --git a/tasks/FixedSequenceSlot.cpp b/tasks/FixedSequenceSlot.cpp index d7aeff0af..f5d82178d 100644 --- a/tasks/FixedSequenceSlot.cpp +++ b/tasks/FixedSequenceSlot.cpp @@ -1,5 +1,5 @@ -#include "../objectmanager/SystemObjectIF.h" -#include "../tasks/FixedSequenceSlot.h" +#include "FixedSequenceSlot.h" +#include "PeriodicTaskIF.h" #include FixedSequenceSlot::FixedSequenceSlot(object_id_t handlerId, uint32_t setTime, diff --git a/tasks/FixedSequenceSlot.h b/tasks/FixedSequenceSlot.h index 151173e96..1744ec198 100644 --- a/tasks/FixedSequenceSlot.h +++ b/tasks/FixedSequenceSlot.h @@ -1,8 +1,9 @@ -#ifndef FRAMEWORK_TASKS_FIXEDSEQUENCESLOT_H_ -#define FRAMEWORK_TASKS_FIXEDSEQUENCESLOT_H_ +#ifndef FSFW_TASKS_FIXEDSEQUENCESLOT_H_ +#define FSFW_TASKS_FIXEDSEQUENCESLOT_H_ +#include "ExecutableObjectIF.h" #include "../objectmanager/ObjectManagerIF.h" -#include "../tasks/ExecutableObjectIF.h" + class PeriodicTaskIF; /** @@ -56,4 +57,4 @@ public: }; -#endif /* FIXEDSEQUENCESLOT_H_ */ +#endif /* FSFW_TASKS_FIXEDSEQUENCESLOT_H_ */ diff --git a/tasks/FixedSlotSequence.cpp b/tasks/FixedSlotSequence.cpp index 59859ce51..e5db4301e 100644 --- a/tasks/FixedSlotSequence.cpp +++ b/tasks/FixedSlotSequence.cpp @@ -1,5 +1,5 @@ +#include "FixedSlotSequence.h" #include "../serviceinterface/ServiceInterfaceStream.h" -#include "../tasks/FixedSlotSequence.h" #include FixedSlotSequence::FixedSlotSequence(uint32_t setLengthMs) : @@ -91,21 +91,31 @@ void FixedSlotSequence::addSlot(object_id_t componentId, uint32_t slotTimeMs, ReturnValue_t FixedSlotSequence::checkSequence() const { if(slotList.empty()) { - sif::error << "Fixed Slot Sequence: Slot list is empty!" << std::endl; + sif::error << "FixedSlotSequence::checkSequence:" + << " Slot list is empty!" << std::endl; return HasReturnvaluesIF::RETURN_FAILED; } - uint32_t count = 0; + if(customCheckFunction != nullptr) { + ReturnValue_t result = customCheckFunction(slotList); + if(result != HasReturnvaluesIF::RETURN_OK) { + // Continue for now but print error output. + sif::error << "FixedSlotSequence::checkSequence:" + << " Custom check failed!" << std::endl; + } + } + + uint32_t errorCount = 0; uint32_t time = 0; for(const auto& slot: slotList) { if (slot.executableObject == nullptr) { - count++; + errorCount++; } else if (slot.pollingTimeMs < time) { - sif::error << "FixedSlotSequence::initialize: Time: " + sif::error << "FixedSlotSequence::checkSequence: Time: " << slot.pollingTimeMs << " is smaller than previous with " << time << std::endl; - count++; + errorCount++; } else { // All ok, print slot. @@ -117,7 +127,7 @@ ReturnValue_t FixedSlotSequence::checkSequence() const { } //sif::info << "Number of elements in slot list: " // << slotList.size() << std::endl; - if (count > 0) { + if (errorCount > 0) { return HasReturnvaluesIF::RETURN_FAILED; } return HasReturnvaluesIF::RETURN_OK; @@ -145,3 +155,8 @@ ReturnValue_t FixedSlotSequence::intializeSequenceAfterTaskCreation() const { } return HasReturnvaluesIF::RETURN_OK; } + +void FixedSlotSequence::addCustomCheck(ReturnValue_t + (*customCheckFunction)(const SlotList&)) { + this->customCheckFunction = customCheckFunction; +} diff --git a/tasks/FixedSlotSequence.h b/tasks/FixedSlotSequence.h index 1140dd254..19a05f210 100644 --- a/tasks/FixedSlotSequence.h +++ b/tasks/FixedSlotSequence.h @@ -1,26 +1,30 @@ -#ifndef FRAMEWORK_TASKS_FIXEDSLOTSEQUENCE_H_ -#define FRAMEWORK_TASKS_FIXEDSLOTSEQUENCE_H_ +#ifndef FSFW_TASKS_FIXEDSLOTSEQUENCE_H_ +#define FSFW_TASKS_FIXEDSLOTSEQUENCE_H_ +#include "FixedSequenceSlot.h" #include "../objectmanager/SystemObject.h" -#include "../tasks/FixedSequenceSlot.h" #include /** - * @brief This class is the representation of a Polling Sequence Table in software. + * @brief This class is the representation of a + * Polling Sequence Table in software. * @details * The FixedSlotSequence object maintains the dynamic execution of - * device handler objects. + * objects with stricter timing requirements for the FixedTimeslotTask. * - * The main idea is to create a list of device handlers, to announce all - * handlers to thepolling sequence and to maintain a list of - * polling slot objects. This slot list represents the Polling Sequence Table - * in software. + * The main idea is to create a list of executable objects (for example + * device handlers), to announce all handlers to the polling sequence and to + * maintain a list of polling slot objects. + * This slot list represents the Polling Sequence Table in software. * * Each polling slot contains information to indicate when and - * which device handler shall be executed within a given polling period. - * The sequence is then executed by iterating through this slot list. - * Handlers are invoking by calling a certain function stored in the handler list. + * which executable object shall be executed within a given polling period. + * When adding a slot, a pointer to the executing task, a pointer to the + * executable object and a step number can be passed. The step number will be + * passed to the periodic handler. + * The sequence is executed by iterating through the slot sequence and + * executing the executable object in the correct timeslot. */ class FixedSlotSequence { public: @@ -29,41 +33,44 @@ public: /** * @brief The constructor of the FixedSlotSequence object. - * - * @details The constructor takes two arguments, the period length and the init function. - * * @param setLength The period length, expressed in ms. */ FixedSlotSequence(uint32_t setLengthMs); /** * @brief The destructor of the FixedSlotSequence object. - * - * @details The destructor frees all allocated memory by iterating through the slotList - * and deleting all allocated resources. + * @details + * The destructor frees all allocated memory by iterating through the + * slotList and deleting all allocated resources. */ virtual ~FixedSlotSequence(); /** * @brief This is a method to add an PollingSlot object to slotList. * - * @details Here, a polling slot object is added to the slot list. It is appended - * to the end of the list. The list is currently NOT reordered. - * Afterwards, the iterator current is set to the beginning of the list. - * @param Object ID of the object to add - * @param setTime Value between (0 to 1) * slotLengthMs, when a FixedTimeslotTask - * will be called inside the slot period. - * @param setSequenceId ID which can be used to distinguish - * different task operations + * @details + * Here, a polling slot object is added to the slot list. It is appended + * to the end of the list. The list is currently NOT reordered. + * Afterwards, the iterator current is set to the beginning of the list. + * @param handlerId ID of the object to add + * @param setTime + * Value between (0 to 1) * slotLengthMs, when a FixedTimeslotTask + * will be called inside the slot period. + * @param setSequenceId + * ID which can be used to distinguish different task operations. This + * value will be passed to the executable function. * @param * @param */ void addSlot(object_id_t handlerId, uint32_t setTime, int8_t setSequenceId, - ExecutableObjectIF* executableObject, PeriodicTaskIF* executingTask); + ExecutableObjectIF* executableObject, + PeriodicTaskIF* executingTask); /** - * Checks if the current slot shall be executed immediately after the one before. - * This allows to distinguish between grouped and not grouped handlers. + * @brief Checks if the current slot shall be executed immediately + * after the one before. + * @details + * This allows to distinguish between grouped and separated handlers. * @return - @c true if the slot has the same polling time as the previous * - @c false else */ @@ -128,12 +135,18 @@ public: * @brief Check and initialize slot list. * @details * Checks if timing is ok (must be ascending) and if all handlers were found. - * Also calls any initialization steps which are required after task - * creation. * @return */ ReturnValue_t checkSequence() const; + void addCustomCheck(ReturnValue_t (*customCheckFunction)(const SlotList &)); + + /** + * @brief Perform any initialization steps required after the executing + * task has been created. This function should be called from the + * executing task! + * @return + */ ReturnValue_t intializeSequenceAfterTaskCreation() const; protected: @@ -151,9 +164,9 @@ protected: */ SlotList slotList; - uint32_t lengthMs; + ReturnValue_t (*customCheckFunction)(const SlotList&) = nullptr; - bool isEmpty = false; + uint32_t lengthMs; }; -#endif /* FIXEDSLOTSEQUENCE_H_ */ +#endif /* FSFW_TASKS_FIXEDSLOTSEQUENCE_H_ */ diff --git a/tcdistribution/CCSDSDistributor.cpp b/tcdistribution/CCSDSDistributor.cpp index dda26d7f9..ddd633083 100644 --- a/tcdistribution/CCSDSDistributor.cpp +++ b/tcdistribution/CCSDSDistributor.cpp @@ -1,5 +1,6 @@ +#include "CCSDSDistributor.h" + #include "../serviceinterface/ServiceInterfaceStream.h" -#include "../tcdistribution/CCSDSDistributor.h" #include "../tmtcpacket/SpacePacketBase.h" CCSDSDistributor::CCSDSDistributor(uint16_t setDefaultApid, @@ -19,7 +20,7 @@ TcDistributor::TcMqMapIter CCSDSDistributor::selectDestination() { &packet, &size ); if(result != HasReturnvaluesIF::RETURN_OK) { sif::error << "CCSDSDistributor::selectDestination: Getting data from" - "store failed!" << std::endl; + " store failed!" << std::endl; } SpacePacketBase currentPacket(packet); @@ -42,9 +43,9 @@ MessageQueueId_t CCSDSDistributor::getRequestQueue() { ReturnValue_t CCSDSDistributor::registerApplication( AcceptsTelecommandsIF* application) { ReturnValue_t returnValue = RETURN_OK; - bool errorCode = true; - errorCode = this->queueMap.insert( std::pair( application->getIdentifier(), application->getRequestQueue() ) ).second; - if( errorCode == false ) { + auto insertPair = this->queueMap.emplace(application->getIdentifier(), + application->getRequestQueue()); + if(not insertPair.second) { returnValue = RETURN_FAILED; } return returnValue; @@ -53,9 +54,8 @@ ReturnValue_t CCSDSDistributor::registerApplication( ReturnValue_t CCSDSDistributor::registerApplication(uint16_t apid, MessageQueueId_t id) { ReturnValue_t returnValue = RETURN_OK; - bool errorCode = true; - errorCode = this->queueMap.insert( std::pair( apid, id ) ).second; - if( errorCode == false ) { + auto insertPair = this->queueMap.emplace(apid, id); + if(not insertPair.second) { returnValue = RETURN_FAILED; } return returnValue; @@ -69,7 +69,11 @@ uint16_t CCSDSDistributor::getIdentifier() { ReturnValue_t CCSDSDistributor::initialize() { ReturnValue_t status = this->TcDistributor::initialize(); this->tcStore = objectManager->get( objects::TC_STORE ); - if (this->tcStore == NULL) status = RETURN_FAILED; + if (this->tcStore == nullptr) { + sif::error << "CCSDSDistributor::initialize: Could not initialize" + " TC store!" << std::endl; + status = RETURN_FAILED; + } return status; } diff --git a/tcdistribution/CCSDSDistributor.h b/tcdistribution/CCSDSDistributor.h index 6abd952b4..e8d54c9c9 100644 --- a/tcdistribution/CCSDSDistributor.h +++ b/tcdistribution/CCSDSDistributor.h @@ -38,7 +38,7 @@ public: MessageQueueId_t id) override; ReturnValue_t registerApplication( AcceptsTelecommandsIF* application) override; - uint16_t getIdentifier(); + uint16_t getIdentifier() override; ReturnValue_t initialize() override; protected: @@ -50,6 +50,12 @@ protected: * @return Iterator to map entry of found APID or iterator to default APID. */ TcMqMapIter selectDestination() override; + /** + * The callback here handles the generation of acceptance + * success/failure messages. + */ + ReturnValue_t callbackAfterSending( ReturnValue_t queueStatus ) override; + /** * The default APID, where packets with unknown APID are sent to. */ @@ -59,11 +65,7 @@ protected: * pure Space Packets and there exists no SpacePacketStored class. */ StorageManagerIF* tcStore = nullptr; - /** - * The callback here handles the generation of acceptance - * success/failure messages. - */ - ReturnValue_t callbackAfterSending( ReturnValue_t queueStatus ); + }; #endif /* FRAMEWORK_TCDISTRIBUTION_CCSDSDISTRIBUTOR_H_ */ diff --git a/tcdistribution/CCSDSDistributorIF.h b/tcdistribution/CCSDSDistributorIF.h index be3c28114..6334a35ad 100644 --- a/tcdistribution/CCSDSDistributorIF.h +++ b/tcdistribution/CCSDSDistributorIF.h @@ -1,34 +1,38 @@ -#ifndef CCSDSDISTRIBUTORIF_H_ -#define CCSDSDISTRIBUTORIF_H_ +#ifndef FSFW_TCDISTRIBUTION_CCSDSDISTRIBUTORIF_H_ +#define FSFW_TCDISTRIBUTION_CCSDSDISTRIBUTORIF_H_ #include "../tmtcservices/AcceptsTelecommandsIF.h" #include "../ipc/MessageQueueSenderIF.h" /** * This is the Interface to a CCSDS Distributor. - * On a CCSDS Distributor, Applications (in terms of CCSDS) may register themselves, - * either by passing a pointer to themselves (and implementing the CCSDSApplicationIF, - * or by explicitly passing an APID and a MessageQueueId to route the TC's to. - * \ingroup tc_distribution + * On a CCSDS Distributor, Applications (in terms of CCSDS) may register + * themselves, either by passing a pointer to themselves (and implementing the + * CCSDSApplicationIF), or by explicitly passing an APID and a MessageQueueId + * to route the TC's to. + * @ingroup tc_distribution */ class CCSDSDistributorIF { public: /** - * With this call, a class implementing the CCSDSApplicationIF can register at the - * distributor. + * With this call, a class implementing the CCSDSApplicationIF can register + * at the distributor. * @param application A pointer to the Application to register. - * @return - \c RETURN_OK on success, - * - \c RETURN_FAILED on failure. + * @return - @c RETURN_OK on success, + * - @c RETURN_FAILED on failure. */ - virtual ReturnValue_t registerApplication( AcceptsTelecommandsIF* application ) = 0; + virtual ReturnValue_t registerApplication( + AcceptsTelecommandsIF* application) = 0; /** * With this call, other Applications can register to the CCSDS distributor. * This is done by passing an APID and a MessageQueueId to the method. * @param apid The APID to register. - * @param id The MessageQueueId of the message queue to send the TC Packets to. - * @return - \c RETURN_OK on success, - * - \c RETURN_FAILED on failure. + * @param id The MessageQueueId of the message queue to send the + * TC Packets to. + * @return - @c RETURN_OK on success, + * - @c RETURN_FAILED on failure. */ - virtual ReturnValue_t registerApplication( uint16_t apid, MessageQueueId_t id ) = 0; + virtual ReturnValue_t registerApplication( uint16_t apid, + MessageQueueId_t id) = 0; /** * The empty virtual destructor. */ @@ -37,4 +41,4 @@ public: }; -#endif /* CCSDSDISTRIBUTORIF_H_ */ +#endif /* FSFW_TCDISTRIBUTION_CCSDSDISTRIBUTORIF_H_ */ diff --git a/tcdistribution/PUSDistributor.cpp b/tcdistribution/PUSDistributor.cpp index 0c710ef28..63d1dcde5 100644 --- a/tcdistribution/PUSDistributor.cpp +++ b/tcdistribution/PUSDistributor.cpp @@ -1,57 +1,69 @@ +#include "CCSDSDistributorIF.h" +#include "PUSDistributor.h" + #include "../serviceinterface/ServiceInterfaceStream.h" -#include "../tcdistribution/CCSDSDistributorIF.h" -#include "../tcdistribution/PUSDistributor.h" #include "../tmtcpacket/pus/TcPacketStored.h" #include "../tmtcservices/PusVerificationReport.h" PUSDistributor::PUSDistributor(uint16_t setApid, object_id_t setObjectId, object_id_t setPacketSource) : TcDistributor(setObjectId), checker(setApid), verifyChannel(), - currentPacket(), tcStatus(RETURN_FAILED), - packetSource(setPacketSource) {} + tcStatus(RETURN_FAILED), packetSource(setPacketSource) {} PUSDistributor::~PUSDistributor() {} -TcDistributor::TcMqMapIter PUSDistributor::selectDestination() { - TcMqMapIter queueMapIt = this->queueMap.end(); - this->currentPacket.setStoreAddress(this->currentMessage.getStorageId()); - if (currentPacket.getWholeData() != NULL) { - tcStatus = checker.checkPacket(¤tPacket); -// sif::debug << "PUSDistributor::handlePacket: packetCheck returned with " -// << (int)tcStatus << std::endl; - uint32_t queue_id = currentPacket.getService(); - queueMapIt = this->queueMap.find(queue_id); - } else { - tcStatus = PACKET_LOST; - } - if (queueMapIt == this->queueMap.end()) { - tcStatus = DESTINATION_NOT_FOUND; - } +PUSDistributor::TcMqMapIter PUSDistributor::selectDestination() { + // sif:: debug << "PUSDistributor::handlePacket received: " + // << this->current_packet_id.store_index << ", " + // << this->current_packet_id.packet_index << std::endl; + TcMqMapIter queueMapIt = this->queueMap.end(); + if(this->currentPacket == nullptr) { + return queueMapIt; + } + this->currentPacket->setStoreAddress(this->currentMessage.getStorageId()); + if (currentPacket->getWholeData() != nullptr) { + tcStatus = checker.checkPacket(currentPacket); +#ifdef DEBUG + if(tcStatus != HasReturnvaluesIF::RETURN_OK) { + sif::debug << "PUSDistributor::handlePacket: Packet format " + << "invalid, code "<< static_cast(tcStatus) + << std::endl; + } +#endif + uint32_t queue_id = currentPacket->getService(); + queueMapIt = this->queueMap.find(queue_id); + } + else { + tcStatus = PACKET_LOST; + } - if (tcStatus != RETURN_OK) { - sif::debug << "PUSDistributor::handlePacket: Error with " << tcStatus - << ", 0x"<< std::hex << tcStatus << std::dec << std::endl; - return this->queueMap.end(); - } else { - return queueMapIt; - } + if (queueMapIt == this->queueMap.end()) { + tcStatus = DESTINATION_NOT_FOUND; +#ifdef DEBUG + sif::debug << "PUSDistributor::handlePacket: Destination not found, " + << "code "<< static_cast(tcStatus) << std::endl; +#endif + } + + if (tcStatus != RETURN_OK) { + return this->queueMap.end(); + } + else { + return queueMapIt; + } } -//uint16_t PUSDistributor::createDestination( uint8_t service_id, uint8_t subservice_id ) { -// return ( service_id << 8 ) + subservice_id; -//} ReturnValue_t PUSDistributor::registerService(AcceptsTelecommandsIF* service) { uint16_t serviceId = service->getIdentifier(); - //info << "Service ID: " << (int)serviceId << std::endl; + // sif::info << "Service ID: " << (int)serviceId << std::endl; MessageQueueId_t queue = service->getRequestQueue(); auto returnPair = queueMap.emplace(serviceId, queue); if (not returnPair.second) { - //TODO Return Code sif::error << "PUSDistributor::registerService: Service ID already" " exists in map." << std::endl; - return HasReturnvaluesIF::RETURN_FAILED; + return SERVICE_ID_ALREADY_EXISTS; } return HasReturnvaluesIF::RETURN_OK; } @@ -66,13 +78,14 @@ ReturnValue_t PUSDistributor::callbackAfterSending(ReturnValue_t queueStatus) { } if (tcStatus != RETURN_OK) { this->verifyChannel.sendFailureReport(TC_VERIFY::ACCEPTANCE_FAILURE, - ¤tPacket, tcStatus); - //A failed packet is deleted immediately after reporting, otherwise it will block memory. - currentPacket.deletePacket(); + currentPacket, tcStatus); + // A failed packet is deleted immediately after reporting, + // otherwise it will block memory. + currentPacket->deletePacket(); return RETURN_FAILED; } else { this->verifyChannel.sendSuccessReport(TC_VERIFY::ACCEPTANCE_SUCCESS, - ¤tPacket); + currentPacket); return RETURN_OK; } } @@ -84,9 +97,14 @@ uint16_t PUSDistributor::getIdentifier() { ReturnValue_t PUSDistributor::initialize() { CCSDSDistributorIF* ccsdsDistributor = objectManager->get(packetSource); - if (ccsdsDistributor == NULL) { - return RETURN_FAILED; - } else { + currentPacket = new TcPacketStored(); + if (ccsdsDistributor == nullptr) { + sif::error << "PUSDistributor::initialize: Packet source invalid." + << " Make sure it exists and implements CCSDSDistributorIF!" + << std::endl; + return RETURN_FAILED; + } + else { return ccsdsDistributor->registerApplication(this); } } diff --git a/tcdistribution/PUSDistributor.h b/tcdistribution/PUSDistributor.h index b8cff1f44..be3804ef2 100644 --- a/tcdistribution/PUSDistributor.h +++ b/tcdistribution/PUSDistributor.h @@ -1,10 +1,11 @@ -#ifndef FRAMEWORK_TCDISTRIBUTION_PUSDISTRIBUTOR_H_ -#define FRAMEWORK_TCDISTRIBUTION_PUSDISTRIBUTOR_H_ +#ifndef FSFW_TCDISTRIBUTION_PUSDISTRIBUTOR_H_ +#define FSFW_TCDISTRIBUTION_PUSDISTRIBUTOR_H_ + +#include "PUSDistributorIF.h" +#include "TcDistributor.h" +#include "TcPacketCheck.h" #include "../returnvalues/HasReturnvaluesIF.h" -#include "../tcdistribution/PUSDistributorIF.h" -#include "../tcdistribution/TcDistributor.h" -#include "../tcdistribution/TcPacketCheck.h" #include "../tmtcservices/AcceptsTelecommandsIF.h" #include "../tmtcservices/VerificationReporter.h" @@ -50,7 +51,7 @@ protected: /** * The currently handled packet is stored here. */ - TcPacketStored currentPacket; + TcPacketStored* currentPacket = nullptr; /** * With this variable, the current check status is stored to generate * acceptance messages later. @@ -58,6 +59,7 @@ protected: ReturnValue_t tcStatus; const object_id_t packetSource; + /** * This method reads the packet service, checks if such a service is * registered and forwards the packet to the destination. @@ -71,7 +73,7 @@ protected: * The callback here handles the generation of acceptance * success/failure messages. */ - ReturnValue_t callbackAfterSending(ReturnValue_t queueStatus); + ReturnValue_t callbackAfterSending(ReturnValue_t queueStatus) override; }; -#endif /* FRAMEWORK_TCDISTRIBUTION_PUSDISTRIBUTOR_H_ */ +#endif /* FSFW_TCDISTRIBUTION_PUSDISTRIBUTOR_H_ */ diff --git a/tcdistribution/PUSDistributorIF.h b/tcdistribution/PUSDistributorIF.h index 5e27b35c5..0125c08f3 100644 --- a/tcdistribution/PUSDistributorIF.h +++ b/tcdistribution/PUSDistributorIF.h @@ -1,11 +1,12 @@ -#ifndef PUSDISTRIBUTORIF_H_ -#define PUSDISTRIBUTORIF_H_ +#ifndef FSFW_TCDISTRIBUTION_PUSDISTRIBUTORIF_H_ +#define FSFW_TCDISTRIBUTION_PUSDISTRIBUTORIF_H_ #include "../tmtcservices/AcceptsTelecommandsIF.h" #include "../ipc/MessageQueueSenderIF.h" + /** * This interface allows PUS Services to register themselves at a PUS Distributor. - * \ingroup tc_distribution + * @ingroup tc_distribution */ class PUSDistributorIF { public: @@ -17,10 +18,10 @@ public: /** * With this method, Services can register themselves at the PUS Distributor. * @param service A pointer to the registering Service. - * @return - \c RETURN_OK on success, - * - \c RETURN_FAILED on failure. + * @return - @c RETURN_OK on success, + * - @c RETURN_FAILED on failure. */ virtual ReturnValue_t registerService( AcceptsTelecommandsIF* service ) = 0; }; -#endif /* PUSDISTRIBUTORIF_H_ */ +#endif /* FSFW_TCDISTRIBUTION_PUSDISTRIBUTORIF_H_ */ diff --git a/tcdistribution/TcDistributor.cpp b/tcdistribution/TcDistributor.cpp index b03545581..06e1817f8 100644 --- a/tcdistribution/TcDistributor.cpp +++ b/tcdistribution/TcDistributor.cpp @@ -1,12 +1,13 @@ +#include "TcDistributor.h" + #include "../serviceinterface/ServiceInterfaceStream.h" -#include "../serviceinterface/ServiceInterfaceStream.h" -#include "../tcdistribution/TcDistributor.h" #include "../tmtcservices/TmTcMessage.h" #include "../ipc/QueueFactory.h" -TcDistributor::TcDistributor(object_id_t set_object_id) : - SystemObject(set_object_id), tcQueue(NULL) { - tcQueue = QueueFactory::instance()->createMessageQueue(DISTRIBUTER_MAX_PACKETS); +TcDistributor::TcDistributor(object_id_t objectId) : + SystemObject(objectId) { + tcQueue = QueueFactory::instance()-> + createMessageQueue(DISTRIBUTER_MAX_PACKETS); } TcDistributor::~TcDistributor() { @@ -38,14 +39,14 @@ ReturnValue_t TcDistributor::handlePacket() { } void TcDistributor::print() { - sif::debug << "Distributor content is: " << std::endl << "ID\t| message queue id" - << std::endl; - for (TcMqMapIter it = this->queueMap.begin(); it != this->queueMap.end(); - it++) { - sif::debug << it->first << "\t| 0x" << std::hex << it->second << std::dec - << std::endl; + sif::debug << "Distributor content is: " << std::endl + << "ID\t| Message Queue ID" << std::endl; + sif::debug << std::setfill('0') << std::setw(8) << std::hex; + for (const auto& queueMapIter: queueMap) { + sif::debug << queueMapIter.first << "\t| 0x" << queueMapIter.second + << std::endl; } - sif::debug << std::dec; + sif::debug << std::setfill(' ') << std::dec; } diff --git a/tcdistribution/TcDistributor.h b/tcdistribution/TcDistributor.h index 95b7d25b8..5d0ca45d2 100644 --- a/tcdistribution/TcDistributor.h +++ b/tcdistribution/TcDistributor.h @@ -1,5 +1,5 @@ -#ifndef FRAMEWORK_TMTCSERVICES_TCDISTRIBUTOR_H_ -#define FRAMEWORK_TMTCSERVICES_TCDISTRIBUTOR_H_ +#ifndef FSFW_TMTCSERVICES_TCDISTRIBUTOR_H_ +#define FSFW_TMTCSERVICES_TCDISTRIBUTOR_H_ #include "../objectmanager/ObjectManagerIF.h" #include "../objectmanager/SystemObject.h" @@ -34,9 +34,10 @@ public: using TcMessageQueueMap = std::map; using TcMqMapIter = std::map::iterator; - static const uint8_t INTERFACE_ID = CLASS_ID::PACKET_DISTRIBUTION; - static const ReturnValue_t PACKET_LOST = MAKE_RETURN_CODE( 1 ); - static const ReturnValue_t DESTINATION_NOT_FOUND = MAKE_RETURN_CODE( 2 ); + static constexpr uint8_t INTERFACE_ID = CLASS_ID::PACKET_DISTRIBUTION; + static constexpr ReturnValue_t PACKET_LOST = MAKE_RETURN_CODE( 1 ); + static constexpr ReturnValue_t DESTINATION_NOT_FOUND = MAKE_RETURN_CODE( 2 ); + static constexpr ReturnValue_t SERVICE_ID_ALREADY_EXISTS = MAKE_RETURN_CODE(3); /** * Within the default constructor, the SystemObject id is set and the * message queue is initialized. @@ -44,7 +45,7 @@ public: * @param set_object_id This id is assigned to the distributor * implementation. */ - TcDistributor( object_id_t set_object_id ); + TcDistributor(object_id_t objectId); /** * The destructor is empty, the message queues are not in the vicinity of * this class. @@ -69,7 +70,7 @@ protected: * This is the receiving queue for incoming Telecommands. * The child classes must make its queue id public. */ - MessageQueueIF* tcQueue; + MessageQueueIF* tcQueue = nullptr; /** * The last received incoming packet information is stored in this * member. @@ -94,18 +95,19 @@ protected: /** * The handlePacket method calls the child class's selectDestination method * and forwards the packet to its destination, if found. - * @return The message queue return value or \c RETURN_FAILED, in case no + * @return The message queue return value or @c RETURN_FAILED, in case no * destination was found. */ ReturnValue_t handlePacket(); /** - * This method gives the child class a chance to perform some kind of operation - * after the parent tried to forward the message. + * This method gives the child class a chance to perform some kind of + * operation after the parent tried to forward the message. * A typically application would be sending success/failure messages. - * The default implementation just returns \c RETURN_OK. - * @param queueStatus The status of the message queue after an attempt to send the TC. - * @return - \c RETURN_OK on success - * - \c RETURN_FAILED on failure + * The default implementation just returns @c RETURN_OK. + * @param queueStatus The status of the message queue after an attempt + * to send the TC. + * @return - @c RETURN_OK on success + * - @c RETURN_FAILED on failure */ virtual ReturnValue_t callbackAfterSending( ReturnValue_t queueStatus ); @@ -113,8 +115,8 @@ private: /** * This constant sets the maximum number of packets distributed per call. */ - static const uint8_t DISTRIBUTER_MAX_PACKETS = 128; + static constexpr uint8_t DISTRIBUTER_MAX_PACKETS = 128; }; -#endif /* TCDISTRIBUTOR_H_ */ +#endif /* FSFW_TMTCSERVICES_TCDISTRIBUTOR_H_ */ diff --git a/tcdistribution/TcPacketCheck.cpp b/tcdistribution/TcPacketCheck.cpp index 4701ce238..38ed04aaf 100644 --- a/tcdistribution/TcPacketCheck.cpp +++ b/tcdistribution/TcPacketCheck.cpp @@ -1,31 +1,33 @@ +#include "TcPacketCheck.h" + #include "../globalfunctions/CRC.h" #include "../serviceinterface/ServiceInterfaceStream.h" #include "../storagemanager/StorageManagerIF.h" -#include "../tcdistribution/TcPacketCheck.h" #include "../tmtcservices/VerificationCodes.h" -TcPacketCheck::TcPacketCheck( uint16_t set_apid ) : apid(set_apid) { +TcPacketCheck::TcPacketCheck( uint16_t setApid ) : apid(setApid) { } -ReturnValue_t TcPacketCheck::checkPacket( TcPacketStored* current_packet ) { - uint16_t calculated_crc = CRC::crc16ccitt( current_packet->getWholeData(), current_packet->getFullSize() ); +ReturnValue_t TcPacketCheck::checkPacket( TcPacketStored* currentPacket ) { + uint16_t calculated_crc = CRC::crc16ccitt( currentPacket->getWholeData(), + currentPacket->getFullSize() ); if ( calculated_crc != 0 ) { return INCORRECT_CHECKSUM; } - bool condition = !(current_packet->hasSecondaryHeader()) || - current_packet->getPacketVersionNumber() != CCSDS_VERSION_NUMBER || - !(current_packet->isTelecommand()); + bool condition = (not currentPacket->hasSecondaryHeader()) or + (currentPacket->getPacketVersionNumber() != CCSDS_VERSION_NUMBER) or + (not currentPacket->isTelecommand()); if ( condition ) { return INCORRECT_PRIMARY_HEADER; } - if ( current_packet->getAPID() != this->apid ) + if ( currentPacket->getAPID() != this->apid ) return ILLEGAL_APID; - if ( !current_packet->isSizeCorrect() ) { + if ( not currentPacket->isSizeCorrect() ) { return INCOMPLETE_PACKET; } - condition = (current_packet->getSecondaryHeaderFlag() != CCSDS_SECONDARY_HEADER_FLAG) || - (current_packet->getPusVersionNumber() != PUS_VERSION_NUMBER); + condition = (currentPacket->getSecondaryHeaderFlag() != CCSDS_SECONDARY_HEADER_FLAG) || + (currentPacket->getPusVersionNumber() != PUS_VERSION_NUMBER); if ( condition ) { return INCORRECT_SECONDARY_HEADER; } diff --git a/tcdistribution/TcPacketCheck.h b/tcdistribution/TcPacketCheck.h index 4ba269f5e..703bb1bb5 100644 --- a/tcdistribution/TcPacketCheck.h +++ b/tcdistribution/TcPacketCheck.h @@ -1,28 +1,29 @@ -#ifndef TCPACKETCHECK_H_ -#define TCPACKETCHECK_H_ +#ifndef FSFW_TCDISTRIBUTION_TCPACKETCHECK_H_ +#define FSFW_TCDISTRIBUTION_TCPACKETCHECK_H_ #include "../returnvalues/HasReturnvaluesIF.h" #include "../tmtcpacket/pus/TcPacketStored.h" #include "../tmtcservices/PusVerificationReport.h" + /** * This class performs a formal packet check for incoming PUS Telecommand Packets. * Currently, it only checks if the APID and CRC are correct. - * \ingroup tc_distribution + * @ingroup tc_distribution */ class TcPacketCheck : public HasReturnvaluesIF { protected: /** * Describes the version number a packet must have to pass. */ - static const uint8_t CCSDS_VERSION_NUMBER = 0; + static constexpr uint8_t CCSDS_VERSION_NUMBER = 0; /** * Describes the secondary header a packet must have to pass. */ - static const uint8_t CCSDS_SECONDARY_HEADER_FLAG = 0; + static constexpr uint8_t CCSDS_SECONDARY_HEADER_FLAG = 0; /** * Describes the TC Packet PUS Version Number a packet must have to pass. */ - static const uint8_t PUS_VERSION_NUMBER = 1; + static constexpr uint8_t PUS_VERSION_NUMBER = 1; /** * The packet id each correct packet should have. * It is composed of the APID and some static fields. @@ -41,19 +42,19 @@ public: * The constructor only sets the APID attribute. * @param set_apid The APID to set. */ - TcPacketCheck( uint16_t set_apid ); + TcPacketCheck( uint16_t setApid ); /** * This is the actual method to formally check a certain Telecommand Packet. * The packet's Application Data can not be checked here. * @param current_packet The packt to check - * @return - \c RETURN_OK on success. - * - \c INCORRECT_CHECKSUM if checksum is invalid. - * - \c ILLEGAL_APID if APID does not match. + * @return - @c RETURN_OK on success. + * - @c INCORRECT_CHECKSUM if checksum is invalid. + * - @c ILLEGAL_APID if APID does not match. */ - ReturnValue_t checkPacket( TcPacketStored* current_packet ); + ReturnValue_t checkPacket( TcPacketStored* currentPacket ); uint16_t getApid() const; }; -#endif /* TCPACKETCHECK_H_ */ +#endif /* FSFW_TCDISTRIBUTION_TCPACKETCHECK_H_ */ diff --git a/timemanager/CCSDSTime.cpp b/timemanager/CCSDSTime.cpp index 130b3175c..8878a38a7 100644 --- a/timemanager/CCSDSTime.cpp +++ b/timemanager/CCSDSTime.cpp @@ -1,7 +1,9 @@ #include "../timemanager/CCSDSTime.h" -#include -#include -#include +#include +#include +#include +#include + CCSDSTime::CCSDSTime() { } @@ -157,7 +159,7 @@ ReturnValue_t CCSDSTime::convertFromASCII(Clock::TimeOfDay_t* to, const uint8_t* } // Newlib nano can't parse uint8, see SCNu8 documentation and https://sourceware.org/newlib/README // Suggestion: use uint16 all the time. This should work on all systems. -#ifdef NEWLIB_NANO_NO_C99_IO +#if FSFW_NO_C99_IO == 1 uint16_t year; uint16_t month; uint16_t day; diff --git a/timemanager/CCSDSTime.h b/timemanager/CCSDSTime.h index b9efa49cb..89fcff92f 100644 --- a/timemanager/CCSDSTime.h +++ b/timemanager/CCSDSTime.h @@ -3,9 +3,9 @@ // COULDDO: have calls in Clock.h which return time quality and use timespec accordingly -#include "../timemanager/Clock.h" +#include "Clock.h" #include "../returnvalues/HasReturnvaluesIF.h" -#include +#include bool operator<(const timeval& lhs, const timeval& rhs); bool operator<=(const timeval& lhs, const timeval& rhs); diff --git a/timemanager/Clock.h b/timemanager/Clock.h index 9463b5a6e..1ad883055 100644 --- a/timemanager/Clock.h +++ b/timemanager/Clock.h @@ -10,7 +10,6 @@ //! Don't use these for time points, type is not large enough for UNIX epoch. using dur_millis_t = uint32_t; -using dur_seconds_t = double; class Clock { public: @@ -68,6 +67,8 @@ public: static timeval getUptime(); + static uint32_t getUptimeSeconds(); + /** * Get the time since boot in milliseconds * diff --git a/timemanager/Countdown.cpp b/timemanager/Countdown.cpp index 95cce029a..20b56189f 100644 --- a/timemanager/Countdown.cpp +++ b/timemanager/Countdown.cpp @@ -1,14 +1,6 @@ -/** - * @file Countdown.cpp - * @brief This file defines the Countdown class. - * @date 21.03.2013 - * @author baetz - */ +#include "Countdown.h" - -#include "../timemanager/Countdown.h" - -Countdown::Countdown(uint32_t initialTimeout) : startTime(0), timeout(initialTimeout) { +Countdown::Countdown(uint32_t initialTimeout): timeout(initialTimeout) { } Countdown::~Countdown() { diff --git a/timemanager/Countdown.h b/timemanager/Countdown.h index 20380e715..f6a41e73d 100644 --- a/timemanager/Countdown.h +++ b/timemanager/Countdown.h @@ -1,18 +1,13 @@ +#ifndef FSFW_TIMEMANAGER_COUNTDOWN_H_ +#define FSFW_TIMEMANAGER_COUNTDOWN_H_ + +#include "Clock.h" + /** - * @file Countdown.h * @brief This file defines the Countdown class. - * @date 21.03.2013 * @author baetz */ - -#ifndef COUNTDOWN_H_ -#define COUNTDOWN_H_ - -#include "../timemanager/Clock.h" - class Countdown { -private: - uint32_t startTime; public: uint32_t timeout; Countdown(uint32_t initialTimeout = 0); @@ -23,9 +18,14 @@ public: bool isBusy() const; - ReturnValue_t resetTimer(); //!< Use last set timeout value and restart timer. + //!< Use last set timeout value and restart timer. + ReturnValue_t resetTimer(); - void timeOut(); //!< Make hasTimedOut() return true + //!< Make hasTimedOut() return true + void timeOut(); + +private: + uint32_t startTime = 0; }; -#endif /* COUNTDOWN_H_ */ +#endif /* FSFW_TIMEMANAGER_COUNTDOWN_H_ */ diff --git a/timemanager/Stopwatch.cpp b/timemanager/Stopwatch.cpp index 637c50780..2cd31969b 100644 --- a/timemanager/Stopwatch.cpp +++ b/timemanager/Stopwatch.cpp @@ -6,19 +6,22 @@ Stopwatch::Stopwatch(bool displayOnDestruction, StopwatchDisplayMode displayMode): displayOnDestruction( displayOnDestruction), displayMode(displayMode) { // Measures start time on initialization. - Clock::getClock_timeval(&startTime); + Clock::getUptime(&startTime); } void Stopwatch::start() { - Clock::getClock_timeval(&startTime); + Clock::getUptime(&startTime); } -dur_millis_t Stopwatch::stop() { +dur_millis_t Stopwatch::stop(bool display) { stopInternal(); + if(display) { + this->display(); + } return elapsedTime.tv_sec * 1000 + elapsedTime.tv_usec / 1000; } -dur_seconds_t Stopwatch::stopSeconds() { +double Stopwatch::stopSeconds() { stopInternal(); return timevalOperations::toDouble(elapsedTime); } @@ -52,6 +55,6 @@ StopwatchDisplayMode Stopwatch::getDisplayMode() const { void Stopwatch::stopInternal() { timeval endTime; - Clock::getClock_timeval(&endTime); + Clock::getUptime(&endTime); elapsedTime = endTime - startTime; } diff --git a/timemanager/Stopwatch.h b/timemanager/Stopwatch.h index 191929dc1..ea72c66e0 100644 --- a/timemanager/Stopwatch.h +++ b/timemanager/Stopwatch.h @@ -1,6 +1,7 @@ -#ifndef FRAMEWORK_TIMEMANAGER_STOPWATCH_H_ -#define FRAMEWORK_TIMEMANAGER_STOPWATCH_H_ -#include "../timemanager/Clock.h" +#ifndef FSFW_TIMEMANAGER_STOPWATCH_H_ +#define FSFW_TIMEMANAGER_STOPWATCH_H_ + +#include "Clock.h" enum class StopwatchDisplayMode { MILLIS, @@ -40,12 +41,12 @@ public: * Calculates the elapsed time since start and returns it * @return elapsed time in milliseconds (rounded) */ - dur_millis_t stop(); + dur_millis_t stop(bool display = false); /** * Calculates the elapsed time since start and returns it * @return elapsed time in seconds (double precision) */ - dur_seconds_t stopSeconds(); + double stopSeconds(); /** * Displays the elapsed times on the osstream, depending on internal display @@ -66,6 +67,4 @@ private: }; - - -#endif /* FRAMEWORK_TIMEMANAGER_STOPWATCH_H_ */ +#endif /* FSFW_TIMEMANAGER_STOPWATCH_H_ */ diff --git a/tmtcpacket/pus/TmPacketStored.cpp b/tmtcpacket/pus/TmPacketStored.cpp index 17b49f43a..4cf76589b 100644 --- a/tmtcpacket/pus/TmPacketStored.cpp +++ b/tmtcpacket/pus/TmPacketStored.cpp @@ -1,8 +1,9 @@ +#include "TmPacketStored.h" + #include "../../objectmanager/ObjectManagerIF.h" #include "../../serviceinterface/ServiceInterfaceStream.h" -#include "../../tmtcpacket/pus/TmPacketStored.h" #include "../../tmtcservices/TmTcMessage.h" -#include +#include TmPacketStored::TmPacketStored(store_address_t setAddress) : TmPacketBase(NULL), storeAddress(setAddress) { @@ -11,7 +12,7 @@ TmPacketStored::TmPacketStored(store_address_t setAddress) : TmPacketStored::TmPacketStored(uint16_t apid, uint8_t service, uint8_t subservice, uint8_t packetSubcounter, const uint8_t *data, - uint32_t size, const uint8_t *headerData, uint32_t headerSize) : + size_t size, const uint8_t *headerData, size_t headerSize) : TmPacketBase(NULL) { storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; if (!checkAndSetStore()) { diff --git a/tmtcpacket/pus/TmPacketStored.h b/tmtcpacket/pus/TmPacketStored.h index 98e37ed53..81a6f6e5d 100644 --- a/tmtcpacket/pus/TmPacketStored.h +++ b/tmtcpacket/pus/TmPacketStored.h @@ -1,9 +1,9 @@ -#ifndef TMPACKETSTORED_H_ -#define TMPACKETSTORED_H_ +#ifndef FSFW_TMTCPACKET_TMPACKETSTORED_H_ +#define FSFW_TMTCPACKET_TMPACKETSTORED_H_ +#include "TmPacketBase.h" #include "../../serialize/SerializeIF.h" #include "../../storagemanager/StorageManagerIF.h" -#include "../../tmtcpacket/pus/TmPacketBase.h" #include "../../internalError/InternalErrorReporterIF.h" #include "../../ipc/MessageQueueSenderIF.h" @@ -21,7 +21,7 @@ class TmPacketStored : public TmPacketBase { private: /** * This is a pointer to the store all instances of the class use. - * If the store is not yet set (i.e. \c store is NULL), every constructor + * If the store is not yet set (i.e. @c store is NULL), every constructor * call tries to set it and throws an error message in case of failures. * The default store is objects::TM_STORE. */ @@ -37,8 +37,8 @@ private: * A helper method to check if a store is assigned to the class. * If not, the method tries to retrieve the store from the global * ObjectManager. - * @return @li \c true if the store is linked or could be created. - * @li \c false otherwise. + * @return @li @c true if the store is linked or could be created. + * @li @c false otherwise. */ bool checkAndSetStore(); @@ -52,8 +52,9 @@ public: /** * With this constructor, new space is allocated in the packet store and * a new PUS Telemetry Packet is created there. - * Packet Application Data passed in data is copied into the packet. The Application data is - * passed in two parts, first a header, then a data field. This allows building a Telemetry + * Packet Application Data passed in data is copied into the packet. + * The Application data is passed in two parts, first a header, then a + * data field. This allows building a Telemetry * Packet from two separate data sources. * @param apid Sets the packet's APID field. * @param service Sets the packet's Service ID field. @@ -61,20 +62,29 @@ public: * @param subservice Sets the packet's Service Subtype field. * This specifies the source sub-service. * @param packet_counter Sets the Packet counter field of this packet - * @param data The payload data to be copied to the Application Data Field + * @param data The payload data to be copied to the Application + * Data Field * @param size The amount of data to be copied. - * @param headerData The header Data of the Application field; will be copied in front of data + * @param headerData The header Data of the Application field; will be + * copied in front of data * @param headerSize The size of the headerDataF */ - TmPacketStored( uint16_t apid, uint8_t service, uint8_t subservice, uint8_t packet_counter = 0, const uint8_t* data = NULL, uint32_t size = 0, const uint8_t* headerData = NULL, uint32_t headerSize = 0); + TmPacketStored(uint16_t apid, uint8_t service, uint8_t subservice, + uint8_t packet_counter = 0, const uint8_t* data = nullptr, + size_t size = 0, const uint8_t* headerData = nullptr, + size_t headerSize = 0); /** - * Another ctor to directly pass structured content and header data to the packet to avoid additional buffers. + * Another ctor to directly pass structured content and header data to the + * packet to avoid additional buffers. */ - TmPacketStored( uint16_t apid, uint8_t service, uint8_t subservice, uint8_t packet_counter, SerializeIF* content, SerializeIF* header = NULL); + TmPacketStored(uint16_t apid, uint8_t service, uint8_t subservice, + uint8_t packet_counter, SerializeIF* content, + SerializeIF* header = nullptr); /** * This is a getter for the current store address of the packet. - * @return The current store address. The (raw) value is \c StorageManagerIF::INVALID_ADDRESS if - * the packet is not linked. + * @return + * The current store address. The (raw) value is + * @c StorageManagerIF::INVALID_ADDRESS if the packet is not linked. */ store_address_t getStoreAddress(); /** @@ -87,10 +97,11 @@ public: * if the packet is a class member and used for more than one packet. * @param setAddress The new packet id to link to. */ - void setStoreAddress( store_address_t setAddress ); + void setStoreAddress(store_address_t setAddress); - ReturnValue_t sendPacket( MessageQueueId_t destination, MessageQueueId_t sentFrom, bool doErrorReporting = true ); + ReturnValue_t sendPacket(MessageQueueId_t destination, + MessageQueueId_t sentFrom, bool doErrorReporting = true); }; -#endif /* TMPACKETSTORED_H_ */ +#endif /* FSFW_TMTCPACKET_TMPACKETSTORED_H_ */ diff --git a/tmtcservices/CommandingServiceBase.cpp b/tmtcservices/CommandingServiceBase.cpp index e5a87f180..0ebc3944f 100644 --- a/tmtcservices/CommandingServiceBase.cpp +++ b/tmtcservices/CommandingServiceBase.cpp @@ -1,9 +1,9 @@ #include "../tcdistribution/PUSDistributorIF.h" -#include "../tmtcservices/AcceptsTelemetryIF.h" +#include "AcceptsTelemetryIF.h" #include "../objectmanager/ObjectManagerIF.h" -#include "../tmtcservices/CommandingServiceBase.h" -#include "../tmtcservices/TmTcMessage.h" +#include "CommandingServiceBase.h" +#include "TmTcMessage.h" #include "../ipc/QueueFactory.h" #include "../tmtcpacket/pus/TcPacketStored.h" #include "../tmtcpacket/pus/TmPacketStored.h" @@ -122,8 +122,8 @@ void CommandingServiceBase::handleCommandMessage(CommandMessage* reply) { // Implemented by child class, specifies what to do with reply. - ReturnValue_t result = handleReply(reply, iter->command, &iter->state, - &nextCommand, iter->objectId, &isStep); + ReturnValue_t result = handleReply(reply, iter->second.command, &iter->second.state, + &nextCommand, iter->second.objectId, &isStep); /* If the child implementation does not implement special handling for * rejected replies (RETURN_FAILED or INVALID_REPLY is returned), a @@ -132,7 +132,7 @@ void CommandingServiceBase::handleCommandMessage(CommandMessage* reply) { if((reply->getCommand() == CommandMessage::REPLY_REJECTED) and (result == RETURN_FAILED or result == INVALID_REPLY)) { result = reply->getReplyRejectedReason(); - failureParameter1 = iter->command; + failureParameter1 = iter->second.command; } switch (result) { @@ -149,14 +149,14 @@ void CommandingServiceBase::handleCommandMessage(CommandMessage* reply) { default: if (isStep) { verificationReporter.sendFailureReport( - TC_VERIFY::PROGRESS_FAILURE, iter->tcInfo.ackFlags, - iter->tcInfo.tcPacketId, iter->tcInfo.tcSequenceControl, - result, ++iter->step, failureParameter1, + TC_VERIFY::PROGRESS_FAILURE, iter->second.tcInfo.ackFlags, + iter->second.tcInfo.tcPacketId, iter->second.tcInfo.tcSequenceControl, + result, ++iter->second.step, failureParameter1, failureParameter2); } else { verificationReporter.sendFailureReport( - TC_VERIFY::COMPLETION_FAILURE, iter->tcInfo.ackFlags, - iter->tcInfo.tcPacketId, iter->tcInfo.tcSequenceControl, + TC_VERIFY::COMPLETION_FAILURE, iter->second.tcInfo.ackFlags, + iter->second.tcInfo.tcPacketId, iter->second.tcInfo.tcSequenceControl, result, 0, failureParameter1, failureParameter2); } failureParameter1 = 0; @@ -170,7 +170,7 @@ void CommandingServiceBase::handleCommandMessage(CommandMessage* reply) { void CommandingServiceBase::handleReplyHandlerResult(ReturnValue_t result, CommandMapIter iter, CommandMessage* nextCommand, CommandMessage* reply, bool& isStep) { - iter->command = nextCommand->getCommand(); + iter->second.command = nextCommand->getCommand(); // In case a new command is to be sent immediately, this is performed here. // If no new command is sent, only analyse reply result by initializing @@ -185,14 +185,14 @@ void CommandingServiceBase::handleReplyHandlerResult(ReturnValue_t result, if (isStep and result != NO_STEP_MESSAGE) { verificationReporter.sendSuccessReport( TC_VERIFY::PROGRESS_SUCCESS, - iter->tcInfo.ackFlags, iter->tcInfo.tcPacketId, - iter->tcInfo.tcSequenceControl, ++iter->step); + iter->second.tcInfo.ackFlags, iter->second.tcInfo.tcPacketId, + iter->second.tcInfo.tcSequenceControl, ++iter->second.step); } else { verificationReporter.sendSuccessReport( TC_VERIFY::COMPLETION_SUCCESS, - iter->tcInfo.ackFlags, iter->tcInfo.tcPacketId, - iter->tcInfo.tcSequenceControl, 0); + iter->second.tcInfo.ackFlags, iter->second.tcInfo.tcPacketId, + iter->second.tcInfo.tcSequenceControl, 0); checkAndExecuteFifo(iter); } } @@ -200,16 +200,16 @@ void CommandingServiceBase::handleReplyHandlerResult(ReturnValue_t result, if (isStep) { nextCommand->clearCommandMessage(); verificationReporter.sendFailureReport( - TC_VERIFY::PROGRESS_FAILURE, iter->tcInfo.ackFlags, - iter->tcInfo.tcPacketId, - iter->tcInfo.tcSequenceControl, sendResult, - ++iter->step, failureParameter1, failureParameter2); + TC_VERIFY::PROGRESS_FAILURE, iter->second.tcInfo.ackFlags, + iter->second.tcInfo.tcPacketId, + iter->second.tcInfo.tcSequenceControl, sendResult, + ++iter->second.step, failureParameter1, failureParameter2); } else { nextCommand->clearCommandMessage(); verificationReporter.sendFailureReport( TC_VERIFY::COMPLETION_FAILURE, - iter->tcInfo.ackFlags, iter->tcInfo.tcPacketId, - iter->tcInfo.tcSequenceControl, sendResult, 0, + iter->second.tcInfo.ackFlags, iter->second.tcInfo.tcPacketId, + iter->second.tcInfo.tcSequenceControl, sendResult, 0, failureParameter1, failureParameter2); } failureParameter1 = 0; @@ -248,7 +248,7 @@ void CommandingServiceBase::handleRequestQueue() { iter = commandMap.find(queue); if (iter != commandMap.end()) { - result = iter->fifo.insert(address); + result = iter->second.fifo.insert(address); if (result != RETURN_OK) { rejectPacket(TC_VERIFY::START_FAILURE, &packet, OBJECT_BUSY); } @@ -316,11 +316,11 @@ void CommandingServiceBase::startExecution(TcPacketStored *storedPacket, CommandMapIter iter) { ReturnValue_t result = RETURN_OK; CommandMessage command; - iter->subservice = storedPacket->getSubService(); - result = prepareCommand(&command, iter->subservice, + iter->second.subservice = storedPacket->getSubService(); + result = prepareCommand(&command, iter->second.subservice, storedPacket->getApplicationData(), - storedPacket->getApplicationDataSize(), &iter->state, - iter->objectId); + storedPacket->getApplicationDataSize(), &iter->second.state, + iter->second.objectId); ReturnValue_t sendResult = RETURN_OK; switch (result) { @@ -330,13 +330,13 @@ void CommandingServiceBase::startExecution(TcPacketStored *storedPacket, &command); } if (sendResult == RETURN_OK) { - Clock::getUptime(&iter->uptimeOfStart); - iter->step = 0; - iter->subservice = storedPacket->getSubService(); - iter->command = command.getCommand(); - iter->tcInfo.ackFlags = storedPacket->getAcknowledgeFlags(); - iter->tcInfo.tcPacketId = storedPacket->getPacketId(); - iter->tcInfo.tcSequenceControl = + Clock::getUptime(&iter->second.uptimeOfStart); + iter->second.step = 0; + iter->second.subservice = storedPacket->getSubService(); + iter->second.command = command.getCommand(); + iter->second.tcInfo.ackFlags = storedPacket->getAcknowledgeFlags(); + iter->second.tcInfo.tcPacketId = storedPacket->getPacketId(); + iter->second.tcInfo.tcSequenceControl = storedPacket->getPacketSequenceControl(); acceptPacket(TC_VERIFY::START_SUCCESS, storedPacket); } else { @@ -384,9 +384,9 @@ void CommandingServiceBase::acceptPacket(uint8_t reportId, } -void CommandingServiceBase::checkAndExecuteFifo(CommandMapIter iter) { +void CommandingServiceBase::checkAndExecuteFifo(CommandMapIter& iter) { store_address_t address; - if (iter->fifo.retrieve(&address) != RETURN_OK) { + if (iter->second.fifo.retrieve(&address) != RETURN_OK) { commandMap.erase(&iter); } else { TcPacketStored newPacket(address); @@ -412,10 +412,10 @@ void CommandingServiceBase::checkTimeout() { Clock::getUptime(&uptime); CommandMapIter iter; for (iter = commandMap.begin(); iter != commandMap.end(); ++iter) { - if ((iter->uptimeOfStart + (timeoutSeconds * 1000)) < uptime) { + if ((iter->second.uptimeOfStart + (timeoutSeconds * 1000)) < uptime) { verificationReporter.sendFailureReport( - TC_VERIFY::COMPLETION_FAILURE, iter->tcInfo.ackFlags, - iter->tcInfo.tcPacketId, iter->tcInfo.tcSequenceControl, + TC_VERIFY::COMPLETION_FAILURE, iter->second.tcInfo.ackFlags, + iter->second.tcInfo.tcPacketId, iter->second.tcInfo.tcSequenceControl, TIMEOUT); checkAndExecuteFifo(iter); } diff --git a/tmtcservices/CommandingServiceBase.h b/tmtcservices/CommandingServiceBase.h index 29ab967a1..9f1d4c4f9 100644 --- a/tmtcservices/CommandingServiceBase.h +++ b/tmtcservices/CommandingServiceBase.h @@ -5,14 +5,16 @@ #include "../storagemanager/StorageManagerIF.h" #include "../tasks/ExecutableObjectIF.h" #include "../ipc/MessageQueueIF.h" -#include "../tmtcservices/AcceptsTelecommandsIF.h" +#include "AcceptsTelecommandsIF.h" -#include "../tmtcservices/VerificationReporter.h" +#include "VerificationReporter.h" #include "../ipc/CommandMessage.h" #include "../container/FixedMap.h" #include "../container/FIFO.h" #include "../serialize/SerializeIF.h" +#include + class TcPacketStored; namespace Factory{ @@ -39,7 +41,11 @@ class CommandingServiceBase: public SystemObject, public HasReturnvaluesIF { friend void (Factory::setStaticFrameworkObjectIds)(); public: + // We could make this configurable via preprocessor and the FSFWConfig file. + static constexpr uint8_t COMMAND_INFO_FIFO_DEPTH = FSFW_CSB_FIFO_DEPTH; + static const uint8_t INTERFACE_ID = CLASS_ID::COMMAND_SERVICE_BASE; + static const ReturnValue_t EXECUTION_COMPLETE = MAKE_RETURN_CODE(1); static const ReturnValue_t NO_STEP_MESSAGE = MAKE_RETURN_CODE(2); static const ReturnValue_t OBJECT_BUSY = MAKE_RETURN_CODE(3); @@ -211,8 +217,7 @@ protected: virtual void doPeriodicOperation(); - - struct CommandInfo { + struct CommandInfo: public SerializeIF{ struct tcInfo { uint8_t ackFlags; uint16_t tcPacketId; @@ -224,7 +229,21 @@ protected: uint32_t state; Command_t command; object_id_t objectId; - FIFO fifo; + FIFO fifo; + + virtual ReturnValue_t serialize(uint8_t **buffer, size_t *size, + size_t maxSize, Endianness streamEndianness) const override{ + return HasReturnvaluesIF::RETURN_FAILED; + }; + + virtual size_t getSerializedSize() const override { + return 0; + }; + + virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size, + Endianness streamEndianness) override { + return HasReturnvaluesIF::RETURN_FAILED; + }; }; using CommandMapIter = FixedMapmessageSize += sizeof(store_address_t); - this->setStorageId(store_id); + this->setStorageId(storeId); } size_t TmTcMessage::getMinimumMessageSize() { return this->HEADER_SIZE + sizeof(store_address_t); } -void TmTcMessage::setStorageId(store_address_t store_id) { - memcpy(this->getData(), &store_id, sizeof(store_address_t) ); +void TmTcMessage::setStorageId(store_address_t storeId) { + memcpy(this->getData(), &storeId, sizeof(store_address_t) ); } diff --git a/tmtcservices/TmTcMessage.h b/tmtcservices/TmTcMessage.h index b5e1ff8d4..41fe198a9 100644 --- a/tmtcservices/TmTcMessage.h +++ b/tmtcservices/TmTcMessage.h @@ -1,5 +1,5 @@ -#ifndef TMTCMESSAGE_H_ -#define TMTCMESSAGE_H_ +#ifndef FSFW_TMTCSERVICES_TMTCMESSAGE_H_ +#define FSFW_TMTCSERVICES_TMTCMESSAGE_H_ #include "../ipc/MessageQueueMessage.h" #include "../storagemanager/StorageManagerIF.h" @@ -10,13 +10,13 @@ * a packet stored in one of the IPC stores (typically a special TM and * a special TC store). This makes passing commands very simple and * efficient. - * \ingroup message_queue + * @ingroup message_queue */ class TmTcMessage : public MessageQueueMessage { protected: /** * @brief This call always returns the same fixed size of the message. - * @return Returns HEADER_SIZE + \c sizeof(store_address_t). + * @return Returns HEADER_SIZE + @c sizeof(store_address_t). */ size_t getMinimumMessageSize(); public: @@ -29,7 +29,7 @@ public: * into the message. * @param packet_id The packet id to put into the message. */ - TmTcMessage( store_address_t packet_id ); + TmTcMessage( store_address_t packetId ); /** * @brief The class's destructor is empty. */ @@ -42,9 +42,9 @@ public: /** * @brief In some cases it might be useful to have a setter for packet id * as well. - * @param packet_id The packet id to put into the message. + * @param packetId The packet id to put into the message. */ - void setStorageId( store_address_t packet_id ); + void setStorageId( store_address_t packetId ); }; -#endif /* TMTCMESSAGE_H_ */ +#endif /* FSFW_TMTCSERVICES_TMTCMESSAGE_H_ */ diff --git a/tmtcservices/VerificationReporter.cpp b/tmtcservices/VerificationReporter.cpp index 4f9f4e54e..7e40bd275 100644 --- a/tmtcservices/VerificationReporter.cpp +++ b/tmtcservices/VerificationReporter.cpp @@ -1,12 +1,13 @@ -#include "../tmtcservices/VerificationReporter.h" +#include "VerificationReporter.h" +#include "AcceptsVerifyMessageIF.h" +#include "PusVerificationReport.h" #include "../ipc/MessageQueueIF.h" -#include "../tmtcservices/AcceptsVerifyMessageIF.h" -#include "../tmtcservices/PusVerificationReport.h" #include "../serviceinterface/ServiceInterfaceStream.h" #include "../objectmanager/frameworkObjects.h" -object_id_t VerificationReporter::messageReceiver = objects::PUS_SERVICE_1; +object_id_t VerificationReporter::messageReceiver = + objects::PUS_SERVICE_1_VERIFICATION; VerificationReporter::VerificationReporter() : acknowledgeQueue(MessageQueueIF::NO_QUEUE) { @@ -63,8 +64,8 @@ void VerificationReporter::sendFailureReport(uint8_t report_id, ReturnValue_t status = MessageQueueSenderIF::sendMessage(acknowledgeQueue, &message); if (status != HasReturnvaluesIF::RETURN_OK) { - sif::error << "VerificationReporter::sendFailureReport Error writing " - << "to queue. Code: " << std::hex << status << std::dec + sif::error << "VerificationReporter::sendFailureReport: Error writing " + << "to queue. Code: " << std::hex << "0x" << status << std::dec << std::endl; } } @@ -81,8 +82,8 @@ void VerificationReporter::sendFailureReport(uint8_t report_id, ReturnValue_t status = MessageQueueSenderIF::sendMessage(acknowledgeQueue, &message); if (status != HasReturnvaluesIF::RETURN_OK) { - sif::error << "VerificationReporter::sendFailureReport Error writing " - << "to queue. Code: " << std::hex << status << std::dec + sif::error << "VerificationReporter::sendFailureReport: Error writing " + << "to queue. Code: " << std::hex << "0x" << status << std::dec << std::endl; } } @@ -98,8 +99,8 @@ void VerificationReporter::initialize() { if (temp == nullptr) { sif::error << "VerificationReporter::initialize: Message " << "receiver invalid. Make sure it is set up properly and " - <<"implementsAcceptsVerifyMessageIF" << std::endl; - + << "implementsAcceptsVerifyMessageIF" << std::endl; + return; } this->acknowledgeQueue = temp->getVerificationQueue(); } diff --git a/tmtcservices/VerificationReporter.h b/tmtcservices/VerificationReporter.h index 4d92f6b38..f26fa54f5 100644 --- a/tmtcservices/VerificationReporter.h +++ b/tmtcservices/VerificationReporter.h @@ -1,8 +1,8 @@ -#ifndef FRAMEWORK_TMTCSERVICES_VERIFICATIONREPORTER_H_ -#define FRAMEWORK_TMTCSERVICES_VERIFICATIONREPORTER_H_ +#ifndef FSFW_TMTCSERVICES_VERIFICATIONREPORTER_H_ +#define FSFW_TMTCSERVICES_VERIFICATIONREPORTER_H_ +#include "PusVerificationReport.h" #include "../objectmanager/ObjectManagerIF.h" -#include "../tmtcservices/PusVerificationReport.h" namespace Factory{ void setStaticFrameworkObjectIds(); @@ -47,4 +47,4 @@ private: MessageQueueId_t acknowledgeQueue; }; -#endif /* FRAMEWORK_TMTCSERVICES_VERIFICATIONREPORTER_H_ */ +#endif /* FSFW_TMTCSERVICES_VERIFICATIONREPORTER_H_ */