diff --git a/action/ActionHelper.cpp b/action/ActionHelper.cpp index 18e46fba9..b43c676d0 100644 --- a/action/ActionHelper.cpp +++ b/action/ActionHelper.cpp @@ -1,9 +1,9 @@ -#include -#include -#include +#include "ActionHelper.h" +#include "HasActionsIF.h" +#include "../objectmanager/ObjectManagerIF.h" + ActionHelper::ActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue) : - owner(setOwner), queueToUse(useThisQueue), ipcStore( - NULL) { + owner(setOwner), queueToUse(useThisQueue), ipcStore(nullptr) { } ActionHelper::~ActionHelper() { @@ -16,16 +16,18 @@ ReturnValue_t ActionHelper::handleActionMessage(CommandMessage* command) { ActionMessage::getStoreId(command)); return HasReturnvaluesIF::RETURN_OK; } else { - return CommandMessage::UNKNOW_COMMAND; + return CommandMessage::UNKNOWN_COMMAND; } } ReturnValue_t ActionHelper::initialize(MessageQueueIF* queueToUse_) { ipcStore = objectManager->get(objects::IPC_STORE); - if (ipcStore == NULL) { + if (ipcStore == nullptr) { return HasReturnvaluesIF::RETURN_FAILED; } - setQueueToUse(queueToUse_); + if(queueToUse_ != nullptr) { + setQueueToUse(queueToUse_); + } return HasReturnvaluesIF::RETURN_OK; } @@ -67,22 +69,23 @@ void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t act } } -ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo, ActionId_t replyId, SerializeIF* data, bool hideSender) { +ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo, + ActionId_t replyId, SerializeIF* data, bool hideSender) { CommandMessage reply; store_address_t storeAddress; uint8_t *dataPtr; - uint32_t maxSize = data->getSerializedSize(); + size_t maxSize = data->getSerializedSize(); if (maxSize == 0) { //No error, there's simply nothing to report. return HasReturnvaluesIF::RETURN_OK; } - uint32_t size = 0; + size_t size = 0; ReturnValue_t result = ipcStore->getFreeElement(&storeAddress, maxSize, &dataPtr); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = data->serialize(&dataPtr, &size, maxSize, true); + result = data->serialize(&dataPtr, &size, maxSize, SerializeIF::Endianness::BIG); if (result != HasReturnvaluesIF::RETURN_OK) { ipcStore->deleteData(storeAddress); return result; diff --git a/action/ActionHelper.h b/action/ActionHelper.h index 6ba6dd89b..bbc6d114d 100644 --- a/action/ActionHelper.h +++ b/action/ActionHelper.h @@ -1,9 +1,9 @@ #ifndef ACTIONHELPER_H_ #define ACTIONHELPER_H_ -#include -#include -#include +#include "ActionMessage.h" +#include "../serialize/SerializeIF.h" +#include "../ipc/MessageQueueIF.h" /** * \brief Action Helper is a helper class which handles action messages * @@ -35,10 +35,10 @@ public: 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 + * @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_); + 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. * diff --git a/action/ActionMessage.cpp b/action/ActionMessage.cpp index 96ff59b66..b0bcabaa0 100644 --- a/action/ActionMessage.cpp +++ b/action/ActionMessage.cpp @@ -1,6 +1,6 @@ -#include -#include -#include +#include "ActionMessage.h" +#include "../objectmanager/ObjectManagerIF.h" +#include "../storagemanager/StorageManagerIF.h" ActionMessage::ActionMessage() { } diff --git a/action/ActionMessage.h b/action/ActionMessage.h index 59ad619ef..0a718aab6 100644 --- a/action/ActionMessage.h +++ b/action/ActionMessage.h @@ -1,9 +1,9 @@ #ifndef ACTIONMESSAGE_H_ #define ACTIONMESSAGE_H_ -#include -#include -#include +#include "../ipc/CommandMessage.h" +#include "../objectmanager/ObjectManagerIF.h" +#include "../storagemanager/StorageManagerIF.h" typedef uint32_t ActionId_t; class ActionMessage { diff --git a/action/CommandActionHelper.cpp b/action/CommandActionHelper.cpp index ceb97d3b9..4e88f3c34 100644 --- a/action/CommandActionHelper.cpp +++ b/action/CommandActionHelper.cpp @@ -1,33 +1,34 @@ -#include -#include -#include -#include -#include +#include "ActionMessage.h" +#include "CommandActionHelper.h" +#include "CommandsActionsIF.h" +#include "HasActionsIF.h" +#include "../objectmanager/ObjectManagerIF.h" -CommandActionHelper::CommandActionHelper(CommandsActionsIF* setOwner) : +CommandActionHelper::CommandActionHelper(CommandsActionsIF *setOwner) : owner(setOwner), queueToUse(NULL), ipcStore( - NULL), commandCount(0), lastTarget(0) { + NULL), commandCount(0), lastTarget(0) { } CommandActionHelper::~CommandActionHelper() { } ReturnValue_t CommandActionHelper::commandAction(object_id_t commandTo, - ActionId_t actionId, SerializeIF* data) { - HasActionsIF* receiver = objectManager->get(commandTo); + ActionId_t actionId, SerializeIF *data) { + HasActionsIF *receiver = objectManager->get(commandTo); if (receiver == NULL) { return CommandsActionsIF::OBJECT_HAS_NO_FUNCTIONS; } store_address_t storeId; - uint8_t* storePointer; - uint32_t maxSize = data->getSerializedSize(); + uint8_t *storePointer; + size_t maxSize = data->getSerializedSize(); ReturnValue_t result = ipcStore->getFreeElement(&storeId, maxSize, &storePointer); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - uint32_t size = 0; - result = data->serialize(&storePointer, &size, maxSize, true); + size_t size = 0; + result = data->serialize(&storePointer, &size, maxSize, + SerializeIF::Endianness::BIG); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } @@ -35,11 +36,11 @@ ReturnValue_t CommandActionHelper::commandAction(object_id_t commandTo, } ReturnValue_t CommandActionHelper::commandAction(object_id_t commandTo, - ActionId_t actionId, const uint8_t* data, uint32_t size) { + ActionId_t actionId, const uint8_t *data, uint32_t size) { // if (commandCount != 0) { // return CommandsFunctionsIF::ALREADY_COMMANDING; // } - HasActionsIF* receiver = objectManager->get(commandTo); + HasActionsIF *receiver = objectManager->get(commandTo); if (receiver == NULL) { return CommandsActionsIF::OBJECT_HAS_NO_FUNCTIONS; } @@ -71,13 +72,13 @@ ReturnValue_t CommandActionHelper::initialize() { } queueToUse = owner->getCommandQueuePtr(); - if(queueToUse == NULL){ + if (queueToUse == NULL) { return HasReturnvaluesIF::RETURN_FAILED; } return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t CommandActionHelper::handleReply(CommandMessage* reply) { +ReturnValue_t CommandActionHelper::handleReply(CommandMessage *reply) { if (reply->getSender() != lastTarget) { return HasReturnvaluesIF::RETURN_FAILED; } @@ -88,7 +89,8 @@ ReturnValue_t CommandActionHelper::handleReply(CommandMessage* reply) { return HasReturnvaluesIF::RETURN_OK; case ActionMessage::COMPLETION_FAILED: commandCount--; - owner->completionFailedReceived(ActionMessage::getActionId(reply), ActionMessage::getReturnCode(reply)); + owner->completionFailedReceived(ActionMessage::getActionId(reply), + ActionMessage::getReturnCode(reply)); return HasReturnvaluesIF::RETURN_OK; case ActionMessage::STEP_SUCCESS: owner->stepSuccessfulReceived(ActionMessage::getActionId(reply), @@ -96,11 +98,13 @@ ReturnValue_t CommandActionHelper::handleReply(CommandMessage* reply) { return HasReturnvaluesIF::RETURN_OK; case ActionMessage::STEP_FAILED: commandCount--; - owner->stepFailedReceived(ActionMessage::getActionId(reply), ActionMessage::getStep(reply), + owner->stepFailedReceived(ActionMessage::getActionId(reply), + ActionMessage::getStep(reply), ActionMessage::getReturnCode(reply)); return HasReturnvaluesIF::RETURN_OK; case ActionMessage::DATA_REPLY: - extractDataForOwner(ActionMessage::getActionId(reply), ActionMessage::getStoreId(reply)); + extractDataForOwner(ActionMessage::getActionId(reply), + ActionMessage::getStoreId(reply)); return HasReturnvaluesIF::RETURN_OK; default: return HasReturnvaluesIF::RETURN_FAILED; diff --git a/action/CommandActionHelper.h b/action/CommandActionHelper.h index 24d0380c6..cfed8c941 100644 --- a/action/CommandActionHelper.h +++ b/action/CommandActionHelper.h @@ -1,12 +1,12 @@ #ifndef COMMANDACTIONHELPER_H_ #define COMMANDACTIONHELPER_H_ -#include -#include -#include -#include -#include -#include +#include "ActionMessage.h" +#include "../objectmanager/ObjectManagerIF.h" +#include "../returnvalues/HasReturnvaluesIF.h" +#include "../serialize/SerializeIF.h" +#include "../storagemanager/StorageManagerIF.h" +#include "../ipc/MessageQueueIF.h" class CommandsActionsIF; diff --git a/action/CommandsActionsIF.h b/action/CommandsActionsIF.h index db76fb505..3d04015d1 100644 --- a/action/CommandsActionsIF.h +++ b/action/CommandsActionsIF.h @@ -1,9 +1,9 @@ #ifndef COMMANDSACTIONSIF_H_ #define COMMANDSACTIONSIF_H_ -#include -#include -#include +#include "CommandActionHelper.h" +#include "../returnvalues/HasReturnvaluesIF.h" +#include "../ipc/MessageQueueIF.h" /** * Interface to separate commanding actions of other objects. diff --git a/action/HasActionsIF.h b/action/HasActionsIF.h index f30fcb45e..886d08377 100644 --- a/action/HasActionsIF.h +++ b/action/HasActionsIF.h @@ -1,33 +1,41 @@ -#ifndef HASACTIONSIF_H_ -#define HASACTIONSIF_H_ +#ifndef FRAMEWORK_ACTION_HASACTIONSIF_H_ +#define FRAMEWORK_ACTION_HASACTIONSIF_H_ -#include -#include -#include -#include -#include +#include "ActionHelper.h" +#include "ActionMessage.h" +#include "SimpleActionHelper.h" +#include "../returnvalues/HasReturnvaluesIF.h" +#include "../ipc/MessageQueueIF.h" /** - * \brief Interface for component which uses actions + * @brief + * Interface for component which uses actions * - * This interface is used to execute actions in the component. Actions, in the sense of this interface, are activities with a well-defined beginning and - * end in time. They may adjust sub-states of components, but are not supposed to change - * the main mode of operation, which is handled with the HasModesIF described below. + * @details + * This interface is used to execute actions in the component. Actions, in the + * sense of this interface, are activities with a well-defined beginning and + * end in time. They may adjust sub-states of components, but are not supposed + * to change the main mode of operation, which is handled with the HasModesIF + * described below. * - * The HasActionsIF allows components to define such actions and make them available - * for other components to use. Implementing the interface is straightforward: There’s a - * single executeAction call, which provides an identifier for the action to execute, as well - * as arbitrary parameters for input. Aside from direct, software-based - * actions, it is used in device handler components as an interface to forward commands to - * devices. - * Implementing components of the interface are supposed to check identifier (ID) and - * parameters and immediately start execution of the action. It is, however, not required to - * immediately finish execution. Instead, this may be deferred to a later point in time, at - * which the component needs to inform the caller about finished or failed execution. + * The HasActionsIF allows components to define such actions and make them + * available for other components to use. Implementing the interface is + * straightforward: There’s a single executeAction call, which provides an + * identifier for the action to execute, as well as arbitrary parameters for + * input. + * Aside from direct, software-based actions, it is used in device handler + * components as an interface to forward commands to devices. + * Implementing components of the interface are supposed to check identifier + * (ID) and parameters and immediately start execution of the action. + * It is, however, not required to immediately finish execution. + * Instead, this may be deferred to a later point in time, at which the + * component needs to inform the caller about finished or failed execution. + * + * @ingroup interfaces */ class HasActionsIF { public: static const uint8_t INTERFACE_ID = CLASS_ID::HAS_ACTIONS_IF; - static const ReturnValue_t IS_BUSY = MAKE_RETURN_CODE(1);//!< + static const ReturnValue_t IS_BUSY = MAKE_RETURN_CODE(1); static const ReturnValue_t INVALID_PARAMETERS = MAKE_RETURN_CODE(2); static const ReturnValue_t EXECUTION_FINISHED = MAKE_RETURN_CODE(3); static const ReturnValue_t INVALID_ACTION_ID = MAKE_RETURN_CODE(4); @@ -39,12 +47,14 @@ 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! + * 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! */ - virtual ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, const uint8_t* data, uint32_t size) = 0; + virtual ReturnValue_t executeAction(ActionId_t actionId, + MessageQueueId_t commandedBy, const uint8_t* data, size_t size) = 0; }; -#endif /* HASACTIONSIF_H_ */ +#endif /* FRAMEWORK_ACTION_HASACTIONSIF_H_ */ diff --git a/action/SimpleActionHelper.cpp b/action/SimpleActionHelper.cpp index 6861fc28c..d79a3c977 100644 --- a/action/SimpleActionHelper.cpp +++ b/action/SimpleActionHelper.cpp @@ -1,5 +1,5 @@ -#include -#include +#include "HasActionsIF.h" +#include "SimpleActionHelper.h" SimpleActionHelper::SimpleActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue) : ActionHelper(setOwner, useThisQueue), isExecuting(false), lastCommander( diff --git a/action/SimpleActionHelper.h b/action/SimpleActionHelper.h index 71e73c5ad..1329b5fb5 100644 --- a/action/SimpleActionHelper.h +++ b/action/SimpleActionHelper.h @@ -1,7 +1,7 @@ #ifndef SIMPLEACTIONHELPER_H_ #define SIMPLEACTIONHELPER_H_ -#include +#include "ActionHelper.h" class SimpleActionHelper: public ActionHelper { public: diff --git a/container/ArrayList.h b/container/ArrayList.h index 9c4c4cebc..018f98945 100644 --- a/container/ArrayList.h +++ b/container/ArrayList.h @@ -1,9 +1,9 @@ #ifndef ARRAYLIST_H_ #define ARRAYLIST_H_ -#include -#include -#include +#include "../returnvalues/HasReturnvaluesIF.h" +#include "../serialize/SerializeAdapter.h" +#include "../serialize/SerializeIF.h" /** * A List that stores its values in an array. diff --git a/container/FIFO.h b/container/FIFO.h index f70c78b0d..3172d9d12 100644 --- a/container/FIFO.h +++ b/container/FIFO.h @@ -1,7 +1,7 @@ #ifndef FIFO_H_ #define FIFO_H_ -#include +#include "../returnvalues/HasReturnvaluesIF.h" /** * @brief Simple First-In-First-Out data structure diff --git a/container/FixedArrayList.h b/container/FixedArrayList.h index eeffcc870..42b59177c 100644 --- a/container/FixedArrayList.h +++ b/container/FixedArrayList.h @@ -1,7 +1,7 @@ #ifndef FIXEDARRAYLIST_H_ #define FIXEDARRAYLIST_H_ -#include +#include "ArrayList.h" /** * \ingroup container */ diff --git a/container/FixedMap.h b/container/FixedMap.h index 0b84bf4ea..dc19ce539 100644 --- a/container/FixedMap.h +++ b/container/FixedMap.h @@ -1,8 +1,8 @@ #ifndef FIXEDMAP_H_ #define FIXEDMAP_H_ -#include -#include +#include "ArrayList.h" +#include "../returnvalues/HasReturnvaluesIF.h" #include /** @@ -148,47 +148,47 @@ public: return theMap.maxSize(); } - virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { - ReturnValue_t result = SerializeAdapter::serialize(&this->_size, - buffer, size, max_size, bigEndian); + virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const { + ReturnValue_t result = SerializeAdapter::serialize(&this->_size, + buffer, size, maxSize, streamEndianness); uint32_t i = 0; while ((result == HasReturnvaluesIF::RETURN_OK) && (i < this->_size)) { - result = SerializeAdapter::serialize(&theMap[i].first, buffer, - size, max_size, bigEndian); - result = SerializeAdapter::serialize(&theMap[i].second, buffer, size, - max_size, bigEndian); + result = SerializeAdapter::serialize(&theMap[i].first, buffer, + size, maxSize, streamEndianness); + result = SerializeAdapter::serialize(&theMap[i].second, buffer, size, + maxSize, streamEndianness); ++i; } return result; } - virtual uint32_t getSerializedSize() const { + virtual size_t getSerializedSize() const { uint32_t printSize = sizeof(_size); uint32_t i = 0; for (i = 0; i < _size; ++i) { - printSize += SerializeAdapter::getSerializedSize( + printSize += SerializeAdapter::getSerializedSize( &theMap[i].first); - printSize += SerializeAdapter::getSerializedSize(&theMap[i].second); + printSize += SerializeAdapter::getSerializedSize(&theMap[i].second); } return printSize; } - virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) { - ReturnValue_t result = SerializeAdapter::deSerialize(&this->_size, - buffer, size, bigEndian); + virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) { + ReturnValue_t result = SerializeAdapter::deSerialize(&this->_size, + buffer, size, streamEndianness); if (this->_size > theMap.maxSize()) { return SerializeIF::TOO_MANY_ELEMENTS; } uint32_t i = 0; while ((result == HasReturnvaluesIF::RETURN_OK) && (i < this->_size)) { - result = SerializeAdapter::deSerialize(&theMap[i].first, buffer, - size, bigEndian); - result = SerializeAdapter::deSerialize(&theMap[i].second, buffer, size, - bigEndian); + result = SerializeAdapter::deSerialize(&theMap[i].first, buffer, + size, streamEndianness); + result = SerializeAdapter::deSerialize(&theMap[i].second, buffer, size, + streamEndianness); ++i; } return result; diff --git a/container/FixedOrderedMultimap.h b/container/FixedOrderedMultimap.h index 21629664b..6152d8d7f 100644 --- a/container/FixedOrderedMultimap.h +++ b/container/FixedOrderedMultimap.h @@ -1,7 +1,7 @@ #ifndef FRAMEWORK_CONTAINER_FIXEDORDEREDMULTIMAP_H_ #define FRAMEWORK_CONTAINER_FIXEDORDEREDMULTIMAP_H_ -#include +#include "ArrayList.h" #include #include /** diff --git a/container/HybridIterator.h b/container/HybridIterator.h index b34fdfd01..8d020cb93 100644 --- a/container/HybridIterator.h +++ b/container/HybridIterator.h @@ -1,41 +1,39 @@ -#ifndef HYBRIDITERATOR_H_ -#define HYBRIDITERATOR_H_ +#ifndef FRAMEWORK_CONTAINER_HYBRIDITERATOR_H_ +#define FRAMEWORK_CONTAINER_HYBRIDITERATOR_H_ -#include -#include +#include "ArrayList.h" +#include "SinglyLinkedList.h" template class HybridIterator: public LinkedElement::Iterator, public ArrayList::Iterator { public: - HybridIterator() : - value(NULL), linked(NULL), end(NULL) { - } + HybridIterator() {} HybridIterator(typename LinkedElement::Iterator *iter) : - LinkedElement::Iterator(*iter), value( - iter->value), linked(true), end(NULL) { + LinkedElement::Iterator(*iter), value(iter->value), + linked(true) { } HybridIterator(LinkedElement *start) : - LinkedElement::Iterator(start), value( - start->value), linked(true), end(NULL) { + LinkedElement::Iterator(start), value(start->value), + linked(true) { } HybridIterator(typename ArrayList::Iterator start, typename ArrayList::Iterator end) : - ArrayList::Iterator(start), value(start.value), linked( - false), end(end.value) { + ArrayList::Iterator(start), value(start.value), + linked(false), end(end.value) { if (value == this->end) { value = NULL; } } HybridIterator(T *firstElement, T *lastElement) : - ArrayList::Iterator(firstElement), value(firstElement), linked( - false), end(++lastElement) { + ArrayList::Iterator(firstElement), value(firstElement), + linked(false), end(++lastElement) { if (value == end) { value = NULL; } @@ -44,17 +42,17 @@ public: HybridIterator& operator++() { if (linked) { LinkedElement::Iterator::operator++(); - if (LinkedElement::Iterator::value != NULL) { + if (LinkedElement::Iterator::value != nullptr) { value = LinkedElement::Iterator::value->value; } else { - value = NULL; + value = nullptr; } } else { ArrayList::Iterator::operator++(); value = ArrayList::Iterator::value; if (value == end) { - value = NULL; + value = nullptr; } } return *this; @@ -66,11 +64,11 @@ public: return tmp; } - bool operator==(HybridIterator other) { - return value == other->value; + bool operator==(const HybridIterator& other) const { + return value == other.value; } - bool operator!=(HybridIterator other) { + bool operator!=(const HybridIterator& other) const { return !(*this == other); } @@ -82,11 +80,11 @@ public: return value; } - T* value; + T* value = nullptr; private: - bool linked; - T *end; + bool linked = false; + T *end = nullptr; }; -#endif /* HYBRIDITERATOR_H_ */ +#endif /* FRAMEWORK_CONTAINER_HYBRIDITERATOR_H_ */ diff --git a/container/IndexedRingMemoryArray.h b/container/IndexedRingMemoryArray.h index 992b7489a..0d85b49bc 100644 --- a/container/IndexedRingMemoryArray.h +++ b/container/IndexedRingMemoryArray.h @@ -1,11 +1,11 @@ #ifndef FRAMEWORK_CONTAINER_INDEXEDRINGMEMORY_H_ #define FRAMEWORK_CONTAINER_INDEXEDRINGMEMORY_H_ -#include -#include -#include -#include -#include +#include "ArrayList.h" +#include "../globalfunctions/CRC.h" +#include "../serviceinterface/ServiceInterfaceStream.h" +#include "../returnvalues/HasReturnvaluesIF.h" +#include "../serialize/SerialArrayListAdapter.h" #include template @@ -68,50 +68,50 @@ public: return this->storedPackets; } - ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { - ReturnValue_t result = AutoSerializeAdapter::serialize(&blockStartAddress,buffer,size,max_size,bigEndian); + ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const { + ReturnValue_t result = SerializeAdapter::serialize(&blockStartAddress,buffer,size,maxSize,streamEndianness); if(result != HasReturnvaluesIF::RETURN_OK){ return result; } - result = indexType.serialize(buffer,size,max_size,bigEndian); + result = indexType.serialize(buffer,size,maxSize,streamEndianness); if(result != HasReturnvaluesIF::RETURN_OK){ return result; } - result = AutoSerializeAdapter::serialize(&this->size,buffer,size,max_size,bigEndian); + result = SerializeAdapter::serialize(&this->size,buffer,size,maxSize,streamEndianness); if(result != HasReturnvaluesIF::RETURN_OK){ return result; } - result = AutoSerializeAdapter::serialize(&this->storedPackets,buffer,size,max_size,bigEndian); + result = SerializeAdapter::serialize(&this->storedPackets,buffer,size,maxSize,streamEndianness); return result; } - ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian){ - ReturnValue_t result = AutoSerializeAdapter::deSerialize(&blockStartAddress,buffer,size,bigEndian); + ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness){ + ReturnValue_t result = SerializeAdapter::deSerialize(&blockStartAddress,buffer,size,streamEndianness); if(result != HasReturnvaluesIF::RETURN_OK){ return result; } - result = indexType.deSerialize(buffer,size,bigEndian); + result = indexType.deSerialize(buffer,size,streamEndianness); if(result != HasReturnvaluesIF::RETURN_OK){ return result; } - result = AutoSerializeAdapter::deSerialize(&this->size,buffer,size,bigEndian); + result = SerializeAdapter::deSerialize(&this->size,buffer,size,streamEndianness); if(result != HasReturnvaluesIF::RETURN_OK){ return result; } - result = AutoSerializeAdapter::deSerialize(&this->storedPackets,buffer,size,bigEndian); + result = SerializeAdapter::deSerialize(&this->storedPackets,buffer,size,streamEndianness); if(result != HasReturnvaluesIF::RETURN_OK){ return result; } return result; } - uint32_t getSerializedSize() const { - uint32_t size = AutoSerializeAdapter::getSerializedSize(&blockStartAddress); + size_t getSerializedSize() const { + uint32_t size = SerializeAdapter::getSerializedSize(&blockStartAddress); size += indexType.getSerializedSize(); - size += AutoSerializeAdapter::getSerializedSize(&this->size); - size += AutoSerializeAdapter::getSerializedSize(&this->storedPackets); + size += SerializeAdapter::getSerializedSize(&this->size); + size += SerializeAdapter::getSerializedSize(&this->storedPackets); return size; } @@ -485,37 +485,37 @@ public: * Parameters according to HasSerializeIF * @param buffer * @param size - * @param max_size - * @param bigEndian + * @param maxSize + * @param streamEndianness * @return */ - ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const{ + ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const{ uint8_t* crcBuffer = *buffer; uint32_t oldSize = *size; if(additionalInfo!=NULL){ - additionalInfo->serialize(buffer,size,max_size,bigEndian); + additionalInfo->serialize(buffer,size,maxSize,streamEndianness); } - ReturnValue_t result = currentWriteBlock->serialize(buffer,size,max_size,bigEndian); + ReturnValue_t result = currentWriteBlock->serialize(buffer,size,maxSize,streamEndianness); if(result != HasReturnvaluesIF::RETURN_OK){ return result; } - result = AutoSerializeAdapter::serialize(&this->size,buffer,size,max_size,bigEndian); + result = SerializeAdapter::serialize(&this->size,buffer,size,maxSize,streamEndianness); if(result != HasReturnvaluesIF::RETURN_OK){ return result; } uint32_t i = 0; while ((result == HasReturnvaluesIF::RETURN_OK) && (i < this->size)) { - result = SerializeAdapter >::serialize(&this->entries[i], buffer, size, - max_size, bigEndian); + result = SerializeAdapter::serialize(&this->entries[i], buffer, size, + maxSize, streamEndianness); ++i; } if(result != HasReturnvaluesIF::RETURN_OK){ return result; } uint16_t crc = Calculate_CRC(crcBuffer,(*size-oldSize)); - result = AutoSerializeAdapter::serialize(&crc,buffer,size,max_size,bigEndian); + result = SerializeAdapter::serialize(&crc,buffer,size,maxSize,streamEndianness); return result; } @@ -524,17 +524,17 @@ public: * Get the serialized Size of the index * @return The serialized size of the index */ - uint32_t getSerializedSize() const { + size_t getSerializedSize() const { uint32_t size = 0; if(additionalInfo!=NULL){ size += additionalInfo->getSerializedSize(); } size += currentWriteBlock->getSerializedSize(); - size += AutoSerializeAdapter::getSerializedSize(&this->size); + size += SerializeAdapter::getSerializedSize(&this->size); size += (this->entries[0].getSerializedSize()) * this->size; uint16_t crc = 0; - size += AutoSerializeAdapter::getSerializedSize(&crc); + size += SerializeAdapter::getSerializedSize(&crc); return size; } /** @@ -542,28 +542,28 @@ public: * CRC Has to be checked before! * @param buffer * @param size - * @param bigEndian + * @param streamEndianness * @return */ - ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian){ + ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness){ ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; if(additionalInfo!=NULL){ - result = additionalInfo->deSerialize(buffer,size,bigEndian); + result = additionalInfo->deSerialize(buffer,size,streamEndianness); } if(result != HasReturnvaluesIF::RETURN_OK){ return result; } Index tempIndex; - result = tempIndex.deSerialize(buffer,size,bigEndian); + result = tempIndex.deSerialize(buffer,size,streamEndianness); if(result != HasReturnvaluesIF::RETURN_OK){ return result; } uint32_t tempSize = 0; - result = AutoSerializeAdapter::deSerialize(&tempSize,buffer,size,bigEndian); + result = SerializeAdapter::deSerialize(&tempSize,buffer,size,streamEndianness); if(result != HasReturnvaluesIF::RETURN_OK){ return result; } @@ -572,9 +572,9 @@ public: } uint32_t i = 0; while ((result == HasReturnvaluesIF::RETURN_OK) && (i < this->size)) { - result = SerializeAdapter >::deSerialize( + result = SerializeAdapter::deSerialize( &this->entries[i], buffer, size, - bigEndian); + streamEndianness); ++i; } if(result != HasReturnvaluesIF::RETURN_OK){ diff --git a/container/PlacementFactory.h b/container/PlacementFactory.h index daf4ee20c..055384780 100644 --- a/container/PlacementFactory.h +++ b/container/PlacementFactory.h @@ -1,7 +1,7 @@ #ifndef FRAMEWORK_CONTAINER_PLACEMENTFACTORY_H_ #define FRAMEWORK_CONTAINER_PLACEMENTFACTORY_H_ -#include +#include "../storagemanager/StorageManagerIF.h" #include class PlacementFactory { diff --git a/container/RingBufferBase.h b/container/RingBufferBase.h index 3ef782d87..e3a87d9d8 100644 --- a/container/RingBufferBase.h +++ b/container/RingBufferBase.h @@ -1,7 +1,7 @@ #ifndef FRAMEWORK_CONTAINER_RINGBUFFERBASE_H_ #define FRAMEWORK_CONTAINER_RINGBUFFERBASE_H_ -#include +#include "../returnvalues/HasReturnvaluesIF.h" template class RingBufferBase { diff --git a/container/SimpleRingBuffer.cpp b/container/SimpleRingBuffer.cpp index 63dc3514b..ee0876439 100644 --- a/container/SimpleRingBuffer.cpp +++ b/container/SimpleRingBuffer.cpp @@ -1,4 +1,4 @@ -#include +#include "SimpleRingBuffer.h" #include SimpleRingBuffer::SimpleRingBuffer(uint32_t size, bool overwriteOld) : diff --git a/container/SimpleRingBuffer.h b/container/SimpleRingBuffer.h index 6d7d67e1d..5d4fecabe 100644 --- a/container/SimpleRingBuffer.h +++ b/container/SimpleRingBuffer.h @@ -1,7 +1,7 @@ #ifndef FRAMEWORK_CONTAINER_SIMPLERINGBUFFER_H_ #define FRAMEWORK_CONTAINER_SIMPLERINGBUFFER_H_ -#include +#include "RingBufferBase.h" #include class SimpleRingBuffer: public RingBufferBase<> { diff --git a/container/SinglyLinkedList.h b/container/SinglyLinkedList.h index 0a2e0531d..eb6ae276a 100644 --- a/container/SinglyLinkedList.h +++ b/container/SinglyLinkedList.h @@ -1,10 +1,13 @@ -#ifndef SINGLYLINKEDLIST_H_ -#define SINGLYLINKEDLIST_H_ +#ifndef FRAMEWORK_CONTAINER_SINGLYLINKEDLIST_H_ +#define FRAMEWORK_CONTAINER_SINGLYLINKEDLIST_H_ + +#include +#include -#include -#include /** - * \ingroup container + * @brief Linked list data structure, + * each entry has a pointer to the next entry (singly) + * @ingroup container */ template class LinkedElement { @@ -12,11 +15,8 @@ public: T *value; class Iterator { public: - LinkedElement *value; - Iterator() : - value(NULL) { - - } + LinkedElement *value = nullptr; + Iterator() {} Iterator(LinkedElement *element) : value(element) { @@ -45,12 +45,11 @@ public: } }; - LinkedElement(T* setElement, LinkedElement* setNext = NULL) : value(setElement), - next(setNext) { - } - virtual ~LinkedElement(){ + LinkedElement(T* setElement, LinkedElement* setNext = nullptr): + value(setElement), next(setNext) {} + + virtual ~LinkedElement(){} - } virtual LinkedElement* getNext() const { return next; } @@ -58,11 +57,16 @@ public: virtual void setNext(LinkedElement* next) { this->next = next; } + + virtual void setEnd() { + this->next = nullptr; + } + LinkedElement* begin() { return this; } LinkedElement* end() { - return NULL; + return nullptr; } private: LinkedElement *next; @@ -71,37 +75,80 @@ private: template class SinglyLinkedList { public: - SinglyLinkedList() : - start(NULL) { - } + using ElementIterator = typename LinkedElement::Iterator; + + SinglyLinkedList() {} + + SinglyLinkedList(ElementIterator start) : + start(start.value) {} - SinglyLinkedList(typename LinkedElement::Iterator start) : - start(start.value) { - } SinglyLinkedList(LinkedElement* startElement) : - start(startElement) { - } - typename LinkedElement::Iterator begin() const { - return LinkedElement::Iterator::Iterator(start); - } - typename LinkedElement::Iterator::Iterator end() const { - return LinkedElement::Iterator::Iterator(); + start(startElement) {} + + ElementIterator begin() const { + return ElementIterator::Iterator(start); } - uint32_t getSize() const { - uint32_t size = 0; + /** Returns iterator to nulltr */ + ElementIterator end() const { + return ElementIterator::Iterator(); + } + + /** + * Returns last element in singly linked list. + * @return + */ + ElementIterator back() const { + LinkedElement *element = start; + while (element->getNext() != nullptr) { + element = element->getNext(); + } + return ElementIterator::Iterator(element); + } + + size_t getSize() const { + size_t size = 0; LinkedElement *element = start; - while (element != NULL) { + while (element != nullptr) { size++; element = element->getNext(); } return size; } - void setStart(LinkedElement* setStart) { - start = setStart; + void setStart(LinkedElement* firstElement) { + start = firstElement; } + + void setNext(LinkedElement* currentElement, + LinkedElement* nextElement) { + currentElement->setNext(nextElement); + } + + void setLast(LinkedElement* lastElement) { + lastElement->setEnd(); + } + + void insertElement(LinkedElement* element, size_t position) { + LinkedElement *currentElement = start; + for(size_t count = 0; count < position; count++) { + if(currentElement == nullptr) { + return; + } + currentElement = currentElement->getNext(); + } + LinkedElement* elementAfterCurrent = currentElement->next; + currentElement->setNext(element); + if(elementAfterCurrent != nullptr) { + element->setNext(elementAfterCurrent); + } + } + + void insertBack(LinkedElement* lastElement) { + back().value->setNext(lastElement); + } + protected: - LinkedElement *start; + LinkedElement *start = nullptr; }; #endif /* SINGLYLINKEDLIST_H_ */ diff --git a/controller/ControllerBase.cpp b/controller/ControllerBase.cpp index 7b11bdfa3..695517310 100644 --- a/controller/ControllerBase.cpp +++ b/controller/ControllerBase.cpp @@ -1,8 +1,8 @@ -#include -#include -#include -#include -#include +#include "../subsystem/SubsystemBase.h" +#include "ControllerBase.h" +#include "../subsystem/SubsystemBase.h" +#include "../ipc/QueueFactory.h" +#include "../action/HasActionsIF.h" ControllerBase::ControllerBase(uint32_t setObjectId, uint32_t parentId, size_t commandQueueDepth) : diff --git a/controller/ControllerBase.h b/controller/ControllerBase.h index 804bc7c25..f5182ceb3 100644 --- a/controller/ControllerBase.h +++ b/controller/ControllerBase.h @@ -1,13 +1,13 @@ #ifndef CONTROLLERBASE_H_ #define CONTROLLERBASE_H_ -#include -#include -#include -#include -#include -#include -#include +#include "../health/HasHealthIF.h" +#include "../health/HealthHelper.h" +#include "../modes/HasModesIF.h" +#include "../modes/ModeHelper.h" +#include "../objectmanager/SystemObject.h" +#include "../tasks/ExecutableObjectIF.h" +#include "../datapool/HkSwitchHelper.h" class ControllerBase: public HasModesIF, diff --git a/coordinates/CoordinateTransformations.cpp b/coordinates/CoordinateTransformations.cpp index b57519a38..4e2debbe8 100644 --- a/coordinates/CoordinateTransformations.cpp +++ b/coordinates/CoordinateTransformations.cpp @@ -1,7 +1,7 @@ -#include -#include -#include -#include +#include "CoordinateTransformations.h" +#include "../globalfunctions/constants.h" +#include "../globalfunctions/math/MatrixOperations.h" +#include "../globalfunctions/math/VectorOperations.h" #include #include diff --git a/coordinates/CoordinateTransformations.h b/coordinates/CoordinateTransformations.h index b072271fc..09ea2c48c 100644 --- a/coordinates/CoordinateTransformations.h +++ b/coordinates/CoordinateTransformations.h @@ -1,7 +1,7 @@ #ifndef COORDINATETRANSFORMATIONS_H_ #define COORDINATETRANSFORMATIONS_H_ -#include +#include "../timemanager/Clock.h" #include class CoordinateTransformations { diff --git a/coordinates/Jgm3Model.h b/coordinates/Jgm3Model.h index 8f0598f84..884ed1418 100644 --- a/coordinates/Jgm3Model.h +++ b/coordinates/Jgm3Model.h @@ -2,10 +2,10 @@ #define FRAMEWORK_COORDINATES_JGM3MODEL_H_ #include -#include -#include -#include -#include +#include "CoordinateTransformations.h" +#include "../globalfunctions/math/VectorOperations.h" +#include "../globalfunctions/timevalOperations.h" +#include "../globalfunctions/constants.h" #include diff --git a/coordinates/Sgp4Propagator.cpp b/coordinates/Sgp4Propagator.cpp index 0eb20f08a..5cb1497cf 100644 --- a/coordinates/Sgp4Propagator.cpp +++ b/coordinates/Sgp4Propagator.cpp @@ -1,9 +1,9 @@ -#include -#include -#include -#include -#include -#include +#include "CoordinateTransformations.h" +#include "Sgp4Propagator.h" +#include "../globalfunctions/constants.h" +#include "../globalfunctions/math/MatrixOperations.h" +#include "../globalfunctions/math/VectorOperations.h" +#include "../globalfunctions/timevalOperations.h" #include Sgp4Propagator::Sgp4Propagator() : initialized(false), epoch({0, 0}), whichconst(wgs84) { diff --git a/coordinates/Sgp4Propagator.h b/coordinates/Sgp4Propagator.h index 957397620..3949547e1 100644 --- a/coordinates/Sgp4Propagator.h +++ b/coordinates/Sgp4Propagator.h @@ -3,7 +3,7 @@ #include #include "../contrib/sgp4/sgp4unit.h" -#include +#include "../returnvalues/HasReturnvaluesIF.h" class Sgp4Propagator { public: diff --git a/datalinklayer/BCFrame.h b/datalinklayer/BCFrame.h index bcdf53008..b7795556d 100644 --- a/datalinklayer/BCFrame.h +++ b/datalinklayer/BCFrame.h @@ -8,7 +8,7 @@ #ifndef BCFRAME_H_ #define BCFRAME_H_ -#include +#include "CCSDSReturnValuesIF.h" /** * Small helper class to identify a BcFrame. diff --git a/datalinklayer/CCSDSReturnValuesIF.h b/datalinklayer/CCSDSReturnValuesIF.h index 4d4f4bde9..805b6969f 100644 --- a/datalinklayer/CCSDSReturnValuesIF.h +++ b/datalinklayer/CCSDSReturnValuesIF.h @@ -8,7 +8,7 @@ #ifndef CCSDSRETURNVALUESIF_H_ #define CCSDSRETURNVALUESIF_H_ -#include +#include "../returnvalues/HasReturnvaluesIF.h" /** * This is a helper class to collect special return values that come up during CCSDS Handling. * @ingroup ccsds_handling diff --git a/datalinklayer/Clcw.cpp b/datalinklayer/Clcw.cpp index ee497e206..dc435a2b4 100644 --- a/datalinklayer/Clcw.cpp +++ b/datalinklayer/Clcw.cpp @@ -7,8 +7,8 @@ -#include -#include +#include "Clcw.h" +#include "../serviceinterface/ServiceInterfaceStream.h" Clcw::Clcw() { content.raw = 0; diff --git a/datalinklayer/Clcw.h b/datalinklayer/Clcw.h index f19f37b66..8116d63b6 100644 --- a/datalinklayer/Clcw.h +++ b/datalinklayer/Clcw.h @@ -8,7 +8,7 @@ #ifndef CLCW_H_ #define CLCW_H_ -#include +#include "ClcwIF.h" /** * Small helper method to handle the Clcw values. * It has a content struct that manages the register and can be set externally. diff --git a/datalinklayer/DataLinkLayer.cpp b/datalinklayer/DataLinkLayer.cpp index 4ca7f2705..75f2edda0 100644 --- a/datalinklayer/DataLinkLayer.cpp +++ b/datalinklayer/DataLinkLayer.cpp @@ -1,6 +1,6 @@ -#include -#include -#include +#include "DataLinkLayer.h" +#include "../globalfunctions/CRC.h" +#include "../serviceinterface/ServiceInterfaceStream.h" DataLinkLayer::DataLinkLayer(uint8_t* set_frame_buffer, ClcwIF* setClcw, uint8_t set_start_sequence_length, uint16_t set_scid) : diff --git a/datalinklayer/DataLinkLayer.h b/datalinklayer/DataLinkLayer.h index 8a3bb8e5a..5a900099e 100644 --- a/datalinklayer/DataLinkLayer.h +++ b/datalinklayer/DataLinkLayer.h @@ -1,11 +1,11 @@ #ifndef DATALINKLAYER_H_ #define DATALINKLAYER_H_ -#include -#include -#include -#include -#include +#include "CCSDSReturnValuesIF.h" +#include "ClcwIF.h" +#include "TcTransferFrame.h" +#include "VirtualChannelReceptionIF.h" +#include "../events/Event.h" #include diff --git a/datalinklayer/Farm1StateIF.h b/datalinklayer/Farm1StateIF.h index 25836e6a4..71794d75e 100644 --- a/datalinklayer/Farm1StateIF.h +++ b/datalinklayer/Farm1StateIF.h @@ -8,7 +8,7 @@ #ifndef FARM1STATEIF_H_ #define FARM1STATEIF_H_ -#include +#include "CCSDSReturnValuesIF.h" class VirtualChannelReception; class TcTransferFrame; class ClcwIF; diff --git a/datalinklayer/Farm1StateLockout.cpp b/datalinklayer/Farm1StateLockout.cpp index 45ae47f9b..1b339a85f 100644 --- a/datalinklayer/Farm1StateLockout.cpp +++ b/datalinklayer/Farm1StateLockout.cpp @@ -7,10 +7,10 @@ -#include -#include -#include -#include +#include "ClcwIF.h" +#include "Farm1StateLockout.h" +#include "TcTransferFrame.h" +#include "VirtualChannelReception.h" Farm1StateLockout::Farm1StateLockout(VirtualChannelReception* setMyVC) : myVC(setMyVC) { } diff --git a/datalinklayer/Farm1StateLockout.h b/datalinklayer/Farm1StateLockout.h index aac8ed74c..63cdc4d2b 100644 --- a/datalinklayer/Farm1StateLockout.h +++ b/datalinklayer/Farm1StateLockout.h @@ -8,7 +8,7 @@ #ifndef FARM1STATELOCKOUT_H_ #define FARM1STATELOCKOUT_H_ -#include +#include "Farm1StateIF.h" /** * This class represents the FARM-1 "Lockout" State. diff --git a/datalinklayer/Farm1StateOpen.cpp b/datalinklayer/Farm1StateOpen.cpp index b06cff48d..61c0997f9 100644 --- a/datalinklayer/Farm1StateOpen.cpp +++ b/datalinklayer/Farm1StateOpen.cpp @@ -8,10 +8,10 @@ -#include -#include -#include -#include +#include "ClcwIF.h" +#include "Farm1StateOpen.h" +#include "TcTransferFrame.h" +#include "VirtualChannelReception.h" Farm1StateOpen::Farm1StateOpen(VirtualChannelReception* setMyVC) : myVC(setMyVC) { } diff --git a/datalinklayer/Farm1StateOpen.h b/datalinklayer/Farm1StateOpen.h index 09caacbbb..3b3a26048 100644 --- a/datalinklayer/Farm1StateOpen.h +++ b/datalinklayer/Farm1StateOpen.h @@ -8,7 +8,7 @@ #ifndef FARM1STATEOPEN_H_ #define FARM1STATEOPEN_H_ -#include +#include "Farm1StateIF.h" /** * This class represents the FARM-1 "Open" State. diff --git a/datalinklayer/Farm1StateWait.cpp b/datalinklayer/Farm1StateWait.cpp index 1c72e68f8..9001e1f5f 100644 --- a/datalinklayer/Farm1StateWait.cpp +++ b/datalinklayer/Farm1StateWait.cpp @@ -6,10 +6,10 @@ */ -#include -#include -#include -#include +#include "ClcwIF.h" +#include "Farm1StateWait.h" +#include "TcTransferFrame.h" +#include "VirtualChannelReception.h" Farm1StateWait::Farm1StateWait(VirtualChannelReception* setMyVC) : myVC(setMyVC) { } diff --git a/datalinklayer/Farm1StateWait.h b/datalinklayer/Farm1StateWait.h index f12017912..877c36c26 100644 --- a/datalinklayer/Farm1StateWait.h +++ b/datalinklayer/Farm1StateWait.h @@ -8,7 +8,7 @@ #ifndef FARM1STATEWAIT_H_ #define FARM1STATEWAIT_H_ -#include +#include "Farm1StateIF.h" /** * This class represents the FARM-1 "Wait" State. diff --git a/datalinklayer/MapPacketExtraction.cpp b/datalinklayer/MapPacketExtraction.cpp index 11b0792a9..cb12b3210 100644 --- a/datalinklayer/MapPacketExtraction.cpp +++ b/datalinklayer/MapPacketExtraction.cpp @@ -5,13 +5,13 @@ * @author baetz */ -#include -#include -#include -#include -#include -#include -#include +#include "MapPacketExtraction.h" +#include "../ipc/QueueFactory.h" +#include "../serviceinterface/ServiceInterfaceStream.h" +#include "../storagemanager/StorageManagerIF.h" +#include "../tmtcpacket/SpacePacketBase.h" +#include "../tmtcservices/AcceptsTelecommandsIF.h" +#include "../tmtcservices/TmTcMessage.h" #include MapPacketExtraction::MapPacketExtraction(uint8_t setMapId, diff --git a/datalinklayer/MapPacketExtraction.h b/datalinklayer/MapPacketExtraction.h index 5a32366c4..507f13dbe 100644 --- a/datalinklayer/MapPacketExtraction.h +++ b/datalinklayer/MapPacketExtraction.h @@ -8,10 +8,10 @@ #ifndef MAPPACKETEXTRACTION_H_ #define MAPPACKETEXTRACTION_H_ -#include -#include -#include -#include +#include "MapPacketExtractionIF.h" +#include "../objectmanager/ObjectManagerIF.h" +#include "../returnvalues/HasReturnvaluesIF.h" +#include "../ipc/MessageQueueSenderIF.h" class StorageManagerIF; diff --git a/datalinklayer/MapPacketExtractionIF.h b/datalinklayer/MapPacketExtractionIF.h index 802a893d0..e29ac6660 100644 --- a/datalinklayer/MapPacketExtractionIF.h +++ b/datalinklayer/MapPacketExtractionIF.h @@ -8,8 +8,8 @@ #ifndef MAPPACKETEXTRACTIONIF_H_ #define MAPPACKETEXTRACTIONIF_H_ -#include -#include +#include "CCSDSReturnValuesIF.h" +#include "TcTransferFrame.h" /** * This is the interface for MAP Packet Extraction classes. diff --git a/datalinklayer/TcTransferFrame.cpp b/datalinklayer/TcTransferFrame.cpp index 30398e9bf..f1a70bdcf 100644 --- a/datalinklayer/TcTransferFrame.cpp +++ b/datalinklayer/TcTransferFrame.cpp @@ -7,8 +7,8 @@ -#include -#include +#include "TcTransferFrame.h" +#include "../serviceinterface/ServiceInterfaceStream.h" TcTransferFrame::TcTransferFrame() { frame = NULL; diff --git a/datalinklayer/TcTransferFrameLocal.cpp b/datalinklayer/TcTransferFrameLocal.cpp index 79e141674..e8785c92a 100644 --- a/datalinklayer/TcTransferFrameLocal.cpp +++ b/datalinklayer/TcTransferFrameLocal.cpp @@ -5,9 +5,9 @@ * @author baetz */ -#include -#include -#include +#include "TcTransferFrameLocal.h" +#include "../globalfunctions/CRC.h" +#include "../serviceinterface/ServiceInterfaceStream.h" #include TcTransferFrameLocal::TcTransferFrameLocal(bool bypass, bool controlCommand, uint16_t scid, diff --git a/datalinklayer/TcTransferFrameLocal.h b/datalinklayer/TcTransferFrameLocal.h index f20f12ec2..487d8940b 100644 --- a/datalinklayer/TcTransferFrameLocal.h +++ b/datalinklayer/TcTransferFrameLocal.h @@ -8,7 +8,7 @@ #ifndef TCTRANSFERFRAMELOCAL_H_ #define TCTRANSFERFRAMELOCAL_H_ -#include +#include "TcTransferFrame.h" /** * This is a helper class to locally create TC Transfer Frames. diff --git a/datalinklayer/VirtualChannelReception.cpp b/datalinklayer/VirtualChannelReception.cpp index 373f6c62d..cde28de37 100644 --- a/datalinklayer/VirtualChannelReception.cpp +++ b/datalinklayer/VirtualChannelReception.cpp @@ -5,9 +5,9 @@ * @author baetz */ -#include -#include -#include +#include "BCFrame.h" +#include "VirtualChannelReception.h" +#include "../serviceinterface/ServiceInterfaceStream.h" VirtualChannelReception::VirtualChannelReception(uint8_t setChannelId, uint8_t setSlidingWindowWidth) : diff --git a/datalinklayer/VirtualChannelReception.h b/datalinklayer/VirtualChannelReception.h index f364c6e5d..9b4e2987e 100644 --- a/datalinklayer/VirtualChannelReception.h +++ b/datalinklayer/VirtualChannelReception.h @@ -8,14 +8,14 @@ #ifndef VIRTUALCHANNELRECEPTION_H_ #define VIRTUALCHANNELRECEPTION_H_ -#include -#include -#include -#include -#include -#include -#include -#include +#include "CCSDSReturnValuesIF.h" +#include "Clcw.h" +#include "Farm1StateIF.h" +#include "Farm1StateLockout.h" +#include "Farm1StateOpen.h" +#include "Farm1StateWait.h" +#include "MapPacketExtractionIF.h" +#include "VirtualChannelReceptionIF.h" #include /** * Implementation of a TC Virtual Channel. diff --git a/datalinklayer/VirtualChannelReceptionIF.h b/datalinklayer/VirtualChannelReceptionIF.h index 98a9b72c8..36f60e8c4 100644 --- a/datalinklayer/VirtualChannelReceptionIF.h +++ b/datalinklayer/VirtualChannelReceptionIF.h @@ -8,9 +8,9 @@ #ifndef VIRTUALCHANNELRECEPTIONIF_H_ #define VIRTUALCHANNELRECEPTIONIF_H_ -#include -#include -#include +#include "ClcwIF.h" +#include "TcTransferFrame.h" +#include "../returnvalues/HasReturnvaluesIF.h" /** * This is the interface for Virtual Channel reception classes. diff --git a/datapool/ControllerSet.cpp b/datapool/ControllerSet.cpp index eb4f6d0fd..6339034c1 100644 --- a/datapool/ControllerSet.cpp +++ b/datapool/ControllerSet.cpp @@ -1,4 +1,4 @@ -#include +#include "ControllerSet.h" ControllerSet::ControllerSet() { diff --git a/datapool/ControllerSet.h b/datapool/ControllerSet.h index de06bf918..e27debff0 100644 --- a/datapool/ControllerSet.h +++ b/datapool/ControllerSet.h @@ -1,7 +1,7 @@ #ifndef CONTROLLERSET_H_ #define CONTROLLERSET_H_ -#include +#include "DataSet.h" class ControllerSet :public DataSet { public: diff --git a/datapool/DataPool.cpp b/datapool/DataPool.cpp index 70a2a3fb5..1b6cb7a19 100644 --- a/datapool/DataPool.cpp +++ b/datapool/DataPool.cpp @@ -1,6 +1,6 @@ -#include -#include -#include +#include "DataPool.h" +#include "../serviceinterface/ServiceInterfaceStream.h" +#include "../ipc/MutexFactory.h" DataPool::DataPool( void ( *initFunction )( std::map* pool_map ) ) { mutex = MutexFactory::instance()->createMutex(); @@ -39,10 +39,10 @@ PoolEntryIF* DataPool::getRawData( uint32_t data_pool_id ) { } } -//uint8_t DataPool::getRawData( uint32_t data_pool_id, uint8_t* address, uint16_t* size, uint32_t max_size ) { +//uint8_t DataPool::getRawData( uint32_t data_pool_id, uint8_t* address, uint16_t* size, uint32_t maxSize ) { // std::map::iterator it = this->data_pool.find( data_pool_id ); // if ( it != this->data_pool.end() ) { -// if ( it->second->getByteSize() <= max_size ) { +// if ( it->second->getByteSize() <= maxSize ) { // *size = it->second->getByteSize(); // memcpy( address, it->second->getRawData(), *size ); // return DP_SUCCESSFUL; @@ -61,7 +61,7 @@ ReturnValue_t DataPool::freeDataPoolLock() { } ReturnValue_t DataPool::lockDataPool() { - ReturnValue_t status = mutex->lockMutex(MutexIF::NO_TIMEOUT); + ReturnValue_t status = mutex->lockMutex(MutexIF::BLOCKING); if ( status != RETURN_OK ) { sif::error << "DataPool::DataPool: lock of mutex failed with error code: " << status << std::endl; } diff --git a/datapool/DataPool.h b/datapool/DataPool.h index 6e38dc1b9..7abf28980 100644 --- a/datapool/DataPool.h +++ b/datapool/DataPool.h @@ -11,9 +11,9 @@ #ifndef DATAPOOL_H_ #define DATAPOOL_H_ -#include -#include -#include +#include "PoolEntry.h" +#include "../globalfunctions/Type.h" +#include "../ipc/MutexIF.h" #include /** diff --git a/datapool/DataPoolAdmin.cpp b/datapool/DataPoolAdmin.cpp index 99d2b51b2..f298d530d 100644 --- a/datapool/DataPoolAdmin.cpp +++ b/datapool/DataPoolAdmin.cpp @@ -1,10 +1,10 @@ -#include -#include -#include -#include -#include -#include -#include +#include "DataPool.h" +#include "DataPoolAdmin.h" +#include "DataSet.h" +#include "PoolRawAccess.h" +#include "../ipc/CommandMessage.h" +#include "../ipc/QueueFactory.h" +#include "../parameters/ParameterMessage.h" DataPoolAdmin::DataPoolAdmin(object_id_t objectId) : SystemObject(objectId), storage(NULL), commandQueue(NULL), memoryHelper( @@ -26,7 +26,7 @@ MessageQueueId_t DataPoolAdmin::getCommandQueue() const { } ReturnValue_t DataPoolAdmin::executeAction(ActionId_t actionId, - MessageQueueId_t commandedBy, const uint8_t* data, uint32_t size) { + MessageQueueId_t commandedBy, const uint8_t* data, size_t size) { if (actionId != SET_VALIDITY) { return INVALID_ACTION_ID; } @@ -91,7 +91,7 @@ void DataPoolAdmin::handleCommand() { } ReturnValue_t DataPoolAdmin::handleMemoryLoad(uint32_t address, - const uint8_t* data, uint32_t size, uint8_t** dataPointer) { + const uint8_t* data, size_t size, uint8_t** dataPointer) { uint32_t poolId = ::dataPool.PIDToDataPoolId(address); uint8_t arrayIndex = ::dataPool.PIDToArrayIndex(address); DataSet testSet; @@ -129,7 +129,7 @@ ReturnValue_t DataPoolAdmin::handleMemoryLoad(uint32_t address, return ACTIVITY_COMPLETED; } -ReturnValue_t DataPoolAdmin::handleMemoryDump(uint32_t address, uint32_t size, +ReturnValue_t DataPoolAdmin::handleMemoryDump(uint32_t address, size_t size, uint8_t** dataPointer, uint8_t* copyHere) { uint32_t poolId = ::dataPool.PIDToDataPoolId(address); uint8_t arrayIndex = ::dataPool.PIDToArrayIndex(address); @@ -151,7 +151,7 @@ ReturnValue_t DataPoolAdmin::handleMemoryDump(uint32_t address, uint32_t size, PoolVariableIF::VAR_READ); status = rawSet.read(); if (status == RETURN_OK) { - uint32_t temp = 0; + size_t temp = 0; status = variable.getEntryEndianSafe(ptrToCopy, &temp, size); if (status != RETURN_OK) { return RETURN_FAILED; @@ -261,7 +261,7 @@ ReturnValue_t DataPoolAdmin::handleParameterCommand(CommandMessage* command) { //identical to ParameterHelper::sendParameter() ReturnValue_t DataPoolAdmin::sendParameter(MessageQueueId_t to, uint32_t id, const DataPoolParameterWrapper* wrapper) { - uint32_t serializedSize = wrapper->getSerializedSize(); + size_t serializedSize = wrapper->getSerializedSize(); uint8_t *storeElement; store_address_t address; @@ -272,10 +272,10 @@ ReturnValue_t DataPoolAdmin::sendParameter(MessageQueueId_t to, uint32_t id, return result; } - uint32_t storeElementSize = 0; + size_t storeElementSize = 0; result = wrapper->serialize(&storeElement, &storeElementSize, - serializedSize, true); + serializedSize, SerializeIF::Endianness::BIG); if (result != HasReturnvaluesIF::RETURN_OK) { storage->deleteData(address); diff --git a/datapool/DataPoolAdmin.h b/datapool/DataPoolAdmin.h index 448d78fbc..e2d1e9e18 100644 --- a/datapool/DataPoolAdmin.h +++ b/datapool/DataPoolAdmin.h @@ -1,15 +1,15 @@ #ifndef DATAPOOLADMIN_H_ #define DATAPOOLADMIN_H_ -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "../memory/MemoryHelper.h" +#include "../action/HasActionsIF.h" +#include "../action/SimpleActionHelper.h" +#include "../objectmanager/SystemObject.h" +#include "../returnvalues/HasReturnvaluesIF.h" +#include "../tasks/ExecutableObjectIF.h" +#include "../parameters/ReceivesParameterMessagesIF.h" +#include "DataPoolParameterWrapper.h" +#include "../ipc/MessageQueueIF.h" class DataPoolAdmin: public HasActionsIF, public ExecutableObjectIF, @@ -29,12 +29,12 @@ public: MessageQueueId_t getCommandQueue() const; ReturnValue_t handleMemoryLoad(uint32_t address, const uint8_t* data, - uint32_t size, uint8_t** dataPointer); - ReturnValue_t handleMemoryDump(uint32_t address, uint32_t size, + size_t size, uint8_t** dataPointer); + ReturnValue_t handleMemoryDump(uint32_t address, size_t size, uint8_t** dataPointer, uint8_t* copyHere); ReturnValue_t executeAction(ActionId_t actionId, - MessageQueueId_t commandedBy, const uint8_t* data, uint32_t size); + MessageQueueId_t commandedBy, const uint8_t* data, size_t size); //not implemented as ParameterHelper is no used ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId, diff --git a/datapool/DataPoolParameterWrapper.cpp b/datapool/DataPoolParameterWrapper.cpp index 0ff2121d6..79367405a 100644 --- a/datapool/DataPoolParameterWrapper.cpp +++ b/datapool/DataPoolParameterWrapper.cpp @@ -1,10 +1,10 @@ #include "DataPoolParameterWrapper.h" //for returncodes -#include +#include "../parameters/HasParametersIF.h" -#include -#include +#include "DataSet.h" +#include "PoolRawAccess.h" DataPoolParameterWrapper::DataPoolParameterWrapper() : type(Type::UNKNOWN_TYPE), rows(0), columns(0), poolId( @@ -36,22 +36,22 @@ ReturnValue_t DataPoolParameterWrapper::set(uint8_t domainId, } ReturnValue_t DataPoolParameterWrapper::serialize(uint8_t** buffer, - uint32_t* size, const uint32_t max_size, bool bigEndian) const { + size_t* size, size_t maxSize, Endianness streamEndianness) const { ReturnValue_t result; - result = SerializeAdapter::serialize(&type, buffer, size, max_size, - bigEndian); + result = SerializeAdapter::serialize(&type, buffer, size, maxSize, + streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::serialize(&columns, buffer, size, - max_size, bigEndian); + result = SerializeAdapter::serialize(&columns, buffer, size, + maxSize, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::serialize(&rows, buffer, size, max_size, - bigEndian); + result = SerializeAdapter::serialize(&rows, buffer, size, maxSize, + streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } @@ -60,7 +60,7 @@ ReturnValue_t DataPoolParameterWrapper::serialize(uint8_t** buffer, DataSet mySet; PoolRawAccess raw(poolId, index, &mySet,PoolVariableIF::VAR_READ); mySet.read(); - result = raw.serialize(buffer,size,max_size,bigEndian); + result = raw.serialize(buffer,size,maxSize,streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK){ return result; } @@ -69,8 +69,8 @@ ReturnValue_t DataPoolParameterWrapper::serialize(uint8_t** buffer, } //same as ParameterWrapper -uint32_t DataPoolParameterWrapper::getSerializedSize() const { - uint32_t serializedSize = 0; +size_t DataPoolParameterWrapper::getSerializedSize() const { + size_t serializedSize = 0; serializedSize += type.getSerializedSize(); serializedSize += sizeof(rows); serializedSize += sizeof(columns); @@ -80,7 +80,7 @@ uint32_t DataPoolParameterWrapper::getSerializedSize() const { } ReturnValue_t DataPoolParameterWrapper::deSerialize(const uint8_t** buffer, - int32_t* size, bool bigEndian) { + size_t* size, Endianness streamEndianness) { return HasReturnvaluesIF::RETURN_FAILED; } diff --git a/datapool/DataPoolParameterWrapper.h b/datapool/DataPoolParameterWrapper.h index faadf6599..b1e505a75 100644 --- a/datapool/DataPoolParameterWrapper.h +++ b/datapool/DataPoolParameterWrapper.h @@ -1,8 +1,8 @@ #ifndef DATAPOOLPARAMETERWRAPPER_H_ #define DATAPOOLPARAMETERWRAPPER_H_ -#include -#include +#include "../globalfunctions/Type.h" +#include "../parameters/ParameterWrapper.h" class DataPoolParameterWrapper: public SerializeIF { public: @@ -11,13 +11,13 @@ public: ReturnValue_t set(uint8_t domainId, uint16_t parameterId); - virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const; + virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const override; - virtual uint32_t getSerializedSize() const; + virtual size_t getSerializedSize() const override; - virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian); + virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) override; ReturnValue_t copyFrom(const ParameterWrapper *from, uint16_t startWritingAtIndex); diff --git a/datapool/DataSet.cpp b/datapool/DataSet.cpp index b43026af7..e41489bd9 100644 --- a/datapool/DataSet.cpp +++ b/datapool/DataSet.cpp @@ -1,5 +1,5 @@ -#include -#include +#include "DataSet.h" +#include "../serviceinterface/ServiceInterfaceStream.h" DataSet::DataSet() : fill_count(0), state(DATA_SET_UNINITIALISED) { @@ -106,12 +106,12 @@ uint8_t DataSet::lockDataPool() { return ::dataPool.lockDataPool(); } -ReturnValue_t DataSet::serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { +ReturnValue_t DataSet::serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const { ReturnValue_t result = RETURN_FAILED; for (uint16_t count = 0; count < fill_count; count++) { - result = registeredVariables[count]->serialize(buffer, size, max_size, - bigEndian); + result = registeredVariables[count]->serialize(buffer, size, maxSize, + streamEndianness); if (result != RETURN_OK) { return result; } @@ -119,8 +119,8 @@ ReturnValue_t DataSet::serialize(uint8_t** buffer, uint32_t* size, return result; } -uint32_t DataSet::getSerializedSize() const { - uint32_t size = 0; +size_t DataSet::getSerializedSize() const { + size_t size = 0; for (uint16_t count = 0; count < fill_count; count++) { size += registeredVariables[count]->getSerializedSize(); } @@ -136,12 +136,12 @@ void DataSet::setValid(uint8_t valid) { } } -ReturnValue_t DataSet::deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) { +ReturnValue_t DataSet::deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) { ReturnValue_t result = RETURN_FAILED; for (uint16_t count = 0; count < fill_count; count++) { result = registeredVariables[count]->deSerialize(buffer, size, - bigEndian); + streamEndianness); if (result != RETURN_OK) { return result; } diff --git a/datapool/DataSet.h b/datapool/DataSet.h index 982be6928..04044bfe5 100644 --- a/datapool/DataSet.h +++ b/datapool/DataSet.h @@ -12,13 +12,13 @@ #ifndef DATASET_H_ #define DATASET_H_ -#include -#include -#include -#include -#include -#include -#include +#include "DataPool.h" +#include "DataSetIF.h" +#include "PoolRawAccess.h" +#include "PoolVariable.h" +#include "PoolVarList.h" +#include "PoolVector.h" +#include "../serialize/SerializeAdapter.h" /** * \brief The DataSet class manages a set of locally checked out variables. * @@ -146,13 +146,13 @@ public: */ void setValid(uint8_t valid); - ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const; + ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const override; - uint32_t getSerializedSize() const; + size_t getSerializedSize() const override; - ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian); + ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) override; }; diff --git a/datapool/HkSwitchHelper.cpp b/datapool/HkSwitchHelper.cpp index caae21461..04096acaf 100644 --- a/datapool/HkSwitchHelper.cpp +++ b/datapool/HkSwitchHelper.cpp @@ -1,6 +1,6 @@ -#include +#include "HkSwitchHelper.h" //#include -#include +#include "../ipc/QueueFactory.h" HkSwitchHelper::HkSwitchHelper(EventReportingProxyIF* eventProxy) : commandActionHelper(this), eventProxy(eventProxy) { diff --git a/datapool/HkSwitchHelper.h b/datapool/HkSwitchHelper.h index 1a3b62758..385b2047f 100644 --- a/datapool/HkSwitchHelper.h +++ b/datapool/HkSwitchHelper.h @@ -1,9 +1,9 @@ #ifndef FRAMEWORK_DATAPOOL_HKSWITCHHELPER_H_ #define FRAMEWORK_DATAPOOL_HKSWITCHHELPER_H_ -#include -#include -#include +#include "../tasks/ExecutableObjectIF.h" +#include "../action/CommandsActionsIF.h" +#include "../events/EventReportingProxyIF.h" //TODO this class violations separation between mission and framework //but it is only a transitional solution until the Datapool is diff --git a/datapool/PIDReader.h b/datapool/PIDReader.h index 63a62cf64..3b38b51d1 100644 --- a/datapool/PIDReader.h +++ b/datapool/PIDReader.h @@ -1,11 +1,11 @@ #ifndef PIDREADER_H_ #define PIDREADER_H_ -#include -#include -#include -#include -#include -#include +#include "DataPool.h" +#include "DataSetIF.h" +#include "PoolEntry.h" +#include "PoolVariableIF.h" +#include "../serialize/SerializeAdapter.h" +#include "../serviceinterface/ServiceInterfaceStream.h" template class PIDReaderList; @@ -17,7 +17,7 @@ protected: uint8_t valid; ReturnValue_t read() { uint8_t arrayIndex = DataPool::PIDToArrayIndex(parameterId); - PoolEntry* read_out = ::dataPool.getData( + PoolEntry *read_out = ::dataPool.getData( DataPool::PIDToDataPoolId(parameterId), arrayIndex); if (read_out != NULL) { valid = read_out->valid; @@ -43,7 +43,8 @@ protected: * Empty ctor for List initialization */ PIDReader() : - parameterId(PoolVariableIF::NO_PARAMETER), valid(PoolVariableIF::INVALID), value(0) { + parameterId(PoolVariableIF::NO_PARAMETER), valid( + PoolVariableIF::INVALID), value(0) { } public: @@ -63,9 +64,9 @@ public: * \param setWritable If this flag is set to true, changes in the value attribute can be * written back to the data pool, otherwise not. */ - PIDReader(uint32_t setParameterId, DataSetIF* dataSet) : - parameterId(setParameterId), valid( - PoolVariableIF::INVALID), value(0) { + PIDReader(uint32_t setParameterId, DataSetIF *dataSet) : + parameterId(setParameterId), valid(PoolVariableIF::INVALID), value( + 0) { if (dataSet != NULL) { dataSet->registerVariable(this); } @@ -74,7 +75,7 @@ public: /** * Copy ctor to copy classes containing Pool Variables. */ - PIDReader(const PIDReader& rhs) : + PIDReader(const PIDReader &rhs) : parameterId(rhs.parameterId), valid(rhs.valid), value(rhs.value) { } @@ -121,24 +122,25 @@ public: return value; } - PIDReader &operator=(T newValue) { + PIDReader& operator=(T newValue) { value = newValue; return *this; } - virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { - return SerializeAdapter::serialize(&value, buffer, size, max_size, - bigEndian); + virtual ReturnValue_t serialize(uint8_t **buffer, size_t *size, + size_t maxSize, Endianness streamEndianness) const override { + return SerializeAdapter::serialize(&value, buffer, size, maxSize, + streamEndianness); } - virtual uint32_t getSerializedSize() const { - return SerializeAdapter::getSerializedSize(&value); + virtual size_t getSerializedSize() const override { + return SerializeAdapter::getSerializedSize(&value); } - virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) { - return SerializeAdapter::deSerialize(&value, buffer, size, bigEndian); + virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size, + Endianness streamEndianness) override { + return SerializeAdapter::deSerialize(&value, buffer, size, + streamEndianness); } }; diff --git a/datapool/PIDReaderList.h b/datapool/PIDReaderList.h index 07d1b8e6d..1f6aa99cd 100644 --- a/datapool/PIDReaderList.h +++ b/datapool/PIDReaderList.h @@ -1,8 +1,8 @@ #ifndef FRAMEWORK_DATAPOOL_PIDREADERLIST_H_ #define FRAMEWORK_DATAPOOL_PIDREADERLIST_H_ -#include -#include +#include "PIDReader.h" +#include "PoolVariableIF.h" template class PIDReaderList { private: diff --git a/datapool/PoolEntry.cpp b/datapool/PoolEntry.cpp index de024c812..56e489a5e 100644 --- a/datapool/PoolEntry.cpp +++ b/datapool/PoolEntry.cpp @@ -1,13 +1,34 @@ -#include -#include +#include "PoolEntry.h" +#include "../serviceinterface/ServiceInterfaceStream.h" +#include "../globalfunctions/arrayprinter.h" +#include template -PoolEntry::PoolEntry( T* initValue, uint8_t set_length, uint8_t set_valid ) : length(set_length), valid(set_valid) { +PoolEntry::PoolEntry(std::initializer_list initValue, uint8_t setLength, + bool setValid ) : length(setLength), valid(setValid) { this->address = new T[this->length]; - if (initValue != NULL) { - memcpy(this->address, initValue, this->getByteSize() ); + if(initValue.size() == 0) { + std::memset(this->address, 0, this->getByteSize()); + } + else if (initValue.size() != setLength){ + sif::warning << "PoolEntry: setLength is not equal to initializer list" + "length! Performing zero initialization with given setLength" + << std::endl; + std::memset(this->address, 0, this->getByteSize()); + } + else { + std::copy(initValue.begin(), initValue.end(), this->address); + } +} + +template +PoolEntry::PoolEntry( T* initValue, uint8_t setLength, bool setValid ) : + length(setLength), valid(setValid) { + this->address = new T[this->length]; + if (initValue != nullptr) { + std::memcpy(this->address, initValue, this->getByteSize() ); } else { - memset(this->address, 0, this->getByteSize() ); + std::memset(this->address, 0, this->getByteSize() ); } } @@ -34,21 +55,20 @@ void* PoolEntry::getRawData() { } template -void PoolEntry::setValid( uint8_t isValid ) { +void PoolEntry::setValid(bool isValid) { this->valid = isValid; } template -uint8_t PoolEntry::getValid() { +bool PoolEntry::getValid() { return valid; } template void PoolEntry::print() { - for (uint8_t size = 0; size < this->length; size++ ) { - sif::debug << "| " << std::hex << (double)this->address[size] - << (this->valid? " (valid) " : " (invalid) "); - } + sif::debug << "Pool Entry Validity: " << + (this->valid? " (valid) " : " (invalid) ") << std::endl; + arrayprinter::print(reinterpret_cast(address), length); sif::debug << std::dec << std::endl; } diff --git a/datapool/PoolEntry.h b/datapool/PoolEntry.h index ce41a9917..7b47c6739 100644 --- a/datapool/PoolEntry.h +++ b/datapool/PoolEntry.h @@ -1,81 +1,126 @@ -#ifndef POOLENTRY_H_ -#define POOLENTRY_H_ +#ifndef FRAMEWORK_DATAPOOL_POOLENTRY_H_ +#define FRAMEWORK_DATAPOOL_POOLENTRY_H_ +#include "PoolEntryIF.h" + +#include +#include +#include -#include -#include -#include /** - * \brief This is a small helper class that defines a single data pool entry. + * @brief This is a small helper class that defines a single data pool entry. + * @details + * The helper is used to store all information together with the data as a + * single data pool entry. The content's type is defined by the template + * argument. * - * \details The helper is used to store all information together with the data as a single data pool entry. - * The content's type is defined by the template argument. - * It is prepared for use with plain old data types, - * but may be extended to complex types if necessary. - * It can be initialized with a certain value, size and validity flag. - * It holds a pointer to the real data and offers methods to access this data and to acquire - * additional information (such as validity and array/byte size). - * It is NOT intended to be used outside the DataPool class. + * It is prepared for use with plain old data types, but may be + * extended to complex types if necessary. It can be initialized with a + * certain value, size and validity flag. * - * \ingroup data_pool + * It holds a pointer to the real data and offers methods to access this data + * and to acquire additional information (such as validity and array/byte size). + * It is NOT intended to be used outside DataPool implementations as it performs + * dynamic memory allocation. * + * @ingroup data_pool */ template class PoolEntry : public PoolEntryIF { public: + static_assert(not std::is_same::value, + "Do not use boolean for the PoolEntry type, use uint8_t " + "instead! The ECSS standard defines a boolean as a one bit " + "field. Therefore it is preferred to store a boolean as an " + "uint8_t"); /** - * \brief In the classe's constructor, space is allocated on the heap and + * @brief In the classe's constructor, space is allocated on the heap and * potential init values are copied to that space. - * \param initValue A pointer to the single value or array that holds the init value. - * With the default value (NULL), the entry is initalized with all 0. - * \param set_length Defines the array length of this entry. - * \param set_valid Sets the initialization flag. It is invalid (0) by default. + * @details + * Not passing any arguments will initialize an non-array pool entry + * (setLength = 1) with an initial invalid state. + * Please note that if an initializer list is passed, the correct + * corresponding length should be passed too, otherwise a zero + * initialization will be performed with the given setLength. + * @param initValue + * Initializer list with values to initialize with, for example {0,0} to + * initialize the two entries to zero. + * @param setLength + * Defines the array length of this entry. Should be equal to the + * intializer list length. + * @param setValid + * Sets the initialization flag. It is invalid by default. */ - PoolEntry( T* initValue = NULL, uint8_t set_length = 1, uint8_t set_valid = 0 ); + PoolEntry(std::initializer_list initValue = {}, uint8_t setLength = 1, + bool setValid = false); /** - * \brief The allocated memory for the variable is freed in the destructor. - * \details As the data pool is global, this dtor is only called on program exit. - * PoolEntries shall never be copied, as a copy might delete the variable on the heap. + * @brief In the classe's constructor, space is allocated on the heap and + * potential init values are copied to that space. + * @param initValue + * A pointer to the single value or array that holds the init value. + * With the default value (nullptr), the entry is initalized with all 0. + * @param setLength + * Defines the array length of this entry. + * @param setValid + * Sets the initialization flag. It is invalid by default. + */ + PoolEntry(T* initValue, uint8_t setLength = 1, bool setValid = false); + + //! Explicitely deleted copy ctor, copying is not allowed! + PoolEntry(const PoolEntry&) = delete; + //! Explicitely deleted copy assignment, copying is not allowed! + PoolEntry& operator=(const PoolEntry&) = delete; + + /** + * @brief The allocated memory for the variable is freed + * in the destructor. + * @details + * As the data pool is global, this dtor is only called on program exit. + * PoolEntries shall never be copied, as a copy might delete the variable + * on the heap. */ ~PoolEntry(); + /** - * \brief This is the address pointing to the allocated memory. + * @brief This is the address pointing to the allocated memory. */ T* address; /** - * \brief This attribute stores the length information. + * @brief This attribute stores the length information. */ uint8_t length; /** - * \brief Here, the validity information for a variable is stored. + * @brief Here, the validity information for a variable is stored. * Every entry (single variable or vector) has one valid flag. */ uint8_t valid; /** - * \brief getSize returns the array size of the entry. - * \details A single parameter has size 1. + * @brief getSize returns the array size of the entry. + * @details A single parameter has size 1. */ uint8_t getSize(); /** - * \brief This operation returns the size in bytes. - * \details The size is calculated by sizeof(type) * array_size. + * @brief This operation returns the size in bytes. + * @details The size is calculated by sizeof(type) * array_size. */ uint16_t getByteSize(); /** - * \brief This operation returns a the address pointer casted to void*. + * @brief This operation returns a the address pointer casted to void*. */ void* getRawData(); /** - * \brief This method allows to set the valid information of the pool entry. + * @brief This method allows to set the valid information + * of the pool entry. */ - void setValid( uint8_t isValid ); + void setValid( bool isValid ); /** - * \brief This method allows to get the valid information of the pool entry. + * @brief This method allows to get the valid information + * of the pool entry. */ - uint8_t getValid(); + bool getValid(); /** - * \brief This is a debug method that prints all values and the valid information to the screen. - * It prints all array entries in a row. + * @brief This is a debug method that prints all values and the valid + * information to the screen. It prints all array entries in a row. */ void print(); diff --git a/datapool/PoolEntryIF.h b/datapool/PoolEntryIF.h index 514e67ef9..462de18b8 100644 --- a/datapool/PoolEntryIF.h +++ b/datapool/PoolEntryIF.h @@ -1,62 +1,57 @@ -/** - * \file PoolEntryIF.h - * - * \brief This file holds the class that defines the Interface for Pool Entry elements. - * - * \date 10/18/2012 - * - * \author Bastian Baetz - */ - -#ifndef POOLENTRYIF_H_ -#define POOLENTRYIF_H_ - -#include -#include - +#ifndef FRAMEWORK_DATAPOOL_POOLENTRYIF_H_ +#define FRAMEWORK_DATAPOOL_POOLENTRYIF_H_ +#include "../globalfunctions/Type.h" +#include /** - * \brief This interface defines the access possibilities to a single data pool entry. + * @brief This interface defines the access possibilities to a + * single data pool entry. + * @details + * The interface provides methods to determine the size and the validity + * information of a value. It also defines a method to receive a pointer to the + * raw data content. It is mainly used by DataPool itself, but also as a + * return pointer. * - * \details The interface provides methods to determine the size and the validity information of a value. - * It also defines a method to receive a pointer to the raw data content. - * It is mainly used by DataPool itself, but also as a return pointer. - * - * \ingroup data_pool + * @author Bastian Baetz + * @ingroup data_pool * */ class PoolEntryIF { public: /** - * \brief This is an empty virtual destructor, as it is proposed for C++ interfaces. + * @brief This is an empty virtual destructor, + * as it is required for C++ interfaces. */ virtual ~PoolEntryIF() { } /** - * \brief getSize returns the array size of the entry. A single variable parameter has size 1. + * @brief getSize returns the array size of the entry. + * A single variable parameter has size 1. */ virtual uint8_t getSize() = 0; /** - * \brief This operation returns the size in bytes, which is calculated by + * @brief This operation returns the size in bytes, which is calculated by * sizeof(type) * array_size. */ virtual uint16_t getByteSize() = 0; /** - * \brief This operation returns a the address pointer casted to void*. + * @brief This operation returns a the address pointer casted to void*. */ virtual void* getRawData() = 0; /** - * \brief This method allows to set the valid information of the pool entry. + * @brief This method allows to set the valid information of the pool entry. */ - virtual void setValid(uint8_t isValid) = 0; + virtual void setValid(bool isValid) = 0; /** - * \brief This method allows to set the valid information of the pool entry. + * @brief This method allows to set the valid information of the pool entry. */ - virtual uint8_t getValid() = 0; + virtual bool getValid() = 0; /** - * \brief This is a debug method that prints all values and the valid information to the screen. - * It prints all array entries in a row. + * @brief This is a debug method that prints all values and the valid + * information to the screen. It prints all array entries in a row. + * @details + * Also displays whether the pool entry is valid or invalid. */ virtual void print() = 0; /** diff --git a/datapool/PoolRawAccess.cpp b/datapool/PoolRawAccess.cpp index ba68bcd25..f92640813 100644 --- a/datapool/PoolRawAccess.cpp +++ b/datapool/PoolRawAccess.cpp @@ -1,13 +1,16 @@ -#include -#include -#include -#include -#include +#include "DataPool.h" +#include "PoolEntryIF.h" +#include "PoolRawAccess.h" +#include "../serviceinterface/ServiceInterfaceStream.h" +#include "../serialize/EndianConverter.h" + +#include PoolRawAccess::PoolRawAccess(uint32_t set_id, uint8_t setArrayEntry, - DataSetIF* data_set, ReadWriteMode_t setReadWriteMode) : - dataPoolId(set_id), arrayEntry(setArrayEntry), valid(false), type(Type::UNKNOWN_TYPE), typeSize( - 0), arraySize(0), sizeTillEnd(0), readWriteMode(setReadWriteMode) { + DataSetIF *data_set, ReadWriteMode_t setReadWriteMode) : + dataPoolId(set_id), arrayEntry(setArrayEntry), valid(false), type( + Type::UNKNOWN_TYPE), typeSize(0), arraySize(0), sizeTillEnd(0), readWriteMode( + setReadWriteMode) { memset(value, 0, sizeof(value)); if (data_set != NULL) { data_set->registerVariable(this); @@ -19,7 +22,7 @@ PoolRawAccess::~PoolRawAccess() { } ReturnValue_t PoolRawAccess::read() { - PoolEntryIF* read_out = ::dataPool.getRawData(dataPoolId); + PoolEntryIF *read_out = ::dataPool.getRawData(dataPoolId); if (read_out != NULL) { valid = read_out->getValid(); if (read_out->getSize() > arrayEntry) { @@ -29,7 +32,7 @@ ReturnValue_t PoolRawAccess::read() { if (typeSize <= sizeof(value)) { uint16_t arrayPosition = arrayEntry * typeSize; sizeTillEnd = read_out->getByteSize() - arrayPosition; - uint8_t* ptr = + uint8_t *ptr = &((uint8_t*) read_out->getRawData())[arrayPosition]; memcpy(value, ptr, typeSize); return HasReturnvaluesIF::RETURN_OK; @@ -42,8 +45,8 @@ ReturnValue_t PoolRawAccess::read() { } else { //Error entry does not exist. } - sif::error << "PoolRawAccess: read of DP Variable 0x" << std::hex << dataPoolId - << std::dec << " failed." << std::endl; + sif::error << "PoolRawAccess: read of DP Variable 0x" << std::hex + << dataPoolId << std::dec << " failed." << std::endl; valid = INVALID; typeSize = 0; sizeTillEnd = 0; @@ -52,11 +55,11 @@ ReturnValue_t PoolRawAccess::read() { } ReturnValue_t PoolRawAccess::commit() { - PoolEntryIF* write_back = ::dataPool.getRawData(dataPoolId); + PoolEntryIF *write_back = ::dataPool.getRawData(dataPoolId); if ((write_back != NULL) && (readWriteMode != VAR_READ)) { write_back->setValid(valid); uint8_t array_position = arrayEntry * typeSize; - uint8_t* ptr = &((uint8_t*) write_back->getRawData())[array_position]; + uint8_t *ptr = &((uint8_t*) write_back->getRawData())[array_position]; memcpy(ptr, value, typeSize); return HasReturnvaluesIF::RETURN_OK; } else { @@ -68,23 +71,17 @@ uint8_t* PoolRawAccess::getEntry() { return value; } -ReturnValue_t PoolRawAccess::getEntryEndianSafe(uint8_t* buffer, - uint32_t* writtenBytes, uint32_t max_size) { - uint8_t* data_ptr = getEntry(); +ReturnValue_t PoolRawAccess::getEntryEndianSafe(uint8_t *buffer, + size_t *writtenBytes, size_t maxSize) { + uint8_t *data_ptr = getEntry(); // debug << "PoolRawAccess::getEntry: Array position: " << index * size_of_type << " Size of T: " << (int)size_of_type << " ByteSize: " << byte_size << " Position: " << *size << std::endl; - if (typeSize == 0) + if (typeSize == 0) { return DATA_POOL_ACCESS_FAILED; - if (typeSize > max_size) - return INCORRECT_SIZE; -#ifndef BYTE_ORDER_SYSTEM -#error BYTE_ORDER_SYSTEM not defined -#elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN - for (uint8_t count = 0; count < typeSize; count++) { - buffer[count] = data_ptr[typeSize - count - 1]; } -#elif BYTE_ORDER_SYSTEM == BIG_ENDIAN - memcpy(buffer, data_ptr, typeSize); -#endif + if (typeSize > maxSize) { + return INCORRECT_SIZE; + } + EndianConverter::convertBigEndian(buffer, data_ptr, typeSize); *writtenBytes = typeSize; return HasReturnvaluesIF::RETURN_OK; } @@ -93,11 +90,11 @@ Type PoolRawAccess::getType() { return type; } -uint8_t PoolRawAccess::getSizeOfType() { +size_t PoolRawAccess::getSizeOfType() { return typeSize; } -uint8_t PoolRawAccess::getArraySize(){ +size_t PoolRawAccess::getArraySize() { return arraySize; } @@ -109,21 +106,14 @@ PoolVariableIF::ReadWriteMode_t PoolRawAccess::getReadWriteMode() const { return readWriteMode; } -ReturnValue_t PoolRawAccess::setEntryFromBigEndian(const uint8_t* buffer, - uint32_t setSize) { +ReturnValue_t PoolRawAccess::setEntryFromBigEndian(const uint8_t *buffer, + size_t setSize) { if (typeSize == setSize) { -#ifndef BYTE_ORDER_SYSTEM -#error BYTE_ORDER_SYSTEM not defined -#elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN - for (uint8_t count = 0; count < typeSize; count++) { - value[count] = buffer[typeSize - count - 1]; - } -#elif BYTE_ORDER_SYSTEM == BIG_ENDIAN - memcpy(value, buffer, typeSize); -#endif + EndianConverter::convertBigEndian(value, buffer, typeSize); return HasReturnvaluesIF::RETURN_OK; } else { - sif::error << "PoolRawAccess::setEntryFromBigEndian: Illegal sizes: Internal" + sif::error + << "PoolRawAccess::setEntryFromBigEndian: Illegal sizes: Internal" << (uint32_t) typeSize << ", Requested: " << setSize << std::endl; return INCORRECT_SIZE; @@ -141,25 +131,24 @@ void PoolRawAccess::setValid(uint8_t valid) { this->valid = valid; } -uint16_t PoolRawAccess::getSizeTillEnd() const { +size_t PoolRawAccess::getSizeTillEnd() const { return sizeTillEnd; } -ReturnValue_t PoolRawAccess::serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { - if (typeSize + *size <= max_size) { - if (bigEndian) { -#ifndef BYTE_ORDER_SYSTEM -#error BYTE_ORDER_SYSTEM not defined -#elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN - for (uint8_t count = 0; count < typeSize; count++) { - (*buffer)[count] = value[typeSize - count - 1]; - } -#elif BYTE_ORDER_SYSTEM == BIG_ENDIAN - memcpy(*buffer, value, typeSize); -#endif - } else { +ReturnValue_t PoolRawAccess::serialize(uint8_t **buffer, size_t *size, + size_t maxSize, Endianness streamEndianness) const { + if (typeSize + *size <= maxSize) { + switch (streamEndianness) { + case (Endianness::BIG): + EndianConverter::convertBigEndian(*buffer, value, typeSize); + break; + case (Endianness::LITTLE): + EndianConverter::convertLittleEndian(*buffer, value, typeSize); + break; + default: + case (Endianness::MACHINE): memcpy(*buffer, value, typeSize); + break; } *size += typeSize; (*buffer) += typeSize; @@ -169,28 +158,27 @@ ReturnValue_t PoolRawAccess::serialize(uint8_t** buffer, uint32_t* size, } } -uint32_t PoolRawAccess::getSerializedSize() const { +size_t PoolRawAccess::getSerializedSize() const { return typeSize; } -ReturnValue_t PoolRawAccess::deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) { - *size -= typeSize; - if (*size >= 0) { +ReturnValue_t PoolRawAccess::deSerialize(const uint8_t **buffer, size_t *size, + Endianness streamEndianness) { - if (bigEndian) { -#ifndef BYTE_ORDER_SYSTEM -#error BYTE_ORDER_SYSTEM not defined -#elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN - for (uint8_t count = 0; count < typeSize; count++) { - value[count] = (*buffer)[typeSize - count - 1]; - } -#elif BYTE_ORDER_SYSTEM == BIG_ENDIAN - memcpy(value, *buffer, typeSize); -#endif - } else { + if (*size >= typeSize) { + switch (streamEndianness) { + case (Endianness::BIG): + EndianConverter::convertBigEndian(value, *buffer, typeSize); + break; + case (Endianness::LITTLE): + EndianConverter::convertLittleEndian(value, *buffer, typeSize); + break; + default: + case (Endianness::MACHINE): memcpy(value, *buffer, typeSize); + break; } + *size -= typeSize; *buffer += typeSize; return HasReturnvaluesIF::RETURN_OK; } else { diff --git a/datapool/PoolRawAccess.h b/datapool/PoolRawAccess.h index 3e2bd7ae3..0c7a06bf6 100644 --- a/datapool/PoolRawAccess.h +++ b/datapool/PoolRawAccess.h @@ -1,8 +1,8 @@ #ifndef POOLRAWACCESS_H_ #define POOLRAWACCESS_H_ -#include -#include +#include "DataSetIF.h" +#include "PoolVariableIF.h" /** * This class allows accessing Data Pool variables as raw bytes. @@ -32,15 +32,15 @@ private: /** * \brief This value contains the size of the data pool entry in bytes. */ - uint8_t typeSize; + size_t typeSize; /** * The size of the DP array (single values return 1) */ - uint8_t arraySize; + size_t arraySize; /** * The size (in bytes) from the selected entry till the end of this DataPool variable. */ - uint16_t sizeTillEnd; + size_t sizeTillEnd; /** * \brief The information whether the class is read-write or read-only is stored here. */ @@ -70,7 +70,7 @@ public: static const ReturnValue_t DATA_POOL_ACCESS_FAILED = MAKE_RETURN_CODE(0x02); uint8_t value[RAW_MAX_SIZE]; PoolRawAccess(uint32_t data_pool_id, uint8_t arrayEntry, - DataSetIF* data_set, ReadWriteMode_t setReadWriteMode = + DataSetIF *data_set, ReadWriteMode_t setReadWriteMode = PoolVariableIF::VAR_READ); /** * \brief The classes destructor is empty. If commit() was not called, the local value is @@ -90,15 +90,15 @@ public: * \details It makes use of the getEntry call of this function, but additionally flips the * bytes to big endian, which is the default for external communication (as House- * keeping telemetry). To achieve this, the data is copied directly to the passed - * buffer, if it fits in the given max_size. + * buffer, if it fits in the given maxSize. * \param buffer A pointer to a buffer to write to * \param writtenBytes The number of bytes written is returned with this value. - * \param max_size The maximum size that the function may write to buffer. + * \param maxSize The maximum size that the function may write to buffer. * \return - \c RETURN_OK if entry could be acquired * - \c RETURN_FAILED else. */ - ReturnValue_t getEntryEndianSafe(uint8_t* buffer, uint32_t* size, - uint32_t max_size); + ReturnValue_t getEntryEndianSafe(uint8_t *buffer, size_t *size, + size_t maxSize); /** * With this method, the content can be set from a big endian buffer safely. * @param buffer Pointer to the data to set @@ -106,8 +106,8 @@ public: * @return - \c RETURN_OK on success * - \c RETURN_FAILED on failure */ - ReturnValue_t setEntryFromBigEndian(const uint8_t* buffer, - uint32_t setSize); + ReturnValue_t setEntryFromBigEndian(const uint8_t *buffer, + size_t setSize); /** * \brief This operation returns the type of the entry currently stored. */ @@ -115,12 +115,12 @@ public: /** * \brief This operation returns the size of the entry currently stored. */ - uint8_t getSizeOfType(); + size_t getSizeOfType(); /** * * @return the size of the datapool array */ - uint8_t getArraySize(); + size_t getArraySize(); /** * \brief This operation returns the data pool id of the variable. */ @@ -138,15 +138,15 @@ public: /** * Getter for the remaining size. */ - uint16_t getSizeTillEnd() const; + size_t getSizeTillEnd() const; - ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const; + ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize, + Endianness streamEndianness) const override; - uint32_t getSerializedSize() const; + size_t getSerializedSize() const override; - ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian); + ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size, + Endianness streamEndianness) override; }; #endif /* POOLRAWACCESS_H_ */ diff --git a/datapool/PoolVarList.h b/datapool/PoolVarList.h index 90c9f1785..035ff2ac8 100644 --- a/datapool/PoolVarList.h +++ b/datapool/PoolVarList.h @@ -1,8 +1,8 @@ #ifndef POOLVARLIST_H_ #define POOLVARLIST_H_ -#include -#include +#include "PoolVariable.h" +#include "PoolVariableIF.h" template class PoolVarList { private: diff --git a/datapool/PoolVariable.h b/datapool/PoolVariable.h index d395d4092..a9d3407d0 100644 --- a/datapool/PoolVariable.h +++ b/datapool/PoolVariable.h @@ -11,11 +11,11 @@ #ifndef POOLVARIABLE_H_ #define POOLVARIABLE_H_ -#include -#include -#include -#include -#include +#include "DataSetIF.h" +#include "PoolEntry.h" +#include "PoolVariableIF.h" +#include "../serialize/SerializeAdapter.h" +#include "../serviceinterface/ServiceInterfaceStream.h" template class PoolVarList; @@ -58,7 +58,7 @@ protected: * The operation does NOT provide any mutual exclusive protection by itself. */ ReturnValue_t read() { - PoolEntry* read_out = ::dataPool.getData(dataPoolId, 1); + PoolEntry *read_out = ::dataPool.getData < T > (dataPoolId, 1); if (read_out != NULL) { valid = read_out->valid; value = *(read_out->address); @@ -79,7 +79,7 @@ protected: * */ ReturnValue_t commit() { - PoolEntry* write_back = ::dataPool.getData(dataPoolId, 1); + PoolEntry *write_back = ::dataPool.getData < T > (dataPoolId, 1); if ((write_back != NULL) && (readWriteMode != VAR_READ)) { write_back->valid = valid; *(write_back->address) = value; @@ -115,7 +115,7 @@ public: * \param setWritable If this flag is set to true, changes in the value attribute can be * written back to the data pool, otherwise not. */ - PoolVariable(uint32_t set_id, DataSetIF* dataSet, + PoolVariable(uint32_t set_id, DataSetIF *dataSet, ReadWriteMode_t setReadWriteMode) : dataPoolId(set_id), valid(PoolVariableIF::INVALID), readWriteMode( setReadWriteMode), value(0) { @@ -126,7 +126,7 @@ public: /** * Copy ctor to copy classes containing Pool Variables. */ - PoolVariable(const PoolVariable& rhs) : + PoolVariable(const PoolVariable &rhs) : dataPoolId(rhs.dataPoolId), valid(rhs.valid), readWriteMode( rhs.readWriteMode), value(rhs.value) { } @@ -184,29 +184,29 @@ public: return value; } - PoolVariable &operator=(T newValue) { + PoolVariable& operator=(T newValue) { value = newValue; return *this; } - PoolVariable &operator=(PoolVariable newPoolVariable) { + PoolVariable& operator=(PoolVariable newPoolVariable) { value = newPoolVariable.value; return *this; } - virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { - return SerializeAdapter::serialize(&value, buffer, size, max_size, - bigEndian); + virtual ReturnValue_t serialize(uint8_t **buffer, size_t *size, + size_t maxSize, Endianness streamEndianness) const override { + return SerializeAdapter::serialize(&value, buffer, size, maxSize, + streamEndianness); } - virtual uint32_t getSerializedSize() const { - return SerializeAdapter::getSerializedSize(&value); + virtual size_t getSerializedSize() const override { + return SerializeAdapter::getSerializedSize(&value); } - virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) { - return SerializeAdapter::deSerialize(&value, buffer, size, bigEndian); + virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size, + Endianness streamEndianness) override { + return SerializeAdapter::deSerialize(&value, buffer, size, streamEndianness); } }; diff --git a/datapool/PoolVariableIF.h b/datapool/PoolVariableIF.h index 7626c9c17..f47173df3 100644 --- a/datapool/PoolVariableIF.h +++ b/datapool/PoolVariableIF.h @@ -11,8 +11,8 @@ #ifndef POOLVARIABLEIF_H_ #define POOLVARIABLEIF_H_ -#include -#include +#include "../returnvalues/HasReturnvaluesIF.h" +#include "../serialize/SerializeIF.h" /** * \brief This interface is used to control local data pool variable representations. diff --git a/datapool/PoolVector.h b/datapool/PoolVector.h index 929f2d315..d4ca08426 100644 --- a/datapool/PoolVector.h +++ b/datapool/PoolVector.h @@ -11,11 +11,11 @@ #ifndef POOLVECTOR_H_ #define POOLVECTOR_H_ -#include -#include -#include -#include -#include +#include "DataSetIF.h" +#include "PoolEntry.h" +#include "PoolVariableIF.h" +#include "../serialize/SerializeAdapter.h" +#include "../serviceinterface/ServiceInterfaceStream.h" /** * \brief This is the access class for array-type data pool entries. @@ -197,13 +197,13 @@ public: return *this; } - virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { + virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const { uint16_t i; ReturnValue_t result; for (i = 0; i < vector_size; i++) { - result = SerializeAdapter::serialize(&(value[i]), buffer, size, - max_size, bigEndian); + result = SerializeAdapter::serialize(&(value[i]), buffer, size, + maxSize, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } @@ -211,17 +211,17 @@ public: return result; } - virtual uint32_t getSerializedSize() const { - return vector_size * SerializeAdapter::getSerializedSize(value); + virtual size_t getSerializedSize() const { + return vector_size * SerializeAdapter::getSerializedSize(value); } - virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) { + virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) { uint16_t i; ReturnValue_t result; for (i = 0; i < vector_size; i++) { - result = SerializeAdapter::deSerialize(&(value[i]), buffer, size, - bigEndian); + result = SerializeAdapter::deSerialize(&(value[i]), buffer, size, + streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } diff --git a/devicehandlers/AcceptsDeviceResponsesIF.h b/devicehandlers/AcceptsDeviceResponsesIF.h index 0eedae889..8dc69de4f 100644 --- a/devicehandlers/AcceptsDeviceResponsesIF.h +++ b/devicehandlers/AcceptsDeviceResponsesIF.h @@ -8,7 +8,7 @@ #ifndef ACCEPTSDEVICERESPONSESIF_H_ #define ACCEPTSDEVICERESPONSESIF_H_ -#include +#include "../ipc/MessageQueueSenderIF.h" class AcceptsDeviceResponsesIF { public: diff --git a/devicehandlers/AssemblyBase.cpp b/devicehandlers/AssemblyBase.cpp index c250cf735..8b3f7f4dc 100644 --- a/devicehandlers/AssemblyBase.cpp +++ b/devicehandlers/AssemblyBase.cpp @@ -1,4 +1,4 @@ -#include +#include "AssemblyBase.h" AssemblyBase::AssemblyBase(object_id_t objectId, object_id_t parentId, uint16_t commandQueueDepth) : diff --git a/devicehandlers/AssemblyBase.h b/devicehandlers/AssemblyBase.h index ee1210324..bd2e8fada 100644 --- a/devicehandlers/AssemblyBase.h +++ b/devicehandlers/AssemblyBase.h @@ -1,9 +1,9 @@ #ifndef ASSEMBLYBASE_H_ #define ASSEMBLYBASE_H_ -#include -#include -#include +#include "../container/FixedArrayList.h" +#include "DeviceHandlerBase.h" +#include "../subsystem/SubsystemBase.h" class AssemblyBase: public SubsystemBase { public: diff --git a/devicehandlers/ChildHandlerBase.cpp b/devicehandlers/ChildHandlerBase.cpp index 50a5c07e5..cee2a349c 100644 --- a/devicehandlers/ChildHandlerBase.cpp +++ b/devicehandlers/ChildHandlerBase.cpp @@ -1,16 +1,17 @@ -#include -#include -#include +#include "../subsystem/SubsystemBase.h" +#include "ChildHandlerBase.h" +#include "../subsystem/SubsystemBase.h" -ChildHandlerBase::ChildHandlerBase(uint32_t ioBoardAddress, - object_id_t setObjectId, object_id_t deviceCommunication, - uint32_t maxDeviceReplyLen, uint8_t setDeviceSwitch, - uint32_t thermalStatePoolId, uint32_t thermalRequestPoolId, - uint32_t parent, FailureIsolationBase* customFdir, uint32_t cmdQueueSize) : - DeviceHandlerBase(ioBoardAddress, setObjectId, maxDeviceReplyLen, - setDeviceSwitch, deviceCommunication, thermalStatePoolId, - thermalRequestPoolId, (customFdir == NULL? &childHandlerFdir : customFdir), cmdQueueSize), parentId( - parent), childHandlerFdir(setObjectId) { +ChildHandlerBase::ChildHandlerBase(object_id_t setObjectId, + object_id_t deviceCommunication, CookieIF * comCookie, + uint8_t setDeviceSwitch, uint32_t thermalStatePoolId, + uint32_t thermalRequestPoolId, uint32_t parent, + FailureIsolationBase* customFdir, size_t cmdQueueSize) : + DeviceHandlerBase(setObjectId, deviceCommunication, comCookie, + setDeviceSwitch, thermalStatePoolId,thermalRequestPoolId, + (customFdir == nullptr? &childHandlerFdir : customFdir), + cmdQueueSize), + parentId(parent), childHandlerFdir(setObjectId) { } ChildHandlerBase::~ChildHandlerBase() { @@ -34,7 +35,7 @@ ReturnValue_t ChildHandlerBase::initialize() { parent->registerChild(getObjectId()); } - healthHelper.setParentQeueue(parentQueue); + healthHelper.setParentQueue(parentQueue); modeHelper.setParentQueue(parentQueue); diff --git a/devicehandlers/ChildHandlerBase.h b/devicehandlers/ChildHandlerBase.h index 3879f66fe..005e80659 100644 --- a/devicehandlers/ChildHandlerBase.h +++ b/devicehandlers/ChildHandlerBase.h @@ -1,17 +1,17 @@ #ifndef PAYLOADHANDLERBASE_H_ #define PAYLOADHANDLERBASE_H_ -#include -#include +#include "ChildHandlerFDIR.h" +#include "DeviceHandlerBase.h" class ChildHandlerBase: public DeviceHandlerBase { public: - ChildHandlerBase(uint32_t ioBoardAddress, object_id_t setObjectId, - object_id_t deviceCommunication, uint32_t maxDeviceReplyLen, + ChildHandlerBase(object_id_t setObjectId, + object_id_t deviceCommunication, CookieIF * comCookie, uint8_t setDeviceSwitch, uint32_t thermalStatePoolId, uint32_t thermalRequestPoolId, uint32_t parent, - FailureIsolationBase* customFdir = NULL, - uint32_t cmdQueueSize = 20); + FailureIsolationBase* customFdir = nullptr, + size_t cmdQueueSize = 20); virtual ~ChildHandlerBase(); virtual ReturnValue_t initialize(); diff --git a/devicehandlers/ChildHandlerFDIR.cpp b/devicehandlers/ChildHandlerFDIR.cpp index 1bba47fec..14043a779 100644 --- a/devicehandlers/ChildHandlerFDIR.cpp +++ b/devicehandlers/ChildHandlerFDIR.cpp @@ -1,4 +1,4 @@ -#include +#include "ChildHandlerFDIR.h" ChildHandlerFDIR::ChildHandlerFDIR(object_id_t owner, object_id_t faultTreeParent, uint32_t recoveryCount) : DeviceHandlerFailureIsolation(owner, faultTreeParent) { diff --git a/devicehandlers/ChildHandlerFDIR.h b/devicehandlers/ChildHandlerFDIR.h index 7df9d238f..ce8445183 100644 --- a/devicehandlers/ChildHandlerFDIR.h +++ b/devicehandlers/ChildHandlerFDIR.h @@ -1,7 +1,7 @@ #ifndef FRAMEWORK_DEVICEHANDLERS_CHILDHANDLERFDIR_H_ #define FRAMEWORK_DEVICEHANDLERS_CHILDHANDLERFDIR_H_ -#include +#include "DeviceHandlerFailureIsolation.h" /** * Very simple extension to normal FDIR. diff --git a/devicehandlers/Cookie.h b/devicehandlers/Cookie.h deleted file mode 100644 index 495c8c403..000000000 --- a/devicehandlers/Cookie.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef COOKIE_H_ -#define COOKIE_H_ - -class Cookie{ -public: - virtual ~Cookie(){} -}; - - -#endif /* COOKIE_H_ */ diff --git a/devicehandlers/CookieIF.h b/devicehandlers/CookieIF.h new file mode 100644 index 000000000..496cf0d2f --- /dev/null +++ b/devicehandlers/CookieIF.h @@ -0,0 +1,34 @@ +#ifndef COOKIE_H_ +#define COOKIE_H_ +#include + +/** + * @brief Physical address type + */ +typedef std::uint32_t address_t; + +/** + * @brief This datatype is used to identify different connection over a + * single interface (like RMAP or I2C) + * @details + * To use this class, implement a communication specific child cookie which + * inherits Cookie. Cookie instances are created in config/Factory.cpp by + * calling @code{.cpp} CookieIF* childCookie = new ChildCookie(...) + * @endcode . + * + * [not implemented yet] + * This cookie is then passed to the child device handlers, which stores the + * pointer and passes it to the communication interface functions. + * + * The cookie can be used to store all kinds of information + * about the communication, like slave addresses, communication status, + * communication parameters etc. + * + * @ingroup comm + */ +class CookieIF { +public: + virtual ~CookieIF() {}; +}; + +#endif /* COOKIE_H_ */ diff --git a/devicehandlers/DeviceCommunicationIF.h b/devicehandlers/DeviceCommunicationIF.h index e0aca5731..11960d8e3 100644 --- a/devicehandlers/DeviceCommunicationIF.h +++ b/devicehandlers/DeviceCommunicationIF.h @@ -1,63 +1,131 @@ #ifndef DEVICECOMMUNICATIONIF_H_ #define DEVICECOMMUNICATIONIF_H_ -#include -#include +#include "CookieIF.h" +#include "../returnvalues/HasReturnvaluesIF.h" +#include +/** + * @defgroup interfaces Interfaces + * @brief Interfaces for flight software objects + */ +/** + * @defgroup comm Communication + * @brief Communication software components. + */ + +/** + * @brief This is an interface to decouple device communication from + * the device handler to allow reuse of these components. + * @details + * Documentation: Dissertation Baetz p.138. + * It works with the assumption that received data + * is polled by a component. There are four generic steps of device communication: + * + * 1. Send data to a device + * 2. Get acknowledgement for sending + * 3. Request reading data from a device + * 4. Read received data + * + * To identify different connection over a single interface can return + * so-called cookies to components. + * The CommunicationMessage message type can be used to extend the + * functionality of the ComIF if a separate polling task is required. + * @ingroup interfaces + * @ingroup comm + */ class DeviceCommunicationIF: public HasReturnvaluesIF { public: static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_COMMUNICATION_IF; - static const ReturnValue_t INVALID_COOKIE_TYPE = MAKE_RETURN_CODE(0x01); - static const ReturnValue_t NOT_ACTIVE = MAKE_RETURN_CODE(0x02); - static const ReturnValue_t INVALID_ADDRESS = MAKE_RETURN_CODE(0x03); - static const ReturnValue_t TOO_MUCH_DATA = MAKE_RETURN_CODE(0x04); - static const ReturnValue_t NULLPOINTER = MAKE_RETURN_CODE(0x05); - static const ReturnValue_t PROTOCOL_ERROR = MAKE_RETURN_CODE(0x06); - static const ReturnValue_t CANT_CHANGE_REPLY_LEN = MAKE_RETURN_CODE(0x07); + //! Standard Error Codes + //! General protocol error. Define more concrete errors in child handler + static const ReturnValue_t PROTOCOL_ERROR = MAKE_RETURN_CODE(0x01); + //! If cookie is a null pointer + static const ReturnValue_t NULLPOINTER = MAKE_RETURN_CODE(0x02); + static const ReturnValue_t INVALID_COOKIE_TYPE = MAKE_RETURN_CODE(0x03); + // is this needed if there is no open/close call? + static const ReturnValue_t NOT_ACTIVE = MAKE_RETURN_CODE(0x05); + static const ReturnValue_t INVALID_ADDRESS = MAKE_RETURN_CODE(0x06); + static const ReturnValue_t TOO_MUCH_DATA = MAKE_RETURN_CODE(0x07); + static const ReturnValue_t CANT_CHANGE_REPLY_LEN = MAKE_RETURN_CODE(0x08); - virtual ~DeviceCommunicationIF() { + //! Can be used in readReceivedMessage() if no reply was received. + static const ReturnValue_t NO_REPLY_RECEIVED = MAKE_RETURN_CODE(0xA1); - } + virtual ~DeviceCommunicationIF() {} - virtual ReturnValue_t open(Cookie **cookie, uint32_t address, - uint32_t maxReplyLen) = 0; /** - * Use an existing cookie to open a connection to a new DeviceCommunication. - * The previous connection must not be closed. - * If the returnvalue is not RETURN_OK, the cookie is unchanged and - * can be used with the previous connection. + * @brief Device specific initialization, using the cookie. + * @details + * The cookie is already prepared in the factory. If the communication + * interface needs to be set up in some way and requires cookie information, + * this can be performed in this function, which is called on device handler + * initialization. + * @param cookie + * @return + * - @c RETURN_OK if initialization was successfull + * - Everything else triggers failure event with returnvalue as parameter 1 + */ + virtual ReturnValue_t initializeInterface(CookieIF * cookie) = 0; + + /** + * Called by DHB in the SEND_WRITE doSendWrite(). + * This function is used to send data to the physical device + * by implementing and calling related drivers or wrapper functions. + * @param cookie + * @param data + * @param len + * @return + * - @c RETURN_OK for successfull send + * - Everything else triggers failure event with returnvalue as parameter 1 + */ + virtual ReturnValue_t sendMessage(CookieIF *cookie, const uint8_t * sendData, + size_t sendLen) = 0; + + /** + * Called by DHB in the GET_WRITE doGetWrite(). + * Get send confirmation that the data in sendMessage() was sent successfully. + * @param cookie + * @return - @c RETURN_OK if data was sent successfull + * - Everything else triggers falure event with + * returnvalue as parameter 1 + */ + virtual ReturnValue_t getSendSuccess(CookieIF *cookie) = 0; + + /** + * Called by DHB in the SEND_WRITE doSendRead(). + * It is assumed that it is always possible to request a reply + * from a device. If a requestLen of 0 is supplied, no reply was enabled + * and communication specific action should be taken (e.g. read nothing + * or read everything). * * @param cookie - * @param address - * @param maxReplyLen - * @return + * @param requestLen Size of data to read + * @return - @c RETURN_OK to confirm the request for data has been sent. + * - Everything else triggers failure event with + * returnvalue as parameter 1 */ - virtual ReturnValue_t reOpen(Cookie *cookie, uint32_t address, - uint32_t maxReplyLen) = 0; - - virtual void close(Cookie *cookie) = 0; - - //SHOULDDO can data be const? - virtual ReturnValue_t sendMessage(Cookie *cookie, uint8_t *data, - uint32_t len) = 0; - - virtual ReturnValue_t getSendSuccess(Cookie *cookie) = 0; - - virtual ReturnValue_t requestReceiveMessage(Cookie *cookie) = 0; - - virtual ReturnValue_t readReceivedMessage(Cookie *cookie, uint8_t **buffer, - uint32_t *size) = 0; - - virtual ReturnValue_t setAddress(Cookie *cookie, uint32_t address) = 0; - - virtual uint32_t getAddress(Cookie *cookie) = 0; - - virtual ReturnValue_t setParameter(Cookie *cookie, uint32_t parameter) = 0; - - virtual uint32_t getParameter(Cookie *cookie) = 0; + virtual ReturnValue_t requestReceiveMessage(CookieIF *cookie, + size_t requestLen) = 0; + /** + * Called by DHB in the GET_WRITE doGetRead(). + * This function is used to receive data from the physical device + * by implementing and calling related drivers or wrapper functions. + * @param cookie + * @param buffer [out] Set reply here (by using *buffer = ...) + * @param size [out] size pointer to set (by using *size = ...). + * Set to 0 if no reply was received + * @return - @c RETURN_OK for successfull receive + * - @c NO_REPLY_RECEIVED if not reply was received. Setting size to + * 0 has the same effect + * - Everything else triggers failure event with + * returnvalue as parameter 1 + */ + virtual ReturnValue_t readReceivedMessage(CookieIF *cookie, uint8_t **buffer, + size_t *size) = 0; }; #endif /* DEVICECOMMUNICATIONIF_H_ */ diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index 90875838e..a87b6de18 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -1,52 +1,60 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "DeviceHandlerBase.h" +#include "../objectmanager/ObjectManager.h" +#include "../storagemanager/StorageManagerIF.h" +#include "../thermal/ThermalComponentIF.h" +#include "AcceptsDeviceResponsesIF.h" + +#include "../datapool/DataSet.h" +#include "../datapool/PoolVariable.h" +#include "DeviceTmReportingWrapper.h" +#include "../globalfunctions/CRC.h" +#include "../subsystem/SubsystemBase.h" +#include "../ipc/QueueFactory.h" +#include "../serviceinterface/ServiceInterfaceStream.h" + +#include object_id_t DeviceHandlerBase::powerSwitcherId = 0; object_id_t DeviceHandlerBase::rawDataReceiverId = 0; object_id_t DeviceHandlerBase::defaultFDIRParentId = 0; -DeviceHandlerBase::DeviceHandlerBase(uint32_t ioBoardAddress, - object_id_t setObjectId, uint32_t maxDeviceReplyLen, - uint8_t setDeviceSwitch, object_id_t deviceCommunication, - uint32_t thermalStatePoolId, uint32_t thermalRequestPoolId, - FailureIsolationBase* fdirInstance, uint32_t cmdQueueSize) : - SystemObject(setObjectId), rawPacket(0), rawPacketLen(0), mode( - MODE_OFF), submode(SUBMODE_NONE), pstStep(0), maxDeviceReplyLen( - maxDeviceReplyLen), wiretappingMode(OFF), defaultRawReceiver(0), storedRawData( - StorageManagerIF::INVALID_ADDRESS), requestedRawTraffic(0), powerSwitcher( - NULL), IPCStore(NULL), deviceCommunicationId(deviceCommunication), communicationInterface( - NULL), cookie( - NULL), commandQueue(NULL), deviceThermalStatePoolId(thermalStatePoolId), deviceThermalRequestPoolId( - thermalRequestPoolId), healthHelper(this, setObjectId), modeHelper( - this), parameterHelper(this), childTransitionFailure(RETURN_OK), ignoreMissedRepliesCount( - 0), fdirInstance(fdirInstance), hkSwitcher(this), defaultFDIRUsed( - fdirInstance == NULL), switchOffWasReported(false),executingTask(NULL), actionHelper(this, NULL), cookieInfo(), ioBoardAddress( - ioBoardAddress), timeoutStart(0), childTransitionDelay(5000), transitionSourceMode( - _MODE_POWER_DOWN), transitionSourceSubMode(SUBMODE_NONE), deviceSwitch( - setDeviceSwitch) { +DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, + object_id_t deviceCommunication, CookieIF * comCookie, + uint8_t setDeviceSwitch, uint32_t thermalStatePoolId, + uint32_t thermalRequestPoolId, FailureIsolationBase* fdirInstance, + size_t cmdQueueSize) : + SystemObject(setObjectId), mode(MODE_OFF), submode(SUBMODE_NONE), + wiretappingMode(OFF), storedRawData(StorageManagerIF::INVALID_ADDRESS), + deviceCommunicationId(deviceCommunication), comCookie(comCookie), + deviceThermalStatePoolId(thermalStatePoolId), + deviceThermalRequestPoolId(thermalRequestPoolId), + healthHelper(this,setObjectId), modeHelper(this), parameterHelper(this), + childTransitionFailure(RETURN_OK), fdirInstance(fdirInstance), + hkSwitcher(this), defaultFDIRUsed(fdirInstance == nullptr), + switchOffWasReported(false), actionHelper(this, nullptr), + childTransitionDelay(5000), + transitionSourceMode(_MODE_POWER_DOWN), transitionSourceSubMode( + SUBMODE_NONE), deviceSwitch(setDeviceSwitch) { commandQueue = QueueFactory::instance()->createMessageQueue(cmdQueueSize, CommandMessage::MAX_MESSAGE_SIZE); - cookieInfo.state = COOKIE_UNUSED; insertInCommandMap(RAW_COMMAND_ID); - if (this->fdirInstance == NULL) { + cookieInfo.state = COOKIE_UNUSED; + cookieInfo.pendingCommand = deviceCommandMap.end(); + if (comCookie == nullptr) { + sif::error << "DeviceHandlerBase: ObjectID 0x" << std::hex << + std::setw(8) << std::setfill('0') << this->getObjectId() << + std::dec << ": Do not pass nullptr as a cookie, consider " + << std::setfill(' ') << "passing a dummy cookie instead!" << + std::endl; + } + if (this->fdirInstance == nullptr) { this->fdirInstance = new DeviceHandlerFailureIsolation(setObjectId, defaultFDIRParentId); } } DeviceHandlerBase::~DeviceHandlerBase() { - communicationInterface->close(cookie); + delete comCookie; if (defaultFDIRUsed) { delete fdirInstance; } @@ -56,7 +64,7 @@ DeviceHandlerBase::~DeviceHandlerBase() { ReturnValue_t DeviceHandlerBase::performOperation(uint8_t counter) { this->pstStep = counter; - if (counter == 0) { + if (getComAction() == SEND_WRITE) { cookieInfo.state = COOKIE_UNUSED; readCommandQueue(); doStateMachine(); @@ -64,11 +72,12 @@ ReturnValue_t DeviceHandlerBase::performOperation(uint8_t counter) { decrementDeviceReplyMap(); fdirInstance->checkForFailures(); hkSwitcher.performOperation(); + performOperationHook(); } if (mode == MODE_OFF) { return RETURN_OK; } - switch (getRmapAction()) { + switch (getComAction()) { case SEND_WRITE: if ((cookieInfo.state == COOKIE_UNUSED)) { buildInternalCommand(); @@ -91,13 +100,91 @@ ReturnValue_t DeviceHandlerBase::performOperation(uint8_t counter) { return RETURN_OK; } +ReturnValue_t DeviceHandlerBase::initialize() { + ReturnValue_t result = SystemObject::initialize(); + if (result != RETURN_OK) { + return result; + } + + communicationInterface = objectManager->get( + deviceCommunicationId); + if (communicationInterface == NULL) { + return RETURN_FAILED; + } + + result = communicationInterface->initializeInterface(comCookie); + if (result != RETURN_OK) { + return result; + } + + IPCStore = objectManager->get(objects::IPC_STORE); + if (IPCStore == NULL) { + return RETURN_FAILED; + } + + AcceptsDeviceResponsesIF *rawReceiver = objectManager->get< + AcceptsDeviceResponsesIF>(rawDataReceiverId); + + if (rawReceiver == NULL) { + return RETURN_FAILED; + } + + defaultRawReceiver = rawReceiver->getDeviceQueue(); + + powerSwitcher = objectManager->get(powerSwitcherId); + if (powerSwitcher == NULL) { + return RETURN_FAILED; + } + + result = healthHelper.initialize(); + if (result != RETURN_OK) { + return result; + } + + result = modeHelper.initialize(); + if (result != RETURN_OK) { + return result; + } + result = actionHelper.initialize(commandQueue); + if (result != RETURN_OK) { + return result; + } + result = fdirInstance->initialize(); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + + result = parameterHelper.initialize(); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + + result = hkSwitcher.initialize(); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + + fillCommandAndReplyMap(); + + //Set temperature target state to NON_OP. + DataSet mySet; + PoolVariable thermalRequest(deviceThermalRequestPoolId, &mySet, + PoolVariableIF::VAR_WRITE); + mySet.read(); + thermalRequest = ThermalComponentIF::STATE_REQUEST_NON_OPERATIONAL; + mySet.commit(PoolVariableIF::VALID); + + return RETURN_OK; + +} + void DeviceHandlerBase::decrementDeviceReplyMap() { for (std::map::iterator iter = deviceReplyMap.begin(); iter != deviceReplyMap.end(); iter++) { if (iter->second.delayCycles != 0) { iter->second.delayCycles--; if (iter->second.delayCycles == 0) { - if (iter->second.periodic != 0) { + if (iter->second.periodic) { iter->second.delayCycles = iter->second.maxDelayCycles; } replyToReply(iter, TIMEOUT); @@ -149,7 +236,7 @@ void DeviceHandlerBase::readCommandQueue() { return; } - replyReturnvalueToCommand(CommandMessage::UNKNOW_COMMAND); + replyReturnvalueToCommand(CommandMessage::UNKNOWN_COMMAND); } @@ -256,55 +343,49 @@ ReturnValue_t DeviceHandlerBase::isModeCombinationValid(Mode_t mode, } } -ReturnValue_t DeviceHandlerBase::insertInCommandAndReplyMap( - DeviceCommandId_t deviceCommand, uint16_t maxDelayCycles, - uint8_t periodic, bool hasDifferentReplyId, DeviceCommandId_t replyId) { -//No need to check, as we may try to insert multiple times. +ReturnValue_t DeviceHandlerBase::insertInCommandAndReplyMap(DeviceCommandId_t deviceCommand, + uint16_t maxDelayCycles, size_t replyLen, bool periodic, + bool hasDifferentReplyId, DeviceCommandId_t replyId) { + //No need to check, as we may try to insert multiple times. insertInCommandMap(deviceCommand); if (hasDifferentReplyId) { - return insertInReplyMap(replyId, maxDelayCycles, periodic); + return insertInReplyMap(replyId, maxDelayCycles, replyLen, periodic); } else { - return insertInReplyMap(deviceCommand, maxDelayCycles, periodic); + return insertInReplyMap(deviceCommand, maxDelayCycles, replyLen, periodic); } } ReturnValue_t DeviceHandlerBase::insertInReplyMap(DeviceCommandId_t replyId, - uint16_t maxDelayCycles, uint8_t periodic) { + uint16_t maxDelayCycles, size_t replyLen, bool periodic) { DeviceReplyInfo info; info.maxDelayCycles = maxDelayCycles; info.periodic = periodic; info.delayCycles = 0; + info.replyLen = replyLen; info.command = deviceCommandMap.end(); - std::pair::iterator, bool> returnValue; - returnValue = deviceReplyMap.insert( - std::pair(replyId, info)); - if (returnValue.second) { + auto resultPair = deviceReplyMap.emplace(replyId, info); + if (resultPair.second) { return RETURN_OK; } else { return RETURN_FAILED; } } -ReturnValue_t DeviceHandlerBase::insertInCommandMap( - DeviceCommandId_t deviceCommand) { +ReturnValue_t DeviceHandlerBase::insertInCommandMap(DeviceCommandId_t deviceCommand) { DeviceCommandInfo info; info.expectedReplies = 0; info.isExecuting = false; info.sendReplyTo = NO_COMMANDER; - std::pair::iterator, bool> returnValue; - returnValue = deviceCommandMap.insert( - std::pair(deviceCommand, - info)); - if (returnValue.second) { + auto resultPair = deviceCommandMap.emplace(deviceCommand, info); + if (resultPair.second) { return RETURN_OK; } else { return RETURN_FAILED; } } -ReturnValue_t DeviceHandlerBase::updateReplyMapEntry( - DeviceCommandId_t deviceReply, uint16_t delayCycles, - uint16_t maxDelayCycles, uint8_t periodic) { +ReturnValue_t DeviceHandlerBase::updateReplyMapEntry(DeviceCommandId_t deviceReply, + uint16_t delayCycles, uint16_t maxDelayCycles, bool periodic) { std::map::iterator iter = deviceReplyMap.find(deviceReply); if (iter == deviceReplyMap.end()) { @@ -429,7 +510,7 @@ void DeviceHandlerBase::replyToReply(DeviceReplyMap::iterator iter, void DeviceHandlerBase::doSendWrite() { if (cookieInfo.state == COOKIE_WRITE_READY) { - ReturnValue_t result = communicationInterface->sendMessage(cookie, + ReturnValue_t result = communicationInterface->sendMessage(comCookie, rawPacket, rawPacketLen); if (result == RETURN_OK) { @@ -450,12 +531,14 @@ void DeviceHandlerBase::doGetWrite() { return; } cookieInfo.state = COOKIE_UNUSED; - ReturnValue_t result = communicationInterface->getSendSuccess(cookie); + ReturnValue_t result = communicationInterface->getSendSuccess(comCookie); if (result == RETURN_OK) { if (wiretappingMode == RAW) { replyRawData(rawPacket, rawPacketLen, requestedRawTraffic, true); } - //We need to distinguish here, because a raw command never expects a reply. (Could be done in eRIRM, but then child implementations need to be careful. + + //We need to distinguish here, because a raw command never expects a reply. + //(Could be done in eRIRM, but then child implementations need to be careful. result = enableReplyInReplyMap(cookieInfo.pendingCommand); } else { //always generate a failure event, so that FDIR knows what's up @@ -471,7 +554,17 @@ void DeviceHandlerBase::doGetWrite() { void DeviceHandlerBase::doSendRead() { ReturnValue_t result; - result = communicationInterface->requestReceiveMessage(cookie); + size_t requestLen = 0; + if(cookieInfo.pendingCommand != deviceCommandMap.end()) { + DeviceReplyIter iter = deviceReplyMap.find( + cookieInfo.pendingCommand->first); + if(iter != deviceReplyMap.end()) { + requestLen = iter->second.replyLen; + } + } + + result = communicationInterface->requestReceiveMessage(comCookie, requestLen); + if (result == RETURN_OK) { cookieInfo.state = COOKIE_READ_SENT; } else { @@ -485,10 +578,10 @@ void DeviceHandlerBase::doSendRead() { } void DeviceHandlerBase::doGetRead() { - uint32_t receivedDataLen; + size_t receivedDataLen; uint8_t *receivedData; DeviceCommandId_t foundId = 0xFFFFFFFF; - uint32_t foundLen = 0; + size_t foundLen = 0; ReturnValue_t result; if (cookieInfo.state != COOKIE_READ_SENT) { @@ -498,8 +591,8 @@ void DeviceHandlerBase::doGetRead() { cookieInfo.state = COOKIE_UNUSED; - result = communicationInterface->readReceivedMessage(cookie, &receivedData, - &receivedDataLen); + result = communicationInterface->readReceivedMessage(comCookie, + &receivedData, &receivedDataLen); if (result != RETURN_OK) { triggerEvent(DEVICE_REQUESTING_REPLY_FAILED, result); @@ -508,7 +601,7 @@ void DeviceHandlerBase::doGetRead() { return; } - if (receivedDataLen == 0) + if (receivedDataLen == 0 or result == DeviceCommunicationIF::NO_REPLY_RECEIVED) return; if (wiretappingMode == RAW) { @@ -539,6 +632,8 @@ void DeviceHandlerBase::doGetRead() { break; case IGNORE_REPLY_DATA: break; + case IGNORE_FULL_PACKET: + return; default: //We need to wait for timeout.. don't know what command failed and who sent it. replyRawReplyIfnotWiretapped(receivedData, foundLen); @@ -560,8 +655,8 @@ ReturnValue_t DeviceHandlerBase::getStorageData(store_address_t storageAddress, uint8_t * *data, uint32_t * len) { size_t lenTmp; - if (IPCStore == NULL) { - *data = NULL; + if (IPCStore == nullptr) { + *data = nullptr; *len = 0; return RETURN_FAILED; } @@ -572,90 +667,10 @@ ReturnValue_t DeviceHandlerBase::getStorageData(store_address_t storageAddress, } else { triggerEvent(StorageManagerIF::GET_DATA_FAILED, result, storageAddress.raw); - *data = NULL; + *data = nullptr; *len = 0; return result; } - -} - -ReturnValue_t DeviceHandlerBase::initialize() { - ReturnValue_t result = SystemObject::initialize(); - if (result != RETURN_OK) { - return result; - } - - communicationInterface = objectManager->get( - deviceCommunicationId); - if (communicationInterface == NULL) { - return RETURN_FAILED; - } - - result = communicationInterface->open(&cookie, ioBoardAddress, - maxDeviceReplyLen); - if (result != RETURN_OK) { - return result; - } - - IPCStore = objectManager->get(objects::IPC_STORE); - if (IPCStore == NULL) { - return RETURN_FAILED; - } - - AcceptsDeviceResponsesIF *rawReceiver = objectManager->get< - AcceptsDeviceResponsesIF>(rawDataReceiverId); - - if (rawReceiver == NULL) { - return RETURN_FAILED; - } - - defaultRawReceiver = rawReceiver->getDeviceQueue(); - - powerSwitcher = objectManager->get(powerSwitcherId); - if (powerSwitcher == NULL) { - return RETURN_FAILED; - } - - result = healthHelper.initialize(); - if (result != RETURN_OK) { - return result; - } - - result = modeHelper.initialize(); - if (result != RETURN_OK) { - return result; - } - result = actionHelper.initialize(commandQueue); - if (result != RETURN_OK) { - return result; - } - result = fdirInstance->initialize(); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - - result = parameterHelper.initialize(); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - - result = hkSwitcher.initialize(); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - - fillCommandAndReplyMap(); - - //Set temperature target state to NON_OP. - DataSet mySet; - PoolVariable thermalRequest(deviceThermalRequestPoolId, &mySet, - PoolVariableIF::VAR_WRITE); - mySet.read(); - thermalRequest = ThermalComponentIF::STATE_REQUEST_NON_OPERATIONAL; - mySet.commit(PoolVariableIF::VALID); - - return RETURN_OK; - } void DeviceHandlerBase::replyRawData(const uint8_t *data, size_t len, @@ -687,8 +702,7 @@ void DeviceHandlerBase::replyRawData(const uint8_t *data, size_t len, } //Default child implementations - -DeviceHandlerBase::RmapAction_t DeviceHandlerBase::getRmapAction() { +DeviceHandlerIF::CommunicationAction_t DeviceHandlerBase::getComAction() { switch (pstStep) { case 0: return SEND_WRITE; @@ -727,7 +741,7 @@ void DeviceHandlerBase::handleReply(const uint8_t* receivedData, if (info->delayCycles != 0) { - if (info->periodic != 0) { + if (info->periodic) { info->delayCycles = info->maxDelayCycles; } else { info->delayCycles = 0; @@ -748,20 +762,20 @@ void DeviceHandlerBase::handleReply(const uint8_t* receivedData, } } -ReturnValue_t DeviceHandlerBase::switchCookieChannel(object_id_t newChannelId) { - DeviceCommunicationIF *newCommunication = objectManager->get< - DeviceCommunicationIF>(newChannelId); - - if (newCommunication != NULL) { - ReturnValue_t result = newCommunication->reOpen(cookie, ioBoardAddress, - maxDeviceReplyLen); - if (result != RETURN_OK) { - return result; - } - return RETURN_OK; - } - return RETURN_FAILED; -} +//ReturnValue_t DeviceHandlerBase::switchCookieChannel(object_id_t newChannelId) { +// DeviceCommunicationIF *newCommunication = objectManager->get< +// DeviceCommunicationIF>(newChannelId); +// +// if (newCommunication != NULL) { +// ReturnValue_t result = newCommunication->reOpen(cookie, ioBoardAddress, +// maxDeviceReplyLen); +// if (result != RETURN_OK) { +// return result; +// } +// return RETURN_OK; +// } +// return RETURN_FAILED; +//} void DeviceHandlerBase::buildRawDeviceCommand(CommandMessage* commandMessage) { storedRawData = DeviceHandlerMessage::getStoreAddress(commandMessage); @@ -1022,7 +1036,6 @@ void DeviceHandlerBase::replyRawReplyIfnotWiretapped(const uint8_t* data, ReturnValue_t DeviceHandlerBase::handleDeviceHandlerMessage( CommandMessage * message) { - ReturnValue_t result; switch (message->getCommand()) { case DeviceHandlerMessage::CMD_WIRETAPPING: switch (DeviceHandlerMessage::getWiretappingMode(message)) { @@ -1044,19 +1057,19 @@ ReturnValue_t DeviceHandlerBase::handleDeviceHandlerMessage( } replyReturnvalueToCommand(RETURN_OK); return RETURN_OK; - case DeviceHandlerMessage::CMD_SWITCH_IOBOARD: - if (mode != MODE_OFF) { - replyReturnvalueToCommand(WRONG_MODE_FOR_COMMAND); - } else { - result = switchCookieChannel( - DeviceHandlerMessage::getIoBoardObjectId(message)); - if (result == RETURN_OK) { - replyReturnvalueToCommand(RETURN_OK); - } else { - replyReturnvalueToCommand(CANT_SWITCH_IOBOARD); - } - } - return RETURN_OK; +// case DeviceHandlerMessage::CMD_SWITCH_IOBOARD: +// if (mode != MODE_OFF) { +// replyReturnvalueToCommand(WRONG_MODE_FOR_COMMAND); +// } else { +// result = switchCookieChannel( +// DeviceHandlerMessage::getIoBoardObjectId(message)); +// if (result == RETURN_OK) { +// replyReturnvalueToCommand(RETURN_OK); +// } else { +// replyReturnvalueToCommand(CANT_SWITCH_IO_ADDRESS); +// } +// } +// return RETURN_OK; case DeviceHandlerMessage::CMD_RAW: if ((mode != MODE_RAW)) { DeviceHandlerMessage::clear(message); @@ -1072,7 +1085,7 @@ ReturnValue_t DeviceHandlerBase::handleDeviceHandlerMessage( void DeviceHandlerBase::setParentQueue(MessageQueueId_t parentQueueId) { modeHelper.setParentQueue(parentQueueId); - healthHelper.setParentQeueue(parentQueueId); + healthHelper.setParentQueue(parentQueueId); } bool DeviceHandlerBase::isAwaitingReply() { @@ -1136,7 +1149,7 @@ void DeviceHandlerBase::handleDeviceTM(SerializeIF* data, } ReturnValue_t DeviceHandlerBase::executeAction(ActionId_t actionId, - MessageQueueId_t commandedBy, const uint8_t* data, uint32_t size) { + MessageQueueId_t commandedBy, const uint8_t* data, size_t size) { ReturnValue_t result = acceptExternalDeviceCommands(); if (result != HasReturnvaluesIF::RETURN_OK) { return result; @@ -1270,3 +1283,9 @@ void DeviceHandlerBase::changeHK(Mode_t mode, Submode_t submode, bool enable) { void DeviceHandlerBase::setTaskIF(PeriodicTaskIF* task_){ executingTask = task_; } + +// Default implementations empty. +void DeviceHandlerBase::debugInterface(uint8_t positionTracker, + object_id_t objectId, uint32_t parameter) {} + +void DeviceHandlerBase::performOperationHook() {} diff --git a/devicehandlers/DeviceHandlerBase.h b/devicehandlers/DeviceHandlerBase.h index 756ad530d..7c68ce065 100644 --- a/devicehandlers/DeviceHandlerBase.h +++ b/devicehandlers/DeviceHandlerBase.h @@ -1,26 +1,24 @@ #ifndef DEVICEHANDLERBASE_H_ #define DEVICEHANDLERBASE_H_ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "../objectmanager/SystemObject.h" +#include "../tasks/ExecutableObjectIF.h" +#include "DeviceHandlerIF.h" +#include "../returnvalues/HasReturnvaluesIF.h" +#include "../action/HasActionsIF.h" +#include "../datapool/PoolVariableIF.h" +#include "DeviceCommunicationIF.h" +#include "../modes/HasModesIF.h" +#include "../power/PowerSwitchIF.h" +#include "../ipc/MessageQueueIF.h" + +#include "../action/ActionHelper.h" +#include "../health/HealthHelper.h" +#include "../parameters/ParameterHelper.h" +#include "../datapool/HkSwitchHelper.h" +#include "DeviceHandlerFailureIsolation.h" + #include -#include -#include namespace Factory{ void setStaticFrameworkObjectIds(); @@ -29,29 +27,53 @@ void setStaticFrameworkObjectIds(); class StorageManagerIF; /** - * \defgroup devices Devices + * @defgroup devices Devices * Contains all devices and the DeviceHandlerBase class. */ /** - * \brief This is the abstract base class for device handlers. - * + * @brief This is the abstract base class for device handlers. + * @details * Documentation: Dissertation Baetz p.138,139, p.141-149 - * SpaceWire Remote Memory Access Protocol (RMAP) * - * It features handling of @link DeviceHandlerIF::Mode_t Modes @endlink, the RMAP communication and the - * communication with commanding objects. + * It features handling of @link DeviceHandlerIF::Mode_t Modes @endlink, + * communication with physical devices, using the @link DeviceCommunicationIF @endlink, + * and communication with commanding objects. * It inherits SystemObject and thus can be created by the ObjectManagerIF. * * This class uses the opcode of ExecutableObjectIF to perform a step-wise execution. - * For each step an RMAP action is selected and executed. If data has been received (eg in case of an RMAP Read), the data will be interpreted. - * The action for each step can be defined by the child class but as most device handlers share a 4-call (Read-getRead-write-getWrite) structure, - * a default implementation is provided. + * For each step an RMAP action is selected and executed. + * If data has been received (GET_READ), the data will be interpreted. + * The action for each step can be defined by the child class but as most + * device handlers share a 4-call (sendRead-getRead-sendWrite-getWrite) structure, + * a default implementation is provided. NOTE: RMAP is a standard which is used for FLP. + * RMAP communication is not mandatory for projects implementing the FSFW. + * However, the communication principles are similar to RMAP as there are + * two write and two send calls involved. * * Device handler instances should extend this class and implement the abstract functions. * Components and drivers can send so called cookies which are used for communication + * and contain information about the communcation (e.g. slave address for I2C or RMAP structs). + * The following abstract methods must be implemented by a device handler: + * 1. doStartUp() + * 2. doShutDown() + * 3. buildTransitionDeviceCommand() + * 4. buildNormalDeviceCommand() + * 5. buildCommandFromCommand() + * 6. fillCommandAndReplyMap() + * 7. scanForReply() + * 8. interpretDeviceReply() * - * \ingroup devices + * Other important virtual methods with a default implementation + * are the getTransitionDelayMs() function and the getSwitches() function. + * Please ensure that getSwitches() returns DeviceHandlerIF::NO_SWITCHES if + * power switches are not implemented yet. Otherwise, the device handler will + * not transition to MODE_ON, even if setMode(MODE_ON) is called. + * If a transition to MODE_ON is desired without commanding, override the + * intialize() function and call setMode(_MODE_START_UP) before calling + * DeviceHandlerBase::initialize(). + * + * @ingroup devices */ class DeviceHandlerBase: public DeviceHandlerIF, public HasReturnvaluesIF, @@ -68,59 +90,402 @@ public: * * @param setObjectId the ObjectId to pass to the SystemObject() Constructor * @param maxDeviceReplyLen the length the RMAP getRead call will be sent with - * @param setDeviceSwitch the switch the device is connected to, for devices using two switches, overwrite getSwitches() + * @param setDeviceSwitch the switch the device is connected to, + * for devices using two switches, overwrite getSwitches() + * @param deviceCommuncation Communcation Interface object which is used + * to implement communication functions + * @param thermalStatePoolId + * @param thermalRequestPoolId + * @param fdirInstance + * @param cmdQueueSize */ - DeviceHandlerBase(uint32_t ioBoardAddress, object_id_t setObjectId, - uint32_t maxDeviceReplyLen, uint8_t setDeviceSwitch, - object_id_t deviceCommunication, uint32_t thermalStatePoolId = - PoolVariableIF::NO_PARAMETER, + DeviceHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication, + CookieIF * comCookie, uint8_t setDeviceSwitch, + uint32_t thermalStatePoolId = PoolVariableIF::NO_PARAMETER, uint32_t thermalRequestPoolId = PoolVariableIF::NO_PARAMETER, - FailureIsolationBase* fdirInstance = NULL, uint32_t cmdQueueSize = 20); - - virtual MessageQueueId_t getCommandQueue(void) const; - + FailureIsolationBase* fdirInstance = nullptr, + size_t cmdQueueSize = 20); /** - * This function is a core component and is called periodically. - * General sequence: - * If the State is SEND_WRITE: - * 1. Set the cookie state to COOKIE_UNUSED and read the command queue - * 2. Handles Device State Modes by calling doStateMachine(). - * This function calls callChildStatemachine() which calls the abstract functions - * doStartUp() and doShutDown() - * 3. Check switch states by calling checkSwitchStates() - * 4. Decrements counter for timeout of replies by calling decrementDeviceReplyMap() - * 5. Performs FDIR check for failures - * 6. Calls hkSwitcher.performOperation() - * 7. If the device mode is MODE_OFF, return RETURN_OK. Otherwise, perform the Action property - * and performs depending on value specified - * by input value counter. The child class tells base class what to do by setting this value. - * - SEND_WRITE: Send data or commands to device by calling doSendWrite() - * Calls abstract funtions buildNomalDeviceCommand() - * or buildTransitionDeviceCommand() - * - GET_WRITE: Get ackknowledgement for sending by calling doGetWrite(). - * Calls abstract functions scanForReply() and interpretDeviceReply(). - * - SEND_READ: Request reading data from device by calling doSendRead() - * - GET_READ: Access requested reading data by calling doGetRead() - * @param counter Specifies which Action to perform - * @return RETURN_OK for successful execution - */ + * @brief This function is the device handler base core component and is + * called periodically. + * @details + * General sequence, showing where abstract virtual functions are called: + * If the State is SEND_WRITE: + * 1. Set the cookie state to COOKIE_UNUSED and read the command queue + * 2. Handles Device State Modes by calling doStateMachine(). + * This function calls callChildStatemachine() which calls the + * abstract functions doStartUp() and doShutDown() + * 3. Check switch states by calling checkSwitchStates() + * 4. Decrements counter for timeout of replies by calling + * decrementDeviceReplyMap() + * 5. Performs FDIR check for failures + * 6. Calls hkSwitcher.performOperation() + * 7. If the device mode is MODE_OFF, return RETURN_OK. + * Otherwise, perform the Action property and performs depending + * on value specified by input value counter (incremented in PST). + * The child class tells base class what to do by setting this value. + * - SEND_WRITE: Send data or commands to device by calling + * doSendWrite() which calls sendMessage function + * of #communicationInterface + * and calls buildInternalCommand if the cookie state is COOKIE_UNUSED + * - GET_WRITE: Get ackknowledgement for sending by calling doGetWrite() + * which calls getSendSuccess of #communicationInterface. + * Calls abstract functions scanForReply() and interpretDeviceReply(). + * - SEND_READ: Request reading data from device by calling doSendRead() + * which calls requestReceiveMessage of #communcationInterface + * - GET_READ: Access requested reading data by calling doGetRead() + * which calls readReceivedMessage of #communicationInterface + * @param counter Specifies which Action to perform + * @return RETURN_OK for successful execution + */ virtual ReturnValue_t performOperation(uint8_t counter); + /** + * @brief Initializes the device handler + * @details + * Initialize Device Handler as system object and + * initializes all important helper classes. + * Calls fillCommandAndReplyMap(). + * @return + */ virtual ReturnValue_t initialize(); - /** - * - * @param parentQueueId - */ - virtual void setParentQueue(MessageQueueId_t parentQueueId); /** * Destructor. */ virtual ~DeviceHandlerBase(); +protected: + /** + * @brief This is used to let the child class handle the transition from + * mode @c _MODE_START_UP to @c MODE_ON + * @details + * It is only called when the device handler is in mode @c _MODE_START_UP. + * That means, the device switch(es) are already set to on. + * Device handler commands are read and can be handled by the child class. + * If the child class handles a command, it should also send + * an reply accordingly. + * If an Command is not handled (ie #DeviceHandlerCommand is not @c CMD_NONE, + * the base class handles rejecting the command and sends a reply. + * The replies for mode transitions are handled by the base class. + * + * - If the device is started and ready for operation, the mode should be + * set to MODE_ON. It is possible to set the mode to _MODE_TO_ON to + * use the to on transition if available. + * - If the power-up fails, the mode should be set to _MODE_POWER_DOWN + * which will lead to the device being powered off. + * - If the device does not change the mode, the mode will be changed + * to _MODE_POWER_DOWN, after the timeout (from getTransitionDelay()) + * has passed. + * + * #transitionFailure can be set to a failure code indicating the reason + * for a failed transition + */ + virtual void doStartUp() = 0; + /** + * @brief This is used to let the child class handle the transition + * from mode @c _MODE_SHUT_DOWN to @c _MODE_POWER_DOWN + * @details + * It is only called when the device handler is in mode @c _MODE_SHUT_DOWN. + * Device handler commands are read and can be handled by the child class. + * If the child class handles a command, it should also send an reply + * accordingly. + * If an Command is not handled (ie #DeviceHandlerCommand is not + * @c CMD_NONE, the base class handles rejecting the command and sends a + * reply. The replies for mode transitions are handled by the base class. + * + * - If the device ready to be switched off, + * the mode should be set to _MODE_POWER_DOWN. + * - If the device should not be switched off, the mode can be changed to + * _MODE_TO_ON (or MODE_ON if no transition is needed). + * - If the device does not change the mode, the mode will be changed to + * _MODE_POWER_DOWN, when the timeout (from getTransitionDelay()) + * has passed. + * + * #transitionFailure can be set to a failure code indicating the reason + * for a failed transition + */ + virtual void doShutDown() = 0; + + /** + * Build the device command to send for normal mode. + * + * This is only called in @c MODE_NORMAL. If multiple submodes for + * @c MODE_NORMAL are supported, different commands can built, + * depending on the submode. + * + * #rawPacket and #rawPacketLen must be set by this method to the + * packet to be sent. If variable command frequence is required, a counter + * can be used and the frequency in the reply map has to be set manually + * by calling updateReplyMap(). + * + * @param[out] id the device command id that has been built + * @return + * - @c RETURN_OK to send command after setting #rawPacket and #rawPacketLen. + * - @c NOTHING_TO_SEND when no command is to be sent. + * - Anything else triggers an even with the returnvalue as a parameter. + */ + virtual ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t * id) = 0; + + /** + * Build the device command to send for a transitional mode. + * + * This is only called in @c _MODE_TO_NORMAL, @c _MODE_TO_ON, @c _MODE_TO_RAW, + * @c _MODE_START_UP and @c _MODE_TO_POWER_DOWN. So it is used by doStartUp() + * and doShutDown() as well as doTransition() + * + * A good idea is to implement a flag indicating a command has to be built + * and a variable containing the command number to be built + * and filling them in doStartUp(), doShutDown() and doTransition() so no + * modes have to be checked here. + * + * #rawPacket and #rawPacketLen must be set by this method to the packet to be sent. + * + * @param[out] id the device command id built + * @return + * - @c RETURN_OK when a command is to be sent + * - @c NOTHING_TO_SEND when no command is to be sent + * - Anything else triggers an even with the returnvalue as a parameter + */ + virtual ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t * id) = 0; + + /** + * @brief Build a device command packet from data supplied by a direct command. + * + * @details + * #rawPacket and #rawPacketLen should be set by this method to the packet to be sent. + * The existence of the command in the command map and the command size check + * against 0 are done by the base class. + * + * @param deviceCommand the command to build, already checked against deviceCommandMap + * @param commandData pointer to the data from the direct command + * @param commandDataLen length of commandData + * @return + * - @c RETURN_OK to send command after #rawPacket and #rawPacketLen have been set. + * - Anything else triggers an event with the returnvalue as a parameter + */ + virtual ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand, + const uint8_t * commandData, size_t commandDataLen) = 0; + + /** + * @brief Scans a buffer for a valid reply. + * @details + * This is used by the base class to check the data received for valid packets. + * It only checks if a valid packet starts at @c start. + * It also only checks the structural validy of the packet, + * e.g. checksums lengths and protocol data. No information check is done, + * e.g. range checks etc. + * + * Errors should be reported directly, the base class does NOT report any + * errors based on the return value of this function. + * + * @param start start of remaining buffer to be scanned + * @param len length of remaining buffer to be scanned + * @param[out] foundId the id of the data found in the buffer. + * @param[out] foundLen length of the data found. Is to be set in function, + * buffer is scanned at previous position + foundLen. + * @return + * - @c RETURN_OK a valid packet was found at @c start, @c foundLen is valid + * - @c RETURN_FAILED no reply could be found starting at @c start, + * implies @c foundLen is not valid, base class will call scanForReply() + * again with ++start + * - @c DeviceHandlerIF::INVALID_DATA a packet was found but it is invalid, + * e.g. checksum error, implies @c foundLen is valid, can be used to + * skip some bytes + * - @c DeviceHandlerIF::LENGTH_MISSMATCH @c len is invalid + * - @c DeviceHandlerIF::IGNORE_REPLY_DATA Ignore this specific part of + * the packet + * - @c DeviceHandlerIF::IGNORE_FULL_PACKET Ignore the packet + * - @c APERIODIC_REPLY if a valid reply is received that has not been + * requested by a command, but should be handled anyway + * (@see also fillCommandAndCookieMap() ) + */ + virtual ReturnValue_t scanForReply(const uint8_t *start, size_t len, + DeviceCommandId_t *foundId, size_t *foundLen) = 0; + + /** + * @brief Interpret a reply from the device. + * @details + * This is called after scanForReply() found a valid packet, it can be + * assumed that the length and structure is valid. + * This routine extracts the data from the packet into a DataSet and then + * calls handleDeviceTM(), which either sends a TM packet or stores the + * data in the DataPool depending on whether it was an external command. + * No packet length is given, as it should be defined implicitly by the id. + * + * @param id the id found by scanForReply() + * @param packet + * @return + * - @c RETURN_OK when the reply was interpreted. + * - @c RETURN_FAILED when the reply could not be interpreted, + * e.g. logical errors or range violations occurred + */ + + virtual ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, + const uint8_t *packet) = 0; + + /** + * @brief fill the #deviceCommandMap + * called by the initialize() of the base class + * @details + * This is used to let the base class know which replies are expected. + * There are different scenarios regarding this: + * + * - "Normal" commands. These are commands, that trigger a direct reply + * from the device. In this case, the id of the command should be added + * to the command map with a commandData_t where maxDelayCycles is set + * to the maximum expected number of PST cycles the reply will take. + * Then, scanForReply returns the id of the command and the base class + * can handle time-out and missing replies. + * + * - Periodic, unrequested replies. These are replies that, once enabled, + * are sent by the device on its own in a defined interval. + * In this case, the id of the reply or a placeholder id should be added + * to the deviceCommandMap with a commandData_t where maxDelayCycles is + * set to the maximum expected number of PST cycles between two replies + * (also a tolerance should be added, as an FDIR message will be + * generated if it is missed). + * + * (Robin) This part confuses me. "must do as soon as" implies that + * the developer must do something somewhere else in the code. Is + * that really the case? If I understood correctly, DHB performs + * almost everything (e.g. in erirm function) as long as the commands + * are inserted correctly. + * + * As soon as the replies are enabled, DeviceCommandInfo.periodic must + * be set to true, DeviceCommandInfo.delayCycles to + * DeviceCommandInfo.maxDelayCycles. + * From then on, the base class handles the reception. + * Then, scanForReply returns the id of the reply or the placeholder id + * and the base class will take care of checking that all replies are + * received and the interval is correct. + * When the replies are disabled, DeviceCommandInfo.periodic must be set + * to 0, DeviceCommandInfo.delayCycles to 0; + * + * - Aperiodic, unrequested replies. These are replies that are sent + * by the device without any preceding command and not in a defined + * interval. These are not entered in the deviceCommandMap but + * handled by returning @c APERIODIC_REPLY in scanForReply(). + */ + virtual void fillCommandAndReplyMap() = 0; + + /** + * This is a helper method to facilitate inserting entries in the command map. + * @param deviceCommand Identifier of the command to add. + * @param maxDelayCycles The maximum number of delay cycles the command + * waits until it times out. + * @param periodic Indicates if the command is periodic (i.e. it is sent + * by the device repeatedly without request) or not. Default is aperiodic (0) + * @return - @c RETURN_OK when the command was successfully inserted, + * - @c RETURN_FAILED else. + */ + ReturnValue_t insertInCommandAndReplyMap(DeviceCommandId_t deviceCommand, + uint16_t maxDelayCycles, size_t replyLen = 0, bool periodic = false, + bool hasDifferentReplyId = false, DeviceCommandId_t replyId = 0); + + /** + * @brief This is a helper method to insert replies in the reply map. + * @param deviceCommand Identifier of the reply to add. + * @param maxDelayCycles The maximum number of delay cycles the reply waits + * until it times out. + * @param periodic Indicates if the command is periodic (i.e. it is sent + * by the device repeatedly without request) or not. Default is aperiodic (0) + * @return - @c RETURN_OK when the command was successfully inserted, + * - @c RETURN_FAILED else. + */ + ReturnValue_t insertInReplyMap(DeviceCommandId_t deviceCommand, + uint16_t maxDelayCycles, size_t replyLen = 0, bool periodic = false); + + /** + * @brief A simple command to add a command to the commandList. + * @param deviceCommand The command to add + * @return - @c RETURN_OK when the command was successfully inserted, + * - @c RETURN_FAILED else. + */ + ReturnValue_t insertInCommandMap(DeviceCommandId_t deviceCommand); + /** + * @brief This is a helper method to facilitate updating entries + * in the reply map. + * @param deviceCommand Identifier of the reply to update. + * @param delayCycles The current number of delay cycles to wait. + * As stated in #fillCommandAndCookieMap, to disable periodic commands, + * this is set to zero. + * @param maxDelayCycles The maximum number of delay cycles the reply waits + * until it times out. By passing 0 the entry remains untouched. + * @param periodic Indicates if the command is periodic (i.e. it is sent + * by the device repeatedly without request) or not.Default is aperiodic (0). + * Warning: The setting always overrides the value that was entered in the map. + * @return - @c RETURN_OK when the command was successfully inserted, + * - @c RETURN_FAILED else. + */ + ReturnValue_t updateReplyMapEntry(DeviceCommandId_t deviceReply, + uint16_t delayCycles, uint16_t maxDelayCycles, + bool periodic = false); + + /** + * @brief Can be implemented by child handler to + * perform debugging + * @details Example: Calling this in performOperation + * to track values like mode. + * @param positionTracker Provide the child handler a way to know + * where the debugInterface was called + * @param objectId Provide the child handler object Id to + * specify actions for spefic devices + * @param parameter Supply a parameter of interest + * Please delete all debugInterface calls in DHB after debugging is finished ! + */ + virtual void debugInterface(uint8_t positionTracker = 0, + object_id_t objectId = 0, uint32_t parameter = 0); + + /** + * Get the time needed to transit from modeFrom to modeTo. + * + * Used for the following transitions: + * modeFrom -> modeTo: + * MODE_ON -> [MODE_ON, MODE_NORMAL, MODE_RAW, _MODE_POWER_DOWN] + * MODE_NORMAL -> [MODE_ON, MODE_NORMAL, MODE_RAW, _MODE_POWER_DOWN] + * MODE_RAW -> [MODE_ON, MODE_NORMAL, MODE_RAW, _MODE_POWER_DOWN] + * _MODE_START_UP -> MODE_ON (do not include time to set the switches, + * the base class got you covered) + * + * The default implementation returns 0 ! + * @param modeFrom + * @param modeTo + * @return time in ms + */ + virtual uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo); + + /** + * Return the switches connected to the device. + * + * The default implementation returns one switch set in the ctor. + * + * @param[out] switches pointer to an array of switches + * @param[out] numberOfSwitches length of returned array + * @return + * - @c RETURN_OK if the parameters were set + * - @c RETURN_FAILED if no switches exist + */ + virtual ReturnValue_t getSwitches(const uint8_t **switches, + uint8_t *numberOfSwitches); + + /** + * @brief Hook function for child handlers which is called once per + * performOperation(). Default implementation is empty. + */ + virtual void performOperationHook(); +public: + /** + * @param parentQueueId + */ + virtual void setParentQueue(MessageQueueId_t parentQueueId); + + /** @brief Implementation required for HasActionIF */ ReturnValue_t executeAction(ActionId_t actionId, - MessageQueueId_t commandedBy, const uint8_t* data, uint32_t size); + MessageQueueId_t commandedBy, const uint8_t* data, + size_t size) override; + Mode_t getTransitionSourceMode() const; Submode_t getTransitionSourceSubMode() const; virtual void getMode(Mode_t *mode, Submode_t *submode); @@ -136,24 +501,27 @@ public: * @param task_ Pointer to the taskIF of this task */ virtual void setTaskIF(PeriodicTaskIF* task_); + virtual MessageQueueId_t getCommandQueue(void) const; + protected: /** - * The Returnvalues id of this class, required by HasReturnvaluesIF + * The Returnvalues ID of this class, required by HasReturnvaluesIF */ static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_BASE; - static const ReturnValue_t INVALID_CHANNEL = MAKE_RETURN_CODE(4); - static const ReturnValue_t APERIODIC_REPLY = MAKE_RETURN_CODE(5); - static const ReturnValue_t IGNORE_REPLY_DATA = MAKE_RETURN_CODE(6); -// static const ReturnValue_t ONE_SWITCH = MAKE_RETURN_CODE(8); -// static const ReturnValue_t TWO_SWITCHES = MAKE_RETURN_CODE(9); - static const ReturnValue_t NO_SWITCH = MAKE_RETURN_CODE(10); - static const ReturnValue_t COMMAND_MAP_ERROR = MAKE_RETURN_CODE(11); - static const ReturnValue_t NOTHING_TO_SEND = MAKE_RETURN_CODE(12); - - //Mode handling error Codes - static const ReturnValue_t CHILD_TIMEOUT = MAKE_RETURN_CODE(0xE1); - static const ReturnValue_t SWITCH_FAILED = MAKE_RETURN_CODE(0xE2); + static const ReturnValue_t INVALID_CHANNEL = MAKE_RETURN_CODE(0xA0); + // Returnvalues for scanForReply() + static const ReturnValue_t APERIODIC_REPLY = MAKE_RETURN_CODE(0xB0); //!< This is used to specify for replies from a device which are not replies to requests + static const ReturnValue_t IGNORE_REPLY_DATA = MAKE_RETURN_CODE(0xB1); //!< Ignore parts of the received packet + static const ReturnValue_t IGNORE_FULL_PACKET = MAKE_RETURN_CODE(0xB2); //!< Ignore full received packet + // Returnvalues for command building + static const ReturnValue_t NOTHING_TO_SEND = MAKE_RETURN_CODE(0xC0); //!< Return this if no command sending in required + static const ReturnValue_t COMMAND_MAP_ERROR = MAKE_RETURN_CODE(0xC2); + // Returnvalues for getSwitches() + static const ReturnValue_t NO_SWITCH = MAKE_RETURN_CODE(0xD0); + // Mode handling error Codes + static const ReturnValue_t CHILD_TIMEOUT = MAKE_RETURN_CODE(0xE0); + static const ReturnValue_t SWITCH_FAILED = MAKE_RETURN_CODE(0xE1); static const DeviceCommandId_t RAW_COMMAND_ID = -1; static const DeviceCommandId_t NO_COMMAND_ID = -2; @@ -162,11 +530,11 @@ protected: /** * Pointer to the raw packet that will be sent. */ - uint8_t *rawPacket; + uint8_t *rawPacket = nullptr; /** * Size of the #rawPacket. */ - uint32_t rawPacketLen; + uint32_t rawPacketLen = 0; /** * The mode the device handler is currently in. @@ -185,12 +553,7 @@ protected: /** * This is the counter value from performOperation(). */ - uint8_t pstStep; - - /** - * This will be used in the RMAP getRead command as expected length, is set by the constructor, can be modiefied at will. - */ - const uint32_t maxDeviceReplyLen; + uint8_t pstStep = 0; /** * wiretapping flag: @@ -208,7 +571,7 @@ protected: * Statically initialized in initialize() to a configurable object. Used when there is no method * of finding a recipient, ie raw mode and reporting erreonous replies */ - MessageQueueId_t defaultRawReceiver; + MessageQueueId_t defaultRawReceiver = 0; store_address_t storedRawData; @@ -217,19 +580,19 @@ protected: * * if #isWiretappingActive all raw communication from and to the device will be sent to this queue */ - MessageQueueId_t requestedRawTraffic; + MessageQueueId_t requestedRawTraffic = 0; /** * the object used to set power switches */ - PowerSwitchIF *powerSwitcher; + PowerSwitchIF *powerSwitcher = nullptr; /** * Pointer to the IPCStore. * * This caches the pointer received from the objectManager in the constructor. */ - StorageManagerIF *IPCStore; + StorageManagerIF *IPCStore = nullptr; /** * cached for init @@ -239,17 +602,40 @@ protected: /** * Communication object used for device communication */ - DeviceCommunicationIF *communicationInterface; + DeviceCommunicationIF * communicationInterface = nullptr; /** * Cookie used for communication */ - Cookie *cookie; + CookieIF * comCookie; + + struct DeviceCommandInfo { + bool isExecuting; //!< Indicates if the command is already executing. + uint8_t expectedReplies; //!< Dynamic value to indicate how many replies are expected. Inititated with 0. + MessageQueueId_t sendReplyTo; //!< if this is != NO_COMMANDER, DHB was commanded externally and shall report everything to commander. + }; + using DeviceCommandMap = std::map ; + + /** + * @brief Information about expected replies + * + * This is used to keep track of pending replies + */ + struct DeviceReplyInfo { + uint16_t maxDelayCycles; //!< The maximum number of cycles the handler should wait for a reply to this command. + uint16_t delayCycles; //!< The currently remaining cycles the handler should wait for a reply, 0 means there is no reply expected + size_t replyLen = 0; //!< Expected size of the reply. + bool periodic; //!< if this is !=0, the delayCycles will not be reset to 0 but to maxDelayCycles + DeviceCommandMap::iterator command; //!< The command that expects this reply. + }; + + using DeviceReplyMap = std::map ; + using DeviceReplyIter = DeviceReplyMap::iterator; /** * The MessageQueue used to receive device handler commands and to send replies. */ - MessageQueueIF* commandQueue; + MessageQueueIF* commandQueue = nullptr; /** * this is the datapool variable with the thermal state of the device @@ -280,7 +666,7 @@ protected: */ ReturnValue_t childTransitionFailure; - uint32_t ignoreMissedRepliesCount; //!< Counts if communication channel lost a reply, so some missed replys can be ignored. + uint32_t ignoreMissedRepliesCount = 0; //!< Counts if communication channel lost a reply, so some missed replys can be ignored. FailureIsolationBase* fdirInstance; //!< Pointer to the used FDIR instance. If not provided by child, default class is instantiated. @@ -290,7 +676,7 @@ protected: bool switchOffWasReported; //!< Indicates if SWITCH_WENT_OFF was already thrown. - PeriodicTaskIF* executingTask;//!< Pointer to the task which executes this component, is invalid before setTaskIF was called. + PeriodicTaskIF* executingTask = nullptr;//!< Pointer to the task which executes this component, is invalid before setTaskIF was called. static object_id_t powerSwitcherId; //!< Object which switches power on and off. @@ -317,11 +703,6 @@ protected: void replyReturnvalueToCommand(ReturnValue_t status, uint32_t parameter = 0); - /** - * - - * @param parameter2 additional parameter - */ void replyToCommand(ReturnValue_t status, uint32_t parameter = 0); /** @@ -329,7 +710,8 @@ protected: * * Sets #timeoutStart with every call. * - * Sets #transitionTargetMode if necessary so transitional states can be entered from everywhere without breaking the state machine + * Sets #transitionTargetMode if necessary so transitional states can be + * entered from everywhere without breaking the state machine * (which relies on a correct #transitionTargetMode). * * The submode is left unchanged. @@ -345,41 +727,6 @@ protected: */ void setMode(Mode_t newMode, Submode_t submode); - /** - * This is used to let the child class handle the transition from mode @c _MODE_START_UP to @c MODE_ON - * - * It is only called when the device handler is in mode @c _MODE_START_UP. That means, the device switch(es) are already set to on. - * Device handler commands are read and can be handled by the child class. If the child class handles a command, it should also send - * an reply accordingly. - * If an Command is not handled (ie #DeviceHandlerCommand is not @c CMD_NONE, the base class handles rejecting the command and sends a reply. - * The replies for mode transitions are handled by the base class. - * - * If the device is started and ready for operation, the mode should be set to MODE_ON. It is possible to set the mode to _MODE_TO_ON to - * use the to on transition if available. - * If the power-up fails, the mode should be set to _MODE_POWER_DOWN which will lead to the device being powered off. - * If the device does not change the mode, the mode will be changed to _MODE_POWER_DOWN, after the timeout (from getTransitionDelay()) has passed. - * - * #transitionFailure can be set to a failure code indicating the reason for a failed transition - */ - virtual void doStartUp() = 0; - - /** - * This is used to let the child class handle the transition from mode @c _MODE_SHUT_DOWN to @c _MODE_POWER_DOWN - * - * It is only called when the device handler is in mode @c _MODE_SHUT_DOWN. - * Device handler commands are read and can be handled by the child class. If the child class handles a command, it should also send - * an reply accordingly. - * If an Command is not handled (ie #DeviceHandlerCommand is not @c CMD_NONE, the base class handles rejecting the command and sends a reply. - * The replies for mode transitions are handled by the base class. - * - * If the device ready to be switched off, the mode should be set to _MODE_POWER_DOWN. - * If the device should not be switched off, the mode can be changed to _MODE_TO_ON (or MODE_ON if no transition is needed). - * If the device does not change the mode, the mode will be changed to _MODE_POWER_DOWN, when the timeout (from getTransitionDelay()) has passed. - * - * #transitionFailure can be set to a failure code indicating the reason for a failed transition - */ - virtual void doShutDown() = 0; - /** * Do the transition to the main modes (MODE_ON, MODE_NORMAL and MODE_RAW). * @@ -409,24 +756,6 @@ protected: */ virtual void doTransition(Mode_t modeFrom, Submode_t subModeFrom); - /** - * Get the time needed to transit from modeFrom to modeTo. - * - * Used for the following transitions: - * modeFrom -> modeTo: - * MODE_ON -> [MODE_ON, MODE_NORMAL, MODE_RAW, _MODE_POWER_DOWN] - * MODE_NORMAL -> [MODE_ON, MODE_NORMAL, MODE_RAW, _MODE_POWER_DOWN] - * MODE_RAW -> [MODE_ON, MODE_NORMAL, MODE_RAW, _MODE_POWER_DOWN] - * _MODE_START_UP -> MODE_ON (do not include time to set the switches, the base class got you covered) - * - * The default implementation returns 0; - * - * @param modeFrom - * @param modeTo - * @return time in ms - */ - virtual uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo); - /** * Is the combination of mode and submode valid? * @@ -446,41 +775,8 @@ protected: * * @return The Rmap action to execute in this step */ - virtual RmapAction_t getRmapAction(); - /** - * Build the device command to send for normal mode. - * - * This is only called in @c MODE_NORMAL. If multiple submodes for @c MODE_NORMAL are supported, - * different commands can built returned depending on the submode. - * - * #rawPacket and #rawPacketLen must be set by this method to the packet to be sent. - * - * @param[out] id the device command id that has been built - * @return - * - @c RETURN_OK when a command is to be sent - * - not @c RETURN_OK when no command is to be sent - */ - virtual ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t * id) = 0; - - /** - * Build the device command to send for a transitional mode. - * - * This is only called in @c _MODE_TO_NORMAL, @c _MODE_TO_ON, @c _MODE_TO_RAW, - * @c _MODE_START_UP and @c _MODE_TO_POWER_DOWN. So it is used by doStartUp() and doShutDown() as well as doTransition() - * - * A good idea is to implement a flag indicating a command has to be built and a variable containing the command number to be built - * and filling them in doStartUp(), doShutDown() and doTransition() so no modes have to be checked here. - * - * #rawPacket and #rawPacketLen must be set by this method to the packet to be sent. - * - * @param[out] id the device command id built - * @return - * - @c RETURN_OK when a command is to be sent - * - not @c RETURN_OK when no command is to be sent - */ - virtual ReturnValue_t buildTransitionDeviceCommand( - DeviceCommandId_t * id) = 0; + virtual CommunicationAction_t getComAction(); /** * Build the device command to send for raw mode. @@ -502,80 +798,6 @@ protected: */ virtual ReturnValue_t buildChildRawCommand(); - /** - * Build a device command packet from data supplied by a direct command. - * - * #rawPacket and #rawPacketLen should be set by this method to the packet to be sent. - * - * @param deviceCommand the command to build, already checked against deviceCommandMap - * @param commandData pointer to the data from the direct command - * @param commandDataLen length of commandData - * @return - * - @c RETURN_OK when #rawPacket is valid - * - @c RETURN_FAILED when #rawPacket is invalid and no data should be sent - */ - virtual ReturnValue_t buildCommandFromCommand( - DeviceCommandId_t deviceCommand, const uint8_t * commandData, - size_t commandDataLen) = 0; - - /** - * fill the #deviceCommandMap - * - * called by the initialize() of the base class - * - * This is used to let the base class know which replies are expected. - * There are different scenarios regarding this: - * - "Normal" commands. These are commands, that trigger a direct reply from the device. In this case, the id of the command should be added to the command map - * with a commandData_t where maxDelayCycles is set to the maximum expected number of PST cycles the reply will take. Then, scanForReply returns the id of the command and the base class can handle time-out and missing replies. - * - Periodic, unrequested replies. These are replies that, once enabled, are sent by the device on its own in a defined interval. In this case, the id of the reply or a placeholder id should be added to the deviceCommandMap - * with a commandData_t where maxDelayCycles is set to the maximum expected number of PST cycles between two replies (also a tolerance should be added, as an FDIR message will be generated if it is missed). - * As soon as the replies are enabled, DeviceCommandInfo.periodic must be set to 1, DeviceCommandInfo.delayCycles to DeviceCommandInfo.MaxDelayCycles. From then on, the base class handles the reception. - * Then, scanForReply returns the id of the reply or the placeholder id and the base class will take care of checking that all replies are received and the interval is correct. - * When the replies are disabled, DeviceCommandInfo.periodic must be set to 0, DeviceCommandInfo.delayCycles to 0; - * - Aperiodic, unrequested replies. These are replies that are sent by the device without any preceding command and not in a defined interval. These are not entered in the deviceCommandMap but handled by returning @c APERIODIC_REPLY in scanForReply(). - * - */ - virtual void fillCommandAndReplyMap() = 0; - - /** - * This is a helper method to facilitate inserting entries in the command map. - * @param deviceCommand Identifier of the command to add. - * @param maxDelayCycles The maximum number of delay cycles the command waits until it times out. - * @param periodic Indicates if the command is periodic (i.e. it is sent by the device repeatedly without request) or not. - * Default is aperiodic (0) - * @return RETURN_OK when the command was successfully inserted, COMMAND_MAP_ERROR else. - */ - ReturnValue_t insertInCommandAndReplyMap(DeviceCommandId_t deviceCommand, - uint16_t maxDelayCycles, uint8_t periodic = 0, - bool hasDifferentReplyId = false, DeviceCommandId_t replyId = 0); - /** - * This is a helper method to insert replies in the reply map. - * @param deviceCommand Identifier of the reply to add. - * @param maxDelayCycles The maximum number of delay cycles the reply waits until it times out. - * @param periodic Indicates if the command is periodic (i.e. it is sent by the device repeatedly without request) or not. - * Default is aperiodic (0) - * @return RETURN_OK when the command was successfully inserted, COMMAND_MAP_ERROR else. - */ - ReturnValue_t insertInReplyMap(DeviceCommandId_t deviceCommand, - uint16_t maxDelayCycles, uint8_t periodic = 0); - /** - * A simple command to add a command to the commandList. - * @param deviceCommand The command to add - * @return RETURN_OK if the command was successfully inserted, RETURN_FAILED else. - */ - ReturnValue_t insertInCommandMap(DeviceCommandId_t deviceCommand); - /** - * This is a helper method to facilitate updating entries in the reply map. - * @param deviceCommand Identifier of the reply to update. - * @param delayCycles The current number of delay cycles to wait. As stated in #fillCommandAndCookieMap, to disable periodic commands, this is set to zero. - * @param maxDelayCycles The maximum number of delay cycles the reply waits until it times out. By passing 0 the entry remains untouched. - * @param periodic Indicates if the command is periodic (i.e. it is sent by the device repeatedly without request) or not. - * Default is aperiodic (0). Warning: The setting always overrides the value that was entered in the map. - * @return RETURN_OK when the reply was successfully updated, COMMAND_MAP_ERROR else. - */ - ReturnValue_t updateReplyMapEntry(DeviceCommandId_t deviceReply, - uint16_t delayCycles, uint16_t maxDelayCycles, - uint8_t periodic = 0); /** * Returns the delay cycle count of a reply. * A count != 0 indicates that the command is already executed. @@ -583,48 +805,6 @@ protected: * @return The current delay count. If the command does not exist (should never happen) it returns 0. */ uint8_t getReplyDelayCycles(DeviceCommandId_t deviceCommand); - /** - * Scans a buffer for a valid reply. - * - * This is used by the base class to check the data received from the RMAP stack for valid packets. - * It only checks if a valid packet starts at @c start. - * It also only checks the structural validy of the packet, eg checksums lengths and protocol data. No - * information check is done, eg range checks etc. - * - * Errors should be reported directly, the base class does NOT report any errors based on the return - * value of this function. - * - * @param start start of data - * @param len length of data - * @param[out] foundId the id of the packet starting at @c start - * @param[out] foundLen length of the packet found - * @return - * - @c RETURN_OK a valid packet was found at @c start, @c foundLen is valid - * - @c NO_VALID_REPLY no reply could be found starting at @c start, implies @c foundLen is not valid, base class will call scanForReply() again with ++start - * - @c INVALID_REPLY a packet was found but it is invalid, eg checksum error, implies @c foundLen is valid, can be used to skip some bytes - * - @c TOO_SHORT @c len is too short for any valid packet - * - @c APERIODIC_REPLY if a valid reply is received that has not been requested by a command, but should be handled anyway (@see also fillCommandAndCookieMap() ) - */ - virtual ReturnValue_t scanForReply(const uint8_t *start, uint32_t len, - DeviceCommandId_t *foundId, uint32_t *foundLen) = 0; - - /** - * Interpret a reply from the device. - * - * This is called after scanForReply() found a valid packet, it can be assumed that the length and structure is valid. - * This routine extracts the data from the packet into a DataSet and then calls handleDeviceTM(), which either sends - * a TM packet or stores the data in the DataPool depending on whether the it was an external command. - * No packet length is given, as it should be defined implicitly by the id. - * - * @param id the id found by scanForReply() - * @param packet - * @param commander the one who initiated the command, is 0 if not external commanded - * @return - * - @c RETURN_OK when the reply was interpreted. - * - @c RETURN_FAILED when the reply could not be interpreted, eg. logical errors or range violations occurred - */ - virtual ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, - const uint8_t *packet) = 0; /** * Construct a command reply containing a raw reply. @@ -649,33 +829,11 @@ protected: */ void replyRawReplyIfnotWiretapped(const uint8_t *data, size_t len); - /** - * Return the switches connected to the device. - * - * The default implementation returns one switch set in the ctor. - * - * - * @param[out] switches pointer to an array of switches - * @param[out] numberOfSwitches length of returned array - * @return - * - @c RETURN_OK if the parameters were set - * - @c RETURN_FAILED if no switches exist - */ - virtual ReturnValue_t getSwitches(const uint8_t **switches, - uint8_t *numberOfSwitches); - /** * notify child about mode change */ virtual void modeChanged(void); - struct DeviceCommandInfo { - bool isExecuting; //!< Indicates if the command is already executing. - uint8_t expectedReplies; //!< Dynamic value to indicate how many replies are expected. - MessageQueueId_t sendReplyTo; //!< if this is != NO_COMMANDER, DHB was commanded externally and shall report everything to commander. - }; - - typedef std::map DeviceCommandMap; /** * Enable the reply checking for a command * @@ -686,16 +844,16 @@ protected: * When found, copies maxDelayCycles to delayCycles in the reply information and sets the command to * expect one reply. * - * Can be overwritten by the child, if a command activates multiple replies or replyId differs from - * commandId. + * Can be overwritten by the child, if a command activates multiple replies + * or replyId differs from commandId. * Notes for child implementations: * - If the command was not found in the reply map, NO_REPLY_EXPECTED MUST be returned. * - A failure code may be returned if something went fundamentally wrong. * * @param deviceCommand * @return - RETURN_OK if a reply was activated. - * - NO_REPLY_EXPECTED if there was no reply found. This is not an error case as many commands - * do not expect a reply. + * - NO_REPLY_EXPECTED if there was no reply found. This is not an + * error case as many commands do not expect a reply. */ virtual ReturnValue_t enableReplyInReplyMap(DeviceCommandMap::iterator cmd, uint8_t expectedReplies = 1, bool useAlternateId = false, @@ -794,22 +952,6 @@ protected: bool commandIsExecuting(DeviceCommandId_t commandId); - /** - * Information about expected replies - * - * This is used to keep track of pending replies - */ - struct DeviceReplyInfo { - uint16_t maxDelayCycles; //!< The maximum number of cycles the handler should wait for a reply to this command. - uint16_t delayCycles; //!< The currently remaining cycles the handler should wait for a reply, 0 means there is no reply expected - uint8_t periodic; //!< if this is !=0, the delayCycles will not be reset to 0 but to maxDelayCycles - DeviceCommandMap::iterator command; //!< The command that expects this reply. - }; - - /** - * Definition for the important reply Map. - */ - typedef std::map DeviceReplyMap; /** * This map is used to check and track correct reception of all replies. * @@ -861,17 +1003,12 @@ private: */ CookieInfo cookieInfo; - /** - * cached from ctor for initialize() - */ - const uint32_t ioBoardAddress; - /** * Used for timing out mode transitions. * * Set when setMode() is called. */ - uint32_t timeoutStart; + uint32_t timeoutStart = 0; /** * Delay for the current mode transition, used for time out diff --git a/devicehandlers/DeviceHandlerFailureIsolation.cpp b/devicehandlers/DeviceHandlerFailureIsolation.cpp index 65c40219a..497d64692 100644 --- a/devicehandlers/DeviceHandlerFailureIsolation.cpp +++ b/devicehandlers/DeviceHandlerFailureIsolation.cpp @@ -1,9 +1,9 @@ -#include -#include -#include -#include -#include -#include +#include "DeviceHandlerBase.h" +#include "DeviceHandlerFailureIsolation.h" +#include "../health/HealthTableIF.h" +#include "../power/Fuse.h" +#include "../serviceinterface/ServiceInterfaceStream.h" +#include "../thermal/ThermalComponentIF.h" object_id_t DeviceHandlerFailureIsolation::powerConfirmationId = 0; diff --git a/devicehandlers/DeviceHandlerFailureIsolation.h b/devicehandlers/DeviceHandlerFailureIsolation.h index 91f6ef64a..aa43b762d 100644 --- a/devicehandlers/DeviceHandlerFailureIsolation.h +++ b/devicehandlers/DeviceHandlerFailureIsolation.h @@ -1,8 +1,8 @@ #ifndef FRAMEWORK_DEVICEHANDLERS_DEVICEHANDLERFAILUREISOLATION_H_ #define FRAMEWORK_DEVICEHANDLERS_DEVICEHANDLERFAILUREISOLATION_H_ -#include -#include +#include "../fdir/FaultCounter.h" +#include "../fdir/FailureIsolationBase.h" namespace Factory{ void setStaticFrameworkObjectIds(); } diff --git a/devicehandlers/DeviceHandlerIF.h b/devicehandlers/DeviceHandlerIF.h index fe0ee8e8b..52a3be4d0 100644 --- a/devicehandlers/DeviceHandlerIF.h +++ b/devicehandlers/DeviceHandlerIF.h @@ -1,14 +1,15 @@ #ifndef DEVICEHANDLERIF_H_ #define DEVICEHANDLERIF_H_ -#include -#include -#include -#include -#include +#include "../action/HasActionsIF.h" +#include "DeviceHandlerMessage.h" +#include "../events/Event.h" +#include "../modes/HasModesIF.h" +#include "../ipc/MessageQueueSenderIF.h" /** - * This is the Interface used to communicate with a device handler. + * @brief This is the Interface used to communicate with a device handler. + * @details Includes all expected return values, events and modes. * */ class DeviceHandlerIF { @@ -22,93 +23,127 @@ public: * * @details The mode of the device handler must not be confused with the mode the device is in. * The mode of the device itself is transparent to the user but related to the mode of the handler. + * MODE_ON and MODE_OFF are included in hasModesIF.h */ -// MODE_ON = 0, //!< 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 -// MODE_OFF = 1, //!< The device is powered off. The only command accepted in this mode is a mode change to on. - static const Mode_t MODE_NORMAL = 2; //!< The device is powered on and the device handler periodically sends commands. The commands to be sent are selected by the handler according to the submode. - static const Mode_t MODE_RAW = 3; //!< The device is powered on and ready to perform operations. In this mode, raw commands can be sent. The device handler will send all replies received from the command back to the commanding object. - static const Mode_t MODE_ERROR_ON = 4; //!4< The device is shut down but the switch could not be turned off, so the device still is powered. In this mode, only a mode change to @c MODE_OFF can be commanded, which tries to switch off the device again. - static const Mode_t _MODE_START_UP = TRANSITION_MODE_CHILD_ACTION_MASK | 5; //!< This is a transitional state which can not be commanded. The device handler performs all commands to get the device in a state ready to perform commands. When this is completed, the mode changes to @c MODE_ON. - static const Mode_t _MODE_SHUT_DOWN = TRANSITION_MODE_CHILD_ACTION_MASK | 6; //!< This is a transitional state which can not be commanded. The device handler performs all actions and commands to get the device shut down. When the device is off, the mode changes to @c MODE_OFF. - static const Mode_t _MODE_TO_ON = TRANSITION_MODE_CHILD_ACTION_MASK | HasModesIF::MODE_ON; - static const Mode_t _MODE_TO_RAW = TRANSITION_MODE_CHILD_ACTION_MASK | MODE_RAW; - static const Mode_t _MODE_TO_NORMAL = TRANSITION_MODE_CHILD_ACTION_MASK | MODE_NORMAL; - static const Mode_t _MODE_POWER_DOWN = TRANSITION_MODE_BASE_ACTION_MASK | 1; //!< This is a transitional state which can not be commanded. The device is shut down and ready to be switched off. After the command to set the switch off has been sent, the mode changes to @c MODE_WAIT_OFF - static const Mode_t _MODE_POWER_ON = TRANSITION_MODE_BASE_ACTION_MASK | 2; //!< This is a transitional state which can not be commanded. The device will be switched on in this state. After the command to set the switch on has been sent, the mode changes to @c MODE_WAIT_ON - static const Mode_t _MODE_WAIT_OFF = TRANSITION_MODE_BASE_ACTION_MASK | 3; //!< This is a transitional state which can not be commanded. The switch has been commanded off and the handler waits for it to be off. When the switch is off, the mode changes to @c MODE_OFF. - static const Mode_t _MODE_WAIT_ON = TRANSITION_MODE_BASE_ACTION_MASK | 4; //!< This is a transitional state which can not be commanded. The switch has been commanded on and the handler waits for it to be on. When the switch is on, the mode changes to @c MODE_TO_ON. - static const Mode_t _MODE_SWITCH_IS_OFF = TRANSITION_MODE_BASE_ACTION_MASK | 5; //!< This is a transitional state which can not be commanded. The switch has been commanded off and is off now. This state is only to do an RMAP cycle once more where the doSendRead() function will set the mode to MODE_OFF. The reason to do this is to get rid of stuck packets in the IO Board - static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CDH; - static const Event DEVICE_BUILDING_COMMAND_FAILED = MAKE_EVENT(0, SEVERITY::LOW); - static const Event DEVICE_SENDING_COMMAND_FAILED = MAKE_EVENT(1, SEVERITY::LOW); - static const Event DEVICE_REQUESTING_REPLY_FAILED = MAKE_EVENT(2, SEVERITY::LOW); - static const Event DEVICE_READING_REPLY_FAILED = MAKE_EVENT(3, SEVERITY::LOW); - static const Event DEVICE_INTERPRETING_REPLY_FAILED = MAKE_EVENT(4, SEVERITY::LOW); - static const Event DEVICE_MISSED_REPLY = MAKE_EVENT(5, SEVERITY::LOW); - static const Event DEVICE_UNKNOWN_REPLY = MAKE_EVENT(6, SEVERITY::LOW); - static const Event DEVICE_UNREQUESTED_REPLY = MAKE_EVENT(7, SEVERITY::LOW); - static const Event INVALID_DEVICE_COMMAND = MAKE_EVENT(8, SEVERITY::LOW); //!< Indicates a SW bug in child class. - static const Event MONITORING_LIMIT_EXCEEDED = MAKE_EVENT(9, SEVERITY::LOW); - static const Event MONITORING_AMBIGUOUS = MAKE_EVENT(10, SEVERITY::HIGH); + // MODE_ON = 0, //!< 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 + // MODE_OFF = 1, //!< The device is powered off. The only command accepted in this mode is a mode change to on. + //! The device is powered on and the device handler periodically sends + //! commands. The commands to be sent are selected by the handler + //! according to the submode. + static const Mode_t MODE_NORMAL = 2; + //! The device is powered on and ready to perform operations. In this mode, + //! raw commands can be sent. The device handler will send all replies + //! received from the command back to the commanding object. + static const Mode_t MODE_RAW = 3; + //! The device is shut down but the switch could not be turned off, so the + //! device still is powered. In this mode, only a mode change to @c MODE_OFF + //! can be commanded, which tries to switch off the device again. + static const Mode_t MODE_ERROR_ON = 4; + //! This is a transitional state which can not be commanded. The device + //! handler performs all commands to get the device in a state ready to + //! perform commands. When this is completed, the mode changes to @c MODE_ON. + static const Mode_t _MODE_START_UP = TRANSITION_MODE_CHILD_ACTION_MASK | 5; + //! This is a transitional state which can not be commanded. + //! The device handler performs all actions and commands to get the device + //! shut down. When the device is off, the mode changes to @c MODE_OFF. + static const Mode_t _MODE_SHUT_DOWN = TRANSITION_MODE_CHILD_ACTION_MASK | 6; + //! It is possible to set the mode to _MODE_TO_ON to use the to on + //! transition if available. + static const Mode_t _MODE_TO_ON = TRANSITION_MODE_CHILD_ACTION_MASK | HasModesIF::MODE_ON; + //! It is possible to set the mode to _MODE_TO_RAW to use the to raw + //! transition if available. + static const Mode_t _MODE_TO_RAW = TRANSITION_MODE_CHILD_ACTION_MASK | MODE_RAW; + //! It is possible to set the mode to _MODE_TO_NORMAL to use the to normal + //! transition if available. + static const Mode_t _MODE_TO_NORMAL = TRANSITION_MODE_CHILD_ACTION_MASK | MODE_NORMAL; + //! This is a transitional state which can not be commanded. + //! The device is shut down and ready to be switched off. + //! After the command to set the switch off has been sent, + //! the mode changes to @c MODE_WAIT_OFF + static const Mode_t _MODE_POWER_DOWN = TRANSITION_MODE_BASE_ACTION_MASK | 1; + //! This is a transitional state which can not be commanded. The device + //! will be switched on in this state. After the command to set the switch + //! on has been sent, the mode changes to @c MODE_WAIT_ON. + static const Mode_t _MODE_POWER_ON = TRANSITION_MODE_BASE_ACTION_MASK | 2; + //! This is a transitional state which can not be commanded. The switch has + //! been commanded off and the handler waits for it to be off. + //! When the switch is off, the mode changes to @c MODE_OFF. + static const Mode_t _MODE_WAIT_OFF = TRANSITION_MODE_BASE_ACTION_MASK | 3; + //! This is a transitional state which can not be commanded. The switch + //! has been commanded on and the handler waits for it to be on. + //! When the switch is on, the mode changes to @c MODE_TO_ON. + static const Mode_t _MODE_WAIT_ON = TRANSITION_MODE_BASE_ACTION_MASK | 4; + //! This is a transitional state which can not be commanded. The switch has + //! been commanded off and is off now. This state is only to do an RMAP + //! cycle once more where the doSendRead() function will set the mode to + //! MODE_OFF. The reason to do this is to get rid of stuck packets in the IO Board. + static const Mode_t _MODE_SWITCH_IS_OFF = TRANSITION_MODE_BASE_ACTION_MASK | 5; - static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_IF; - static const ReturnValue_t NO_COMMAND_DATA = MAKE_RETURN_CODE(0xA0); - static const ReturnValue_t COMMAND_NOT_SUPPORTED = MAKE_RETURN_CODE(0xA1); - static const ReturnValue_t COMMAND_ALREADY_SENT = MAKE_RETURN_CODE(0xA2); - static const ReturnValue_t COMMAND_WAS_NOT_SENT = MAKE_RETURN_CODE(0xA3); - static const ReturnValue_t CANT_SWITCH_IOBOARD = MAKE_RETURN_CODE(0xA4); - static const ReturnValue_t WRONG_MODE_FOR_COMMAND = MAKE_RETURN_CODE(0xA5); - static const ReturnValue_t TIMEOUT = MAKE_RETURN_CODE(0xA6); - static const ReturnValue_t BUSY = MAKE_RETURN_CODE(0xA7); - static const ReturnValue_t NO_REPLY_EXPECTED = MAKE_RETURN_CODE(0xA8); //!< Used to indicate that this is a command-only command. - static const ReturnValue_t NON_OP_TEMPERATURE = MAKE_RETURN_CODE(0xA9); - static const ReturnValue_t COMMAND_NOT_IMPLEMENTED = MAKE_RETURN_CODE(0xAA); + static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CDH; + static const Event DEVICE_BUILDING_COMMAND_FAILED = MAKE_EVENT(0, SEVERITY::LOW); + static const Event DEVICE_SENDING_COMMAND_FAILED = MAKE_EVENT(1, SEVERITY::LOW); + static const Event DEVICE_REQUESTING_REPLY_FAILED = MAKE_EVENT(2, SEVERITY::LOW); + static const Event DEVICE_READING_REPLY_FAILED = MAKE_EVENT(3, SEVERITY::LOW); + static const Event DEVICE_INTERPRETING_REPLY_FAILED = MAKE_EVENT(4, SEVERITY::LOW); + static const Event DEVICE_MISSED_REPLY = MAKE_EVENT(5, SEVERITY::LOW); + static const Event DEVICE_UNKNOWN_REPLY = MAKE_EVENT(6, SEVERITY::LOW); + static const Event DEVICE_UNREQUESTED_REPLY = MAKE_EVENT(7, SEVERITY::LOW); + static const Event INVALID_DEVICE_COMMAND = MAKE_EVENT(8, SEVERITY::LOW); //!< Indicates a SW bug in child class. + static const Event MONITORING_LIMIT_EXCEEDED = MAKE_EVENT(9, SEVERITY::LOW); + static const Event MONITORING_AMBIGUOUS = MAKE_EVENT(10, SEVERITY::HIGH); - //standard codes used in scan for reply - // static const ReturnValue_t TOO_SHORT = MAKE_RETURN_CODE(0xB1); - static const ReturnValue_t CHECKSUM_ERROR = MAKE_RETURN_CODE(0xB2); - static const ReturnValue_t LENGTH_MISSMATCH = MAKE_RETURN_CODE(0xB3); - static const ReturnValue_t INVALID_DATA = MAKE_RETURN_CODE(0xB4); - static const ReturnValue_t PROTOCOL_ERROR = MAKE_RETURN_CODE(0xB5); + static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_IF; - //standard codes used in interpret device reply - static const ReturnValue_t DEVICE_DID_NOT_EXECUTE = MAKE_RETURN_CODE(0xC1); //the device reported, that it did not execute the command - static const ReturnValue_t DEVICE_REPORTED_ERROR = MAKE_RETURN_CODE(0xC2); - static const ReturnValue_t UNKNOW_DEVICE_REPLY = MAKE_RETURN_CODE(0xC3); //the deviceCommandId reported by scanforReply is unknown - static const ReturnValue_t DEVICE_REPLY_INVALID = MAKE_RETURN_CODE(0xC4); //syntax etc is correct but still not ok, eg parameters where none are expected + // Standard codes used when building commands. + static const ReturnValue_t NO_COMMAND_DATA = MAKE_RETURN_CODE(0xA0); //!< If the command size is 0. Checked in DHB + static const ReturnValue_t COMMAND_NOT_SUPPORTED = MAKE_RETURN_CODE(0xA1); //!< Command ID not in commandMap. Checked in DHB + static const ReturnValue_t COMMAND_ALREADY_SENT = MAKE_RETURN_CODE(0xA2); //!< Command was already executed. Checked in DHB + static const ReturnValue_t COMMAND_WAS_NOT_SENT = MAKE_RETURN_CODE(0xA3); + static const ReturnValue_t CANT_SWITCH_ADDRESS = MAKE_RETURN_CODE(0xA4); + static const ReturnValue_t WRONG_MODE_FOR_COMMAND = MAKE_RETURN_CODE(0xA5); + static const ReturnValue_t TIMEOUT = MAKE_RETURN_CODE(0xA6); + static const ReturnValue_t BUSY = MAKE_RETURN_CODE(0xA7); + static const ReturnValue_t NO_REPLY_EXPECTED = MAKE_RETURN_CODE(0xA8); //!< Used to indicate that this is a command-only command. + static const ReturnValue_t NON_OP_TEMPERATURE = MAKE_RETURN_CODE(0xA9); + static const ReturnValue_t COMMAND_NOT_IMPLEMENTED = MAKE_RETURN_CODE(0xAA); - //Standard codes used in buildCommandFromCommand - static const ReturnValue_t INVALID_COMMAND_PARAMETER = MAKE_RETURN_CODE( - 0xD0); - static const ReturnValue_t INVALID_NUMBER_OR_LENGTH_OF_PARAMETERS = - MAKE_RETURN_CODE(0xD1); + // Standard codes used in scanForReply + static const ReturnValue_t CHECKSUM_ERROR = MAKE_RETURN_CODE(0xB0); + static const ReturnValue_t LENGTH_MISSMATCH = MAKE_RETURN_CODE(0xB1); + static const ReturnValue_t INVALID_DATA = MAKE_RETURN_CODE(0xB2); + static const ReturnValue_t PROTOCOL_ERROR = MAKE_RETURN_CODE(0xB3); + + // Standard codes used in interpretDeviceReply + static const ReturnValue_t DEVICE_DID_NOT_EXECUTE = MAKE_RETURN_CODE(0xC0); //the device reported, that it did not execute the command + static const ReturnValue_t DEVICE_REPORTED_ERROR = MAKE_RETURN_CODE(0xC1); + static const ReturnValue_t UNKNOW_DEVICE_REPLY = MAKE_RETURN_CODE(0xC2); //the deviceCommandId reported by scanforReply is unknown + static const ReturnValue_t DEVICE_REPLY_INVALID = MAKE_RETURN_CODE(0xC3); //syntax etc is correct but still not ok, eg parameters where none are expected + + // Standard codes used in buildCommandFromCommand + static const ReturnValue_t INVALID_COMMAND_PARAMETER = MAKE_RETURN_CODE(0xD0); + static const ReturnValue_t INVALID_NUMBER_OR_LENGTH_OF_PARAMETERS = MAKE_RETURN_CODE(0xD1); + + /** + * Communication action that will be executed. + * + * This is used by the child class to tell the base class what to do. + */ + enum CommunicationAction_t: uint8_t { + SEND_WRITE,//!< Send write + GET_WRITE, //!< Get write + SEND_READ, //!< Send read + GET_READ, //!< Get read + NOTHING //!< Do nothing. + }; - /** - * RMAP Action that will be executed. - * - * This is used by the child class to tell the base class what to do. - */ - enum RmapAction_t { - SEND_WRITE,//!< RMAP send write - GET_WRITE, //!< RMAP get write - SEND_READ, //!< RMAP send read - GET_READ, //!< RMAP get read - NOTHING //!< Do nothing. - }; /** * Default Destructor */ - virtual ~DeviceHandlerIF() { - - } + virtual ~DeviceHandlerIF() {} /** * This MessageQueue is used to command the device handler. - * - * To command a device handler, a DeviceHandlerCommandMessage can be sent to this Queue. - * The handler replies with a DeviceHandlerCommandMessage containing the DeviceHandlerCommand_t reply. - * * @return the id of the MessageQueue */ virtual MessageQueueId_t getCommandQueue() const = 0; diff --git a/devicehandlers/DeviceHandlerMessage.cpp b/devicehandlers/DeviceHandlerMessage.cpp index 58a6d3126..564fae213 100644 --- a/devicehandlers/DeviceHandlerMessage.cpp +++ b/devicehandlers/DeviceHandlerMessage.cpp @@ -1,6 +1,6 @@ -#include -#include -#include +#include "../objectmanager/ObjectManagerIF.h" +#include "DeviceHandlerMessage.h" +#include "../objectmanager/ObjectManagerIF.h" DeviceHandlerMessage::DeviceHandlerMessage() { } diff --git a/devicehandlers/DeviceHandlerMessage.h b/devicehandlers/DeviceHandlerMessage.h index 26f3b4ed9..8d1c94f41 100644 --- a/devicehandlers/DeviceHandlerMessage.h +++ b/devicehandlers/DeviceHandlerMessage.h @@ -1,10 +1,10 @@ #ifndef DEVICEHANDLERMESSAGE_H_ #define DEVICEHANDLERMESSAGE_H_ -#include -#include -#include -#include +#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. /** diff --git a/devicehandlers/DeviceTmReportingWrapper.cpp b/devicehandlers/DeviceTmReportingWrapper.cpp index 2c9e820fe..84f926f06 100644 --- a/devicehandlers/DeviceTmReportingWrapper.cpp +++ b/devicehandlers/DeviceTmReportingWrapper.cpp @@ -1,6 +1,6 @@ -#include -#include -#include +#include "../serialize/SerializeAdapter.h" +#include "DeviceTmReportingWrapper.h" +#include "../serialize/SerializeAdapter.h" DeviceTmReportingWrapper::DeviceTmReportingWrapper(object_id_t objectId, ActionId_t actionId, SerializeIF* data) : @@ -12,35 +12,35 @@ DeviceTmReportingWrapper::~DeviceTmReportingWrapper() { } ReturnValue_t DeviceTmReportingWrapper::serialize(uint8_t** buffer, - uint32_t* size, const uint32_t max_size, bool bigEndian) const { - ReturnValue_t result = SerializeAdapter::serialize(&objectId, - buffer, size, max_size, bigEndian); + size_t* size, size_t maxSize, Endianness streamEndianness) const { + ReturnValue_t result = SerializeAdapter::serialize(&objectId, + buffer, size, maxSize, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::serialize(&actionId, buffer, - size, max_size, bigEndian); + result = SerializeAdapter::serialize(&actionId, buffer, + size, maxSize, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - return data->serialize(buffer, size, max_size, bigEndian); + return data->serialize(buffer, size, maxSize, streamEndianness); } -uint32_t DeviceTmReportingWrapper::getSerializedSize() const { +size_t DeviceTmReportingWrapper::getSerializedSize() const { return sizeof(objectId) + sizeof(ActionId_t) + data->getSerializedSize(); } ReturnValue_t DeviceTmReportingWrapper::deSerialize(const uint8_t** buffer, - int32_t* size, bool bigEndian) { - ReturnValue_t result = SerializeAdapter::deSerialize(&objectId, - buffer, size, bigEndian); + size_t* size, Endianness streamEndianness) { + ReturnValue_t result = SerializeAdapter::deSerialize(&objectId, + buffer, size, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::deSerialize(&actionId, buffer, - size, bigEndian); + result = SerializeAdapter::deSerialize(&actionId, buffer, + size, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - return data->deSerialize(buffer, size, bigEndian); + return data->deSerialize(buffer, size, streamEndianness); } diff --git a/devicehandlers/DeviceTmReportingWrapper.h b/devicehandlers/DeviceTmReportingWrapper.h index 1cd9470d8..a14c4261d 100644 --- a/devicehandlers/DeviceTmReportingWrapper.h +++ b/devicehandlers/DeviceTmReportingWrapper.h @@ -1,9 +1,9 @@ #ifndef DEVICETMREPORTINGWRAPPER_H_ #define DEVICETMREPORTINGWRAPPER_H_ -#include -#include -#include +#include "../action/HasActionsIF.h" +#include "../objectmanager/SystemObjectIF.h" +#include "../serialize/SerializeIF.h" class DeviceTmReportingWrapper: public SerializeIF { public: @@ -11,13 +11,13 @@ public: SerializeIF *data); virtual ~DeviceTmReportingWrapper(); - virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const; + virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const override; - virtual uint32_t getSerializedSize() const; + virtual size_t getSerializedSize() const override; - virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian); + virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) override; private: object_id_t objectId; ActionId_t actionId; diff --git a/devicehandlers/FixedSequenceSlot.cpp b/devicehandlers/FixedSequenceSlot.cpp index 29e7ee6ab..667aba1d2 100644 --- a/devicehandlers/FixedSequenceSlot.cpp +++ b/devicehandlers/FixedSequenceSlot.cpp @@ -5,8 +5,8 @@ * @author baetz */ -#include -#include +#include "FixedSequenceSlot.h" +#include "../objectmanager/SystemObjectIF.h" #include FixedSequenceSlot::FixedSequenceSlot(object_id_t handlerId, uint32_t setTime, @@ -16,6 +16,5 @@ FixedSequenceSlot::FixedSequenceSlot(object_id_t handlerId, uint32_t setTime, handler->setTaskIF(executingTask); } -FixedSequenceSlot::~FixedSequenceSlot() { -} +FixedSequenceSlot::~FixedSequenceSlot() {} diff --git a/devicehandlers/FixedSequenceSlot.h b/devicehandlers/FixedSequenceSlot.h index 5aff0f4f3..735049550 100644 --- a/devicehandlers/FixedSequenceSlot.h +++ b/devicehandlers/FixedSequenceSlot.h @@ -8,40 +8,52 @@ #ifndef FIXEDSEQUENCESLOT_H_ #define FIXEDSEQUENCESLOT_H_ -#include -#include +#include "../objectmanager/ObjectManagerIF.h" +#include "../tasks/ExecutableObjectIF.h" class PeriodicTaskIF; /** - * \brief This class is the representation of a single polling sequence table entry. + * @brief This class is the representation of a single polling sequence table entry. * - * \details The PollingSlot class is the representation of a single polling sequence table entry. + * @details The PollingSlot class is the representation of a single polling + * sequence table entry. */ class FixedSequenceSlot { public: - FixedSequenceSlot( object_id_t handlerId, uint32_t setTimeMs, int8_t setSequenceId, PeriodicTaskIF* executingTask ); + FixedSequenceSlot( object_id_t handlerId, uint32_t setTimeMs, + int8_t setSequenceId, PeriodicTaskIF* executingTask ); virtual ~FixedSequenceSlot(); /** - * \brief \c handler identifies which device handler object is executed in this slot. + * @brief Handler identifies which device handler object is executed in this slot. */ ExecutableObjectIF* handler; /** - * \brief This attribute defines when a device handler object is executed. + * @brief This attribute defines when a device handler object is executed. * - * \details The pollingTime attribute identifies the time the handler is executed in ms. It must be - * smaller than the period length of the polling sequence, what is ensured by automated calculation - * from a database. + * @details The pollingTime attribute identifies the time the handler is executed in ms. + * It must be smaller than the period length of the polling sequence. */ uint32_t pollingTimeMs; /** - * \brief This value defines the type of device communication. + * @brief This value defines the type of device communication. * - * \details The state of this value decides what communication routine is called in the PST executable or the device handler object. + * @details The state of this value decides what communication routine is + * called in the PST executable or the device handler object. */ uint8_t opcode; + + /** + * @brief Operator overload for the comparison operator to + * allow sorting by polling time. + * @param fixedSequenceSlot + * @return + */ + bool operator <(const FixedSequenceSlot & fixedSequenceSlot) const { + return pollingTimeMs < fixedSequenceSlot.pollingTimeMs; + } }; diff --git a/devicehandlers/FixedSlotSequence.cpp b/devicehandlers/FixedSlotSequence.cpp index 2fa13faef..38d4dcea6 100644 --- a/devicehandlers/FixedSlotSequence.cpp +++ b/devicehandlers/FixedSlotSequence.cpp @@ -1,5 +1,5 @@ -#include -#include +#include "FixedSlotSequence.h" +#include "../serviceinterface/ServiceInterfaceStream.h" FixedSlotSequence::FixedSlotSequence(uint32_t setLengthMs) : lengthMs(setLengthMs) { @@ -7,17 +7,12 @@ FixedSlotSequence::FixedSlotSequence(uint32_t setLengthMs) : } FixedSlotSequence::~FixedSlotSequence() { - std::list::iterator slotIt; - //Iterate through slotList and delete all entries. - slotIt = this->slotList.begin(); - while (slotIt != this->slotList.end()) { - delete (*slotIt); - slotIt++; - } + // Call the destructor on each list entry. + slotList.clear(); } void FixedSlotSequence::executeAndAdvance() { - (*this->current)->handler->performOperation((*this->current)->opcode); + current->handler->performOperation(current->opcode); // if (returnValue != RETURN_OK) { // this->sendErrorMessage( returnValue ); // } @@ -31,53 +26,50 @@ void FixedSlotSequence::executeAndAdvance() { uint32_t FixedSlotSequence::getIntervalToNextSlotMs() { uint32_t oldTime; - std::list::iterator it; - it = current; + SlotListIter slotListIter = current; // Get the pollingTimeMs of the current slot object. - oldTime = (*it)->pollingTimeMs; + oldTime = slotListIter->pollingTimeMs; // Advance to the next object. - it++; + slotListIter++; // Find the next interval which is not 0. - while (it != slotList.end()) { - if (oldTime != (*it)->pollingTimeMs) { - return (*it)->pollingTimeMs - oldTime; + while (slotListIter != slotList.end()) { + if (oldTime != slotListIter->pollingTimeMs) { + return slotListIter->pollingTimeMs - oldTime; } else { - it++; + slotListIter++; } } // If the list end is reached (this is definitely an interval != 0), // the interval is calculated by subtracting the remaining time of the PST // and adding the start time of the first handler in the list. - it = slotList.begin(); - return lengthMs - oldTime + (*it)->pollingTimeMs; + slotListIter = slotList.begin(); + return lengthMs - oldTime + slotListIter->pollingTimeMs; } uint32_t FixedSlotSequence::getIntervalToPreviousSlotMs() { uint32_t currentTime; - std::list::iterator it; - it = current; + SlotListIter slotListIter = current; // Get the pollingTimeMs of the current slot object. - currentTime = (*it)->pollingTimeMs; + currentTime = slotListIter->pollingTimeMs; //if it is the first slot, calculate difference to last slot - if (it == slotList.begin()){ - return lengthMs - (*(--slotList.end()))->pollingTimeMs + currentTime; + if (slotListIter == slotList.begin()){ + return lengthMs - (--slotList.end())->pollingTimeMs + currentTime; } // get previous slot - it--; + slotListIter--; - return currentTime - (*it)->pollingTimeMs; + return currentTime - slotListIter->pollingTimeMs; } bool FixedSlotSequence::slotFollowsImmediately() { - uint32_t currentTime = (*current)->pollingTimeMs; - std::list::iterator it; - it = this->current; + uint32_t currentTime = current->pollingTimeMs; + SlotListIter fixedSequenceIter = this->current; // Get the pollingTimeMs of the current slot object. - if (it == slotList.begin()) + if (fixedSequenceIter == slotList.begin()) return false; - it--; - if ((*it)->pollingTimeMs == currentTime) { + fixedSequenceIter--; + if (fixedSequenceIter->pollingTimeMs == currentTime) { return true; } else { return false; @@ -93,26 +85,30 @@ ReturnValue_t FixedSlotSequence::checkSequence() const { sif::error << "Fixed Slot Sequence: Slot list is empty!" << std::endl; return HasReturnvaluesIF::RETURN_FAILED; } + auto slotIt = slotList.begin(); uint32_t count = 0; uint32_t time = 0; while (slotIt != slotList.end()) { - if ((*slotIt)->handler == NULL) { + if (slotIt->handler == nullptr) { sif::error << "FixedSlotSequene::initialize: ObjectId does not exist!" << std::endl; count++; - } else if ((*slotIt)->pollingTimeMs < time) { + } else if (slotIt->pollingTimeMs < time) { sif::error << "FixedSlotSequence::initialize: Time: " - << (*slotIt)->pollingTimeMs + << slotIt->pollingTimeMs << " is smaller than previous with " << time << std::endl; count++; } else { - //All ok, print slot. -// (*slotIt)->print(); + // All ok, print slot. + //info << "Current slot polling time: " << std::endl; + //info << std::dec << slotIt->pollingTimeMs << std::endl; } - time = (*slotIt)->pollingTimeMs; + time = slotIt->pollingTimeMs; slotIt++; } + //info << "Number of elements in slot list: " + // << slotList.size() << std::endl; if (count > 0) { return HasReturnvaluesIF::RETURN_FAILED; } @@ -121,8 +117,7 @@ ReturnValue_t FixedSlotSequence::checkSequence() const { void FixedSlotSequence::addSlot(object_id_t componentId, uint32_t slotTimeMs, int8_t executionStep, PeriodicTaskIF* executingTask) { - this->slotList.push_back( - new FixedSequenceSlot(componentId, slotTimeMs, executionStep, - executingTask)); + this->slotList.insert(FixedSequenceSlot(componentId, slotTimeMs, executionStep, + executingTask)); this->current = slotList.begin(); } diff --git a/devicehandlers/FixedSlotSequence.h b/devicehandlers/FixedSlotSequence.h index 64c68aeae..be6dc2d1f 100644 --- a/devicehandlers/FixedSlotSequence.h +++ b/devicehandlers/FixedSlotSequence.h @@ -1,9 +1,9 @@ -#ifndef FIXEDSLOTSEQUENCE_H_ -#define FIXEDSLOTSEQUENCE_H_ +#ifndef FRAMEWORK_DEVICEHANDLERS_FIXEDSLOTSEQUENCE_H_ +#define FRAMEWORK_DEVICEHANDLERS_FIXEDSLOTSEQUENCE_H_ -#include -#include -#include +#include "FixedSequenceSlot.h" +#include "../objectmanager/SystemObject.h" +#include /** * @brief This class is the representation of a Polling Sequence Table in software. @@ -24,30 +24,39 @@ */ class FixedSlotSequence { public: + using SlotList = std::multiset; + using SlotListIter = std::multiset::iterator; /** - * \brief The constructor of the FixedSlotSequence object. + * @brief The constructor of the FixedSlotSequence object. * - * \details The constructor takes two arguments, the period length and the init function. + * @details The constructor takes two arguments, the period length and the init function. * - * \param setLength The period length, expressed in ms. + * @param setLength The period length, expressed in ms. */ FixedSlotSequence(uint32_t setLengthMs); /** - * \brief The destructor of the FixedSlotSequence object. + * @brief The destructor of the FixedSlotSequence object. * - * \details The destructor frees all allocated memory by iterating through the slotList + * @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. + * @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 + * @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 + * @param + * @param */ void addSlot(object_id_t handlerId, uint32_t setTime, int8_t setSequenceId, PeriodicTaskIF* executingTask); @@ -61,47 +70,59 @@ public: bool slotFollowsImmediately(); /** - * \brief This method returns the time until the next software component is invoked. + * @brief This method returns the time until the next software + * component is invoked. * - * \details This method is vitally important for the operation of the PST. By fetching the polling time - * of the current slot and that of the next one (or the first one, if the list end is reached) - * it calculates and returns the interval in milliseconds within which the handler execution - * shall take place. If the next slot has the same time as the current one, it is ignored until - * a slot with different time or the end of the PST is found. + * @details + * This method is vitally important for the operation of the PST. + * By fetching the polling time of the current slot and that of the + * next one (or the first one, if the list end is reached) + * it calculates and returns the interval in milliseconds within + * which the handler execution shall take place. + * If the next slot has the same time as the current one, it is ignored + * until a slot with different time or the end of the PST is found. */ uint32_t getIntervalToNextSlotMs(); /** - * \brief This method returns the time difference between the current slot and the previous slot + * @brief This method returns the time difference between the current + * slot and the previous slot * - * \details This method is vitally important for the operation of the PST. By fetching the polling time - * of the current slot and that of the prevous one (or the last one, if the slot is the first one) - * it calculates and returns the interval in milliseconds that the handler execution shall be delayed. + * @details + * This method is vitally important for the operation of the PST. + * By fetching the polling time of the current slot and that of the previous + * one (or the last one, if the slot is the first one) it calculates and + * returns the interval in milliseconds that the handler execution shall + * be delayed. */ uint32_t getIntervalToPreviousSlotMs(); /** - * \brief This method returns the length of this FixedSlotSequence instance. + * @brief This method returns the length of this FixedSlotSequence instance. */ uint32_t getLengthMs() const; /** - * \brief The method to execute the device handler entered in the current OPUSPollingSlot object. + * @brief The method to execute the device handler entered in the current + * PollingSlot object. * - * \details Within this method the device handler object to be executed is chosen by looking up the - * handler address of the current slot in the handlerMap. Either the device handler's - * talkToInterface or its listenToInterface method is invoked, depending on the isTalking flag - * of the polling slot. After execution the iterator current is increased or, by reaching the - * end of slotList, reset to the beginning. + * @details + * Within this method the device handler object to be executed is chosen by + * looking up the handler address of the current slot in the handlerMap. + * Either the device handler's talkToInterface or its listenToInterface + * method is invoked, depending on the isTalking flag of the polling slot. + * After execution the iterator current is increased or, by reaching the + * end of slotList, reset to the beginning. */ void executeAndAdvance(); /** - * \brief An iterator that indicates the current polling slot to execute. + * @brief An iterator that indicates the current polling slot to execute. * - * \details This is an iterator for slotList and always points to the polling slot which is executed next. + * @details This is an iterator for slotList and always points to the + * polling slot which is executed next. */ - std::list::iterator current; + SlotListIter current; /** * Iterate through slotList and check successful creation. @@ -109,18 +130,21 @@ public: * @return */ ReturnValue_t checkSequence() const; + protected: /** - * \brief This list contains all OPUSPollingSlot objects, defining order and execution time of the - * device handler objects. + * @brief This list contains all PollingSlot objects, defining order and + * execution time of the device handler objects. * - * \details The slot list is a std:list object that contains all created OPUSPollingSlot instances. - * They are NOT ordered automatically, so by adding entries, the correct order needs to be ensured. - * By iterating through this list the polling sequence is executed. Two entries with identical - * polling times are executed immediately one after another. + * @details + * The slot list is a std:list object that contains all created + * PollingSlot instances. They are NOT ordered automatically, so by + * adding entries, the correct order needs to be ensured. By iterating + * through this list the polling sequence is executed. Two entries with + * identical polling times are executed immediately one after another. */ - std::list slotList; + SlotList slotList; uint32_t lengthMs; }; diff --git a/devicehandlers/HealthDevice.cpp b/devicehandlers/HealthDevice.cpp index ea0b99ffa..411731dcb 100644 --- a/devicehandlers/HealthDevice.cpp +++ b/devicehandlers/HealthDevice.cpp @@ -1,5 +1,5 @@ -#include -#include +#include "HealthDevice.h" +#include "../ipc/QueueFactory.h" HealthDevice::HealthDevice(object_id_t setObjectId, MessageQueueId_t parentQueue) : @@ -38,7 +38,7 @@ MessageQueueId_t HealthDevice::getCommandQueue() const { } void HealthDevice::setParentQueue(MessageQueueId_t parentQueue) { - healthHelper.setParentQeueue(parentQueue); + healthHelper.setParentQueue(parentQueue); } bool HealthDevice::hasHealthChanged() { diff --git a/devicehandlers/HealthDevice.h b/devicehandlers/HealthDevice.h index ffb9e5bd6..53b0ab097 100644 --- a/devicehandlers/HealthDevice.h +++ b/devicehandlers/HealthDevice.h @@ -1,11 +1,11 @@ #ifndef HEALTHDEVICE_H_ #define HEALTHDEVICE_H_ -#include -#include -#include -#include -#include +#include "../health/HasHealthIF.h" +#include "../health/HealthHelper.h" +#include "../objectmanager/SystemObject.h" +#include "../tasks/ExecutableObjectIF.h" +#include "../ipc/MessageQueueIF.h" class HealthDevice: public SystemObject, public ExecutableObjectIF, diff --git a/events/Event.cpp b/events/Event.cpp index 9ea9f552b..ea3d46fe4 100644 --- a/events/Event.cpp +++ b/events/Event.cpp @@ -1,4 +1,4 @@ -#include +#include "Event.h" namespace EVENT { EventId_t getEventId(Event event) { return (event & 0xFFFF); diff --git a/events/Event.h b/events/Event.h index 96800f34c..e22c9db16 100644 --- a/events/Event.h +++ b/events/Event.h @@ -2,7 +2,7 @@ #define EVENTOBJECT_EVENT_H_ #include -#include +#include "fwSubsystemIdRanges.h" //could be move to more suitable location #include diff --git a/events/EventManager.cpp b/events/EventManager.cpp index 0f1511e4b..e58f251ac 100644 --- a/events/EventManager.cpp +++ b/events/EventManager.cpp @@ -1,8 +1,8 @@ -#include -#include -#include -#include -#include +#include "EventManager.h" +#include "EventMessage.h" +#include "../serviceinterface/ServiceInterfaceStream.h" +#include "../ipc/QueueFactory.h" +#include "../ipc/MutexFactory.h" const uint16_t EventManager::POOL_SIZES[N_POOLS] = { @@ -147,7 +147,7 @@ void EventManager::printEvent(EventMessage* message) { #endif void EventManager::lockMutex() { - mutex->lockMutex(MutexIF::NO_TIMEOUT); + mutex->lockMutex(MutexIF::BLOCKING); } void EventManager::unlockMutex() { diff --git a/events/EventManager.h b/events/EventManager.h index 76dde9f8d..7badc3bf6 100644 --- a/events/EventManager.h +++ b/events/EventManager.h @@ -1,13 +1,13 @@ #ifndef EVENTMANAGER_H_ #define EVENTMANAGER_H_ -#include -#include -#include -#include -#include -#include -#include +#include "eventmatching/EventMatchTree.h" +#include "EventManagerIF.h" +#include "../objectmanager/SystemObject.h" +#include "../storagemanager/LocalPool.h" +#include "../tasks/ExecutableObjectIF.h" +#include "../ipc/MessageQueueIF.h" +#include "../ipc/MutexIF.h" #include class EventManager: public EventManagerIF, diff --git a/events/EventManagerIF.h b/events/EventManagerIF.h index bc0de4329..f9ac420b3 100644 --- a/events/EventManagerIF.h +++ b/events/EventManagerIF.h @@ -1,10 +1,10 @@ #ifndef EVENTMANAGERIF_H_ #define EVENTMANAGERIF_H_ -#include -#include -#include -#include +#include "eventmatching/eventmatching.h" +#include "EventMessage.h" +#include "../objectmanager/ObjectManagerIF.h" +#include "../ipc/MessageQueueSenderIF.h" class EventManagerIF { public: diff --git a/events/EventMessage.cpp b/events/EventMessage.cpp index f06f68c3b..b911abab9 100644 --- a/events/EventMessage.cpp +++ b/events/EventMessage.cpp @@ -1,4 +1,4 @@ -#include +#include "EventMessage.h" #include EventMessage::EventMessage() { diff --git a/events/EventMessage.h b/events/EventMessage.h index 9cbe33363..4d003bd7b 100644 --- a/events/EventMessage.h +++ b/events/EventMessage.h @@ -1,9 +1,9 @@ #ifndef EVENTMESSAGE_H_ #define EVENTMESSAGE_H_ -#include -#include -#include +#include "Event.h" +#include "../ipc/MessageQueueMessage.h" +#include "../objectmanager/ObjectManagerIF.h" /** * Passing on events through IPC. diff --git a/events/EventReportingProxyIF.h b/events/EventReportingProxyIF.h index 8aca4e26a..7a96e3d18 100644 --- a/events/EventReportingProxyIF.h +++ b/events/EventReportingProxyIF.h @@ -1,7 +1,7 @@ #ifndef FRAMEWORK_EVENTS_EVENTREPORTINGPROXYIF_H_ #define FRAMEWORK_EVENTS_EVENTREPORTINGPROXYIF_H_ -#include +#include "Event.h" class EventReportingProxyIF { diff --git a/events/eventmatching/EventIdRangeMatcher.cpp b/events/eventmatching/EventIdRangeMatcher.cpp index ac9156fd5..974567d4f 100644 --- a/events/eventmatching/EventIdRangeMatcher.cpp +++ b/events/eventmatching/EventIdRangeMatcher.cpp @@ -1,4 +1,4 @@ -#include +#include "EventIdRangeMatcher.h" EventIdRangeMatcher::EventIdRangeMatcher(EventId_t lower, EventId_t upper, bool inverted) : EventRangeMatcherBase(lower, upper, inverted) { diff --git a/events/eventmatching/EventIdRangeMatcher.h b/events/eventmatching/EventIdRangeMatcher.h index 57b77cb10..540d372f8 100644 --- a/events/eventmatching/EventIdRangeMatcher.h +++ b/events/eventmatching/EventIdRangeMatcher.h @@ -1,7 +1,7 @@ #ifndef FRAMEWORK_EVENTS_EVENTMATCHING_EVENTIDRANGEMATCHER_H_ #define FRAMEWORK_EVENTS_EVENTMATCHING_EVENTIDRANGEMATCHER_H_ -#include +#include "EventRangeMatcherBase.h" class EventIdRangeMatcher: public EventRangeMatcherBase { public: diff --git a/events/eventmatching/EventMatchTree.cpp b/events/eventmatching/EventMatchTree.cpp index e1925b8f0..55e4083f4 100644 --- a/events/eventmatching/EventMatchTree.cpp +++ b/events/eventmatching/EventMatchTree.cpp @@ -1,7 +1,7 @@ -#include -#include -#include -#include +#include "EventIdRangeMatcher.h" +#include "EventMatchTree.h" +#include "ReporterRangeMatcher.h" +#include "SeverityRangeMatcher.h" EventMatchTree::EventMatchTree(StorageManagerIF* storageBackend, bool invertedMatch) : diff --git a/events/eventmatching/EventMatchTree.h b/events/eventmatching/EventMatchTree.h index bd81e3bed..82a6de817 100644 --- a/events/eventmatching/EventMatchTree.h +++ b/events/eventmatching/EventMatchTree.h @@ -1,10 +1,10 @@ #ifndef FRAMEWORK_EVENTS_EVENTMATCHING_EVENTMATCHTREE_H_ #define FRAMEWORK_EVENTS_EVENTMATCHING_EVENTMATCHTREE_H_ -#include -#include -#include -#include +#include "../../container/PlacementFactory.h" +#include "../../events/EventMessage.h" +#include "../../globalfunctions/matching/MatchTree.h" +#include "../../returnvalues/HasReturnvaluesIF.h" class StorageManagerIF; class EventMatchTree: public MatchTree, public HasReturnvaluesIF { diff --git a/events/eventmatching/EventRangeMatcherBase.h b/events/eventmatching/EventRangeMatcherBase.h index 921a5d6a1..e9d57f1c2 100644 --- a/events/eventmatching/EventRangeMatcherBase.h +++ b/events/eventmatching/EventRangeMatcherBase.h @@ -1,9 +1,9 @@ #ifndef FRAMEWORK_EVENTS_EVENTMATCHING_EVENTRANGEMATCHERBASE_H_ #define FRAMEWORK_EVENTS_EVENTMATCHING_EVENTRANGEMATCHERBASE_H_ -#include -#include -#include +#include "../../events/EventMessage.h" +#include "../../globalfunctions/matching/RangeMatcher.h" +#include "../../globalfunctions/matching/SerializeableMatcherIF.h" template class EventRangeMatcherBase: public SerializeableMatcherIF { @@ -11,16 +11,16 @@ class EventRangeMatcherBase: public SerializeableMatcherIF { public: EventRangeMatcherBase(T from, T till, bool inverted) : rangeMatcher(from, till, inverted) { } virtual ~EventRangeMatcherBase() { } - ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { - return rangeMatcher.serialize(buffer, size, max_size, bigEndian); + ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const { + return rangeMatcher.serialize(buffer, size, maxSize, streamEndianness); } - uint32_t getSerializedSize() const { + size_t getSerializedSize() const { return rangeMatcher.getSerializedSize(); } - ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) { - return rangeMatcher.deSerialize(buffer, size, bigEndian); + ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) { + return rangeMatcher.deSerialize(buffer, size, streamEndianness); } protected: RangeMatcher rangeMatcher; diff --git a/events/eventmatching/ReporterRangeMatcher.cpp b/events/eventmatching/ReporterRangeMatcher.cpp index 76b8e7886..611797260 100644 --- a/events/eventmatching/ReporterRangeMatcher.cpp +++ b/events/eventmatching/ReporterRangeMatcher.cpp @@ -1,4 +1,4 @@ -#include +#include "ReporterRangeMatcher.h" ReporterRangeMatcher::ReporterRangeMatcher(object_id_t lower, object_id_t upper, bool inverted) : EventRangeMatcherBase(lower, upper, inverted) { diff --git a/events/eventmatching/ReporterRangeMatcher.h b/events/eventmatching/ReporterRangeMatcher.h index 65be2365e..9a0a5fcf3 100644 --- a/events/eventmatching/ReporterRangeMatcher.h +++ b/events/eventmatching/ReporterRangeMatcher.h @@ -1,7 +1,7 @@ #ifndef FRAMEWORK_EVENTS_EVENTMATCHING_REPORTERRANGEMATCHER_H_ #define FRAMEWORK_EVENTS_EVENTMATCHING_REPORTERRANGEMATCHER_H_ -#include +#include "EventRangeMatcherBase.h" class ReporterRangeMatcher: public EventRangeMatcherBase { public: diff --git a/events/eventmatching/SeverityRangeMatcher.cpp b/events/eventmatching/SeverityRangeMatcher.cpp index 98f8d7e16..6fd382714 100644 --- a/events/eventmatching/SeverityRangeMatcher.cpp +++ b/events/eventmatching/SeverityRangeMatcher.cpp @@ -1,6 +1,6 @@ -#include -#include -#include +#include "SeverityRangeMatcher.h" +#include "../../events/EventMessage.h" +#include "../../serialize/SerializeAdapter.h" SeverityRangeMatcher::SeverityRangeMatcher(EventSeverity_t from, EventSeverity_t till, bool inverted) : EventRangeMatcherBase(from, till, inverted) { diff --git a/events/eventmatching/SeverityRangeMatcher.h b/events/eventmatching/SeverityRangeMatcher.h index ffacff818..3f7cc418b 100644 --- a/events/eventmatching/SeverityRangeMatcher.h +++ b/events/eventmatching/SeverityRangeMatcher.h @@ -1,7 +1,7 @@ #ifndef FRAMEWORK_EVENTS_EVENTMATCHING_SEVERITYRANGEMATCHER_H_ #define FRAMEWORK_EVENTS_EVENTMATCHING_SEVERITYRANGEMATCHER_H_ -#include +#include "EventRangeMatcherBase.h" class SeverityRangeMatcher: public EventRangeMatcherBase { public: diff --git a/events/eventmatching/eventmatching.h b/events/eventmatching/eventmatching.h index 435c7457f..7a87e177b 100644 --- a/events/eventmatching/eventmatching.h +++ b/events/eventmatching/eventmatching.h @@ -1,10 +1,10 @@ #ifndef EVENTMATCHING_H_ #define EVENTMATCHING_H_ -#include -#include -#include -#include +#include "EventIdRangeMatcher.h" +#include "EventMatchTree.h" +#include "ReporterRangeMatcher.h" +#include "SeverityRangeMatcher.h" #endif /* EVENTMATCHING_H_ */ diff --git a/events/fwSubsystemIdRanges.h b/events/fwSubsystemIdRanges.h index 4c261e57a..a05652c22 100644 --- a/events/fwSubsystemIdRanges.h +++ b/events/fwSubsystemIdRanges.h @@ -18,6 +18,8 @@ enum { SYSTEM_MANAGER = 74, SYSTEM_MANAGER_1 = 75, SYSTEM_1 = 79, + PUS_SERVICE_1 = 80, + FW_SUBSYSTEM_ID_RANGE }; } diff --git a/fdir/ConfirmsFailuresIF.h b/fdir/ConfirmsFailuresIF.h index 99cd212a8..144114612 100644 --- a/fdir/ConfirmsFailuresIF.h +++ b/fdir/ConfirmsFailuresIF.h @@ -1,8 +1,8 @@ #ifndef FRAMEWORK_FDIR_CONFIRMSFAILURESIF_H_ #define FRAMEWORK_FDIR_CONFIRMSFAILURESIF_H_ -#include -#include +#include "../returnvalues/HasReturnvaluesIF.h" +#include "../ipc/MessageQueueSenderIF.h" class ConfirmsFailuresIF { public: diff --git a/fdir/EventCorrelation.cpp b/fdir/EventCorrelation.cpp index 32aa3cd3b..d60fc6ca3 100644 --- a/fdir/EventCorrelation.cpp +++ b/fdir/EventCorrelation.cpp @@ -1,4 +1,4 @@ -#include +#include "EventCorrelation.h" EventCorrelation::EventCorrelation(uint32_t timeout) : eventPending(false) { diff --git a/fdir/EventCorrelation.h b/fdir/EventCorrelation.h index 0cad6265d..b8793edfb 100644 --- a/fdir/EventCorrelation.h +++ b/fdir/EventCorrelation.h @@ -1,7 +1,7 @@ #ifndef FRAMEWORK_FDIR_EVENTCORRELATION_H_ #define FRAMEWORK_FDIR_EVENTCORRELATION_H_ -#include +#include "../timemanager/Countdown.h" class EventCorrelation { public: diff --git a/fdir/FailureIsolationBase.cpp b/fdir/FailureIsolationBase.cpp index 4b7caac53..eb7b1bfca 100644 --- a/fdir/FailureIsolationBase.cpp +++ b/fdir/FailureIsolationBase.cpp @@ -1,9 +1,9 @@ -#include -#include -#include -#include -#include -#include +#include "../events/EventManagerIF.h" +#include "FailureIsolationBase.h" +#include "../health/HasHealthIF.h" +#include "../health/HealthMessage.h" +#include "../ipc/QueueFactory.h" +#include "../objectmanager/ObjectManagerIF.h" FailureIsolationBase::FailureIsolationBase(object_id_t owner, object_id_t parent, uint8_t messageDepth, uint8_t parameterDomainBase) : eventQueue(NULL), ownerId( diff --git a/fdir/FailureIsolationBase.h b/fdir/FailureIsolationBase.h index cd582e399..6f38bc9f3 100644 --- a/fdir/FailureIsolationBase.h +++ b/fdir/FailureIsolationBase.h @@ -1,13 +1,13 @@ #ifndef FRAMEWORK_FDIR_FAILUREISOLATIONBASE_H_ #define FRAMEWORK_FDIR_FAILUREISOLATIONBASE_H_ -#include -#include -#include -#include -#include -#include -#include +#include "../events/EventMessage.h" +#include "ConfirmsFailuresIF.h" +#include "FaultCounter.h" +#include "../health/HealthMessage.h" +#include "../parameters/HasParametersIF.h" +#include "../returnvalues/HasReturnvaluesIF.h" +#include "../ipc/MessageQueueIF.h" class FailureIsolationBase: public HasReturnvaluesIF, public ConfirmsFailuresIF, diff --git a/fdir/FaultCounter.cpp b/fdir/FaultCounter.cpp index 3dc899c26..443adb52e 100644 --- a/fdir/FaultCounter.cpp +++ b/fdir/FaultCounter.cpp @@ -1,4 +1,4 @@ -#include +#include "FaultCounter.h" FaultCounter::FaultCounter(uint32_t failureThreshold, uint32_t decrementAfterMs, uint8_t setParameterDomain) : diff --git a/fdir/FaultCounter.h b/fdir/FaultCounter.h index ac23853cb..dc929debd 100644 --- a/fdir/FaultCounter.h +++ b/fdir/FaultCounter.h @@ -1,8 +1,8 @@ #ifndef FRAMEWORK_FDIR_FAULTCOUNTER_H_ #define FRAMEWORK_FDIR_FAULTCOUNTER_H_ -#include -#include +#include "../parameters/HasParametersIF.h" +#include "../timemanager/Countdown.h" class FaultCounter: public HasParametersIF { public: diff --git a/framework.mk b/fsfw.mk similarity index 83% rename from framework.mk rename to fsfw.mk index a5a653641..c2c6e7475 100644 --- a/framework.mk +++ b/fsfw.mk @@ -1,5 +1,6 @@ -# This file needs FRAMEWORK_PATH and API set correctly -# Valid API settings: rtems, linux, freeRTOS +# This submake file needs to be included by the primary Makefile. +# This file needs FRAMEWORK_PATH and OS_FSFW set correctly by another Makefile. +# Valid API settings: rtems, linux, freeRTOS, host CXXSRC += $(wildcard $(FRAMEWORK_PATH)/action/*.cpp) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/container/*.cpp) @@ -12,7 +13,6 @@ CXXSRC += $(wildcard $(FRAMEWORK_PATH)/devicehandlers/*.cpp) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/events/*.cpp) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/events/eventmatching/*.cpp) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/fdir/*.cpp) -CXXSRC += $(wildcard $(FRAMEWORK_PATH)/framework.mk/*.cpp) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/globalfunctions/*.cpp) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/globalfunctions/matching/*.cpp) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/globalfunctions/math/*.cpp) @@ -26,14 +26,16 @@ CXXSRC += $(wildcard $(FRAMEWORK_PATH)/objectmanager/*.cpp) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/osal/*.cpp) # select the OS -ifeq ($(OS),rtems) +ifeq ($(OS_FSFW),rtems) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/osal/rtems/*.cpp) -else ifeq ($(OS),linux) +else ifeq ($(OS_FSFW),linux) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/osal/linux/*.cpp) -else ifeq ($(OS),freeRTOS) +else ifeq ($(OS_FSFW),freeRTOS) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/osal/FreeRTOS/*.cpp) +else ifeq ($(OS_FSFW),host) +CXXSRC += $(wildcard $(FRAMEWORK_PATH)/osal/host/*.cpp) else -$(error invalid OS specified, valid OS are rtems, linux, freeRTOS) +$(error invalid OS_FSFW specified, valid OS_FSFW are rtems, linux, freeRTOS, host) endif CXXSRC += $(wildcard $(FRAMEWORK_PATH)/parameters/*.cpp) @@ -54,3 +56,4 @@ CXXSRC += $(wildcard $(FRAMEWORK_PATH)/tmtcpacket/*.cpp) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/tmtcpacket/packetmatcher/*.cpp) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/tmtcpacket/pus/*.cpp) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/tmtcservices/*.cpp) +CXXSRC += $(wildcard $(FRAMEWORK_PATH)/pus/*.cpp) diff --git a/globalfunctions/AsciiConverter.cpp b/globalfunctions/AsciiConverter.cpp index 1459a2410..9eb3698fb 100644 --- a/globalfunctions/AsciiConverter.cpp +++ b/globalfunctions/AsciiConverter.cpp @@ -1,4 +1,4 @@ -#include +#include "AsciiConverter.h" #include #include diff --git a/globalfunctions/AsciiConverter.h b/globalfunctions/AsciiConverter.h index acd406dab..7af3cb3d4 100644 --- a/globalfunctions/AsciiConverter.h +++ b/globalfunctions/AsciiConverter.h @@ -1,7 +1,7 @@ #ifndef ASCIICONVERTER_H_ #define ASCIICONVERTER_H_ -#include +#include "../returnvalues/HasReturnvaluesIF.h" class AsciiConverter: public HasReturnvaluesIF { public: diff --git a/globalfunctions/CRC.cpp b/globalfunctions/CRC.cpp index ecd0b6756..7bb568066 100644 --- a/globalfunctions/CRC.cpp +++ b/globalfunctions/CRC.cpp @@ -1,4 +1,4 @@ -#include +#include "CRC.h" #include const uint16_t CRC::crc16ccitt_table[256] = { diff --git a/globalfunctions/DleEncoder.cpp b/globalfunctions/DleEncoder.cpp index a68f15249..088c9d803 100644 --- a/globalfunctions/DleEncoder.cpp +++ b/globalfunctions/DleEncoder.cpp @@ -1,4 +1,4 @@ -#include +#include "DleEncoder.h" DleEncoder::DleEncoder() { } diff --git a/globalfunctions/DleEncoder.h b/globalfunctions/DleEncoder.h index fc1556007..ff3a2727c 100644 --- a/globalfunctions/DleEncoder.h +++ b/globalfunctions/DleEncoder.h @@ -1,7 +1,7 @@ #ifndef DLEENCODER_H_ #define DLEENCODER_H_ -#include +#include "../returnvalues/HasReturnvaluesIF.h" class DleEncoder: public HasReturnvaluesIF { private: diff --git a/globalfunctions/Type.cpp b/globalfunctions/Type.cpp index 814d26f4e..ae595b812 100644 --- a/globalfunctions/Type.cpp +++ b/globalfunctions/Type.cpp @@ -1,6 +1,6 @@ -#include -#include -#include +#include "../serialize/SerializeAdapter.h" +#include "Type.h" +#include "../serialize/SerializeAdapter.h" Type::Type() : actualType(UNKNOWN_TYPE) { @@ -59,8 +59,8 @@ uint8_t Type::getSize() const { } } -ReturnValue_t Type::serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { +ReturnValue_t Type::serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const { uint8_t ptc; uint8_t pfc; ReturnValue_t result = getPtcPfc(&ptc, &pfc); @@ -68,36 +68,36 @@ ReturnValue_t Type::serialize(uint8_t** buffer, uint32_t* size, return result; } - result = SerializeAdapter::serialize(&ptc, buffer, size, max_size, - bigEndian); + result = SerializeAdapter::serialize(&ptc, buffer, size, maxSize, + streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::serialize(&pfc, buffer, size, max_size, - bigEndian); + result = SerializeAdapter::serialize(&pfc, buffer, size, maxSize, + streamEndianness); return result; } -uint32_t Type::getSerializedSize() const { +size_t Type::getSerializedSize() const { uint8_t dontcare = 0; - return 2 * SerializeAdapter::getSerializedSize(&dontcare); + return 2 * SerializeAdapter::getSerializedSize(&dontcare); } -ReturnValue_t Type::deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) { +ReturnValue_t Type::deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) { uint8_t ptc; uint8_t pfc; - ReturnValue_t result = SerializeAdapter::deSerialize(&ptc, buffer, - size, bigEndian); + ReturnValue_t result = SerializeAdapter::deSerialize(&ptc, buffer, + size, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::deSerialize(&pfc, buffer, size, - bigEndian); + result = SerializeAdapter::deSerialize(&pfc, buffer, size, + streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } diff --git a/globalfunctions/Type.h b/globalfunctions/Type.h index 88df07b6f..be499ffc6 100644 --- a/globalfunctions/Type.h +++ b/globalfunctions/Type.h @@ -1,8 +1,8 @@ #ifndef TYPE_H_ #define TYPE_H_ -#include -#include +#include "../returnvalues/HasReturnvaluesIF.h" +#include "../serialize/SerializeIF.h" class Type: public SerializeIF { public: @@ -22,7 +22,7 @@ public: Type(ActualType_t actualType); - Type(const Type& type); + Type(const Type &type); Type& operator=(Type rhs); @@ -30,8 +30,8 @@ public: operator ActualType_t() const; - bool operator==(const Type& rhs); - bool operator!=(const Type& rhs); + bool operator==(const Type &rhs); + bool operator!=(const Type &rhs); uint8_t getSize() const; @@ -39,13 +39,13 @@ public: static ActualType_t getActualType(uint8_t ptc, uint8_t pfc); - virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const; + virtual ReturnValue_t serialize(uint8_t **buffer, size_t *size, + size_t maxSize, Endianness streamEndianness) const override; - virtual uint32_t getSerializedSize() const; + virtual size_t getSerializedSize() const override; - virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian); + virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size, + Endianness streamEndianness) override; private: ActualType_t actualType; diff --git a/globalfunctions/arrayprinter.cpp b/globalfunctions/arrayprinter.cpp index e8fce56c6..b1e888c55 100644 --- a/globalfunctions/arrayprinter.cpp +++ b/globalfunctions/arrayprinter.cpp @@ -1,5 +1,5 @@ -#include -#include +#include "arrayprinter.h" +#include "../serviceinterface/ServiceInterfaceStream.h" #include void arrayprinter::print(const uint8_t *data, size_t size, OutputType type, diff --git a/globalfunctions/conversion.cpp b/globalfunctions/conversion.cpp deleted file mode 100644 index d4f542bd1..000000000 --- a/globalfunctions/conversion.cpp +++ /dev/null @@ -1,104 +0,0 @@ -#include -#include -#include - - - -//SHOULDDO: This shall be optimized (later)! -void convertToByteStream( uint16_t value, uint8_t* buffer, uint32_t* size ) { - buffer[0] = (value & 0xFF00) >> 8; - buffer[1] = (value & 0x00FF); - *size += 2; -} - -void convertToByteStream( uint32_t value, uint8_t* buffer, uint32_t* size ) { - buffer[0] = (value & 0xFF000000) >> 24; - buffer[1] = (value & 0x00FF0000) >> 16; - buffer[2] = (value & 0x0000FF00) >> 8; - buffer[3] = (value & 0x000000FF); - *size +=4; -} - -void convertToByteStream( int16_t value, uint8_t* buffer, uint32_t* size ) { - buffer[0] = (value & 0xFF00) >> 8; - buffer[1] = (value & 0x00FF); - *size += 2; -} - -void convertToByteStream( int32_t value, uint8_t* buffer, uint32_t* size ) { - buffer[0] = (value & 0xFF000000) >> 24; - buffer[1] = (value & 0x00FF0000) >> 16; - buffer[2] = (value & 0x0000FF00) >> 8; - buffer[3] = (value & 0x000000FF); - *size += 4; -} - -//void convertToByteStream( uint64_t value, uint8_t* buffer, uint32_t* size ) { -// buffer[0] = (value & 0xFF00000000000000) >> 56; -// buffer[1] = (value & 0x00FF000000000000) >> 48; -// buffer[2] = (value & 0x0000FF0000000000) >> 40; -// buffer[3] = (value & 0x000000FF00000000) >> 32; -// buffer[4] = (value & 0x00000000FF000000) >> 24; -// buffer[5] = (value & 0x0000000000FF0000) >> 16; -// buffer[6] = (value & 0x000000000000FF00) >> 8; -// buffer[7] = (value & 0x00000000000000FF); -// *size+=8; -//} -// -//void convertToByteStream( int64_t value, uint8_t* buffer, uint32_t* size ) { -// buffer[0] = (value & 0xFF00000000000000) >> 56; -// buffer[1] = (value & 0x00FF000000000000) >> 48; -// buffer[2] = (value & 0x0000FF0000000000) >> 40; -// buffer[3] = (value & 0x000000FF00000000) >> 32; -// buffer[4] = (value & 0x00000000FF000000) >> 24; -// buffer[5] = (value & 0x0000000000FF0000) >> 16; -// buffer[6] = (value & 0x000000000000FF00) >> 8; -// buffer[7] = (value & 0x00000000000000FF); -// *size+=8; -//} - -void convertToByteStream( float in_value, uint8_t* buffer, uint32_t* size ) { -#ifndef BYTE_ORDER_SYSTEM - #error BYTE_ORDER_SYSTEM not defined -#elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN - union float_union { - float value; - uint8_t chars[4]; - }; - float_union temp; - temp.value = in_value; - buffer[0] = temp.chars[3]; - buffer[1] = temp.chars[2]; - buffer[2] = temp.chars[1]; - buffer[3] = temp.chars[0]; - *size += 4; -#elif BYTE_ORDER_SYSTEM == BIG_ENDIAN - memcpy(buffer, &in_value, sizeof(in_value)); - *size += sizeof(in_value); -#endif -} - -void convertToByteStream( double in_value, uint8_t* buffer, uint32_t* size ) { -#ifndef BYTE_ORDER_SYSTEM - #error BYTE_ORDER_SYSTEM not defined -#elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN - union double_union { - double value; - uint8_t chars[8]; - }; - double_union temp; - temp.value = in_value; - buffer[0] = temp.chars[7]; - buffer[1] = temp.chars[6]; - buffer[2] = temp.chars[5]; - buffer[3] = temp.chars[4]; - buffer[4] = temp.chars[3]; - buffer[5] = temp.chars[2]; - buffer[6] = temp.chars[1]; - buffer[7] = temp.chars[0]; - *size += 8; -#elif BYTE_ORDER_SYSTEM == BIG_ENDIAN - memcpy(buffer, &in_value, sizeof(in_value)); - *size += sizeof(in_value); -#endif -} diff --git a/globalfunctions/conversion.h b/globalfunctions/conversion.h deleted file mode 100644 index 0d1ca1a6b..000000000 --- a/globalfunctions/conversion.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef CONVERSION_H_ -#define CONVERSION_H_ - - -#include - - -void convertToByteStream( uint16_t value, uint8_t* buffer, uint32_t* size ); - -void convertToByteStream( uint32_t value, uint8_t* buffer, uint32_t* size ); - -void convertToByteStream( int16_t value, uint8_t* buffer, uint32_t* size ); - -void convertToByteStream( int32_t value, uint8_t* buffer, uint32_t* size ); - -//void convertToByteStream( uint64_t value, uint8_t* buffer, uint32_t* size ); -// -//void convertToByteStream( int64_t value, uint8_t* buffer, uint32_t* size ); - -void convertToByteStream( float value, uint8_t* buffer, uint32_t* size ); - -void convertToByteStream( double value, uint8_t* buffer, uint32_t* size ); - -#endif /* CONVERSION_H_ */ diff --git a/globalfunctions/matching/BinaryMatcher.h b/globalfunctions/matching/BinaryMatcher.h index df7325cff..4f6db85d8 100644 --- a/globalfunctions/matching/BinaryMatcher.h +++ b/globalfunctions/matching/BinaryMatcher.h @@ -1,7 +1,7 @@ #ifndef BINARYMATCHER_H_ #define BINARYMATCHER_H_ -#include +#include "MatcherIF.h" template class BinaryMatcher: public MatcherIF { diff --git a/globalfunctions/matching/DecimalMatcher.h b/globalfunctions/matching/DecimalMatcher.h index f4722e6bd..535050205 100644 --- a/globalfunctions/matching/DecimalMatcher.h +++ b/globalfunctions/matching/DecimalMatcher.h @@ -1,7 +1,7 @@ #ifndef DECIMALMATCHER_H_ #define DECIMALMATCHER_H_ -#include +#include "MatcherIF.h" template class DecimalMatcher: public MatcherIF { diff --git a/globalfunctions/matching/MatchTree.h b/globalfunctions/matching/MatchTree.h index 398cf3f0b..755687b28 100644 --- a/globalfunctions/matching/MatchTree.h +++ b/globalfunctions/matching/MatchTree.h @@ -1,9 +1,9 @@ #ifndef FRAMEWORK_GLOBALFUNCTIONS_MATCHING_MATCHTREE_H_ #define FRAMEWORK_GLOBALFUNCTIONS_MATCHING_MATCHTREE_H_ -#include -#include -#include +#include "../../container/BinaryTree.h" +#include "SerializeableMatcherIF.h" +#include "../../serialize/SerializeAdapter.h" template class MatchTree: public SerializeableMatcherIF, public BinaryTree< @@ -45,38 +45,38 @@ public: return matchSubtree(iter, number); } - ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { + ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, SerializeIF::Endianness streamEndianness) const override { iterator iter = this->begin(); uint8_t count = this->countRight(iter); - ReturnValue_t result = SerializeAdapter::serialize(&count, - buffer, size, max_size, bigEndian); + ReturnValue_t result = SerializeAdapter::serialize(&count, + buffer, size, maxSize, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } if (iter == this->end()) { return HasReturnvaluesIF::RETURN_OK; } - result = iter->serialize(buffer, size, max_size, bigEndian); + result = iter->serialize(buffer, size, maxSize, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } if (maxDepth > 0) { MatchTree temp(iter.left(), maxDepth - 1); - result = temp.serialize(buffer, size, max_size, bigEndian); + result = temp.serialize(buffer, size, maxSize, streamEndianness); } if (result != HasReturnvaluesIF::RETURN_OK) { return result; } iter = iter.right(); while (iter != this->end()) { - result = iter->serialize(buffer, size, max_size, bigEndian); + result = iter->serialize(buffer, size, maxSize, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } if (maxDepth > 0) { MatchTree temp(iter.left(), maxDepth - 1); - result = temp.serialize(buffer, size, max_size, bigEndian); + result = temp.serialize(buffer, size, maxSize, streamEndianness); } if (result != HasReturnvaluesIF::RETURN_OK) { return result; @@ -86,7 +86,7 @@ public: return result; } - uint32_t getSerializedSize() const { + size_t getSerializedSize() const override { //Analogous to serialize! uint32_t size = 1; //One for count iterator iter = this->begin(); @@ -115,8 +115,8 @@ public: return size; } - ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) { + ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + SerializeIF::Endianness streamEndianness) override { return HasReturnvaluesIF::RETURN_OK; } diff --git a/globalfunctions/matching/RangeMatcher.h b/globalfunctions/matching/RangeMatcher.h index 10e07173b..b64b9e30b 100644 --- a/globalfunctions/matching/RangeMatcher.h +++ b/globalfunctions/matching/RangeMatcher.h @@ -1,9 +1,8 @@ #ifndef RANGEMATCHER_H_ #define RANGEMATCHER_H_ -#include -#include - +#include "SerializeableMatcherIF.h" +#include "../../serialize/SerializeAdapter.h" template class RangeMatcher: public SerializeableMatcherIF { @@ -27,34 +26,40 @@ public: } } - ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { - ReturnValue_t result = SerializeAdapter::serialize(&lowerBound, buffer, size, max_size, bigEndian); + ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize, + SerializeIF::Endianness streamEndianness) const override { + ReturnValue_t result = SerializeAdapter::serialize(&lowerBound, buffer, + size, maxSize, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::serialize(&upperBound, buffer, size, max_size, bigEndian); + result = SerializeAdapter::serialize(&upperBound, buffer, size, + maxSize, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - return SerializeAdapter::serialize(&inverted, buffer, size, max_size, bigEndian); + return SerializeAdapter::serialize(&inverted, buffer, size, maxSize, + streamEndianness); } - uint32_t getSerializedSize() const { + size_t getSerializedSize() const override { return sizeof(lowerBound) + sizeof(upperBound) + sizeof(bool); } - ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) { - ReturnValue_t result = SerializeAdapter::deSerialize(&lowerBound, buffer, size, bigEndian); + ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size, + SerializeIF::Endianness streamEndianness) override { + ReturnValue_t result = SerializeAdapter::deSerialize(&lowerBound, + buffer, size, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::deSerialize(&upperBound, buffer, size, bigEndian); + result = SerializeAdapter::deSerialize(&upperBound, buffer, size, + streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - return SerializeAdapter::deSerialize(&inverted, buffer, size, bigEndian); + return SerializeAdapter::deSerialize(&inverted, buffer, size, + streamEndianness); } protected: bool doMatch(T input) { diff --git a/globalfunctions/matching/SerializeableMatcherIF.h b/globalfunctions/matching/SerializeableMatcherIF.h index 7b00a1b3b..067b0251a 100644 --- a/globalfunctions/matching/SerializeableMatcherIF.h +++ b/globalfunctions/matching/SerializeableMatcherIF.h @@ -1,8 +1,8 @@ #ifndef FRAMEWORK_GLOBALFUNCTIONS_MATCHING_SERIALIZEABLEMATCHERIF_H_ #define FRAMEWORK_GLOBALFUNCTIONS_MATCHING_SERIALIZEABLEMATCHERIF_H_ -#include -#include +#include "MatcherIF.h" +#include "../../serialize/SerializeIF.h" template class SerializeableMatcherIF : public MatcherIF, public SerializeIF { diff --git a/globalfunctions/math/QuaternionOperations.cpp b/globalfunctions/math/QuaternionOperations.cpp index f8c751493..c09426daa 100644 --- a/globalfunctions/math/QuaternionOperations.cpp +++ b/globalfunctions/math/QuaternionOperations.cpp @@ -1,5 +1,5 @@ #include "QuaternionOperations.h" -#include +#include "VectorOperations.h" #include #include diff --git a/globalfunctions/timevalOperations.cpp b/globalfunctions/timevalOperations.cpp index 253b6eb77..6efe75ba7 100644 --- a/globalfunctions/timevalOperations.cpp +++ b/globalfunctions/timevalOperations.cpp @@ -1,4 +1,4 @@ -#include +#include "timevalOperations.h" timeval& operator+=(timeval& lhs, const timeval& rhs) { int64_t sum = lhs.tv_sec * 1000000. + lhs.tv_usec; diff --git a/health/HasHealthIF.h b/health/HasHealthIF.h index dd27fe39f..ac4043008 100644 --- a/health/HasHealthIF.h +++ b/health/HasHealthIF.h @@ -1,9 +1,9 @@ #ifndef HASHEALTHIF_H_ #define HASHEALTHIF_H_ -#include -#include -#include +#include "../events/Event.h" +#include "../returnvalues/HasReturnvaluesIF.h" +#include "../ipc/MessageQueueSenderIF.h" class HasHealthIF { public: diff --git a/health/HealthHelper.cpp b/health/HealthHelper.cpp index ed97f3d3d..1cc7d858f 100644 --- a/health/HealthHelper.cpp +++ b/health/HealthHelper.cpp @@ -1,6 +1,6 @@ -#include -#include -#include +#include "HealthHelper.h" +#include "../ipc/MessageQueueSenderIF.h" +#include "../serviceinterface/ServiceInterfaceStream.h" HealthHelper::HealthHelper(HasHealthIF* owner, object_id_t objectId) : healthTable(NULL), eventSender(NULL), objectId(objectId), parentQueue( 0), owner(owner) { @@ -29,11 +29,11 @@ HasHealthIF::HealthState HealthHelper::getHealth() { } ReturnValue_t HealthHelper::initialize(MessageQueueId_t parentQueue) { - setParentQeueue(parentQueue); + setParentQueue(parentQueue); return initialize(); } -void HealthHelper::setParentQeueue(MessageQueueId_t parentQueue) { +void HealthHelper::setParentQueue(MessageQueueId_t parentQueue) { this->parentQueue = parentQueue; } diff --git a/health/HealthHelper.h b/health/HealthHelper.h index a1ca2c525..90155ad45 100644 --- a/health/HealthHelper.h +++ b/health/HealthHelper.h @@ -1,13 +1,13 @@ #ifndef HEALTHHELPER_H_ #define HEALTHHELPER_H_ -#include -#include -#include -#include -#include -#include -#include +#include "../events/EventManagerIF.h" +#include "../events/EventReportingProxyIF.h" +#include "HasHealthIF.h" +#include "HealthMessage.h" +#include "HealthTableIF.h" +#include "../objectmanager/ObjectManagerIF.h" +#include "../returnvalues/HasReturnvaluesIF.h" /** * Helper class for Objects that implement HasHealthIF @@ -78,7 +78,7 @@ public: /** * @param parentQueue the Queue id of the parent object. Set to 0 if no parent present */ - void setParentQeueue(MessageQueueId_t parentQueue); + void setParentQueue(MessageQueueId_t parentQueue); /** * diff --git a/health/HealthMessage.cpp b/health/HealthMessage.cpp index 768dea469..1bb29526f 100644 --- a/health/HealthMessage.cpp +++ b/health/HealthMessage.cpp @@ -1,4 +1,4 @@ -#include +#include "HealthMessage.h" void HealthMessage::setHealthMessage(CommandMessage* message, Command_t command, HasHealthIF::HealthState health, HasHealthIF::HealthState oldHealth) { diff --git a/health/HealthMessage.h b/health/HealthMessage.h index 13e79b88e..db2a77191 100644 --- a/health/HealthMessage.h +++ b/health/HealthMessage.h @@ -1,8 +1,8 @@ #ifndef HEALTHMESSAGE_H_ #define HEALTHMESSAGE_H_ -#include -#include +#include "HasHealthIF.h" +#include "../ipc/CommandMessage.h" class HealthMessage { public: diff --git a/health/HealthTable.cpp b/health/HealthTable.cpp index a575b2828..4d2564a31 100644 --- a/health/HealthTable.cpp +++ b/health/HealthTable.cpp @@ -1,6 +1,6 @@ -#include -#include -#include +#include "HealthTable.h" +#include "../serialize/SerializeAdapter.h" +#include "../ipc/MutexFactory.h" HealthTable::HealthTable(object_id_t objectid) : SystemObject(objectid) { @@ -26,7 +26,7 @@ ReturnValue_t HealthTable::registerObject(object_id_t object, void HealthTable::setHealth(object_id_t object, HasHealthIF::HealthState newState) { - mutex->lockMutex(MutexIF::NO_TIMEOUT); + mutex->lockMutex(MutexIF::BLOCKING); HealthMap::iterator iter = healthMap.find(object); if (iter != healthMap.end()) { iter->second = newState; @@ -36,7 +36,7 @@ void HealthTable::setHealth(object_id_t object, HasHealthIF::HealthState HealthTable::getHealth(object_id_t object) { HasHealthIF::HealthState state = HasHealthIF::HEALTHY; - mutex->lockMutex(MutexIF::NO_TIMEOUT); + mutex->lockMutex(MutexIF::BLOCKING); HealthMap::iterator iter = healthMap.find(object); if (iter != healthMap.end()) { state = iter->second; @@ -46,7 +46,7 @@ HasHealthIF::HealthState HealthTable::getHealth(object_id_t object) { } uint32_t HealthTable::getPrintSize() { - mutex->lockMutex(MutexIF::NO_TIMEOUT); + mutex->lockMutex(MutexIF::BLOCKING); uint32_t size = healthMap.size() * 5 + 2; mutex->unlockMutex(); return size; @@ -54,7 +54,7 @@ uint32_t HealthTable::getPrintSize() { bool HealthTable::hasHealth(object_id_t object) { bool exits = false; - mutex->lockMutex(MutexIF::NO_TIMEOUT); + mutex->lockMutex(MutexIF::BLOCKING); HealthMap::iterator iter = healthMap.find(object); if (iter != healthMap.end()) { exits = true; @@ -63,21 +63,21 @@ bool HealthTable::hasHealth(object_id_t object) { return exits; } -void HealthTable::printAll(uint8_t* pointer, uint32_t maxSize) { - mutex->lockMutex(MutexIF::NO_TIMEOUT); - uint32_t size = 0; +void HealthTable::printAll(uint8_t* pointer, size_t maxSize) { + mutex->lockMutex(MutexIF::BLOCKING); + size_t size = 0; uint16_t count = healthMap.size(); - ReturnValue_t result = SerializeAdapter::serialize(&count, - &pointer, &size, maxSize, true); + ReturnValue_t result = 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, - &pointer, &size, maxSize, true); + result = SerializeAdapter::serialize(&iter->first, + &pointer, &size, maxSize, SerializeIF::Endianness::BIG); uint8_t health = iter->second; - result = SerializeAdapter::serialize(&health, &pointer, &size, - maxSize, true); + result = SerializeAdapter::serialize(&health, &pointer, &size, + maxSize, SerializeIF::Endianness::BIG); } mutex->unlockMutex(); } @@ -85,7 +85,7 @@ void HealthTable::printAll(uint8_t* pointer, uint32_t maxSize) { ReturnValue_t HealthTable::iterate( std::pair *value, bool reset) { ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; - mutex->lockMutex(MutexIF::NO_TIMEOUT); + mutex->lockMutex(MutexIF::BLOCKING); if (reset) { mapIterator = healthMap.begin(); } diff --git a/health/HealthTable.h b/health/HealthTable.h index 32a7eee2f..6f5dd18d6 100644 --- a/health/HealthTable.h +++ b/health/HealthTable.h @@ -1,9 +1,9 @@ #ifndef HEALTHTABLE_H_ #define HEALTHTABLE_H_ -#include -#include -#include +#include "HealthTableIF.h" +#include "../objectmanager/SystemObject.h" +#include "../ipc/MutexIF.h" #include typedef std::map HealthMap; @@ -21,7 +21,7 @@ public: virtual HasHealthIF::HealthState getHealth(object_id_t); virtual uint32_t getPrintSize(); - virtual void printAll(uint8_t *pointer, uint32_t maxSize); + virtual void printAll(uint8_t *pointer, size_t maxSize); protected: MutexIF* mutex; diff --git a/health/HealthTableIF.h b/health/HealthTableIF.h index 6fdfc2c04..404c03e43 100644 --- a/health/HealthTableIF.h +++ b/health/HealthTableIF.h @@ -1,9 +1,9 @@ #ifndef HEALTHTABLEIF_H_ #define HEALTHTABLEIF_H_ -#include -#include -#include +#include "ManagesHealthIF.h" +#include "../objectmanager/ObjectManagerIF.h" +#include "../returnvalues/HasReturnvaluesIF.h" #include @@ -17,7 +17,7 @@ public: HasHealthIF::HealthState initilialState = HasHealthIF::HEALTHY) = 0; virtual uint32_t getPrintSize() = 0; - virtual void printAll(uint8_t *pointer, uint32_t maxSize) = 0; + virtual void printAll(uint8_t *pointer, size_t maxSize) = 0; protected: virtual ReturnValue_t iterate(std::pair *value, bool reset = false) = 0; diff --git a/health/ManagesHealthIF.h b/health/ManagesHealthIF.h index ff0c53860..42d4c4f04 100644 --- a/health/ManagesHealthIF.h +++ b/health/ManagesHealthIF.h @@ -1,8 +1,8 @@ #ifndef FRAMEWORK_HEALTH_MANAGESHEALTHIF_H_ #define FRAMEWORK_HEALTH_MANAGESHEALTHIF_H_ -#include -#include +#include "HasHealthIF.h" +#include "../objectmanager/ObjectManagerIF.h" class ManagesHealthIF { public: virtual ~ManagesHealthIF() { diff --git a/internalError/InternalErrorReporter.cpp b/internalError/InternalErrorReporter.cpp index 9a8ede002..861e1595e 100644 --- a/internalError/InternalErrorReporter.cpp +++ b/internalError/InternalErrorReporter.cpp @@ -1,10 +1,10 @@ #include "InternalErrorReporter.h" -#include -#include -#include +#include "../datapool/DataSet.h" +#include "../datapool/PoolVariable.h" +#include "../ipc/MutexFactory.h" -#include +#include "../serviceinterface/ServiceInterfaceStream.h" InternalErrorReporter::InternalErrorReporter(object_id_t setObjectId, uint32_t queuePoolId, uint32_t tmPoolId, uint32_t storePoolId) : @@ -54,7 +54,7 @@ void InternalErrorReporter::lostTm() { uint32_t InternalErrorReporter::getAndResetQueueHits() { uint32_t value; - mutex->lockMutex(MutexIF::NO_TIMEOUT); + mutex->lockMutex(MutexIF::BLOCKING); value = queueHits; queueHits = 0; mutex->unlockMutex(); @@ -63,21 +63,21 @@ uint32_t InternalErrorReporter::getAndResetQueueHits() { uint32_t InternalErrorReporter::getQueueHits() { uint32_t value; - mutex->lockMutex(MutexIF::NO_TIMEOUT); + mutex->lockMutex(MutexIF::BLOCKING); value = queueHits; mutex->unlockMutex(); return value; } void InternalErrorReporter::incrementQueueHits() { - mutex->lockMutex(MutexIF::NO_TIMEOUT); + mutex->lockMutex(MutexIF::BLOCKING); queueHits++; mutex->unlockMutex(); } uint32_t InternalErrorReporter::getAndResetTmHits() { uint32_t value; - mutex->lockMutex(MutexIF::NO_TIMEOUT); + mutex->lockMutex(MutexIF::BLOCKING); value = tmHits; tmHits = 0; mutex->unlockMutex(); @@ -86,14 +86,14 @@ uint32_t InternalErrorReporter::getAndResetTmHits() { uint32_t InternalErrorReporter::getTmHits() { uint32_t value; - mutex->lockMutex(MutexIF::NO_TIMEOUT); + mutex->lockMutex(MutexIF::BLOCKING); value = tmHits; mutex->unlockMutex(); return value; } void InternalErrorReporter::incrementTmHits() { - mutex->lockMutex(MutexIF::NO_TIMEOUT); + mutex->lockMutex(MutexIF::BLOCKING); tmHits++; mutex->unlockMutex(); } @@ -104,7 +104,7 @@ void InternalErrorReporter::storeFull() { uint32_t InternalErrorReporter::getAndResetStoreHits() { uint32_t value; - mutex->lockMutex(MutexIF::NO_TIMEOUT); + mutex->lockMutex(MutexIF::BLOCKING); value = storeHits; storeHits = 0; mutex->unlockMutex(); @@ -113,14 +113,14 @@ uint32_t InternalErrorReporter::getAndResetStoreHits() { uint32_t InternalErrorReporter::getStoreHits() { uint32_t value; - mutex->lockMutex(MutexIF::NO_TIMEOUT); + mutex->lockMutex(MutexIF::BLOCKING); value = storeHits; mutex->unlockMutex(); return value; } void InternalErrorReporter::incrementStoreHits() { - mutex->lockMutex(MutexIF::NO_TIMEOUT); + mutex->lockMutex(MutexIF::BLOCKING); storeHits++; mutex->unlockMutex(); } diff --git a/internalError/InternalErrorReporter.h b/internalError/InternalErrorReporter.h index 7c1df6a7b..9aa24a0fa 100644 --- a/internalError/InternalErrorReporter.h +++ b/internalError/InternalErrorReporter.h @@ -3,9 +3,9 @@ #include "InternalErrorReporterIF.h" -#include -#include -#include +#include "../tasks/ExecutableObjectIF.h" +#include "../objectmanager/SystemObject.h" +#include "../ipc/MutexIF.h" class InternalErrorReporter: public SystemObject, public ExecutableObjectIF, diff --git a/ipc/CommandMessage.cpp b/ipc/CommandMessage.cpp index 69a0bfd3d..dbea85333 100644 --- a/ipc/CommandMessage.cpp +++ b/ipc/CommandMessage.cpp @@ -5,15 +5,15 @@ * @author baetz */ -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "../devicehandlers/DeviceHandlerMessage.h" +#include "../health/HealthMessage.h" +#include "CommandMessage.h" +#include "../memory/MemoryMessage.h" +#include "../modes/ModeMessage.h" +#include "../monitoring/MonitoringMessage.h" +#include "../subsystem/modes/ModeSequenceMessage.h" +#include "../tmstorage/TmStoreMessage.h" +#include "../parameters/ParameterMessage.h" namespace messagetypes { void clearMissionMessage(CommandMessage* message); @@ -111,7 +111,7 @@ size_t CommandMessage::getMinimumMessageSize() const { void CommandMessage::setToUnknownCommand() { Command_t initialCommand = getCommand(); clearCommandMessage(); - setReplyRejected(UNKNOW_COMMAND, initialCommand); + setReplyRejected(UNKNOWN_COMMAND, initialCommand); } void CommandMessage::setReplyRejected(ReturnValue_t reason, @@ -120,3 +120,12 @@ void CommandMessage::setReplyRejected(ReturnValue_t reason, setParameter(reason); setParameter2(initialCommand); } + +ReturnValue_t CommandMessage::getReplyRejectedReason( + Command_t *initialCommand) const { + ReturnValue_t reason = getParameter(); + if(initialCommand != nullptr) { + *initialCommand = getParameter2(); + } + return reason; +} diff --git a/ipc/CommandMessage.h b/ipc/CommandMessage.h index 3d563607b..e984ad3d6 100644 --- a/ipc/CommandMessage.h +++ b/ipc/CommandMessage.h @@ -9,10 +9,10 @@ #define COMMANDMESSAGE_H_ -#include +#include "FwMessageTypes.h" #include -#include +#include "MessageQueueMessage.h" #define MAKE_COMMAND_ID( number ) ((MESSAGE_ID << 8) + (number)) typedef ReturnValue_t Command_t; @@ -20,7 +20,7 @@ typedef ReturnValue_t Command_t; class CommandMessage : public MessageQueueMessage { public: static const uint8_t INTERFACE_ID = CLASS_ID::COMMAND_MESSAGE; - static const ReturnValue_t UNKNOW_COMMAND = MAKE_RETURN_CODE(0x01); + static const ReturnValue_t UNKNOWN_COMMAND = MAKE_RETURN_CODE(0x01); static const uint8_t MESSAGE_ID = messagetypes::COMMAND; @@ -124,6 +124,9 @@ public: */ void setToUnknownCommand(); void setReplyRejected(ReturnValue_t reason, Command_t initialCommand = CMD_NONE); + ReturnValue_t getReplyRejectedReason( + Command_t *initialCommand = nullptr) const; + size_t getMinimumMessageSize() const; }; diff --git a/ipc/MessageQueueIF.h b/ipc/MessageQueueIF.h index 18e2d99ab..9fff5287c 100644 --- a/ipc/MessageQueueIF.h +++ b/ipc/MessageQueueIF.h @@ -3,9 +3,9 @@ // COULDDO: We could support blocking calls -#include -#include -#include +#include "MessageQueueMessage.h" +#include "MessageQueueSenderIF.h" +#include "../returnvalues/HasReturnvaluesIF.h" class MessageQueueIF { public: diff --git a/ipc/MessageQueueMessage.cpp b/ipc/MessageQueueMessage.cpp index 30e0325cf..05dde1f53 100644 --- a/ipc/MessageQueueMessage.cpp +++ b/ipc/MessageQueueMessage.cpp @@ -1,5 +1,5 @@ -#include -#include +#include "MessageQueueMessage.h" +#include "../serviceinterface/ServiceInterfaceStream.h" #include diff --git a/ipc/MessageQueueMessage.h b/ipc/MessageQueueMessage.h index 8c4ec947b..aa3559d61 100644 --- a/ipc/MessageQueueMessage.h +++ b/ipc/MessageQueueMessage.h @@ -1,7 +1,7 @@ #ifndef MESSAGEQUEUEMESSAGE_H_ #define MESSAGEQUEUEMESSAGE_H_ -#include +#include "MessageQueueSenderIF.h" #include /** diff --git a/ipc/MessageQueueSenderIF.h b/ipc/MessageQueueSenderIF.h index 9e7e11c03..d9692f540 100644 --- a/ipc/MessageQueueSenderIF.h +++ b/ipc/MessageQueueSenderIF.h @@ -1,7 +1,7 @@ #ifndef FRAMEWORK_IPC_MESSAGEQUEUESENDERIF_H_ #define FRAMEWORK_IPC_MESSAGEQUEUESENDERIF_H_ -#include +#include "../objectmanager/ObjectManagerIF.h" class MessageQueueMessage; diff --git a/ipc/MutexFactory.h b/ipc/MutexFactory.h index b2e58b6e7..f8133d814 100644 --- a/ipc/MutexFactory.h +++ b/ipc/MutexFactory.h @@ -1,7 +1,7 @@ #ifndef FRAMEWORK_IPC_MUTEXFACTORY_H_ #define FRAMEWORK_IPC_MUTEXFACTORY_H_ -#include +#include "MutexIF.h" /** * Creates Mutex. * This class is a "singleton" interface, i.e. it provides an diff --git a/ipc/MutexHelper.h b/ipc/MutexHelper.h index f76ccec47..3dc369213 100644 --- a/ipc/MutexHelper.h +++ b/ipc/MutexHelper.h @@ -1,20 +1,26 @@ #ifndef FRAMEWORK_IPC_MUTEXHELPER_H_ #define FRAMEWORK_IPC_MUTEXHELPER_H_ -#include -#include +#include "MutexFactory.h" +#include "../serviceinterface/ServiceInterfaceStream.h" class MutexHelper { public: - MutexHelper(MutexIF* mutex, uint32_t timeoutMs) : + MutexHelper(MutexIF* mutex, MutexIF::TimeoutType timeoutType = + MutexIF::TimeoutType::BLOCKING, uint32_t timeoutMs = 0) : internalMutex(mutex) { - ReturnValue_t status = mutex->lockMutex(timeoutMs); - if(status != HasReturnvaluesIF::RETURN_OK){ - sif::error << "MutexHelper: Lock of Mutex failed " << status << std::endl; + ReturnValue_t status = mutex->lockMutex(timeoutType, + timeoutMs); + if(status == MutexIF::MUTEX_TIMEOUT) { + sif::error << "MutexHelper: Lock of mutex failed with timeout of " + << timeoutMs << " milliseconds!" << std::endl; + } + else if(status != HasReturnvaluesIF::RETURN_OK){ + sif::error << "MutexHelper: Lock of Mutex failed with code " << + status << std::endl; } } - ~MutexHelper() { internalMutex->unlockMutex(); } diff --git a/ipc/MutexIF.h b/ipc/MutexIF.h index 35786d6a3..5673e4d79 100644 --- a/ipc/MutexIF.h +++ b/ipc/MutexIF.h @@ -1,11 +1,35 @@ #ifndef FRAMEWORK_IPC_MUTEXIF_H_ #define FRAMEWORK_IPC_MUTEXIF_H_ -#include +#include "../returnvalues/HasReturnvaluesIF.h" +/** + * @brief Common interface for OS Mutex objects which provide MUTual EXclusion. + * @details https://en.wikipedia.org/wiki/Lock_(computer_science) + * @ingroup osal + * @ingroup interface + */ class MutexIF { public: - static const uint32_t NO_TIMEOUT; //!< Needs to be defined in implementation. + /** + * Different types of timeout for the mutex lock. + */ + enum TimeoutType { + POLLING, //!< If mutex is not available, return immediately + WAITING, //!< Wait a specified time for the mutex to become available + BLOCKING //!< Block indefinitely until the mutex becomes available. + }; + + /** + * Lock the mutex. The timeout value will only be used for + * TimeoutType::WAITING + * @param timeoutType + * @param timeoutMs + * @return + */ + virtual ReturnValue_t lockMutex(TimeoutType timeoutType = + TimeoutType::BLOCKING, uint32_t timeoutMs = 0) = 0; + virtual ReturnValue_t unlockMutex() = 0; static const uint8_t INTERFACE_ID = CLASS_ID::MUTEX_IF; /** @@ -57,9 +81,7 @@ public: */ static const ReturnValue_t MUTEX_DESTROYED_WHILE_WAITING = MAKE_RETURN_CODE(12); - virtual ~MutexIF() {} - virtual ReturnValue_t lockMutex(uint32_t timeoutMs) = 0; - virtual ReturnValue_t unlockMutex() = 0; + virtual ~MutexIF() {} }; diff --git a/ipc/QueueFactory.h b/ipc/QueueFactory.h index c385b15df..4f4d72c7c 100644 --- a/ipc/QueueFactory.h +++ b/ipc/QueueFactory.h @@ -1,7 +1,7 @@ #ifndef FRAMEWORK_IPC_QUEUEFACTORY_H_ #define FRAMEWORK_IPC_QUEUEFACTORY_H_ -#include +#include "MessageQueueIF.h" #include /** * Creates message queues. @@ -18,8 +18,8 @@ public: */ static QueueFactory* instance(); - MessageQueueIF* createMessageQueue(uint32_t message_depth = 3, - uint32_t max_message_size = MessageQueueMessage::MAX_MESSAGE_SIZE); + MessageQueueIF* createMessageQueue(uint32_t messageDepth = 3, + size_t maxMessageSize = MessageQueueMessage::MAX_MESSAGE_SIZE); void deleteMessageQueue(MessageQueueIF* queue); private: diff --git a/memory/AcceptsMemoryMessagesIF.h b/memory/AcceptsMemoryMessagesIF.h index 2b37f1af2..a1cbddf81 100644 --- a/memory/AcceptsMemoryMessagesIF.h +++ b/memory/AcceptsMemoryMessagesIF.h @@ -8,9 +8,9 @@ #ifndef ACCEPTSMEMORYMESSAGESIF_H_ #define ACCEPTSMEMORYMESSAGESIF_H_ -#include -#include -#include +#include "HasMemoryIF.h" +#include "MemoryMessage.h" +#include "../ipc/MessageQueueSenderIF.h" class AcceptsMemoryMessagesIF : public HasMemoryIF { public: diff --git a/memory/HasMemoryIF.h b/memory/HasMemoryIF.h index cd6e66654..4096d1b74 100644 --- a/memory/HasMemoryIF.h +++ b/memory/HasMemoryIF.h @@ -1,7 +1,7 @@ #ifndef HASMEMORYIF_H_ #define HASMEMORYIF_H_ -#include +#include "../returnvalues/HasReturnvaluesIF.h" class HasMemoryIF { public: diff --git a/memory/MemoryHelper.cpp b/memory/MemoryHelper.cpp index 2a830c5a5..48a605be1 100644 --- a/memory/MemoryHelper.cpp +++ b/memory/MemoryHelper.cpp @@ -1,9 +1,9 @@ -#include -#include -#include -#include -#include -#include +#include "../globalfunctions/CRC.h" +#include "MemoryHelper.h" +#include "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(NULL), ipcAddress(), lastCommand( @@ -53,7 +53,7 @@ void MemoryHelper::completeLoad(ReturnValue_t errorCode, memcpy(copyHere, dataToCopy, size); break; case HasMemoryIF::POINTS_TO_VARIABLE: - EndianSwapper::swap(copyHere, dataToCopy, size); + EndianConverter::convertBigEndian(copyHere, dataToCopy, size); break; case HasMemoryIF::ACTIVITY_COMPLETED: case RETURN_OK: @@ -86,7 +86,7 @@ void MemoryHelper::completeDump(ReturnValue_t errorCode, case HasMemoryIF::POINTS_TO_VARIABLE: //"data" must be valid pointer! if (errorCode == HasMemoryIF::POINTS_TO_VARIABLE) { - EndianSwapper::swap(reservedSpaceInIPC, dataToCopy, size); + EndianConverter::convertBigEndian(reservedSpaceInIPC, dataToCopy, size); } else { memcpy(reservedSpaceInIPC, dataToCopy, size); } @@ -136,7 +136,7 @@ void MemoryHelper::swapMatrixCopy(uint8_t* out, const uint8_t *in, } while (totalSize > 0){ - EndianSwapper::swap(out,in,datatypeSize); + EndianConverter::convertBigEndian(out,in,datatypeSize); out += datatypeSize; in += datatypeSize; totalSize -= datatypeSize; diff --git a/memory/MemoryHelper.h b/memory/MemoryHelper.h index 2ff82eb39..5e1a99b65 100644 --- a/memory/MemoryHelper.h +++ b/memory/MemoryHelper.h @@ -1,10 +1,10 @@ #ifndef MEMORYHELPER_H_ #define MEMORYHELPER_H_ -#include -#include -#include -#include -#include +#include "../ipc/CommandMessage.h" +#include "AcceptsMemoryMessagesIF.h" +#include "../returnvalues/HasReturnvaluesIF.h" +#include "../storagemanager/StorageManagerIF.h" +#include "../ipc/MessageQueueIF.h" class MemoryHelper : public HasReturnvaluesIF { public: diff --git a/memory/MemoryMessage.cpp b/memory/MemoryMessage.cpp index c1116e08a..741565fc0 100644 --- a/memory/MemoryMessage.cpp +++ b/memory/MemoryMessage.cpp @@ -1,5 +1,5 @@ -#include -#include +#include "MemoryMessage.h" +#include "../objectmanager/ObjectManagerIF.h" MemoryMessage::MemoryMessage() { } diff --git a/memory/MemoryMessage.h b/memory/MemoryMessage.h index 48badb05f..a4c2de632 100644 --- a/memory/MemoryMessage.h +++ b/memory/MemoryMessage.h @@ -1,8 +1,8 @@ #ifndef MEMORYMESSAGE_H_ #define MEMORYMESSAGE_H_ -#include -#include +#include "../ipc/CommandMessage.h" +#include "../storagemanager/StorageManagerIF.h" class MemoryMessage { diff --git a/memory/MemoryProxyIF.h b/memory/MemoryProxyIF.h index d325ba4eb..1494d5238 100644 --- a/memory/MemoryProxyIF.h +++ b/memory/MemoryProxyIF.h @@ -1,7 +1,7 @@ #ifndef FRAMEWORK_MEMORY_MEMORYPROXYIF_H_ #define FRAMEWORK_MEMORY_MEMORYPROXYIF_H_ -#include +#include "AcceptsMemoryMessagesIF.h" /** * This was a nice idea to transparently forward incoming messages to another object. diff --git a/modes/HasModesIF.h b/modes/HasModesIF.h index 263b0a87f..4381046cd 100644 --- a/modes/HasModesIF.h +++ b/modes/HasModesIF.h @@ -8,10 +8,10 @@ #ifndef HASMODESIF_H_ #define HASMODESIF_H_ -#include -#include -#include -#include +#include "../events/Event.h" +#include "ModeHelper.h" +#include "ModeMessage.h" +#include "../returnvalues/HasReturnvaluesIF.h" #include diff --git a/modes/ModeHelper.cpp b/modes/ModeHelper.cpp index 7b98bdc64..cb62c4687 100644 --- a/modes/ModeHelper.cpp +++ b/modes/ModeHelper.cpp @@ -1,6 +1,6 @@ -#include -#include -#include +#include "HasModesIF.h" +#include "ModeHelper.h" +#include "../ipc/MessageQueueSenderIF.h" ModeHelper::ModeHelper(HasModesIF *owner) : theOneWhoCommandedAMode(0), commandedMode(HasModesIF::MODE_OFF), commandedSubmode( diff --git a/modes/ModeHelper.h b/modes/ModeHelper.h index 87f6d4112..542fe780d 100644 --- a/modes/ModeHelper.h +++ b/modes/ModeHelper.h @@ -1,9 +1,9 @@ #ifndef MODEHELPER_H_ #define MODEHELPER_H_ -#include -#include -#include +#include "ModeMessage.h" +#include "../returnvalues/HasReturnvaluesIF.h" +#include "../timemanager/Countdown.h" class HasModesIF; diff --git a/modes/ModeMessage.cpp b/modes/ModeMessage.cpp index 1d3baad54..14dbbb314 100644 --- a/modes/ModeMessage.cpp +++ b/modes/ModeMessage.cpp @@ -1,4 +1,4 @@ -#include +#include "ModeMessage.h" Mode_t ModeMessage::getMode(const CommandMessage* message) { return message->getParameter(); diff --git a/modes/ModeMessage.h b/modes/ModeMessage.h index 675c614b2..925f3fc16 100644 --- a/modes/ModeMessage.h +++ b/modes/ModeMessage.h @@ -8,7 +8,7 @@ #ifndef MODEMESSAGE_H_ #define MODEMESSAGE_H_ -#include +#include "../ipc/CommandMessage.h" typedef uint32_t Mode_t; typedef uint8_t Submode_t; diff --git a/monitoring/AbsLimitMonitor.h b/monitoring/AbsLimitMonitor.h index 3525ba2c7..2e60f6f8c 100644 --- a/monitoring/AbsLimitMonitor.h +++ b/monitoring/AbsLimitMonitor.h @@ -1,7 +1,7 @@ #ifndef FRAMEWORK_MONITORING_ABSLIMITMONITOR_H_ #define FRAMEWORK_MONITORING_ABSLIMITMONITOR_H_ -#include +#include "MonitorBase.h" #include template diff --git a/monitoring/HasMonitorsIF.h b/monitoring/HasMonitorsIF.h index 6f1dc1b3e..85d92b6b9 100644 --- a/monitoring/HasMonitorsIF.h +++ b/monitoring/HasMonitorsIF.h @@ -7,9 +7,9 @@ #ifndef HASMONITORSIF_H_ #define HASMONITORSIF_H_ -#include -#include -#include +#include "../events/EventReportingProxyIF.h" +#include "../objectmanager/ObjectManagerIF.h" +#include "../ipc/MessageQueueSenderIF.h" class HasMonitorsIF { public: diff --git a/monitoring/LimitMonitor.h b/monitoring/LimitMonitor.h index 45abe48bf..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 +#include "MonitorBase.h" /** * Variant of a limit checking class. diff --git a/monitoring/LimitViolationReporter.cpp b/monitoring/LimitViolationReporter.cpp index 760e8b93d..c531a6e69 100644 --- a/monitoring/LimitViolationReporter.cpp +++ b/monitoring/LimitViolationReporter.cpp @@ -4,11 +4,11 @@ * @date 17.07.2014 * @author baetz */ -#include -#include -#include -#include -#include +#include "LimitViolationReporter.h" +#include "MonitoringIF.h" +#include "ReceivesMonitoringReportsIF.h" +#include "../objectmanager/ObjectManagerIF.h" +#include "../serialize/SerializeAdapter.h" ReturnValue_t LimitViolationReporter::sendLimitViolationReport(const SerializeIF* data) { ReturnValue_t result = checkClassLoaded(); @@ -17,7 +17,7 @@ ReturnValue_t LimitViolationReporter::sendLimitViolationReport(const SerializeIF } store_address_t storeId; uint8_t* dataTarget = NULL; - uint32_t maxSize = data->getSerializedSize(); + size_t maxSize = data->getSerializedSize(); if (maxSize > MonitoringIF::VIOLATION_REPORT_MAX_SIZE) { return MonitoringIF::INVALID_SIZE; } @@ -26,8 +26,8 @@ ReturnValue_t LimitViolationReporter::sendLimitViolationReport(const SerializeIF if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - uint32_t size = 0; - result = data->serialize(&dataTarget, &size, maxSize, true); + size_t size = 0; + result = data->serialize(&dataTarget, &size, maxSize, SerializeIF::Endianness::BIG); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } diff --git a/monitoring/LimitViolationReporter.h b/monitoring/LimitViolationReporter.h index 3a9d04ddc..a71b972ff 100644 --- a/monitoring/LimitViolationReporter.h +++ b/monitoring/LimitViolationReporter.h @@ -7,10 +7,10 @@ #ifndef LIMITVIOLATIONREPORTER_H_ #define LIMITVIOLATIONREPORTER_H_ -#include -#include -#include -#include +#include "../returnvalues/HasReturnvaluesIF.h" +#include "../serialize/SerializeIF.h" +#include "../storagemanager/StorageManagerIF.h" +#include "../ipc/MessageQueueSenderIF.h" namespace Factory{ void setStaticFrameworkObjectIds(); diff --git a/monitoring/MonitorBase.h b/monitoring/MonitorBase.h index 796226452..b2d0e6cbb 100644 --- a/monitoring/MonitorBase.h +++ b/monitoring/MonitorBase.h @@ -1,12 +1,12 @@ #ifndef MONITORBASE_H_ #define MONITORBASE_H_ -#include -#include -#include -#include -#include -#include +#include "../datapool/DataSet.h" +#include "../datapool/PIDReader.h" +#include "LimitViolationReporter.h" +#include "MonitoringIF.h" +#include "MonitoringMessageContent.h" +#include "MonitorReporter.h" /** * Base class for monitoring of parameters. diff --git a/monitoring/MonitorReporter.h b/monitoring/MonitorReporter.h index 6274313f6..ca2b534b9 100644 --- a/monitoring/MonitorReporter.h +++ b/monitoring/MonitorReporter.h @@ -1,11 +1,11 @@ #ifndef FRAMEWORK_MONITORING_MONITORREPORTER_H_ #define FRAMEWORK_MONITORING_MONITORREPORTER_H_ -#include -#include -#include -#include -#include +#include "../events/EventManagerIF.h" +#include "LimitViolationReporter.h" +#include "MonitoringIF.h" +#include "MonitoringMessageContent.h" +#include "../parameters/HasParametersIF.h" template class MonitorReporter: public HasParametersIF { diff --git a/monitoring/MonitoringIF.h b/monitoring/MonitoringIF.h index d2d62f351..44218c36d 100644 --- a/monitoring/MonitoringIF.h +++ b/monitoring/MonitoringIF.h @@ -1,9 +1,9 @@ #ifndef MONITORINGIF_H_ #define MONITORINGIF_H_ -#include -#include -#include +#include "../memory/HasMemoryIF.h" +#include "MonitoringMessage.h" +#include "../serialize/SerializeIF.h" class MonitoringIF : public SerializeIF { public: diff --git a/monitoring/MonitoringMessage.cpp b/monitoring/MonitoringMessage.cpp index 77919bfe8..8caa27aee 100644 --- a/monitoring/MonitoringMessage.cpp +++ b/monitoring/MonitoringMessage.cpp @@ -1,5 +1,5 @@ -#include -#include +#include "MonitoringMessage.h" +#include "../objectmanager/ObjectManagerIF.h" MonitoringMessage::~MonitoringMessage() { } diff --git a/monitoring/MonitoringMessage.h b/monitoring/MonitoringMessage.h index 793e1fbf3..84b027504 100644 --- a/monitoring/MonitoringMessage.h +++ b/monitoring/MonitoringMessage.h @@ -1,8 +1,8 @@ #ifndef MONITORINGMESSAGE_H_ #define MONITORINGMESSAGE_H_ -#include -#include +#include "../ipc/CommandMessage.h" +#include "../storagemanager/StorageManagerIF.h" class MonitoringMessage: public CommandMessage { public: diff --git a/monitoring/MonitoringMessageContent.h b/monitoring/MonitoringMessageContent.h index 7e1aca626..c82506f3a 100644 --- a/monitoring/MonitoringMessageContent.h +++ b/monitoring/MonitoringMessageContent.h @@ -1,15 +1,15 @@ #ifndef MONITORINGMESSAGECONTENT_H_ #define MONITORINGMESSAGECONTENT_H_ -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "HasMonitorsIF.h" +#include "MonitoringIF.h" +#include "../objectmanager/ObjectManagerIF.h" +#include "../serialize/SerialBufferAdapter.h" +#include "../serialize/SerialFixedArrayListAdapter.h" +#include "../serialize/SerializeElement.h" +#include "../serialize/SerialLinkedListAdapter.h" +#include "../serviceinterface/ServiceInterfaceStream.h" +#include "../timemanager/TimeStamperIF.h" namespace Factory{ void setStaticFrameworkObjectIds(); diff --git a/monitoring/ReceivesMonitoringReportsIF.h b/monitoring/ReceivesMonitoringReportsIF.h index 42c365c16..fb37c16c4 100644 --- a/monitoring/ReceivesMonitoringReportsIF.h +++ b/monitoring/ReceivesMonitoringReportsIF.h @@ -1,7 +1,7 @@ #ifndef RECEIVESMONITORINGREPORTSIF_H_ #define RECEIVESMONITORINGREPORTSIF_H_ -#include +#include "../ipc/MessageQueueSenderIF.h" class ReceivesMonitoringReportsIF { public: diff --git a/monitoring/TriplexMonitor.h b/monitoring/TriplexMonitor.h index 9a2e69c3b..9b60aeb63 100644 --- a/monitoring/TriplexMonitor.h +++ b/monitoring/TriplexMonitor.h @@ -1,11 +1,11 @@ #ifndef FRAMEWORK_MONITORING_TRIPLEXMONITOR_H_ #define FRAMEWORK_MONITORING_TRIPLEXMONITOR_H_ -#include -#include -#include -#include -#include +#include "../datapool/DataSet.h" +#include "../datapool/PIDReaderList.h" +#include "../health/HealthTableIF.h" +#include "../parameters/HasParametersIF.h" +#include "../objectmanager/ObjectManagerIF.h" //SHOULDDO: This is by far not perfect. Could be merged with new Monitor classes. But still, it's over-engineering. diff --git a/monitoring/TwoValueLimitMonitor.h b/monitoring/TwoValueLimitMonitor.h index c17ad4337..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 +#include "LimitMonitor.h" template class TwoValueLimitMonitor: public LimitMonitor { diff --git a/objectmanager/ObjectManager.cpp b/objectmanager/ObjectManager.cpp index 1c54355a3..dd0ae1886 100644 --- a/objectmanager/ObjectManager.cpp +++ b/objectmanager/ObjectManager.cpp @@ -1,5 +1,5 @@ -#include -#include +#include "ObjectManager.h" +#include "../serviceinterface/ServiceInterfaceStream.h" #include #include diff --git a/objectmanager/ObjectManager.h b/objectmanager/ObjectManager.h index 634510713..0d2b3c4ae 100644 --- a/objectmanager/ObjectManager.h +++ b/objectmanager/ObjectManager.h @@ -8,8 +8,8 @@ #ifndef OBJECTMANAGER_H_ #define OBJECTMANAGER_H_ -#include -#include +#include "ObjectManagerIF.h" +#include "SystemObjectIF.h" #include /** diff --git a/objectmanager/ObjectManagerIF.h b/objectmanager/ObjectManagerIF.h index 90a1ce3be..e0162af99 100644 --- a/objectmanager/ObjectManagerIF.h +++ b/objectmanager/ObjectManagerIF.h @@ -1,10 +1,10 @@ #ifndef FRAMEWORK_OBJECTMANAGER_OBJECTMANAGERIF_H_ #define FRAMEWORK_OBJECTMANAGER_OBJECTMANAGERIF_H_ -#include -#include -#include -#include +#include "frameworkObjects.h" +#include "SystemObjectIF.h" +#include "../returnvalues/HasReturnvaluesIF.h" +#include "../serviceinterface/ServiceInterfaceStream.h" /** * @brief This class provides an interface to the global object manager. @@ -21,7 +21,8 @@ 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: diff --git a/objectmanager/SystemObject.cpp b/objectmanager/SystemObject.cpp index 85daaa358..53aac599f 100644 --- a/objectmanager/SystemObject.cpp +++ b/objectmanager/SystemObject.cpp @@ -1,6 +1,6 @@ -#include -#include -#include +#include "../events/EventManagerIF.h" +#include "ObjectManager.h" +#include "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 6a1b35b6f..8e9f20d5e 100644 --- a/objectmanager/SystemObject.h +++ b/objectmanager/SystemObject.h @@ -8,10 +8,10 @@ #ifndef SYSTEMOBJECT_H_ #define SYSTEMOBJECT_H_ -#include -#include -#include -#include +#include "../events/Event.h" +#include "../events/EventReportingProxyIF.h" +#include "SystemObjectIF.h" +#include "../timemanager/Clock.h" /** * @brief This class automates insertion into the ObjectManager and diff --git a/objectmanager/SystemObjectIF.h b/objectmanager/SystemObjectIF.h index 7540f80fb..c5a921964 100644 --- a/objectmanager/SystemObjectIF.h +++ b/objectmanager/SystemObjectIF.h @@ -8,8 +8,8 @@ #ifndef SYSTEMOBJECTIF_H_ #define SYSTEMOBJECTIF_H_ -#include -#include +#include "../events/EventReportingProxyIF.h" +#include "../returnvalues/HasReturnvaluesIF.h" #include /** * \defgroup system_objects Software System Object Management diff --git a/osal/FreeRTOS/Clock.cpp b/osal/FreeRTOS/Clock.cpp index cffc2125e..acfa98d7a 100644 --- a/osal/FreeRTOS/Clock.cpp +++ b/osal/FreeRTOS/Clock.cpp @@ -1,16 +1,18 @@ -#include -#include -#include +#include "../../timemanager/Clock.h" +#include "../../globalfunctions/timevalOperations.h" #include "Timekeeper.h" -#include -#include +#include +#include + +#include +#include //TODO sanitize input? //TODO much of this code can be reused for tick-only systems uint16_t Clock::leapSeconds = 0; -MutexIF* Clock::timeMutex = NULL; +MutexIF* Clock::timeMutex = nullptr; uint32_t Clock::getTicksPerSecond(void) { return 1000; @@ -56,7 +58,6 @@ ReturnValue_t Clock::getUptime(timeval* uptime) { timeval Clock::getUptime() { TickType_t ticksSinceStart = xTaskGetTickCount(); - return Timekeeper::ticksToTimeval(ticksSinceStart); } @@ -128,7 +129,7 @@ ReturnValue_t Clock::convertTimevalToJD2000(timeval time, double* JD2000) { ReturnValue_t Clock::convertUTCToTT(timeval utc, timeval* tt) { //SHOULDDO: works not for dates in the past (might have less leap seconds) - if (timeMutex == NULL) { + if (timeMutex == nullptr) { return HasReturnvaluesIF::RETURN_FAILED; } @@ -154,7 +155,7 @@ ReturnValue_t Clock::setLeapSeconds(const uint16_t leapSeconds_) { if (checkOrCreateClockMutex() != HasReturnvaluesIF::RETURN_OK) { return HasReturnvaluesIF::RETURN_FAILED; } - ReturnValue_t result = timeMutex->lockMutex(MutexIF::NO_TIMEOUT); + ReturnValue_t result = timeMutex->lockMutex(MutexIF::BLOCKING); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } @@ -169,7 +170,7 @@ ReturnValue_t Clock::getLeapSeconds(uint16_t* leapSeconds_) { if (timeMutex == NULL) { return HasReturnvaluesIF::RETURN_FAILED; } - ReturnValue_t result = timeMutex->lockMutex(MutexIF::NO_TIMEOUT); + ReturnValue_t result = timeMutex->lockMutex(MutexIF::BLOCKING); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } diff --git a/osal/FreeRTOS/FixedTimeslotTask.cpp b/osal/FreeRTOS/FixedTimeslotTask.cpp index fb3c3b03e..902502f95 100644 --- a/osal/FreeRTOS/FixedTimeslotTask.cpp +++ b/osal/FreeRTOS/FixedTimeslotTask.cpp @@ -1,6 +1,7 @@ -#include #include "FixedTimeslotTask.h" +#include "../../serviceinterface/ServiceInterfaceStream.h" + uint32_t FixedTimeslotTask::deadlineMissedCount = 0; const size_t PeriodicTaskIF::MINIMUM_STACK_SIZE = configMINIMAL_STACK_SIZE; @@ -18,16 +19,19 @@ FixedTimeslotTask::~FixedTimeslotTask() { void FixedTimeslotTask::taskEntryPoint(void* argument) { - //The argument is re-interpreted as FixedTimeslotTask. The Task object is global, so it is found from any place. + // The argument is re-interpreted as FixedTimeslotTask. The Task object is + // global, so it is found from any place. FixedTimeslotTask *originalTask(reinterpret_cast(argument)); - // Task should not start until explicitly requested - // in FreeRTOS, tasks start as soon as they are created if the scheduler is running - // but not if the scheduler is not running. - // to be able to accommodate both cases we check a member which is set in #startTask() - // if it is not set and we get here, the scheduler was started before #startTask() was called and we need to suspend - // if it is set, the scheduler was not running before #startTask() was called and we can continue + /* Task should not start until explicitly requested, + * but in FreeRTOS, tasks start as soon as they are created if the scheduler + * is running but not if the scheduler is not running. + * To be able to accommodate both cases we check a member which is set in + * #startTask(). If it is not set and we get here, the scheduler was started + * before #startTask() was called and we need to suspend if it is set, + * the scheduler was not running before #startTask() was called and we + * can continue */ - if (!originalTask->started) { + if (not originalTask->started) { vTaskSuspend(NULL); } @@ -58,11 +62,6 @@ ReturnValue_t FixedTimeslotTask::startTask() { ReturnValue_t FixedTimeslotTask::addSlot(object_id_t componentId, uint32_t slotTimeMs, int8_t executionStep) { if (objectManager->get(componentId) != nullptr) { - if(slotTimeMs == 0) { - // FreeRTOS throws a sanity error for zero values, so we set - // the time to one millisecond. - slotTimeMs = 1; - } pst.addSlot(componentId, slotTimeMs, executionStep, this); return HasReturnvaluesIF::RETURN_OK; } @@ -81,43 +80,78 @@ ReturnValue_t FixedTimeslotTask::checkSequence() const { } void FixedTimeslotTask::taskFunctionality() { - // A local iterator for the Polling Sequence Table is created to find the start time for the first entry. - std::list::iterator it = pst.current; + // A local iterator for the Polling Sequence Table is created to find the + // start time for the first entry. + FixedSlotSequence::SlotListIter slotListIter = pst.current; //The start time for the first entry is read. - uint32_t intervalMs = (*it)->pollingTimeMs; + uint32_t intervalMs = slotListIter->pollingTimeMs; TickType_t interval = pdMS_TO_TICKS(intervalMs); TickType_t xLastWakeTime; /* The xLastWakeTime variable needs to be initialized with the current tick - count. Note that this is the only time the variable is written to explicitly. - After this assignment, xLastWakeTime is updated automatically internally within - vTaskDelayUntil(). */ + count. Note that this is the only time the variable is written to + explicitly. After this assignment, xLastWakeTime is updated automatically + internally within vTaskDelayUntil(). */ xLastWakeTime = xTaskGetTickCount(); // wait for first entry's start time - vTaskDelayUntil(&xLastWakeTime, interval); + if(interval > 0) { + vTaskDelayUntil(&xLastWakeTime, interval); + } /* Enter the loop that defines the task behavior. */ for (;;) { //The component for this slot is executed and the next one is chosen. - this->pst.executeAndAdvance(); - if (pst.slotFollowsImmediately()) { - //Do nothing - } else { - // we need to wait before executing the current slot - //this gives us the time to wait: - intervalMs = this->pst.getIntervalToPreviousSlotMs(); - interval = pdMS_TO_TICKS(intervalMs); - vTaskDelayUntil(&xLastWakeTime, interval); - //TODO deadline missed check - } + this->pst.executeAndAdvance(); + if (not pst.slotFollowsImmediately()) { + // Get the interval till execution of the next slot. + intervalMs = this->pst.getIntervalToPreviousSlotMs(); + interval = pdMS_TO_TICKS(intervalMs); + checkMissedDeadline(xLastWakeTime, interval); + + // Wait for the interval. This exits immediately if a deadline was + // missed while also updating the last wake time. + vTaskDelayUntil(&xLastWakeTime, interval); + } } } +void FixedTimeslotTask::checkMissedDeadline(const TickType_t xLastWakeTime, + const TickType_t interval) { + /* Check whether deadline was missed while also taking overflows + * into account. Drawing this on paper with a timeline helps to understand + * it. */ + TickType_t currentTickCount = xTaskGetTickCount(); + TickType_t timeToWake = xLastWakeTime + interval; + // Time to wake has not overflown. + if(timeToWake > xLastWakeTime) { + /* If the current time has overflown exclusively or the current + * tick count is simply larger than the time to wake, a deadline was + * missed */ + if((currentTickCount < xLastWakeTime) or (currentTickCount > timeToWake)) { + handleMissedDeadline(); + } + } + /* Time to wake has overflown. A deadline was missed if the current time + * is larger than the time to wake */ + else if((timeToWake < xLastWakeTime) and (currentTickCount > timeToWake)) { + handleMissedDeadline(); + } +} + +void FixedTimeslotTask::handleMissedDeadline() { +#ifdef DEBUG + sif::warning << "FixedTimeslotTask: " << pcTaskGetName(NULL) << + " missed deadline!\n" << std::flush; +#endif + if(deadlineMissedFunc != nullptr) { + this->deadlineMissedFunc(); + } +} + ReturnValue_t FixedTimeslotTask::sleepFor(uint32_t ms) { vTaskDelay(pdMS_TO_TICKS(ms)); return HasReturnvaluesIF::RETURN_OK; } - diff --git a/osal/FreeRTOS/FixedTimeslotTask.h b/osal/FreeRTOS/FixedTimeslotTask.h index bed130511..d65f1fe43 100644 --- a/osal/FreeRTOS/FixedTimeslotTask.h +++ b/osal/FreeRTOS/FixedTimeslotTask.h @@ -1,24 +1,27 @@ -#ifndef POLLINGTASK_H_ -#define POLLINGTASK_H_ +#ifndef FRAMEWORK_OSAL_FREERTOS_FIXEDTIMESLOTTASK_H_ +#define FRAMEWORK_OSAL_FREERTOS_FIXEDTIMESLOTTASK_H_ -#include -#include -#include +#include "../../devicehandlers/FixedSlotSequence.h" +#include "../../tasks/FixedTimeslotTaskIF.h" +#include "../../tasks/Typedef.h" -#include -#include "task.h" +#include +#include class FixedTimeslotTask: public FixedTimeslotTaskIF { public: + /** - * @brief The standard constructor of the class. - * - * @details This is the general constructor of the class. In addition to the TaskBase parameters, - * the following variables are passed: - * - * @param (*setDeadlineMissedFunc)() The function pointer to the deadline missed function that shall be assigned. - * - * @param getPst The object id of the completely initialized polling sequence. + * Keep in mind that you need to call before vTaskStartScheduler()! + * A lot of task parameters are set in "FreeRTOSConfig.h". + * @param name Name of the task, lenght limited by configMAX_TASK_NAME_LEN + * @param setPriority Number of priorities specified by + * configMAX_PRIORITIES. High taskPriority_ number means high priority. + * @param setStack Stack size in words (not bytes!). + * Lower limit specified by configMINIMAL_STACK_SIZE + * @param overallPeriod Period in seconds. + * @param setDeadlineMissedFunc Callback if a deadline was missed. + * @return Pointer to the newly created task. */ FixedTimeslotTask(const char *name, TaskPriority setPriority, TaskStackSize setStack, TaskPeriod overallPeriod, @@ -26,16 +29,18 @@ public: /** * @brief The destructor of the class. - * - * @details The destructor frees all heap memory that was allocated on thread initialization for the PST and - * the device handlers. This is done by calling the PST's destructor. + * @details + * The destructor frees all heap memory that was allocated on thread + * initialization for the PST and the device handlers. This is done by + * calling the PST's destructor. */ virtual ~FixedTimeslotTask(void); ReturnValue_t startTask(void); /** * This static function can be used as #deadlineMissedFunc. - * It counts missedDeadlines and prints the number of missed deadlines every 10th time. + * It counts missedDeadlines and prints the number of missed deadlines + * every 10th time. */ static void missedDeadlineCounter(); /** @@ -44,13 +49,14 @@ public: static uint32_t deadlineMissedCount; ReturnValue_t addSlot(object_id_t componentId, uint32_t slotTimeMs, - int8_t executionStep); + int8_t executionStep) override; - uint32_t getPeriodMs() const; + uint32_t getPeriodMs() const override; - ReturnValue_t checkSequence() const; + ReturnValue_t checkSequence() const override; + + ReturnValue_t sleepFor(uint32_t ms) override; - ReturnValue_t sleepFor(uint32_t ms); protected: bool started; TaskHandle_t handle; @@ -58,32 +64,35 @@ protected: FixedSlotSequence pst; /** - * @brief This attribute holds a function pointer that is executed when a deadline was missed. - * - * @details Another function may be announced to determine the actions to perform when a deadline was missed. - * Currently, only one function for missing any deadline is allowed. - * If not used, it shall be declared NULL. + * @brief This attribute holds a function pointer that is executed when + * a deadline was missed. + * @details + * Another function may be announced to determine the actions to perform + * when a deadline was missed. Currently, only one function for missing + * any deadline is allowed. If not used, it shall be declared NULL. */ void (*deadlineMissedFunc)(void); /** - * @brief This is the entry point in a new polling thread. - * - * @details This method, that is the generalOSAL::checkAndRestartPeriod( this->periodId, interval ); entry point in the new thread, is here set to generate - * and link the Polling Sequence Table to the thread object and start taskFunctionality() - * on success. If operation of the task is ended for some reason, - * the destructor is called to free allocated memory. + * @brief This is the entry point for a new task. + * @details + * This method starts the task by calling taskFunctionality(), as soon as + * all requirements (task scheduler has started and startTask() + * has been called) are met. */ static void taskEntryPoint(void* argument); /** * @brief This function holds the main functionality of the thread. - * - * - * @details Holding the main functionality of the task, this method is most important. - * It links the functionalities provided by FixedSlotSequence with the OS's System Calls - * to keep the timing of the periods. + * @details + * Core function holding the main functionality of the task + * It links the functionalities provided by FixedSlotSequence with the + * OS's System Calls to keep the timing of the periods. */ void taskFunctionality(void); + + void checkMissedDeadline(const TickType_t xLastWakeTime, + const TickType_t interval); + void handleMissedDeadline(); }; -#endif /* POLLINGTASK_H_ */ +#endif /* FRAMEWORK_OSAL_FREERTOS_FIXEDTIMESLOTTASK_H_ */ diff --git a/osal/FreeRTOS/MessageQueue.cpp b/osal/FreeRTOS/MessageQueue.cpp index 18e7aa3d0..3bbd4d9d7 100644 --- a/osal/FreeRTOS/MessageQueue.cpp +++ b/osal/FreeRTOS/MessageQueue.cpp @@ -1,6 +1,6 @@ #include "MessageQueue.h" -#include +#include "../../serviceinterface/ServiceInterfaceStream.h" // TODO I guess we should have a way of checking if we are in an ISR and then use the "fromISR" versions of all calls diff --git a/osal/FreeRTOS/MessageQueue.h b/osal/FreeRTOS/MessageQueue.h index 32f41b44d..aa3d54c13 100644 --- a/osal/FreeRTOS/MessageQueue.h +++ b/osal/FreeRTOS/MessageQueue.h @@ -1,9 +1,9 @@ #ifndef MESSAGEQUEUE_H_ #define MESSAGEQUEUE_H_ -#include -#include -#include +#include "../../internalError/InternalErrorReporterIF.h" +#include "../../ipc/MessageQueueIF.h" +#include "../../ipc/MessageQueueMessage.h" #include #include diff --git a/osal/FreeRTOS/Mutex.cpp b/osal/FreeRTOS/Mutex.cpp index 7c5110915..e5896c411 100644 --- a/osal/FreeRTOS/Mutex.cpp +++ b/osal/FreeRTOS/Mutex.cpp @@ -1,28 +1,32 @@ -#include "Mutex.h" +#include -#include - -const uint32_t MutexIF::NO_TIMEOUT = 0; +#include "../../serviceinterface/ServiceInterfaceStream.h" Mutex::Mutex() { handle = xSemaphoreCreateMutex(); - //TODO print error + if(handle == nullptr) { + sif::error << "Mutex::Mutex(FreeRTOS): Creation failure" << std::endl; + } } Mutex::~Mutex() { - if (handle != 0) { + if (handle != nullptr) { vSemaphoreDelete(handle); } } -ReturnValue_t Mutex::lockMutex(uint32_t timeoutMs) { - if (handle == 0) { - //TODO Does not exist - return HasReturnvaluesIF::RETURN_FAILED; +ReturnValue_t Mutex::lockMutex(TimeoutType timeoutType, + uint32_t timeoutMs) { + if (handle == nullptr) { + return MutexIF::MUTEX_NOT_FOUND; } - TickType_t timeout = portMAX_DELAY; - if (timeoutMs != NO_TIMEOUT) { + // If the timeout type is BLOCKING, this will be the correct value. + uint32_t timeout = portMAX_DELAY; + if(timeoutType == TimeoutType::POLLING) { + timeout = 0; + } + else if(timeoutType == TimeoutType::WAITING){ timeout = pdMS_TO_TICKS(timeoutMs); } @@ -30,21 +34,18 @@ ReturnValue_t Mutex::lockMutex(uint32_t timeoutMs) { if (returncode == pdPASS) { return HasReturnvaluesIF::RETURN_OK; } else { - //TODO could not be acquired/timeout - return HasReturnvaluesIF::RETURN_FAILED; + return MutexIF::MUTEX_TIMEOUT; } } ReturnValue_t Mutex::unlockMutex() { - if (handle == 0) { - //TODO Does not exist - return HasReturnvaluesIF::RETURN_FAILED; + if (handle == nullptr) { + return MutexIF::MUTEX_NOT_FOUND; } BaseType_t returncode = xSemaphoreGive(handle); if (returncode == pdPASS) { return HasReturnvaluesIF::RETURN_OK; } else { - //TODO is not owner - return HasReturnvaluesIF::RETURN_FAILED; + return MutexIF::CURR_THREAD_DOES_NOT_OWN_MUTEX; } } diff --git a/osal/FreeRTOS/Mutex.h b/osal/FreeRTOS/Mutex.h index 91f295853..156d431c2 100644 --- a/osal/FreeRTOS/Mutex.h +++ b/osal/FreeRTOS/Mutex.h @@ -1,22 +1,29 @@ -#ifndef OS_RTEMS_MUTEX_H_ -#define OS_RTEMS_MUTEX_H_ - -#include - - -#include -#include "semphr.h" +#ifndef FRAMEWORK_FREERTOS_MUTEX_H_ +#define FRAMEWORK_FREERTOS_MUTEX_H_ +#include "../../ipc/MutexIF.h" +#include +#include +/** + * @brief OS component to implement MUTual EXclusion + * + * @details + * Mutexes are binary semaphores which include a priority inheritance mechanism. + * Documentation: https://www.freertos.org/Real-time-embedded-RTOS-mutexes.html + * @ingroup osal + */ class Mutex : public MutexIF { public: Mutex(); ~Mutex(); - ReturnValue_t lockMutex(uint32_t timeoutMs); - ReturnValue_t unlockMutex(); + ReturnValue_t lockMutex(TimeoutType timeoutType, + uint32_t timeoutMs) override; + ReturnValue_t unlockMutex() override; + private: SemaphoreHandle_t handle; }; -#endif /* OS_RTEMS_MUTEX_H_ */ +#endif /* FRAMEWORK_FREERTOS_MUTEX_H_ */ diff --git a/osal/FreeRTOS/MutexFactory.cpp b/osal/FreeRTOS/MutexFactory.cpp index cadb54fbd..75b63d078 100644 --- a/osal/FreeRTOS/MutexFactory.cpp +++ b/osal/FreeRTOS/MutexFactory.cpp @@ -1,4 +1,4 @@ -#include +#include "../../ipc/MutexFactory.h" #include "../FreeRTOS/Mutex.h" diff --git a/osal/FreeRTOS/PeriodicTask.cpp b/osal/FreeRTOS/PeriodicTask.cpp index deab2dc15..99c99baf7 100644 --- a/osal/FreeRTOS/PeriodicTask.cpp +++ b/osal/FreeRTOS/PeriodicTask.cpp @@ -1,17 +1,19 @@ -#include -#include #include "PeriodicTask.h" +#include "../../serviceinterface/ServiceInterfaceStream.h" +#include "../../tasks/ExecutableObjectIF.h" + PeriodicTask::PeriodicTask(const char *name, TaskPriority setPriority, TaskStackSize setStack, TaskPeriod setPeriod, void (*setDeadlineMissedFunc)()) : started(false), handle(NULL), period(setPeriod), deadlineMissedFunc( - setDeadlineMissedFunc) { - - BaseType_t status = xTaskCreate(taskEntryPoint, name, setStack, this, setPriority, &handle); + setDeadlineMissedFunc) +{ + BaseType_t status = xTaskCreate(taskEntryPoint, name, + setStack, this, setPriority, &handle); if(status != pdPASS){ - sif::debug << "PeriodicTask Insufficient heap memory remaining. Status: " - << status << std::endl; + sif::debug << "PeriodicTask Insufficient heap memory remaining. " + "Status: " << status << std::endl; } } @@ -21,16 +23,19 @@ PeriodicTask::~PeriodicTask(void) { } void PeriodicTask::taskEntryPoint(void* argument) { - //The argument is re-interpreted as PeriodicTask. The Task object is global, so it is found from any place. + // The argument is re-interpreted as PeriodicTask. The Task object is + // global, so it is found from any place. PeriodicTask *originalTask(reinterpret_cast(argument)); - // Task should not start until explicitly requested - // in FreeRTOS, tasks start as soon as they are created if the scheduler is running - // but not if the scheduler is not running. - // to be able to accommodate both cases we check a member which is set in #startTask() - // if it is not set and we get here, the scheduler was started before #startTask() was called and we need to suspend - // if it is set, the scheduler was not running before #startTask() was called and we can continue + /* Task should not start until explicitly requested, + * but in FreeRTOS, tasks start as soon as they are created if the scheduler + * is running but not if the scheduler is not running. + * To be able to accommodate both cases we check a member which is set in + * #startTask(). If it is not set and we get here, the scheduler was started + * before #startTask() was called and we need to suspend if it is set, + * the scheduler was not running before #startTask() was called and we + * can continue */ - if (!originalTask->started) { + if (not originalTask->started) { vTaskSuspend(NULL); } @@ -59,31 +64,70 @@ void PeriodicTask::taskFunctionality() { TickType_t xLastWakeTime; const TickType_t xPeriod = pdMS_TO_TICKS(this->period * 1000.); /* The xLastWakeTime variable needs to be initialized with the current tick - count. Note that this is the only time the variable is written to explicitly. - After this assignment, xLastWakeTime is updated automatically internally within - vTaskDelayUntil(). */ + count. Note that this is the only time the variable is written to + explicitly. After this assignment, xLastWakeTime is updated automatically + internally within vTaskDelayUntil(). */ xLastWakeTime = xTaskGetTickCount(); /* Enter the loop that defines the task behavior. */ for (;;) { - for (ObjectList::iterator it = objectList.begin(); - it != objectList.end(); ++it) { - (*it)->performOperation(); + for (auto const& object: objectList) { + object->performOperation(); } - //TODO deadline missed check + + checkMissedDeadline(xLastWakeTime, xPeriod); + vTaskDelayUntil(&xLastWakeTime, xPeriod); + } } ReturnValue_t PeriodicTask::addComponent(object_id_t object) { ExecutableObjectIF* newObject = objectManager->get( object); - if (newObject == NULL) { + if (newObject == nullptr) { + 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 HasReturnvaluesIF::RETURN_OK; } uint32_t PeriodicTask::getPeriodMs() const { return period * 1000; } + +void PeriodicTask::checkMissedDeadline(const TickType_t xLastWakeTime, + const TickType_t interval) { + /* Check whether deadline was missed while also taking overflows + * into account. Drawing this on paper with a timeline helps to understand + * it. */ + TickType_t currentTickCount = xTaskGetTickCount(); + TickType_t timeToWake = xLastWakeTime + interval; + // Time to wake has not overflown. + if(timeToWake > xLastWakeTime) { + /* If the current time has overflown exclusively or the current + * tick count is simply larger than the time to wake, a deadline was + * missed */ + if((currentTickCount < xLastWakeTime) or (currentTickCount > timeToWake)) { + handleMissedDeadline(); + } + } + /* Time to wake has overflown. A deadline was missed if the current time + * is larger than the time to wake */ + else if((timeToWake < xLastWakeTime) and (currentTickCount > timeToWake)) { + handleMissedDeadline(); + } +} + +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/PeriodicTask.h b/osal/FreeRTOS/PeriodicTask.h index e7ba8dd26..c5c7643d2 100644 --- a/osal/FreeRTOS/PeriodicTask.h +++ b/osal/FreeRTOS/PeriodicTask.h @@ -1,48 +1,49 @@ -#ifndef MULTIOBJECTTASK_H_ -#define MULTIOBJECTTASK_H_ +#ifndef FRAMEWORK_OSAL_FREERTOS_PERIODICTASK_H_ +#define FRAMEWORK_OSAL_FREERTOS_PERIODICTASK_H_ -#include -#include -#include +#include "../../objectmanager/ObjectManagerIF.h" +#include "../../tasks/PeriodicTaskIF.h" +#include "../../tasks/Typedef.h" -#include -#include "task.h" +#include +#include #include class ExecutableObjectIF; /** - * @brief This class represents a specialized task for periodic activities of multiple objects. - * - * @details MultiObjectTask is an extension to ObjectTask in the way that it is able to execute - * multiple objects that implement the ExecutableObjectIF interface. The objects must be - * added prior to starting the task. - * + * @brief This class represents a specialized task for + * periodic activities of multiple objects. * @ingroup task_handling */ class PeriodicTask: public PeriodicTaskIF { public: /** - * @brief Standard constructor of the class. - * @details The class is initialized without allocated objects. These need to be added - * with #addObject. - * In the underlying TaskBase class, a new operating system task is created. - * In addition to the TaskBase parameters, the period, the pointer to the - * aforementioned initialization function and an optional "deadline-missed" - * function pointer is passed. - * @param priority Sets the priority of a task. Values range from a low 0 to a high 99. - * @param stack_size The stack size reserved by the operating system for the task. - * @param setPeriod The length of the period with which the task's functionality will be - * executed. It is expressed in clock ticks. - * @param setDeadlineMissedFunc The function pointer to the deadline missed function - * that shall be assigned. + * Keep in Mind that you need to call before this vTaskStartScheduler()! + * A lot of task parameters are set in "FreeRTOSConfig.h". + * TODO: why does this need to be called before vTaskStartScheduler? + * @details + * The class is initialized without allocated objects. + * These need to be added with #addComponent. + * @param priority + * Sets the priority of a task. Values depend on freeRTOS configuration, + * high number means high priority. + * @param stack_size + * The stack size reserved by the operating system for the task. + * @param setPeriod + * The length of the period with which the task's + * functionality will be executed. It is expressed in clock ticks. + * @param setDeadlineMissedFunc + * The function pointer to the deadline missed function that shall + * be assigned. */ - PeriodicTask(const char *name, TaskPriority setPriority, TaskStackSize setStack, TaskPeriod setPeriod, - void (*setDeadlineMissedFunc)()); + PeriodicTask(const char *name, TaskPriority setPriority, + TaskStackSize setStack, TaskPeriod setPeriod, + void (*setDeadlineMissedFunc)()); /** - * @brief Currently, the executed object's lifetime is not coupled with the task object's - * lifetime, so the destructor is empty. + * @brief Currently, the executed object's lifetime is not coupled with + * the task object's lifetime, so the destructor is empty. */ virtual ~PeriodicTask(void); @@ -53,58 +54,71 @@ public: * The address of the task object is passed as an argument * to the system call. */ - ReturnValue_t startTask(void); + ReturnValue_t startTask() override; /** * Adds an object to the list of objects to be executed. * The objects are executed in the order added. * @param object Id of the object to add. - * @return RETURN_OK on success, RETURN_FAILED if the object could not be added. + * @return + * -@c RETURN_OK on success + * -@c RETURN_FAILED if the object could not be added. */ - ReturnValue_t addComponent(object_id_t object); + ReturnValue_t addComponent(object_id_t object) override; - uint32_t getPeriodMs() const; + uint32_t getPeriodMs() const override; - ReturnValue_t sleepFor(uint32_t ms); + ReturnValue_t sleepFor(uint32_t ms) override; protected: bool started; TaskHandle_t handle; - typedef std::vector ObjectList; //!< Typedef for the List of objects. + //! Typedef for the List of objects. + typedef std::vector ObjectList; /** * @brief This attribute holds a list of objects to be executed. */ ObjectList objectList; /** * @brief The period of the task. - * @details The period determines the frequency of the task's execution. It is expressed in clock ticks. + * @details + * The period determines the frequency of the task's execution. + * It is expressed in clock ticks. */ TaskPeriod period; /** * @brief The pointer to the deadline-missed function. - * @details This pointer stores the function that is executed if the task's deadline is missed. - * So, each may react individually on a timing failure. The pointer may be NULL, - * then nothing happens on missing the deadline. The deadline is equal to the next execution - * of the periodic task. + * @details + * This pointer stores the function that is executed if the task's deadline + * is missed so each may react individually on a timing failure. + * The pointer may be NULL, then nothing happens on missing the deadline. + * The deadline is equal to the next execution of the periodic task. */ void (*deadlineMissedFunc)(void); /** * @brief This is the function executed in the new task's context. - * @details It converts the argument back to the thread object type and copies the class instance - * to the task context. The taskFunctionality method is called afterwards. + * @details + * It converts the argument back to the thread object type and copies the + * class instance to the task context. The taskFunctionality method is + * called afterwards. * @param A pointer to the task object itself is passed as argument. */ static void taskEntryPoint(void* argument); /** * @brief The function containing the actual functionality of the task. - * @details The method sets and starts - * the task's period, then enters a loop that is repeated as long as the isRunning - * attribute is true. Within the loop, all performOperation methods of the added - * objects are called. Afterwards the checkAndRestartPeriod system call blocks the task - * until the next period. - * On missing the deadline, the deadlineMissedFunction is executed. + * @details + * The method sets and starts the task's period, then enters a loop that is + * repeated as long as the isRunning attribute is true. Within the loop, + * all performOperation methods of the added objects are called. + * Afterwards the checkAndRestartPeriod system call blocks the task until + * the next period. + * On missing the deadline, the deadlineMissedFunction is executed. */ void taskFunctionality(void); + + void checkMissedDeadline(const TickType_t xLastWakeTime, + const TickType_t interval); + void handleMissedDeadline(); }; -#endif /* MULTIOBJECTTASK_H_ */ +#endif /* PERIODICTASK_H_ */ diff --git a/osal/FreeRTOS/QueueFactory.cpp b/osal/FreeRTOS/QueueFactory.cpp index eaf245d37..e639179a9 100644 --- a/osal/FreeRTOS/QueueFactory.cpp +++ b/osal/FreeRTOS/QueueFactory.cpp @@ -1,6 +1,6 @@ -#include +#include "../../ipc/QueueFactory.h" -#include +#include "MessageQueue.h" QueueFactory* QueueFactory::factoryInstance = NULL; @@ -25,8 +25,8 @@ QueueFactory::~QueueFactory() { } MessageQueueIF* QueueFactory::createMessageQueue(uint32_t message_depth, - uint32_t max_message_size) { - return new MessageQueue(message_depth, max_message_size); + size_t maxMessageSize) { + return new MessageQueue(message_depth, maxMessageSize); } void QueueFactory::deleteMessageQueue(MessageQueueIF* queue) { diff --git a/osal/FreeRTOS/TaskFactory.cpp b/osal/FreeRTOS/TaskFactory.cpp index 753da60f7..80df38b2f 100644 --- a/osal/FreeRTOS/TaskFactory.cpp +++ b/osal/FreeRTOS/TaskFactory.cpp @@ -1,5 +1,5 @@ -#include -#include +#include "../../tasks/TaskFactory.h" +#include "../../returnvalues/HasReturnvaluesIF.h" #include "PeriodicTask.h" #include "FixedTimeslotTask.h" diff --git a/osal/FreeRTOS/Timekeeper.cpp b/osal/FreeRTOS/Timekeeper.cpp index 81f7f9979..1031f0c4d 100644 --- a/osal/FreeRTOS/Timekeeper.cpp +++ b/osal/FreeRTOS/Timekeeper.cpp @@ -1,20 +1,19 @@ #include "Timekeeper.h" -#include -Timekeeper::Timekeeper() : - offset( { 0, 0 }) { - // TODO Auto-generated constructor stub +#include "FreeRTOSConfig.h" -} +Timekeeper * Timekeeper::myinstance = nullptr; -Timekeeper * Timekeeper::myinstance = NULL; +Timekeeper::Timekeeper() : offset( { 0, 0 } ) {} + +Timekeeper::~Timekeeper() {} const timeval& Timekeeper::getOffset() const { return offset; } Timekeeper* Timekeeper::instance() { - if (myinstance == NULL) { + if (myinstance == nullptr) { myinstance = new Timekeeper(); } return myinstance; @@ -24,10 +23,6 @@ void Timekeeper::setOffset(const timeval& offset) { this->offset = offset; } -Timekeeper::~Timekeeper() { - // TODO Auto-generated destructor stub -} - timeval Timekeeper::ticksToTimeval(TickType_t ticks) { timeval uptime; uptime.tv_sec = ticks / configTICK_RATE_HZ; @@ -40,3 +35,7 @@ timeval Timekeeper::ticksToTimeval(TickType_t ticks) { return uptime; } + +TickType_t Timekeeper::getTicks() { + return xTaskGetTickCount(); +} diff --git a/osal/FreeRTOS/Timekeeper.h b/osal/FreeRTOS/Timekeeper.h index 2ba3e4a9b..7d583f7db 100644 --- a/osal/FreeRTOS/Timekeeper.h +++ b/osal/FreeRTOS/Timekeeper.h @@ -1,9 +1,11 @@ #ifndef FRAMEWORK_OSAL_FREERTOS_TIMEKEEPER_H_ #define FRAMEWORK_OSAL_FREERTOS_TIMEKEEPER_H_ -#include +#include "../../timemanager/Clock.h" + +#include +#include -#include /** * A Class to basically store the time difference between uptime and UTC @@ -25,6 +27,11 @@ public: virtual ~Timekeeper(); static timeval ticksToTimeval(TickType_t ticks); + /** + * Get elapsed time in system ticks. + * @return + */ + static TickType_t getTicks(); const timeval& getOffset() const; void setOffset(const timeval& offset); diff --git a/osal/InternalErrorCodes.h b/osal/InternalErrorCodes.h index 5419fd94d..1da116fa3 100644 --- a/osal/InternalErrorCodes.h +++ b/osal/InternalErrorCodes.h @@ -1,7 +1,7 @@ #ifndef INTERNALERRORCODES_H_ #define INTERNALERRORCODES_H_ -#include +#include "../returnvalues/HasReturnvaluesIF.h" class InternalErrorCodes { public: diff --git a/osal/linux/Clock.cpp b/osal/linux/Clock.cpp index e24a4fe4b..5f764a6fc 100644 --- a/osal/linux/Clock.cpp +++ b/osal/linux/Clock.cpp @@ -1,10 +1,10 @@ +#include "../../serviceinterface/ServiceInterfaceStream.h" +#include "../../timemanager/Clock.h" + #include -#include -#include - - #include #include +#include #include //#include @@ -65,6 +65,15 @@ ReturnValue_t Clock::getClock_usecs(uint64_t* time) { return HasReturnvaluesIF::RETURN_OK; } +timeval Clock::getUptime() { + timeval uptime; + auto result = getUptime(&uptime); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Clock::getUptime: Error getting uptime" << std::endl; + } + return uptime; +} + ReturnValue_t Clock::getUptime(timeval* uptime) { //TODO This is not posix compatible and delivers only seconds precision struct sysinfo sysInfo; @@ -170,7 +179,7 @@ ReturnValue_t Clock::setLeapSeconds(const uint16_t leapSeconds_) { if(checkOrCreateClockMutex()!=HasReturnvaluesIF::RETURN_OK){ return HasReturnvaluesIF::RETURN_FAILED; } - ReturnValue_t result = timeMutex->lockMutex(MutexIF::NO_TIMEOUT); + ReturnValue_t result = timeMutex->lockMutex(MutexIF::BLOCKING); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } @@ -185,7 +194,7 @@ ReturnValue_t Clock::getLeapSeconds(uint16_t* leapSeconds_) { if(timeMutex==NULL){ return HasReturnvaluesIF::RETURN_FAILED; } - ReturnValue_t result = timeMutex->lockMutex(MutexIF::NO_TIMEOUT); + ReturnValue_t result = timeMutex->lockMutex(MutexIF::BLOCKING); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } diff --git a/osal/linux/FixedTimeslotTask.cpp b/osal/linux/FixedTimeslotTask.cpp index 098753a7a..858a39a7a 100644 --- a/osal/linux/FixedTimeslotTask.cpp +++ b/osal/linux/FixedTimeslotTask.cpp @@ -1,10 +1,7 @@ -#include -#include -#include -#include -#include -#include +#include "../../serviceinterface/ServiceInterfaceStream.h" +#include "FixedTimeslotTask.h" +#include uint32_t FixedTimeslotTask::deadlineMissedCount = 0; const size_t PeriodicTaskIF::MINIMUM_STACK_SIZE = PTHREAD_STACK_MIN; @@ -23,7 +20,7 @@ void* FixedTimeslotTask::taskEntryPoint(void* arg) { FixedTimeslotTask *originalTask(reinterpret_cast(arg)); //The task's functionality is called. originalTask->taskFunctionality(); - return NULL; + return nullptr; } ReturnValue_t FixedTimeslotTask::startTask() { diff --git a/osal/linux/FixedTimeslotTask.h b/osal/linux/FixedTimeslotTask.h index 6350f3472..42802b1dd 100644 --- a/osal/linux/FixedTimeslotTask.h +++ b/osal/linux/FixedTimeslotTask.h @@ -1,14 +1,27 @@ #ifndef FRAMEWORK_OSAL_LINUX_FIXEDTIMESLOTTASK_H_ #define FRAMEWORK_OSAL_LINUX_FIXEDTIMESLOTTASK_H_ -#include -#include -#include +#include "../../tasks/FixedTimeslotTaskIF.h" +#include "../../devicehandlers/FixedSlotSequence.h" +#include "PosixThread.h" #include class FixedTimeslotTask: public FixedTimeslotTaskIF, public PosixThread { public: - FixedTimeslotTask(const char* name_, int priority_, size_t stackSize_, uint32_t periodMs_); + /** + * Create a generic periodic task. + * @param name_ + * Name, maximum allowed size of linux is 16 chars, everything else will + * be truncated. + * @param priority_ + * Real-time priority, ranges from 1 to 99 for Linux. + * See: https://man7.org/linux/man-pages/man7/sched.7.html + * @param stackSize_ + * @param period_ + * @param deadlineMissedFunc_ + */ + FixedTimeslotTask(const char* name_, int priority_, size_t stackSize_, + uint32_t periodMs_); virtual ~FixedTimeslotTask(); virtual ReturnValue_t startTask(); @@ -17,7 +30,9 @@ public: virtual uint32_t getPeriodMs() const; - virtual ReturnValue_t addSlot(object_id_t componentId, uint32_t slotTimeMs, int8_t executionStep); + virtual ReturnValue_t addSlot(object_id_t componentId, uint32_t slotTimeMs, + int8_t executionStep); + virtual ReturnValue_t checkSequence() const; /** @@ -34,11 +49,10 @@ public: protected: /** * @brief This function holds the main functionality of the thread. - * - * - * @details Holding the main functionality of the task, this method is most important. - * It links the functionalities provided by FixedSlotSequence with the OS's System Calls - * to keep the timing of the periods. + * @details + * Holding the main functionality of the task, this method is most important. + * It links the functionalities provided by FixedSlotSequence with the + * OS's System Calls to keep the timing of the periods. */ virtual void taskFunctionality(); @@ -46,8 +60,13 @@ private: /** * @brief This is the entry point in a new thread. * - * @details This method, that is the entry point in the new thread and calls taskFunctionality of the child class. - * Needs a valid pointer to the derived class. + * @details + * This method, that is the entry point in the new thread and calls + * taskFunctionality of the child class. Needs a valid pointer to the + * derived class. + * + * The void* returnvalue is not used yet but could be used to return + * arbitrary data. */ static void* taskEntryPoint(void* arg); FixedSlotSequence pst; diff --git a/osal/linux/InternalErrorCodes.cpp b/osal/linux/InternalErrorCodes.cpp index 7f83663b1..a01cc72ac 100644 --- a/osal/linux/InternalErrorCodes.cpp +++ b/osal/linux/InternalErrorCodes.cpp @@ -1,4 +1,4 @@ -#include +#include "../../osal/InternalErrorCodes.h" ReturnValue_t InternalErrorCodes::translate(uint8_t code) { //TODO This class can be removed diff --git a/osal/linux/MessageQueue.cpp b/osal/linux/MessageQueue.cpp index edabe9467..e5c61caef 100644 --- a/osal/linux/MessageQueue.cpp +++ b/osal/linux/MessageQueue.cpp @@ -1,56 +1,37 @@ -#include +#include "../../serviceinterface/ServiceInterfaceStream.h" +#include "MessageQueue.h" + +#include + #include /* For O_* constants */ #include /* For mode constants */ -#include #include #include -#include -MessageQueue::MessageQueue(size_t message_depth, size_t max_message_size) : - id(0), lastPartner(0), defaultDestination(NO_QUEUE) { +MessageQueue::MessageQueue(uint32_t messageDepth, size_t maxMessageSize): + id(MessageQueueIF::NO_QUEUE),lastPartner(MessageQueueIF::NO_QUEUE), + defaultDestination(MessageQueueIF::NO_QUEUE) { //debug << "MessageQueue::MessageQueue: Creating a queue" << std::endl; mq_attr attributes; this->id = 0; //Set attributes attributes.mq_curmsgs = 0; - attributes.mq_maxmsg = message_depth; - attributes.mq_msgsize = max_message_size; + attributes.mq_maxmsg = messageDepth; + attributes.mq_msgsize = maxMessageSize; attributes.mq_flags = 0; //Flags are ignored on Linux during mq_open - //Set the name of the queue - sprintf(name, "/Q%u\n", queueCounter++); + //Set the name of the queue. The slash is mandatory! + sprintf(name, "/FSFW_MQ%u\n", queueCounter++); - //Create a nonblocking queue if the name is available (the queue is Read and - // writable for the owner as well as the group) - mqd_t tempId = mq_open(name, O_NONBLOCK | O_RDWR | O_CREAT | O_EXCL, - S_IWUSR | S_IREAD | S_IWGRP | S_IRGRP | S_IROTH | S_IWOTH, &attributes); + // Create a nonblocking queue if the name is available (the queue is read + // and writable for the owner as well as the group) + int oflag = O_NONBLOCK | O_RDWR | O_CREAT | O_EXCL; + mode_t mode = S_IWUSR | S_IREAD | S_IWGRP | S_IRGRP | S_IROTH | S_IWOTH; + mqd_t tempId = mq_open(name, oflag, mode, &attributes); if (tempId == -1) { - //An error occured during open - //We need to distinguish if it is caused by an already created queue - if (errno == EEXIST) { - //There's another queue with the same name - //We unlink the other queue - int status = mq_unlink(name); - if (status != 0) { - sif::error << "mq_unlink Failed with status: " << strerror(errno) - << std::endl; - } else { - //Successful unlinking, try to open again - mqd_t tempId = mq_open(name, - O_NONBLOCK | O_RDWR | O_CREAT | O_EXCL, - S_IWUSR | S_IREAD | S_IWGRP | S_IRGRP, &attributes); - if (tempId != -1) { - //Successful mq_open - this->id = tempId; - return; - } - } - } - //Failed either the first time or the second time - sif::error << "MessageQueue::MessageQueue: Creating Queue " << std::hex - << name << std::dec << " failed with status: " - << strerror(errno) << std::endl; - } else { + handleError(&attributes, messageDepth); + } + else { //Successful mq_open call this->id = tempId; } @@ -69,6 +50,73 @@ MessageQueue::~MessageQueue() { } } +ReturnValue_t MessageQueue::handleError(mq_attr* attributes, + uint32_t messageDepth) { + switch(errno) { + case(EINVAL): { + sif::error << "MessageQueue::MessageQueue: Invalid name or attributes" + " for message size" << std::endl; + size_t defaultMqMaxMsg = 0; + // Not POSIX conformant, but should work for all UNIX systems. + // Just an additional helpful printout :-) + if(std::ifstream("/proc/sys/fs/mqueue/msg_max",std::ios::in) >> + defaultMqMaxMsg and defaultMqMaxMsg < messageDepth) { + // See: https://www.man7.org/linux/man-pages/man3/mq_open.3.html + // This happens if the msg_max value is not large enough + // It is ignored if the executable is run in privileged mode. + // Run the unlockRealtime script or grant the mode manually by using: + // sudo setcap 'CAP_SYS_RESOURCE=+ep' + + // Persistent solution for session: + // echo | sudo tee /proc/sys/fs/mqueue/msg_max + + // Permanent solution: + // sudo nano /etc/sysctl.conf + // Append at end: fs/mqueue/msg_max = + // Apply changes with: sudo sysctl -p + sif::error << "MessageQueue::MessageQueue: Default MQ size " + << defaultMqMaxMsg << " is too small for requested size " + << messageDepth << std::endl; + } + break; + } + case(EEXIST): { + // An error occured during open + // We need to distinguish if it is caused by an already created queue + //There's another queue with the same name + //We unlink the other queue + int status = mq_unlink(name); + if (status != 0) { + sif::error << "mq_unlink Failed with status: " << strerror(errno) + << std::endl; + } + else { + // Successful unlinking, try to open again + mqd_t tempId = mq_open(name, + O_NONBLOCK | O_RDWR | O_CREAT | O_EXCL, + S_IWUSR | S_IREAD | S_IWGRP | S_IRGRP, attributes); + if (tempId != -1) { + //Successful mq_open + this->id = tempId; + return HasReturnvaluesIF::RETURN_OK; + } + } + break; + } + + default: + // Failed either the first time or the second time + sif::error << "MessageQueue::MessageQueue: Creating Queue " << std::hex + << name << std::dec << " failed with status: " + << strerror(errno) << std::endl; + + } + return HasReturnvaluesIF::RETURN_FAILED; + + + +} + ReturnValue_t MessageQueue::sendMessage(MessageQueueId_t sendTo, MessageQueueMessage* message, bool ignoreFault) { return sendMessageFrom(sendTo, message, this->getId(), false); @@ -108,12 +156,13 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message) { //Success but no message received return MessageQueueIF::EMPTY; } else { - //No message was received. Keep lastPartner anyway, I might send something later. - //But still, delete packet content. + //No message was received. Keep lastPartner anyway, I might send + //something later. But still, delete packet content. memset(message->getData(), 0, message->MAX_DATA_SIZE); switch(errno){ case EAGAIN: - //O_NONBLOCK or MQ_NONBLOCK was set and there are no messages currently on the specified queue. + //O_NONBLOCK or MQ_NONBLOCK was set and there are no messages + //currently on the specified queue. return MessageQueueIF::EMPTY; case EBADF: //mqdes doesn't represent a valid queue open for reading. @@ -123,9 +172,12 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message) { case EINVAL: /* * This value indicates one of the following: - * * The pointer to the buffer for storing the received message, msg_ptr, is NULL. - * * The number of bytes requested, msg_len is less than zero. - * * msg_len is anything other than the mq_msgsize of the specified queue, and the QNX extended option MQ_READBUF_DYNAMIC hasn't been set in the queue's mq_flags. + * - The pointer to the buffer for storing the received message, + * msg_ptr, is NULL. + * - The number of bytes requested, msg_len is less than zero. + * - msg_len is anything other than the mq_msgsize of the specified + * queue, and the QNX extended option MQ_READBUF_DYNAMIC hasn't + * been set in the queue's mq_flags. */ sif::error << "MessageQueue::receive: configuration error " << strerror(errno) << std::endl; @@ -133,8 +185,12 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message) { case EMSGSIZE: /* * This value indicates one of the following: - * * the QNX extended option MQ_READBUF_DYNAMIC hasn't been set, and the given msg_len is shorter than the mq_msgsize for the given queue. - * * the extended option MQ_READBUF_DYNAMIC has been set, but the given msg_len is too short for the message that would have been received. + * - the QNX extended option MQ_READBUF_DYNAMIC hasn't been set, + * and the given msg_len is shorter than the mq_msgsize for + * the given queue. + * - the extended option MQ_READBUF_DYNAMIC has been set, but the + * given msg_len is too short for the message that would have + * been received. */ sif::error << "MessageQueue::receive: configuration error " << strerror(errno) << std::endl; @@ -182,9 +238,10 @@ ReturnValue_t MessageQueue::flush(uint32_t* count) { case EINVAL: /* * This value indicates one of the following: - * * mq_attr is NULL. - * * MQ_MULT_NOTIFY had been set for this queue, and the given mq_flags includes a 0 in the MQ_MULT_NOTIFY bit. Once MQ_MULT_NOTIFY has been turned on, it may never be turned off. - * + * - mq_attr is NULL. + * - MQ_MULT_NOTIFY had been set for this queue, and the given + * mq_flags includes a 0 in the MQ_MULT_NOTIFY bit. Once + * MQ_MULT_NOTIFY has been turned on, it may never be turned off. */ default: return HasReturnvaluesIF::RETURN_FAILED; @@ -233,7 +290,8 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, //TODO: Check if we're in ISR. if (result != 0) { if(!ignoreFault){ - InternalErrorReporterIF* internalErrorReporter = objectManager->get( + InternalErrorReporterIF* internalErrorReporter = + objectManager->get( objects::INTERNAL_ERROR_REPORTER); if (internalErrorReporter != NULL) { internalErrorReporter->queueMessageNotSent(); @@ -241,10 +299,13 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, } switch(errno){ case EAGAIN: - //The O_NONBLOCK flag was set when opening the queue, or the MQ_NONBLOCK flag was set in its attributes, and the specified queue is full. + //The O_NONBLOCK flag was set when opening the queue, or the + //MQ_NONBLOCK flag was set in its attributes, and the + //specified queue is full. return MessageQueueIF::FULL; case EBADF: - //mq_des doesn't represent a valid message queue descriptor, or mq_des wasn't opened for writing. + //mq_des doesn't represent a valid message queue descriptor, + //or mq_des wasn't opened for writing. sif::error << "MessageQueue::sendMessage: Configuration error " << strerror(errno) << " in mq_send mqSendTo: " << sendTo << " sent from " << sentFrom << std::endl; @@ -254,18 +315,22 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, case EINVAL: /* * This value indicates one of the following: - * * msg_ptr is NULL. - * * msg_len is negative. - * * msg_prio is greater than MQ_PRIO_MAX. - * * msg_prio is less than 0. - * * MQ_PRIO_RESTRICT is set in the mq_attr of mq_des, - * and msg_prio is greater than the priority of the calling process. - * */ + * - msg_ptr is NULL. + * - msg_len is negative. + * - msg_prio is greater than MQ_PRIO_MAX. + * - msg_prio is less than 0. + * - MQ_PRIO_RESTRICT is set in the mq_attr of mq_des, and + * msg_prio is greater than the priority of the calling process. + */ sif::error << "MessageQueue::sendMessage: Configuration error " << strerror(errno) << " in mq_send" << std::endl; /*NO BREAK*/ case EMSGSIZE: - //The msg_len is greater than the msgsize associated with the specified queue. + // The msg_len is greater than the msgsize associated with + //the specified queue. + sif::error << "MessageQueue::sendMessage: Size error [" << + strerror(errno) << "] in mq_send" << std::endl; + /*NO BREAK*/ default: return HasReturnvaluesIF::RETURN_FAILED; } diff --git a/osal/linux/MessageQueue.h b/osal/linux/MessageQueue.h index b8285dc58..31cdca11c 100644 --- a/osal/linux/MessageQueue.h +++ b/osal/linux/MessageQueue.h @@ -1,24 +1,29 @@ #ifndef MESSAGEQUEUE_H_ #define MESSAGEQUEUE_H_ -#include -#include -#include +#include "../../internalError/InternalErrorReporterIF.h" +#include "../../ipc/MessageQueueIF.h" +#include "../../ipc/MessageQueueMessage.h" + +#include /** - * @brief This class manages sending and receiving of message queue messages. + * @brief This class manages sending and receiving of message queue messages. * - * @details Message queues are used to pass asynchronous messages between processes. - * They work like post boxes, where all incoming messages are stored in FIFO - * order. This class creates a new receiving queue and provides methods to fetch - * received messages. Being a child of MessageQueueSender, this class also provides - * methods to send a message to a user-defined or a default destination. In addition - * it also provides a reply method to answer to the queue it received its last message - * from. - * The MessageQueue should be used as "post box" for a single owning object. So all - * message queue communication is "n-to-one". - * For creating the queue, as well as sending and receiving messages, the class makes - * use of the operating system calls provided. - * \ingroup message_queue + * @details + * Message queues are used to pass asynchronous messages between processes. + * They work like post boxes, where all incoming messages are stored in FIFO + * order. This class creates a new receiving queue and provides methods to fetch + * received messages. Being a child of MessageQueueSender, this class also + * provides methods to send a message to a user-defined or a default destination. + * In addition it also provides a reply method to answer to the queue it + * received its last message from. + * + * The MessageQueue should be used as "post box" for a single owning object. + * So all message queue communication is "n-to-one". + * + * The creation of message queues, as well as sending and receiving messages, + * makes use of the operating system calls provided. + * @ingroup message_queue */ class MessageQueue : public MessageQueueIF { friend class MessageQueueSenderIF; @@ -35,7 +40,8 @@ public: * @param max_message_size With this parameter, the maximum message size can be adjusted. * This should be left default. */ - MessageQueue( size_t message_depth = 3, size_t max_message_size = MessageQueueMessage::MAX_MESSAGE_SIZE ); + MessageQueue(uint32_t messageDepth = 3, + size_t maxMessageSize = MessageQueueMessage::MAX_MESSAGE_SIZE ); /** * @brief The destructor deletes the formerly created message queue. * @details This is accomplished by using the delete call provided by the operating system. @@ -168,6 +174,8 @@ private: char name[5]; static uint16_t queueCounter; + + ReturnValue_t handleError(mq_attr* attributes, uint32_t messageDepth); }; #endif /* MESSAGEQUEUE_H_ */ diff --git a/osal/linux/Mutex.cpp b/osal/linux/Mutex.cpp index 36bb3ce43..b27ff8c0a 100644 --- a/osal/linux/Mutex.cpp +++ b/osal/linux/Mutex.cpp @@ -1,8 +1,7 @@ -#include -#include -#include +#include "Mutex.h" +#include "../../serviceinterface/ServiceInterfaceStream.h" +#include "../../timemanager/Clock.h" -const uint32_t MutexIF::NO_TIMEOUT = 0; uint8_t Mutex::count = 0; @@ -25,7 +24,9 @@ Mutex::Mutex() { sif::error << "Mutex: creation with name, id " << mutex.__data.__count << ", " << " failed with " << strerror(status) << std::endl; } - //After a mutex attributes object has been used to initialize one or more mutexes, any function affecting the attributes object (including destruction) shall not affect any previously initialized mutexes. + // After a mutex attributes object has been used to initialize one or more + // mutexes, any function affecting the attributes object + // (including destruction) shall not affect any previously initialized mutexes. status = pthread_mutexattr_destroy(&mutexAttr); if (status != 0) { sif::error << "Mutex: Attribute destroy failed with " << strerror(status) << std::endl; @@ -37,9 +38,13 @@ Mutex::~Mutex() { pthread_mutex_destroy(&mutex); } -ReturnValue_t Mutex::lockMutex(uint32_t timeoutMs) { +ReturnValue_t Mutex::lockMutex(TimeoutType timeoutType, uint32_t timeoutMs) { int status = 0; - if (timeoutMs != MutexIF::NO_TIMEOUT) { + + if(timeoutType == TimeoutType::POLLING) { + status = pthread_mutex_trylock(&mutex); + } + else if (timeoutType == TimeoutType::WAITING) { timespec timeOut; clock_gettime(CLOCK_REALTIME, &timeOut); uint64_t nseconds = timeOut.tv_sec * 1000000000 + timeOut.tv_nsec; @@ -47,27 +52,35 @@ ReturnValue_t Mutex::lockMutex(uint32_t timeoutMs) { timeOut.tv_sec = nseconds / 1000000000; timeOut.tv_nsec = nseconds - timeOut.tv_sec * 1000000000; status = pthread_mutex_timedlock(&mutex, &timeOut); - } else { + } + else if(timeoutType == TimeoutType::BLOCKING) { status = pthread_mutex_lock(&mutex); } + switch (status) { case EINVAL: - //The mutex was created with the protocol attribute having the value PTHREAD_PRIO_PROTECT and the calling thread's priority is higher than the mutex's current priority ceiling. + // The mutex was created with the protocol attribute having the value + // PTHREAD_PRIO_PROTECT and the calling thread's priority is higher + // than the mutex's current priority ceiling. return WRONG_ATTRIBUTE_SETTING; - //The process or thread would have blocked, and the abs_timeout parameter specified a nanoseconds field value less than zero or greater than or equal to 1000 million. - //The value specified by mutex does not refer to an initialized mutex object. + // The process or thread would have blocked, and the abs_timeout + // parameter specified a nanoseconds field value less than zero or + // greater than or equal to 1000 million. + // The value specified by mutex does not refer to an initialized mutex object. //return MUTEX_NOT_FOUND; case EBUSY: - //The mutex could not be acquired because it was already locked. + // The mutex could not be acquired because it was already locked. return MUTEX_ALREADY_LOCKED; case ETIMEDOUT: - //The mutex could not be locked before the specified timeout expired. + // The mutex could not be locked before the specified timeout expired. return MUTEX_TIMEOUT; case EAGAIN: - //The mutex could not be acquired because the maximum number of recursive locks for mutex has been exceeded. + // The mutex could not be acquired because the maximum number of + // recursive locks for mutex has been exceeded. return MUTEX_MAX_LOCKS; case EDEADLK: - //A deadlock condition was detected or the current thread already owns the mutex. + // A deadlock condition was detected or the current thread + // already owns the mutex. return CURR_THREAD_ALREADY_OWNS_MUTEX; case 0: //Success diff --git a/osal/linux/Mutex.h b/osal/linux/Mutex.h index d02d008fe..ecb47a336 100644 --- a/osal/linux/Mutex.h +++ b/osal/linux/Mutex.h @@ -1,14 +1,15 @@ -#ifndef OS_RTEMS_MUTEX_H_ -#define OS_RTEMS_MUTEX_H_ +#ifndef OS_LINUX_MUTEX_H_ +#define OS_LINUX_MUTEX_H_ -#include +#include "../../ipc/MutexIF.h" #include + class Mutex : public MutexIF { public: Mutex(); virtual ~Mutex(); - virtual ReturnValue_t lockMutex(uint32_t timeoutMs); + virtual ReturnValue_t lockMutex(TimeoutType timeoutType, uint32_t timeoutMs); virtual ReturnValue_t unlockMutex(); private: pthread_mutex_t mutex; diff --git a/osal/linux/MutexFactory.cpp b/osal/linux/MutexFactory.cpp index d769cc334..8c2faf888 100644 --- a/osal/linux/MutexFactory.cpp +++ b/osal/linux/MutexFactory.cpp @@ -1,5 +1,5 @@ -#include -#include +#include "../../ipc/MutexFactory.h" +#include "Mutex.h" //TODO: Different variant than the lazy loading in QueueFactory. What's better and why? MutexFactory* MutexFactory::factoryInstance = new MutexFactory(); diff --git a/osal/linux/PeriodicPosixTask.cpp b/osal/linux/PeriodicPosixTask.cpp index b754c3f44..df3694ef0 100644 --- a/osal/linux/PeriodicPosixTask.cpp +++ b/osal/linux/PeriodicPosixTask.cpp @@ -1,11 +1,12 @@ -#include -#include +#include "../../tasks/ExecutableObjectIF.h" +#include "../../serviceinterface/ServiceInterfaceStream.h" #include -#include - -PeriodicPosixTask::PeriodicPosixTask(const char* name_, int priority_, size_t stackSize_, uint32_t period_, void(deadlineMissedFunc_)()):PosixThread(name_,priority_,stackSize_),objectList(),started(false),periodMs(period_),deadlineMissedFunc( - deadlineMissedFunc_) { +#include "PeriodicPosixTask.h" +PeriodicPosixTask::PeriodicPosixTask(const char* name_, int priority_, + size_t stackSize_, uint32_t period_, void(deadlineMissedFunc_)()): + PosixThread(name_,priority_,stackSize_),objectList(),started(false), + periodMs(period_),deadlineMissedFunc(deadlineMissedFunc_) { } PeriodicPosixTask::~PeriodicPosixTask() { @@ -23,10 +24,12 @@ void* PeriodicPosixTask::taskEntryPoint(void* arg) { ReturnValue_t PeriodicPosixTask::addComponent(object_id_t object) { ExecutableObjectIF* newObject = objectManager->get( object); - if (newObject == NULL) { + if (newObject == nullptr) { return HasReturnvaluesIF::RETURN_FAILED; } objectList.push_back(newObject); + newObject->setTaskIF(this); + return HasReturnvaluesIF::RETURN_OK; } @@ -37,7 +40,8 @@ ReturnValue_t PeriodicPosixTask::sleepFor(uint32_t ms) { ReturnValue_t PeriodicPosixTask::startTask(void){ started = true; - createTask(&taskEntryPoint,this); + //sif::info << stackSize << std::endl; + PosixThread::createTask(&taskEntryPoint,this); return HasReturnvaluesIF::RETURN_OK; } @@ -56,9 +60,11 @@ void PeriodicPosixTask::taskFunctionality(void){ char name[20] = {0}; int status = pthread_getname_np(pthread_self(),name,sizeof(name)); if(status==0){ - sif::error << "ObjectTask: " << name << " Deadline missed." << std::endl; + sif::error << "PeriodicPosixTask " << name << ": Deadline " + "missed." << std::endl; }else{ - sif::error << "ObjectTask: X Deadline missed. " << status << std::endl; + sif::error << "PeriodicPosixTask X: Deadline missed. " << + status << std::endl; } if (this->deadlineMissedFunc != NULL) { this->deadlineMissedFunc(); diff --git a/osal/linux/PeriodicPosixTask.h b/osal/linux/PeriodicPosixTask.h index 43647eda1..f23adf4d8 100644 --- a/osal/linux/PeriodicPosixTask.h +++ b/osal/linux/PeriodicPosixTask.h @@ -1,17 +1,30 @@ #ifndef FRAMEWORK_OSAL_LINUX_PERIODICPOSIXTASK_H_ #define FRAMEWORK_OSAL_LINUX_PERIODICPOSIXTASK_H_ -#include -#include -#include -#include +#include "../../tasks/PeriodicTaskIF.h" +#include "../../objectmanager/ObjectManagerIF.h" +#include "PosixThread.h" +#include "../../tasks/ExecutableObjectIF.h" #include class PeriodicPosixTask: public PosixThread, public PeriodicTaskIF { public: + /** + * Create a generic periodic task. + * @param name_ + * Name, maximum allowed size of linux is 16 chars, everything else will + * be truncated. + * @param priority_ + * Real-time priority, ranges from 1 to 99 for Linux. + * See: https://man7.org/linux/man-pages/man7/sched.7.html + * @param stackSize_ + * @param period_ + * @param deadlineMissedFunc_ + */ PeriodicPosixTask(const char* name_, int priority_, size_t stackSize_, uint32_t period_, void(*deadlineMissedFunc_)()); virtual ~PeriodicPosixTask(); + /** * @brief The method to start the task. * @details The method starts the task with the respective system call. @@ -26,11 +39,11 @@ public: * @param object Id of the object to add. * @return RETURN_OK on success, RETURN_FAILED if the object could not be added. */ - ReturnValue_t addComponent(object_id_t object); + ReturnValue_t addComponent(object_id_t object) override; - uint32_t getPeriodMs() const; + uint32_t getPeriodMs() const override; - ReturnValue_t sleepFor(uint32_t ms); + ReturnValue_t sleepFor(uint32_t ms) override; private: typedef std::vector ObjectList; //!< Typedef for the List of objects. diff --git a/osal/linux/PosixThread.cpp b/osal/linux/PosixThread.cpp index 899700f0d..ddb1f74f6 100644 --- a/osal/linux/PosixThread.cpp +++ b/osal/linux/PosixThread.cpp @@ -1,8 +1,13 @@ -#include +#include "../../serviceinterface/ServiceInterfaceStream.h" +#include "PosixThread.h" #include #include -#include +PosixThread::PosixThread(const char* name_, int priority_, size_t stackSize_): + thread(0),priority(priority_),stackSize(stackSize_) { + name[0] = '\0'; + std::strncat(name, name_, PTHREAD_MAX_NAMELEN - 1); +} PosixThread::~PosixThread() { //No deletion and no free of Stack Pointer @@ -55,10 +60,6 @@ void PosixThread::resume(){ pthread_kill(thread,SIGUSR1); } - - - - bool PosixThread::delayUntil(uint64_t* const prevoiusWakeTime_ms, const uint64_t delayTime_ms) { uint64_t nextTimeToWake_ms; @@ -113,12 +114,6 @@ uint64_t PosixThread::getCurrentMonotonicTimeMs(){ return currentTime_ms; } -PosixThread::PosixThread(const char* name_, int priority_, size_t stackSize_): - thread(0),priority(priority_),stackSize(stackSize_) { - strcpy(name,name_); -} - - void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) { //sif::debug << "PosixThread::createTask" << std::endl; @@ -135,14 +130,24 @@ void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) { sif::error << "Posix Thread attribute init failed with: " << strerror(status) << std::endl; } - void* sp; - status = posix_memalign(&sp, sysconf(_SC_PAGESIZE), stackSize); + void* stackPointer; + status = posix_memalign(&stackPointer, sysconf(_SC_PAGESIZE), stackSize); if(status != 0){ - sif::error << "Posix Thread stack init failed with: " << + sif::error << "PosixThread::createTask: Stack init failed with: " << strerror(status) << std::endl; + if(errno == ENOMEM) { + uint64_t stackMb = stackSize/10e6; + sif::error << "PosixThread::createTask: Insufficient memory for" + " the requested " << stackMb << " MB" << std::endl; + } + else if(errno == EINVAL) { + sif::error << "PosixThread::createTask: Wrong alignment argument!" + << std::endl; + } + return; } - status = pthread_attr_setstack(&attributes, sp, stackSize); + status = pthread_attr_setstack(&attributes, stackPointer, stackSize); if(status != 0){ sif::error << "Posix Thread attribute setStack failed with: " << strerror(status) << std::endl; @@ -154,7 +159,7 @@ void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) { strerror(status) << std::endl; } -//TODO FIFO -> This needs root privileges for the process + // TODO FIFO -> This needs root privileges for the process status = pthread_attr_setschedpolicy(&attributes,SCHED_FIFO); if(status != 0){ sif::error << "Posix Thread attribute schedule policy failed with: " << @@ -188,8 +193,18 @@ void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) { status = pthread_setname_np(thread,name); if(status != 0){ - sif::error << "Posix Thread setname failed with: " << + sif::error << "PosixThread::createTask: setname failed with: " << strerror(status) << std::endl; + if(status == ERANGE) { + sif::error << "PosixThread::createTask: Task name length longer" + " than 16 chars. Truncating.." << std::endl; + name[15] = '\0'; + status = pthread_setname_np(thread,name); + if(status != 0){ + sif::error << "PosixThread::createTask: Setting name" + " did not work.." << std::endl; + } + } } status = pthread_attr_destroy(&attributes); diff --git a/osal/linux/PosixThread.h b/osal/linux/PosixThread.h index d96c4156e..7d8d349aa 100644 --- a/osal/linux/PosixThread.h +++ b/osal/linux/PosixThread.h @@ -1,15 +1,15 @@ #ifndef FRAMEWORK_OSAL_LINUX_POSIXTHREAD_H_ #define FRAMEWORK_OSAL_LINUX_POSIXTHREAD_H_ +#include "../../returnvalues/HasReturnvaluesIF.h" #include -#include #include -#include +#include #include -#include class PosixThread { public: + static constexpr uint8_t PTHREAD_MAX_NAMELEN = 16; PosixThread(const char* name_, int priority_, size_t stackSize_); virtual ~PosixThread(); /** @@ -54,21 +54,24 @@ protected: pthread_t thread; /** - * @brief Function that has to be called by derived class because the derived class pointer has to be valid as argument - * @details This function creates a pthread with the given parameters. As the function requires a pointer to the derived object - * it has to be called after the this pointer of the derived object is valid. Sets the taskEntryPoint as - * function to be called by new a thread. - * @param name_ Name of the task - * @param priority_ Priority of the task according to POSIX - * @param stackSize_ Size of the stack attached to that task - * @param arg_ argument of the taskEntryPoint function, needs to be this pointer of derived class + * @brief Function that has to be called by derived class because the + * derived class pointer has to be valid as argument. + * @details + * This function creates a pthread with the given parameters. As the + * function requires a pointer to the derived object it has to be called + * after the this pointer of the derived object is valid. + * Sets the taskEntryPoint as function to be called by new a thread. + * @param fnc_ Function which will be executed by the thread. + * @param arg_ + * argument of the taskEntryPoint function, needs to be this pointer + * of derived class */ void createTask(void* (*fnc_)(void*),void* arg_); private: - char name[10]; + char name[PTHREAD_MAX_NAMELEN]; int priority; - size_t stackSize; + size_t stackSize = 0; }; #endif /* FRAMEWORK_OSAL_LINUX_POSIXTHREAD_H_ */ diff --git a/osal/linux/QueueFactory.cpp b/osal/linux/QueueFactory.cpp index fc4c90261..afeca547b 100644 --- a/osal/linux/QueueFactory.cpp +++ b/osal/linux/QueueFactory.cpp @@ -1,20 +1,22 @@ -#include +#include "../../ipc/QueueFactory.h" #include #include -#include -#include +#include "MessageQueue.h" +#include "../../serviceinterface/ServiceInterfaceStream.h" #include -QueueFactory* QueueFactory::factoryInstance = NULL; +QueueFactory* QueueFactory::factoryInstance = nullptr; ReturnValue_t MessageQueueSenderIF::sendMessage(MessageQueueId_t sendTo, - MessageQueueMessage* message, MessageQueueId_t sentFrom,bool ignoreFault) { - return MessageQueue::sendMessageFromMessageQueue(sendTo,message,sentFrom,ignoreFault); + MessageQueueMessage* message, MessageQueueId_t sentFrom, + bool ignoreFault) { + return MessageQueue::sendMessageFromMessageQueue(sendTo,message, + sentFrom,ignoreFault); } QueueFactory* QueueFactory::instance() { - if (factoryInstance == NULL) { + if (factoryInstance == nullptr) { factoryInstance = new QueueFactory; } return factoryInstance; @@ -26,9 +28,9 @@ QueueFactory::QueueFactory() { QueueFactory::~QueueFactory() { } -MessageQueueIF* QueueFactory::createMessageQueue(uint32_t message_depth, - uint32_t max_message_size) { - return new MessageQueue(message_depth, max_message_size); +MessageQueueIF* QueueFactory::createMessageQueue(uint32_t messageDepth, + size_t maxMessageSize) { + return new MessageQueue(messageDepth, maxMessageSize); } void QueueFactory::deleteMessageQueue(MessageQueueIF* queue) { diff --git a/osal/linux/TaskFactory.cpp b/osal/linux/TaskFactory.cpp index 44f46d90b..f507c7671 100644 --- a/osal/linux/TaskFactory.cpp +++ b/osal/linux/TaskFactory.cpp @@ -1,7 +1,7 @@ -#include -#include -#include -#include +#include "FixedTimeslotTask.h" +#include "PeriodicPosixTask.h" +#include "../../tasks/TaskFactory.h" +#include "../../returnvalues/HasReturnvaluesIF.h" //TODO: Different variant than the lazy loading in QueueFactory. What's better and why? TaskFactory* TaskFactory::factoryInstance = new TaskFactory(); @@ -13,12 +13,20 @@ TaskFactory* TaskFactory::instance() { return TaskFactory::factoryInstance; } -PeriodicTaskIF* TaskFactory::createPeriodicTask(TaskName name_,TaskPriority taskPriority_,TaskStackSize stackSize_,TaskPeriod periodInSeconds_,TaskDeadlineMissedFunction deadLineMissedFunction_) { - return static_cast(new PeriodicPosixTask(name_, taskPriority_,stackSize_,periodInSeconds_ * 1000,deadLineMissedFunction_)); +PeriodicTaskIF* TaskFactory::createPeriodicTask(TaskName name_, + TaskPriority taskPriority_,TaskStackSize stackSize_, + TaskPeriod periodInSeconds_, + TaskDeadlineMissedFunction deadLineMissedFunction_) { + return new PeriodicPosixTask(name_, taskPriority_,stackSize_, + periodInSeconds_ * 1000, deadLineMissedFunction_); } -FixedTimeslotTaskIF* TaskFactory::createFixedTimeslotTask(TaskName name_,TaskPriority taskPriority_,TaskStackSize stackSize_,TaskPeriod periodInSeconds_,TaskDeadlineMissedFunction deadLineMissedFunction_) { - return static_cast(new FixedTimeslotTask(name_, taskPriority_,stackSize_,periodInSeconds_*1000)); +FixedTimeslotTaskIF* TaskFactory::createFixedTimeslotTask(TaskName name_, + TaskPriority taskPriority_,TaskStackSize stackSize_, + TaskPeriod periodInSeconds_, + TaskDeadlineMissedFunction deadLineMissedFunction_) { + return new FixedTimeslotTask(name_, taskPriority_,stackSize_, + periodInSeconds_*1000); } ReturnValue_t TaskFactory::deleteTask(PeriodicTaskIF* task) { diff --git a/osal/linux/Timer.cpp b/osal/linux/Timer.cpp index 5e27c328e..ee964baa0 100644 --- a/osal/linux/Timer.cpp +++ b/osal/linux/Timer.cpp @@ -1,6 +1,6 @@ -#include +#include "../../serviceinterface/ServiceInterfaceStream.h" #include -#include +#include "Timer.h" Timer::Timer() { sigevent sigEvent; diff --git a/osal/rtems/Clock.cpp b/osal/rtems/Clock.cpp index 98198dd31..eeffd7f33 100644 --- a/osal/rtems/Clock.cpp +++ b/osal/rtems/Clock.cpp @@ -1,4 +1,4 @@ -#include +#include "../../timemanager/Clock.h" #include "RtemsBasic.h" #include diff --git a/osal/rtems/CpuUsage.cpp b/osal/rtems/CpuUsage.cpp index 9fc34ff18..d49de4ad6 100644 --- a/osal/rtems/CpuUsage.cpp +++ b/osal/rtems/CpuUsage.cpp @@ -1,6 +1,6 @@ #include "CpuUsage.h" -#include -#include +#include "../../serialize/SerialArrayListAdapter.h" +#include "../../serialize/SerializeAdapter.h" #include extern "C" { @@ -89,15 +89,15 @@ void CpuUsage::clear() { threadData.clear(); } -ReturnValue_t CpuUsage::serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { - ReturnValue_t result = SerializeAdapter::serialize( - &timeSinceLastReset, buffer, size, max_size, bigEndian); +ReturnValue_t CpuUsage::serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const { + ReturnValue_t result = SerializeAdapter::serialize( + &timeSinceLastReset, buffer, size, maxSize, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } return SerialArrayListAdapter::serialize(&threadData, buffer, - size, max_size, bigEndian); + size, maxSize, streamEndianness); } uint32_t CpuUsage::getSerializedSize() const { @@ -109,37 +109,37 @@ uint32_t CpuUsage::getSerializedSize() const { return size; } -ReturnValue_t CpuUsage::deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) { - ReturnValue_t result = SerializeAdapter::deSerialize( - &timeSinceLastReset, buffer, size, bigEndian); +ReturnValue_t CpuUsage::deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) { + ReturnValue_t result = SerializeAdapter::deSerialize( + &timeSinceLastReset, buffer, size, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } return SerialArrayListAdapter::deSerialize(&threadData, buffer, - size, bigEndian); + size, streamEndianness); } -ReturnValue_t CpuUsage::ThreadData::serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { - ReturnValue_t result = SerializeAdapter::serialize(&id, buffer, - size, max_size, bigEndian); +ReturnValue_t CpuUsage::ThreadData::serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const { + ReturnValue_t result = SerializeAdapter::serialize(&id, buffer, + size, maxSize, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - if (*size + MAX_LENGTH_OF_THREAD_NAME > max_size) { + if (*size + MAX_LENGTH_OF_THREAD_NAME > maxSize) { return BUFFER_TOO_SHORT; } memcpy(*buffer, name, MAX_LENGTH_OF_THREAD_NAME); *size += MAX_LENGTH_OF_THREAD_NAME; *buffer += MAX_LENGTH_OF_THREAD_NAME; - result = SerializeAdapter::serialize(&timeRunning, - buffer, size, max_size, bigEndian); + result = SerializeAdapter::serialize(&timeRunning, + buffer, size, maxSize, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::serialize(&percentUsage, - buffer, size, max_size, bigEndian); + result = SerializeAdapter::serialize(&percentUsage, + buffer, size, maxSize, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } @@ -158,9 +158,9 @@ uint32_t CpuUsage::ThreadData::getSerializedSize() const { } ReturnValue_t CpuUsage::ThreadData::deSerialize(const uint8_t** buffer, - int32_t* size, bool bigEndian) { - ReturnValue_t result = SerializeAdapter::deSerialize(&id, buffer, - size, bigEndian); + int32_t* size, Endianness streamEndianness) { + ReturnValue_t result = SerializeAdapter::deSerialize(&id, buffer, + size, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } @@ -169,13 +169,13 @@ ReturnValue_t CpuUsage::ThreadData::deSerialize(const uint8_t** buffer, } memcpy(name, *buffer, MAX_LENGTH_OF_THREAD_NAME); *buffer -= MAX_LENGTH_OF_THREAD_NAME; - result = SerializeAdapter::deSerialize(&timeRunning, - buffer, size, bigEndian); + result = SerializeAdapter::deSerialize(&timeRunning, + buffer, size, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::deSerialize(&percentUsage, - buffer, size, bigEndian); + result = SerializeAdapter::deSerialize(&percentUsage, + buffer, size, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } diff --git a/osal/rtems/CpuUsage.h b/osal/rtems/CpuUsage.h index 3d317e4e2..f487e1911 100644 --- a/osal/rtems/CpuUsage.h +++ b/osal/rtems/CpuUsage.h @@ -1,8 +1,8 @@ #ifndef CPUUSAGE_H_ #define CPUUSAGE_H_ -#include -#include +#include "../../container/FixedArrayList.h" +#include "../../serialize/SerializeIF.h" #include class CpuUsage : public SerializeIF { @@ -18,13 +18,13 @@ public: float timeRunning; float percentUsage; - virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const; + virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const override; - virtual uint32_t getSerializedSize() const; + virtual size_t getSerializedSize() const override; - virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian); + virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) override; }; CpuUsage(); @@ -41,13 +41,13 @@ public: void clear(); - virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const; + virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const override; - virtual uint32_t getSerializedSize() const; + virtual size_t getSerializedSize() const override; - virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian); + virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) override; }; #endif /* CPUUSAGE_H_ */ diff --git a/osal/rtems/InternalErrorCodes.cpp b/osal/rtems/InternalErrorCodes.cpp index dbe3172e8..9346cf15d 100644 --- a/osal/rtems/InternalErrorCodes.cpp +++ b/osal/rtems/InternalErrorCodes.cpp @@ -1,4 +1,4 @@ -#include +#include "../../osal/InternalErrorCodes.h" #include ReturnValue_t InternalErrorCodes::translate(uint8_t code) { diff --git a/osal/rtems/Interrupt.h b/osal/rtems/Interrupt.h index c4c21911d..2152e2f03 100644 --- a/osal/rtems/Interrupt.h +++ b/osal/rtems/Interrupt.h @@ -1,7 +1,7 @@ #ifndef OS_RTEMS_INTERRUPT_H_ #define OS_RTEMS_INTERRUPT_H_ -#include +#include "../../returnvalues/HasReturnvaluesIF.h" #include #include diff --git a/osal/rtems/MessageQueue.cpp b/osal/rtems/MessageQueue.cpp index de148fdc6..700db444e 100644 --- a/osal/rtems/MessageQueue.cpp +++ b/osal/rtems/MessageQueue.cpp @@ -1,4 +1,4 @@ -#include +#include "../../serviceinterface/ServiceInterfaceStream.h" #include "MessageQueue.h" #include "RtemsBasic.h" #include diff --git a/osal/rtems/MessageQueue.h b/osal/rtems/MessageQueue.h index 9bdce7cad..c6fc62d52 100644 --- a/osal/rtems/MessageQueue.h +++ b/osal/rtems/MessageQueue.h @@ -10,9 +10,9 @@ #ifndef MESSAGEQUEUE_H_ #define MESSAGEQUEUE_H_ -#include -#include -#include +#include "../../internalError/InternalErrorReporterIF.h" +#include "../../ipc/MessageQueueIF.h" +#include "../../ipc/MessageQueueMessage.h" #include "RtemsBasic.h" /** diff --git a/osal/rtems/MultiObjectTask.cpp b/osal/rtems/MultiObjectTask.cpp index bb8c2c817..2342c24c2 100644 --- a/osal/rtems/MultiObjectTask.cpp +++ b/osal/rtems/MultiObjectTask.cpp @@ -5,8 +5,8 @@ * @author baetz */ -#include -#include +#include "../../serviceinterface/ServiceInterfaceStream.h" +#include "../../tasks/ExecutableObjectIF.h" #include "MultiObjectTask.h" MultiObjectTask::MultiObjectTask(const char *name, rtems_task_priority setPriority, @@ -78,6 +78,8 @@ ReturnValue_t MultiObjectTask::addComponent(object_id_t object) { return HasReturnvaluesIF::RETURN_FAILED; } objectList.push_back(newObject); + newObject->setTaskIF(this); + return HasReturnvaluesIF::RETURN_OK; } diff --git a/osal/rtems/MultiObjectTask.h b/osal/rtems/MultiObjectTask.h index 64b09c52a..736e79dd1 100644 --- a/osal/rtems/MultiObjectTask.h +++ b/osal/rtems/MultiObjectTask.h @@ -1,14 +1,8 @@ -/** - * @file MultiObjectTask.h - * @brief This file defines the MultiObjectTask class. - * @date 30.01.2014 - * @author baetz - */ -#ifndef MULTIOBJECTTASK_H_ -#define MULTIOBJECTTASK_H_ +#ifndef FSFW_OSAL_RTEMS_MULTIOBJECTTASK_H_ +#define FSFW_OSAL_RTEMS_MULTIOBJECTTASK_H_ -#include -#include +#include "../../objectmanager/ObjectManagerIF.h" +#include "../../tasks/PeriodicTaskIF.h" #include "TaskBase.h" #include @@ -21,7 +15,7 @@ class ExecutableObjectIF; * @details MultiObjectTask is an extension to ObjectTask in the way that it is able to execute * multiple objects that implement the ExecutableObjectIF interface. The objects must be * added prior to starting the task. - * + * @author baetz * @ingroup task_handling */ class MultiObjectTask: public TaskBase, public PeriodicTaskIF { @@ -63,11 +57,11 @@ public: * @param object Id of the object to add. * @return RETURN_OK on success, RETURN_FAILED if the object could not be added. */ - ReturnValue_t addComponent(object_id_t object); + ReturnValue_t addComponent(object_id_t object) override; - uint32_t getPeriodMs() const; + uint32_t getPeriodMs() const override; - ReturnValue_t sleepFor(uint32_t ms); + ReturnValue_t sleepFor(uint32_t ms) override; protected: typedef std::vector ObjectList; //!< Typedef for the List of objects. /** @@ -110,4 +104,4 @@ protected: void taskFunctionality(void); }; -#endif /* MULTIOBJECTTASK_H_ */ +#endif /* FSFW_OSAL_RTEMS_MULTIOBJECTTASK_H_ */ diff --git a/osal/rtems/Mutex.cpp b/osal/rtems/Mutex.cpp index d094e1dce..9553ac79c 100644 --- a/osal/rtems/Mutex.cpp +++ b/osal/rtems/Mutex.cpp @@ -1,7 +1,6 @@ #include "Mutex.h" -#include +#include "../../serviceinterface/ServiceInterfaceStream.h" -const uint32_t MutexIF::NO_TIMEOUT = RTEMS_NO_TIMEOUT; uint8_t Mutex::count = 0; Mutex::Mutex() : @@ -24,8 +23,22 @@ Mutex::~Mutex() { } } -ReturnValue_t Mutex::lockMutex(uint32_t timeoutMs) { - rtems_status_code status = rtems_semaphore_obtain(mutexId, RTEMS_WAIT, timeoutMs); +ReturnValue_t Mutex::lockMutex(TimeoutType timeoutType = + TimeoutType::BLOCKING, uint32_t timeoutMs) { + if(timeoutMs == MutexIF::TimeoutType::BLOCKING) { + rtems_status_code status = rtems_semaphore_obtain(mutexId, + RTEMS_WAIT, RTEMS_NO_TIMEOUT); + } + else if(timeoutMs == MutexIF::TimeoutType::POLLING) { + timeoutMs = RTEMS_NO_TIMEOUT; + rtems_status_code status = rtems_semaphore_obtain(mutexId, + RTEMS_NO_WAIT, 0); + } + else { + rtems_status_code status = rtems_semaphore_obtain(mutexId, + RTEMS_WAIT, timeoutMs); + } + switch(status){ case RTEMS_SUCCESSFUL: //semaphore obtained successfully diff --git a/osal/rtems/Mutex.h b/osal/rtems/Mutex.h index 19b34e7f2..723682104 100644 --- a/osal/rtems/Mutex.h +++ b/osal/rtems/Mutex.h @@ -1,14 +1,14 @@ -#ifndef OS_RTEMS_MUTEX_H_ -#define OS_RTEMS_MUTEX_H_ +#ifndef FRAMEWORK_OSAL_RTEMS_MUTEX_H_ +#define FRAMEWORK_OSAL_RTEMS_MUTEX_H_ -#include +#include "../../ipc/MutexIF.h" #include "RtemsBasic.h" class Mutex : public MutexIF { public: Mutex(); ~Mutex(); - ReturnValue_t lockMutex(uint32_t timeoutMs); + ReturnValue_t lockMutex(TimeoutType timeoutType, uint32_t timeoutMs = 0); ReturnValue_t unlockMutex(); private: rtems_id mutexId; diff --git a/osal/rtems/MutexFactory.cpp b/osal/rtems/MutexFactory.cpp index d7bd16bca..ea5947895 100644 --- a/osal/rtems/MutexFactory.cpp +++ b/osal/rtems/MutexFactory.cpp @@ -1,4 +1,4 @@ -#include +#include "../../ipc/MutexFactory.h" #include "Mutex.h" #include "RtemsBasic.h" diff --git a/osal/rtems/PollingTask.cpp b/osal/rtems/PollingTask.cpp index 03ba09510..04191515b 100644 --- a/osal/rtems/PollingTask.cpp +++ b/osal/rtems/PollingTask.cpp @@ -1,9 +1,9 @@ -#include -#include -#include -#include -#include -#include +#include "../../devicehandlers/FixedSequenceSlot.h" +#include "../../objectmanager/SystemObjectIF.h" +#include "PollingTask.h" +#include "RtemsBasic.h" +#include "../../returnvalues/HasReturnvaluesIF.h" +#include "../../serviceinterface/ServiceInterfaceStream.h" #include #include #include diff --git a/osal/rtems/PollingTask.h b/osal/rtems/PollingTask.h index 82ec65a2d..199c34e71 100644 --- a/osal/rtems/PollingTask.h +++ b/osal/rtems/PollingTask.h @@ -1,8 +1,8 @@ #ifndef POLLINGTASK_H_ #define POLLINGTASK_H_ -#include -#include +#include "../../devicehandlers/FixedSlotSequence.h" +#include "../../tasks/FixedTimeslotTaskIF.h" #include "TaskBase.h" class PollingTask: public TaskBase, public FixedTimeslotTaskIF { diff --git a/osal/rtems/QueueFactory.cpp b/osal/rtems/QueueFactory.cpp index 0f2e0ea9b..fce55a0e4 100644 --- a/osal/rtems/QueueFactory.cpp +++ b/osal/rtems/QueueFactory.cpp @@ -1,4 +1,4 @@ -#include +#include "../../ipc/QueueFactory.h" #include "MessageQueue.h" #include "RtemsBasic.h" @@ -49,9 +49,9 @@ QueueFactory::QueueFactory() { QueueFactory::~QueueFactory() { } -MessageQueueIF* QueueFactory::createMessageQueue(uint32_t message_depth, - uint32_t max_message_size) { - return new MessageQueue(message_depth, max_message_size); +MessageQueueIF* QueueFactory::createMessageQueue(uint32_t messageDepth, + size_t maxMessageSize) { + return new MessageQueue(messageDepth, maxMessageSize); } void QueueFactory::deleteMessageQueue(MessageQueueIF* queue) { diff --git a/osal/rtems/RtemsBasic.h b/osal/rtems/RtemsBasic.h index f7ab86144..78e0d46e7 100644 --- a/osal/rtems/RtemsBasic.h +++ b/osal/rtems/RtemsBasic.h @@ -1,7 +1,7 @@ #ifndef OS_RTEMS_RTEMSBASIC_H_ #define OS_RTEMS_RTEMSBASIC_H_ -#include +#include "../../returnvalues/HasReturnvaluesIF.h" #include #include #include diff --git a/osal/rtems/TaskBase.cpp b/osal/rtems/TaskBase.cpp index ad795645a..adf6ee707 100644 --- a/osal/rtems/TaskBase.cpp +++ b/osal/rtems/TaskBase.cpp @@ -1,4 +1,4 @@ -#include +#include "../../serviceinterface/ServiceInterfaceStream.h" #include "TaskBase.h" const size_t PeriodicTaskIF::MINIMUM_STACK_SIZE=RTEMS_MINIMUM_STACK_SIZE; diff --git a/osal/rtems/TaskBase.h b/osal/rtems/TaskBase.h index b9c1192aa..410d9110e 100644 --- a/osal/rtems/TaskBase.h +++ b/osal/rtems/TaskBase.h @@ -2,7 +2,7 @@ #define TASKBASE_H_ #include "RtemsBasic.h" -#include +#include "../../tasks/PeriodicTaskIF.h" /** * @brief This is the basic task handling class for rtems. diff --git a/osal/rtems/TaskFactory.cpp b/osal/rtems/TaskFactory.cpp index 2bee19c76..bab48a44e 100644 --- a/osal/rtems/TaskFactory.cpp +++ b/osal/rtems/TaskFactory.cpp @@ -1,9 +1,9 @@ -#include +#include "../../tasks/TaskFactory.h" #include "MultiObjectTask.h" #include "PollingTask.h" #include "InitTask.h" #include "RtemsBasic.h" -#include +#include "../../returnvalues/HasReturnvaluesIF.h" //TODO: Different variant than the lazy loading in QueueFactory. What's better and why? TaskFactory* TaskFactory::factoryInstance = new TaskFactory(); diff --git a/parameters/HasParametersIF.h b/parameters/HasParametersIF.h index fbb694454..71212b576 100644 --- a/parameters/HasParametersIF.h +++ b/parameters/HasParametersIF.h @@ -1,8 +1,8 @@ #ifndef HASPARAMETERSIF_H_ #define HASPARAMETERSIF_H_ -#include -#include +#include "ParameterWrapper.h" +#include "../returnvalues/HasReturnvaluesIF.h" #include typedef uint32_t ParameterId_t; diff --git a/parameters/ParameterHelper.cpp b/parameters/ParameterHelper.cpp index 9e4fc4938..8543515fa 100644 --- a/parameters/ParameterHelper.cpp +++ b/parameters/ParameterHelper.cpp @@ -1,6 +1,6 @@ -#include -#include -#include +#include "../objectmanager/ObjectManagerIF.h" +#include "ParameterHelper.h" +#include "ParameterMessage.h" ParameterHelper::ParameterHelper(ReceivesParameterMessagesIF* owner) : owner(owner), storage(NULL) { @@ -83,7 +83,7 @@ ReturnValue_t ParameterHelper::handleParameterMessage(CommandMessage *message) { ReturnValue_t ParameterHelper::sendParameter(MessageQueueId_t to, uint32_t id, const ParameterWrapper* description) { - uint32_t serializedSize = description->getSerializedSize(); + size_t serializedSize = description->getSerializedSize(); uint8_t *storeElement; store_address_t address; @@ -94,10 +94,10 @@ ReturnValue_t ParameterHelper::sendParameter(MessageQueueId_t to, uint32_t id, return result; } - uint32_t storeElementSize = 0; + size_t storeElementSize = 0; result = description->serialize(&storeElement, &storeElementSize, - serializedSize, true); + serializedSize, SerializeIF::Endianness::BIG); if (result != HasReturnvaluesIF::RETURN_OK) { storage->deleteData(address); diff --git a/parameters/ParameterHelper.h b/parameters/ParameterHelper.h index e2fefdba0..d887bf1d1 100644 --- a/parameters/ParameterHelper.h +++ b/parameters/ParameterHelper.h @@ -1,8 +1,8 @@ #ifndef PARAMETERHELPER_H_ #define PARAMETERHELPER_H_ -#include -#include +#include "ParameterMessage.h" +#include "ReceivesParameterMessagesIF.h" class ParameterHelper { public: diff --git a/parameters/ParameterMessage.cpp b/parameters/ParameterMessage.cpp index 1c7d6911d..7e0ed1140 100644 --- a/parameters/ParameterMessage.cpp +++ b/parameters/ParameterMessage.cpp @@ -1,5 +1,5 @@ -#include -#include +#include "ParameterMessage.h" +#include "../objectmanager/ObjectManagerIF.h" ParameterId_t ParameterMessage::getParameterId(const CommandMessage* message) { return message->getParameter(); diff --git a/parameters/ParameterMessage.h b/parameters/ParameterMessage.h index 432832941..f59af5136 100644 --- a/parameters/ParameterMessage.h +++ b/parameters/ParameterMessage.h @@ -1,9 +1,9 @@ #ifndef PARAMETERMESSAGE_H_ #define PARAMETERMESSAGE_H_ -#include -#include -#include +#include "../ipc/CommandMessage.h" +#include "HasParametersIF.h" +#include "../storagemanager/StorageManagerIF.h" class ParameterMessage { private: diff --git a/parameters/ParameterWrapper.cpp b/parameters/ParameterWrapper.cpp index 1dac70757..56f564267 100644 --- a/parameters/ParameterWrapper.cpp +++ b/parameters/ParameterWrapper.cpp @@ -1,42 +1,42 @@ -#include +#include "ParameterWrapper.h" ParameterWrapper::ParameterWrapper() : pointsToStream(false), type(Type::UNKNOWN_TYPE), rows(0), columns(0), data( - NULL), readonlyData(NULL) { + NULL), readonlyData(NULL) { } ParameterWrapper::ParameterWrapper(Type type, uint8_t rows, uint8_t columns, - void* data) : + void *data) : pointsToStream(false), type(type), rows(rows), columns(columns), data( data), readonlyData(data) { } ParameterWrapper::ParameterWrapper(Type type, uint8_t rows, uint8_t columns, - const void* data) : + const void *data) : pointsToStream(false), type(type), rows(rows), columns(columns), data( - NULL), readonlyData(data) { + NULL), readonlyData(data) { } ParameterWrapper::~ParameterWrapper() { } -ReturnValue_t ParameterWrapper::serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { +ReturnValue_t ParameterWrapper::serialize(uint8_t **buffer, size_t *size, + size_t maxSize, Endianness streamEndianness) const { ReturnValue_t result; - result = SerializeAdapter::serialize(&type, buffer, size, max_size, - bigEndian); + result = SerializeAdapter::serialize(&type, buffer, size, maxSize, + streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::serialize(&columns, buffer, size, - max_size, bigEndian); + result = SerializeAdapter::serialize(&columns, buffer, size, maxSize, + streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::serialize(&rows, buffer, size, max_size, - bigEndian); + result = SerializeAdapter::serialize(&rows, buffer, size, maxSize, + streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } @@ -47,28 +47,33 @@ ReturnValue_t ParameterWrapper::serialize(uint8_t** buffer, uint32_t* size, } switch (type) { case Type::UINT8_T: - result = serializeData(buffer, size, max_size, bigEndian); + result = serializeData(buffer, size, maxSize, + streamEndianness); break; case Type::INT8_T: - result = serializeData(buffer, size, max_size, bigEndian); + result = serializeData(buffer, size, maxSize, streamEndianness); break; case Type::UINT16_T: - result = serializeData(buffer, size, max_size, bigEndian); + result = serializeData(buffer, size, maxSize, + streamEndianness); break; case Type::INT16_T: - result = serializeData(buffer, size, max_size, bigEndian); + result = serializeData(buffer, size, maxSize, + streamEndianness); break; case Type::UINT32_T: - result = serializeData(buffer, size, max_size, bigEndian); + result = serializeData(buffer, size, maxSize, + streamEndianness); break; case Type::INT32_T: - result = serializeData(buffer, size, max_size, bigEndian); + result = serializeData(buffer, size, maxSize, + streamEndianness); break; case Type::FLOAT: - result = serializeData(buffer, size, max_size, bigEndian); + result = serializeData(buffer, size, maxSize, streamEndianness); break; case Type::DOUBLE: - result = serializeData(buffer, size, max_size, bigEndian); + result = serializeData(buffer, size, maxSize, streamEndianness); break; default: result = UNKNOW_DATATYPE; @@ -77,7 +82,7 @@ ReturnValue_t ParameterWrapper::serialize(uint8_t** buffer, uint32_t* size, return result; } -uint32_t ParameterWrapper::getSerializedSize() const { +size_t ParameterWrapper::getSerializedSize() const { uint32_t serializedSize = 0; serializedSize += type.getSerializedSize(); serializedSize += sizeof(rows); @@ -88,14 +93,14 @@ uint32_t ParameterWrapper::getSerializedSize() const { } template -ReturnValue_t ParameterWrapper::serializeData(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { +ReturnValue_t ParameterWrapper::serializeData(uint8_t **buffer, size_t *size, + size_t maxSize, Endianness streamEndianness) const { const T *element = (const T*) readonlyData; ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; uint16_t dataSize = columns * rows; while (dataSize != 0) { - result = SerializeAdapter::serialize(element, buffer, size, max_size, - bigEndian); + result = SerializeAdapter::serialize(element, buffer, size, maxSize, + streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } @@ -111,21 +116,21 @@ ReturnValue_t ParameterWrapper::deSerializeData(uint8_t startingRow, uint8_t fromColumns) { //treat from as a continuous Stream as we copy all of it - const uint8_t *fromAsStream = (const uint8_t *) from; - int32_t streamSize = fromRows * fromColumns * sizeof(T); + const uint8_t *fromAsStream = (const uint8_t*) from; + size_t streamSize = fromRows * fromColumns * sizeof(T); ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; for (uint8_t fromRow = 0; fromRow < fromRows; fromRow++) { //get the start element of this row in data - T *dataWithDataType = ((T *) data) + T *dataWithDataType = ((T*) data) + (((startingRow + fromRow) * columns) + startingColumn); for (uint8_t fromColumn = 0; fromColumn < fromColumns; fromColumn++) { - result = SerializeAdapter::deSerialize( + result = SerializeAdapter::deSerialize( dataWithDataType + fromColumn, &fromAsStream, &streamSize, - true); + SerializeIF::Endianness::BIG); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } @@ -136,13 +141,14 @@ ReturnValue_t ParameterWrapper::deSerializeData(uint8_t startingRow, } -ReturnValue_t ParameterWrapper::deSerialize(const uint8_t** buffer, - int32_t* size, bool bigEndian) { - return deSerialize(buffer, size, bigEndian, 0); +ReturnValue_t ParameterWrapper::deSerialize(const uint8_t **buffer, + size_t *size, Endianness streamEndianness) { + return deSerialize(buffer, size, streamEndianness, 0); } -ReturnValue_t ParameterWrapper::deSerialize(const uint8_t** buffer, - int32_t* size, bool bigEndian, uint16_t startWritingAtIndex) { +ReturnValue_t ParameterWrapper::deSerialize(const uint8_t **buffer, + size_t *size, Endianness streamEndianness, + uint16_t startWritingAtIndex) { ParameterWrapper streamDescription; ReturnValue_t result = streamDescription.set(*buffer, *size, buffer, size); @@ -153,26 +159,26 @@ ReturnValue_t ParameterWrapper::deSerialize(const uint8_t** buffer, return copyFrom(&streamDescription, startWritingAtIndex); } -ReturnValue_t ParameterWrapper::set(const uint8_t* stream, int32_t streamSize, - const uint8_t **remainingStream, int32_t *remainingSize) { - ReturnValue_t result = SerializeAdapter::deSerialize(&type, &stream, - &streamSize, true); +ReturnValue_t ParameterWrapper::set(const uint8_t *stream, size_t streamSize, + const uint8_t **remainingStream, size_t *remainingSize) { + ReturnValue_t result = SerializeAdapter::deSerialize(&type, &stream, + &streamSize, SerializeIF::Endianness::BIG); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::deSerialize(&columns, &stream, - &streamSize, true); + result = SerializeAdapter::deSerialize(&columns, &stream, &streamSize, + SerializeIF::Endianness::BIG); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::deSerialize(&rows, &stream, &streamSize, - true); + result = SerializeAdapter::deSerialize(&rows, &stream, &streamSize, + SerializeIF::Endianness::BIG); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - int32_t dataSize = type.getSize() * rows * columns; + size_t dataSize = type.getSize() * rows * columns; if (streamSize < dataSize) { return SerializeIF::STREAM_TOO_SHORT; @@ -194,7 +200,7 @@ ReturnValue_t ParameterWrapper::set(const uint8_t* stream, int32_t streamSize, return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t ParameterWrapper::copyFrom(const ParameterWrapper* from, +ReturnValue_t ParameterWrapper::copyFrom(const ParameterWrapper *from, uint16_t startWritingAtIndex) { if (data == NULL) { return READONLY; @@ -261,7 +267,7 @@ ReturnValue_t ParameterWrapper::copyFrom(const ParameterWrapper* from, } } else { //need a type to do arithmetic - uint8_t *toDataWithType = (uint8_t *) data; + uint8_t *toDataWithType = (uint8_t*) data; for (uint8_t fromRow = 0; fromRow < from->rows; fromRow++) { memcpy( toDataWithType diff --git a/parameters/ParameterWrapper.h b/parameters/ParameterWrapper.h index f61786b8a..b18fe2b92 100644 --- a/parameters/ParameterWrapper.h +++ b/parameters/ParameterWrapper.h @@ -1,11 +1,11 @@ #ifndef PARAMETERWRAPPER_H_ #define PARAMETERWRAPPER_H_ -#include -#include -#include +#include "../returnvalues/HasReturnvaluesIF.h" +#include "../serialize/SerializeAdapter.h" +#include "../serialize/SerializeIF.h" #include -#include +#include "../globalfunctions/Type.h" class ParameterWrapper: public SerializeIF { friend class DataPoolParameterWrapper; @@ -25,16 +25,16 @@ public: const void *data); virtual ~ParameterWrapper(); - virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const; + virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const override; - virtual uint32_t getSerializedSize() const; + virtual size_t getSerializedSize() const override; - virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian); + virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) override; - virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian, uint16_t startWritingAtIndex = 0); + virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness, uint16_t startWritingAtIndex = 0); template ReturnValue_t getElement(T *value, uint8_t row = 0, uint8_t column = 0) const { @@ -54,7 +54,7 @@ public: const uint8_t *streamWithtype = (const uint8_t *) readonlyData; streamWithtype += (row * columns + column) * type.getSize(); int32_t size = type.getSize(); - return SerializeAdapter::deSerialize(value, &streamWithtype, + return SerializeAdapter::deSerialize(value, &streamWithtype, &size, true); } else { const T *dataWithType = (const T *) readonlyData; @@ -111,8 +111,8 @@ public: void setMatrix(const T& member) { this->set(member[0], sizeof(member)/sizeof(member[0]), sizeof(member[0])/sizeof(member[0][0])); } - ReturnValue_t set(const uint8_t *stream, int32_t streamSize, - const uint8_t **remainingStream = NULL, int32_t *remainingSize = + ReturnValue_t set(const uint8_t *stream, size_t streamSize, + const uint8_t **remainingStream = NULL, size_t *remainingSize = NULL); ReturnValue_t copyFrom(const ParameterWrapper *from, @@ -128,8 +128,8 @@ private: const void *readonlyData; template - ReturnValue_t serializeData(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const; + ReturnValue_t serializeData(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const; template ReturnValue_t deSerializeData(uint8_t startingRow, uint8_t startingColumn, diff --git a/parameters/ReceivesParameterMessagesIF.h b/parameters/ReceivesParameterMessagesIF.h index 9bcd226dd..1fcbd4b39 100644 --- a/parameters/ReceivesParameterMessagesIF.h +++ b/parameters/ReceivesParameterMessagesIF.h @@ -2,8 +2,8 @@ #define RECEIVESPARAMETERMESSAGESIF_H_ -#include -#include +#include "HasParametersIF.h" +#include "../ipc/MessageQueueSenderIF.h" class ReceivesParameterMessagesIF : public HasParametersIF { public: diff --git a/power/Fuse.cpp b/power/Fuse.cpp index dd5d3e3f4..9986ab6bb 100644 --- a/power/Fuse.cpp +++ b/power/Fuse.cpp @@ -1,9 +1,9 @@ -#include -#include -#include -#include -#include -#include +#include "../monitoring/LimitViolationReporter.h" +#include "../monitoring/MonitoringMessageContent.h" +#include "../objectmanager/ObjectManagerIF.h" +#include "Fuse.h" +#include "../serialize/SerialFixedArrayListAdapter.h" +#include "../ipc/QueueFactory.h" object_id_t Fuse::powerSwitchId = 0; @@ -86,12 +86,12 @@ ReturnValue_t Fuse::check() { return result; } -ReturnValue_t Fuse::serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { +ReturnValue_t Fuse::serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const { ReturnValue_t result = RETURN_FAILED; for (DeviceList::const_iterator iter = devices.begin(); iter != devices.end(); iter++) { - result = (*iter)->serialize(buffer, size, max_size, bigEndian); + result = (*iter)->serialize(buffer, size, maxSize, streamEndianness); if (result != RETURN_OK) { return result; } @@ -99,7 +99,7 @@ ReturnValue_t Fuse::serialize(uint8_t** buffer, uint32_t* size, return RETURN_OK; } -uint32_t Fuse::getSerializedSize() const { +size_t Fuse::getSerializedSize() const { uint32_t size = 0; for (DeviceList::const_iterator iter = devices.begin(); iter != devices.end(); iter++) { @@ -108,12 +108,12 @@ uint32_t Fuse::getSerializedSize() const { return size; } -ReturnValue_t Fuse::deSerialize(const uint8_t** buffer, int32_t* size, -bool bigEndian) { +ReturnValue_t Fuse::deSerialize(const uint8_t** buffer, size_t* size, +Endianness streamEndianness) { ReturnValue_t result = RETURN_FAILED; for (DeviceList::iterator iter = devices.begin(); iter != devices.end(); iter++) { - result = (*iter)->deSerialize(buffer, size, bigEndian); + result = (*iter)->deSerialize(buffer, size, streamEndianness); if (result != RETURN_OK) { return result; } diff --git a/power/Fuse.h b/power/Fuse.h index 6da241788..279642be6 100644 --- a/power/Fuse.h +++ b/power/Fuse.h @@ -1,24 +1,25 @@ #ifndef FUSE_H_ #define FUSE_H_ -#include -#include -#include -#include -#include -#include -#include -#include +#include "../datapool/DataSet.h" +#include "../datapool/PIDReader.h" +#include "../devicehandlers/HealthDevice.h" +#include "../monitoring/AbsLimitMonitor.h" +#include "PowerComponentIF.h" +#include "PowerSwitchIF.h" +#include "../returnvalues/HasReturnvaluesIF.h" +#include "../parameters/ParameterHelper.h" #include -namespace Factory{ +namespace Factory { void setStaticFrameworkObjectIds(); } class Fuse: public SystemObject, public HasHealthIF, public HasReturnvaluesIF, - public ReceivesParameterMessagesIF { + public ReceivesParameterMessagesIF, + public SerializeIF { friend void (Factory::setStaticFrameworkObjectIds)(); private: static constexpr float RESIDUAL_POWER = 0.005 * 28.5; //!< This is the upper limit of residual power lost by fuses and switches. Worst case is Fuse and one of two switches on. See PCDU ICD 1.9 p29 bottom @@ -40,7 +41,7 @@ public: Fuse(object_id_t fuseObjectId, uint8_t fuseId, VariableIds ids, float maxCurrent, uint16_t confirmationCount = 2); virtual ~Fuse(); - void addDevice(PowerComponentIF* set); + void addDevice(PowerComponentIF *set); float getPower(); bool isPowerValid(); @@ -49,11 +50,11 @@ public: uint8_t getFuseId() const; ReturnValue_t initialize(); DeviceList devices; - ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const; - uint32_t getSerializedSize() const; - ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian); + ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize, + SerializeIF::Endianness streamEndianness) const override; + size_t getSerializedSize() const override; + ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size, + SerializeIF::Endianness streamEndianness) override; void setAllMonitorsToUnchecked(); ReturnValue_t performOperation(uint8_t opCode); MessageQueueId_t getCommandQueue() const; @@ -62,13 +63,13 @@ public: HasHealthIF::HealthState getHealth(); ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId, - ParameterWrapper *parameterWrapper, - const ParameterWrapper *newValues, uint16_t startAtIndex); + ParameterWrapper *parameterWrapper, + const ParameterWrapper *newValues, uint16_t startAtIndex); private: uint8_t oldFuseState; uint8_t fuseId; - PowerSwitchIF* powerIF; //could be static in our case. + PowerSwitchIF *powerIF; //could be static in our case. AbsLimitMonitor currentLimit; class PowerMonitor: public MonitorReporter { public: @@ -88,11 +89,11 @@ private: PIDReader current; PIDReader state; db_float_t power; - MessageQueueIF* commandQueue; + MessageQueueIF *commandQueue; ParameterHelper parameterHelper; HealthHelper healthHelper; static object_id_t powerSwitchId; - void calculatePowerLimits(float* low, float* high); + void calculatePowerLimits(float *low, float *high); void calculateFusePower(); void checkFuseState(); void reportEvents(Event event); diff --git a/power/PowerComponent.cpp b/power/PowerComponent.cpp index 6a87d88b8..6012ad4ca 100644 --- a/power/PowerComponent.cpp +++ b/power/PowerComponent.cpp @@ -5,7 +5,7 @@ * @author baetz */ -#include +#include "PowerComponent.h" PowerComponent::PowerComponent() : deviceObjectId(0), switchId1(0xFF), switchId2(0xFF), doIHaveTwoSwitches( @@ -17,18 +17,18 @@ PowerComponent::PowerComponent(object_id_t setId, uint8_t moduleId, float min, f twoSwitches), min(min), max(max), moduleId(moduleId) { } -ReturnValue_t PowerComponent::serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { - ReturnValue_t result = SerializeAdapter::serialize(&min, buffer, - size, max_size, bigEndian); +ReturnValue_t PowerComponent::serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const { + ReturnValue_t result = SerializeAdapter::serialize(&min, buffer, + size, maxSize, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - return SerializeAdapter::serialize(&max, buffer, size, max_size, - bigEndian); + return SerializeAdapter::serialize(&max, buffer, size, maxSize, + streamEndianness); } -uint32_t PowerComponent::getSerializedSize() const { +size_t PowerComponent::getSerializedSize() const { return sizeof(min) + sizeof(max); } @@ -56,14 +56,14 @@ float PowerComponent::getMax() { return max; } -ReturnValue_t PowerComponent::deSerialize(const uint8_t** buffer, int32_t* size, -bool bigEndian) { - ReturnValue_t result = SerializeAdapter::deSerialize(&min, buffer, - size, bigEndian); +ReturnValue_t PowerComponent::deSerialize(const uint8_t** buffer, size_t* size, +Endianness streamEndianness) { + ReturnValue_t result = SerializeAdapter::deSerialize(&min, buffer, + size, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - return SerializeAdapter::deSerialize(&max, buffer, size, bigEndian); + return SerializeAdapter::deSerialize(&max, buffer, size, streamEndianness); } ReturnValue_t PowerComponent::getParameter(uint8_t domainId, diff --git a/power/PowerComponent.h b/power/PowerComponent.h index a82fe1d7f..6d1c9c06d 100644 --- a/power/PowerComponent.h +++ b/power/PowerComponent.h @@ -1,8 +1,8 @@ #ifndef POWERCOMPONENT_H_ #define POWERCOMPONENT_H_ -#include -#include +#include "../objectmanager/SystemObjectIF.h" +#include "PowerComponentIF.h" class PowerComponent: public PowerComponentIF { public: @@ -19,13 +19,13 @@ public: float getMin(); float getMax(); - ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const; + ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const override; - uint32_t getSerializedSize() const; + size_t getSerializedSize() const override; - ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian); + ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) override; ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId, ParameterWrapper *parameterWrapper, diff --git a/power/PowerComponentIF.h b/power/PowerComponentIF.h index f2aa70aec..c2e3a6a56 100644 --- a/power/PowerComponentIF.h +++ b/power/PowerComponentIF.h @@ -1,8 +1,8 @@ #ifndef POWERCOMPONENTIF_H_ #define POWERCOMPONENTIF_H_ -#include -#include +#include "../serialize/SerializeIF.h" +#include "../parameters/HasParametersIF.h" class PowerComponentIF : public SerializeIF, public HasParametersIF { public: diff --git a/power/PowerSensor.cpp b/power/PowerSensor.cpp index 5433acc93..50cb6acd2 100644 --- a/power/PowerSensor.cpp +++ b/power/PowerSensor.cpp @@ -1,5 +1,5 @@ -#include -#include +#include "PowerSensor.h" +#include "../ipc/QueueFactory.h" PowerSensor::PowerSensor(object_id_t setId, VariableIds ids, DefaultLimits limits, SensorEvents events, uint16_t confirmationCount) : diff --git a/power/PowerSensor.h b/power/PowerSensor.h index 922560d07..0f973e455 100644 --- a/power/PowerSensor.h +++ b/power/PowerSensor.h @@ -1,14 +1,14 @@ #ifndef POWERSENSOR_H_ #define POWERSENSOR_H_ -#include -#include -#include -#include -#include -#include -#include -#include +#include "../datapool/DataSet.h" +#include "../datapool/PIDReader.h" +#include "../datapool/PoolVariable.h" +#include "../devicehandlers/HealthDevice.h" +#include "../monitoring/LimitMonitor.h" +#include "../parameters/ParameterHelper.h" +#include "../objectmanager/SystemObject.h" +#include "../ipc/MessageQueueIF.h" class PowerController; diff --git a/power/PowerSwitchIF.h b/power/PowerSwitchIF.h index 1c4c06f7f..40220fb62 100644 --- a/power/PowerSwitchIF.h +++ b/power/PowerSwitchIF.h @@ -8,8 +8,8 @@ #ifndef POWERSWITCHIF_H_ #define POWERSWITCHIF_H_ -#include -#include +#include "../events/Event.h" +#include "../returnvalues/HasReturnvaluesIF.h" /** * This interface defines a connection to a device that is capable of turning on and off * switches of devices identified by a switch ID. diff --git a/power/PowerSwitcher.cpp b/power/PowerSwitcher.cpp index 6b06bf735..6296a04c7 100644 --- a/power/PowerSwitcher.cpp +++ b/power/PowerSwitcher.cpp @@ -1,6 +1,6 @@ -#include -#include -#include +#include "../objectmanager/ObjectManagerIF.h" +#include "PowerSwitcher.h" +#include "../serviceinterface/ServiceInterfaceStream.h" PowerSwitcher::PowerSwitcher(uint8_t setSwitch1, uint8_t setSwitch2, PowerSwitcher::State_t setStartState) : diff --git a/power/PowerSwitcher.h b/power/PowerSwitcher.h index 5b2789e96..0f1c02deb 100644 --- a/power/PowerSwitcher.h +++ b/power/PowerSwitcher.h @@ -1,8 +1,8 @@ #ifndef POWERSWITCHER_H_ #define POWERSWITCHER_H_ -#include -#include -#include +#include "PowerSwitchIF.h" +#include "../returnvalues/HasReturnvaluesIF.h" +#include "../timemanager/Countdown.h" class PowerSwitcher : public HasReturnvaluesIF { public: diff --git a/pus/CService200ModeCommanding.cpp b/pus/CService200ModeCommanding.cpp new file mode 100644 index 000000000..32f7e5a74 --- /dev/null +++ b/pus/CService200ModeCommanding.cpp @@ -0,0 +1,119 @@ +#include "CService200ModeCommanding.h" +#include "servicepackets/Service200Packets.h" + +#include "../modes/HasModesIF.h" +#include "../serviceinterface/ServiceInterfaceStream.h" +#include "../serialize/SerialLinkedListAdapter.h" +#include "../modes/ModeMessage.h" + +CService200ModeCommanding::CService200ModeCommanding(object_id_t objectId, + uint16_t apid, uint8_t serviceId): + CommandingServiceBase(objectId, apid, serviceId, + NUMBER_OF_PARALLEL_COMMANDS,COMMAND_TIMEOUT_SECONDS) {} + +CService200ModeCommanding::~CService200ModeCommanding() {} + +ReturnValue_t CService200ModeCommanding::isValidSubservice(uint8_t subservice) { + switch(subservice) { + case(Subservice::COMMAND_MODE_COMMAND): + case(Subservice::COMMAND_MODE_READ): + case(Subservice::COMMAND_MODE_ANNCOUNCE): + return RETURN_OK; + default: + return AcceptsTelecommandsIF::INVALID_SUBSERVICE; + } +} + + +ReturnValue_t CService200ModeCommanding::getMessageQueueAndObject( + uint8_t subservice, const uint8_t *tcData, size_t tcDataLen, + MessageQueueId_t *id, object_id_t *objectId) { + if(tcDataLen < sizeof(object_id_t)) { + return CommandingServiceBase::INVALID_TC; + } + SerializeAdapter::deSerialize(objectId, &tcData, &tcDataLen, + SerializeIF::Endianness::BIG); + + return checkInterfaceAndAcquireMessageQueue(id,objectId); +} + +ReturnValue_t CService200ModeCommanding::checkInterfaceAndAcquireMessageQueue( + MessageQueueId_t* messageQueueToSet, object_id_t* objectId) { + HasModesIF * destination = objectManager->get(*objectId); + if(destination == nullptr) { + return CommandingServiceBase::INVALID_OBJECT; + + } + + *messageQueueToSet = destination->getCommandQueue(); + return HasReturnvaluesIF::RETURN_OK; +} + + +ReturnValue_t CService200ModeCommanding::prepareCommand( + CommandMessage* message,uint8_t subservice, const uint8_t *tcData, + size_t tcDataLen, uint32_t *state, object_id_t objectId) { + ModePacket modeCommandPacket; + ReturnValue_t result = modeCommandPacket.deSerialize(&tcData, + &tcDataLen, SerializeIF::Endianness::BIG); + if (result != RETURN_OK) { + return result; + } + + ModeMessage::setModeMessage(dynamic_cast(message), + ModeMessage::CMD_MODE_COMMAND, modeCommandPacket.getMode(), + modeCommandPacket.getSubmode()); + return result; +} + + +ReturnValue_t CService200ModeCommanding::handleReply( + const CommandMessage* reply, Command_t previousCommand, + uint32_t *state, CommandMessage* optionalNextCommand, + object_id_t objectId, bool *isStep) { + Command_t replyId = reply->getCommand(); + ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED; + switch(replyId) { + case(ModeMessage::REPLY_MODE_REPLY): { + result = prepareModeReply(reply, objectId); + break; + } + case(ModeMessage::REPLY_WRONG_MODE_REPLY): { + result = prepareWrongModeReply(reply, objectId); + break; + } + case(ModeMessage::REPLY_CANT_REACH_MODE): { + result = prepareCantReachModeReply(reply, objectId); + break; + } + case(ModeMessage::REPLY_MODE_INFO): + result = INVALID_REPLY; + break; + default: + result = RETURN_FAILED; + } + return result; +} + +ReturnValue_t CService200ModeCommanding::prepareModeReply( + const CommandMessage *reply, object_id_t objectId) { + ModePacket modeReplyPacket(objectId, + ModeMessage::getMode(reply), + ModeMessage::getSubmode(reply)); + return sendTmPacket(Subservice::REPLY_MODE_REPLY, &modeReplyPacket); +} + +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 CService200ModeCommanding::prepareCantReachModeReply( + const CommandMessage *reply, object_id_t objectId) { + CantReachModePacket cantReachModePacket(objectId, + ModeMessage::getCantReachModeReason(reply)); + return sendTmPacket(Subservice::REPLY_CANT_REACH_MODE, + &cantReachModePacket); +} diff --git a/pus/CService200ModeCommanding.h b/pus/CService200ModeCommanding.h new file mode 100644 index 000000000..89347dbd8 --- /dev/null +++ b/pus/CService200ModeCommanding.h @@ -0,0 +1,85 @@ +#ifndef FRAMEWORK_PUS_CSERVICE200MODECOMMANDING_H_ +#define FRAMEWORK_PUS_CSERVICE200MODECOMMANDING_H_ + +#include "../tmtcservices/CommandingServiceBase.h" + +/** + * @brief Custom PUS service to set mode of all objects implementing HasModesIF + * + * Examples: Device Handlers, Assemblies or Subsystems. + * Full Documentation: ECSS-E-ST-70-41C or ECSS-E-70-41A + * Dissertation Baetz p. 115, 116, 165-167. + * + * This is a gateway service. It relays device commands using the software bus. + * @ingroup pus_services + */ +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); + virtual~ CService200ModeCommanding(); + +protected: + //! CommandingServiceBase (CSB) abstract functions. 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; + +private: + ReturnValue_t checkAndAcquireTargetID(object_id_t* objectIdToSet, + const uint8_t* tcData, uint32_t tcDataLen); + ReturnValue_t checkInterfaceAndAcquireMessageQueue( + MessageQueueId_t* MessageQueueToSet, object_id_t* objectId); + + ReturnValue_t prepareModeReply(const CommandMessage *reply, + object_id_t objectId); + ReturnValue_t prepareWrongModeReply(const CommandMessage *reply, + object_id_t objectId); + ReturnValue_t prepareCantReachModeReply(const CommandMessage *reply, + object_id_t objectId); + + enum Subservice { //!< [EXPORT] : [COMMENT] Mode Commanding Subservices + //!< [EXPORT] : [COMMAND] Command assembly, subsystem or device mode + COMMAND_MODE_COMMAND = 1, + //!< [EXPORT] : [COMMAND] Command to set the specified Mode, + //! regardless of external control flag + COMMAND_MODE_COMMAND_FORCED = 2, + //!< [EXPORT] : [COMMAND] Read the current mode and + //! reply with a REPLY_MODE_REPLY + COMMAND_MODE_READ = 3, + //!< [EXPORT] : [COMMAND] Trigger an ModeInfo Event. + //! This command does NOT have a reply + COMMAND_MODE_ANNCOUNCE = 4, + //!< [EXPORT] : [COMMAND] Trigger a ModeInfo Event and to send this + //! command to every child. This command does NOT have a reply. + COMMAND_MODE_ANNOUNCE_RECURSIVELY = 5, + //!< [EXPORT] : [REPLY] Reply to a CMD_MODE_COMMAND or CMD_MODE_READ + REPLY_MODE_REPLY = 6, + //!< [EXPORT] : [REPLY] Reply in case a mode command can't be executed. + REPLY_CANT_REACH_MODE = 7, + //!< [EXPORT] : [REPLY] Reply to a CMD_MODE_COMMAND, indicating that a + //! mode was commanded and a transition started but was aborted, + //! the parameters contain the mode that was reached + REPLY_WRONG_MODE_REPLY = 8 + }; + + enum modeParameters { + MODE_OFF = 0, + MODE_ON = 1, + MODE_NORMAL = 2, + MODE_RAW = 3 + }; +}; + +#endif /* FRAMEWORK_PUS_CSERVICE200MODECOMMANDING_H_ */ diff --git a/pus/Service1TelecommandVerification.cpp b/pus/Service1TelecommandVerification.cpp new file mode 100644 index 000000000..578eb02d4 --- /dev/null +++ b/pus/Service1TelecommandVerification.cpp @@ -0,0 +1,100 @@ +#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): + SystemObject(objectId), apid(apid), serviceId(serviceId), + targetDestination(targetDestination) { + tmQueue = QueueFactory::instance()->createMessageQueue(); +} + +Service1TelecommandVerification::~Service1TelecommandVerification() {} + +MessageQueueId_t Service1TelecommandVerification::getVerificationQueue(){ + return tmQueue->getId(); +} + + +ReturnValue_t Service1TelecommandVerification::performOperation( + uint8_t operationCode){ + PusVerificationMessage message; + ReturnValue_t status = tmQueue->receiveMessage(&message); + while(status == HasReturnvaluesIF::RETURN_OK) { + status = sendVerificationReport(&message); + if(status != HasReturnvaluesIF::RETURN_OK) { + return status; + } + status = tmQueue->receiveMessage(&message); + } + if (status == MessageQueueIF::EMPTY) { + return HasReturnvaluesIF::RETURN_OK; + } + else { + return status; + } +} + + +ReturnValue_t Service1TelecommandVerification::sendVerificationReport( + PusVerificationMessage* message) { + ReturnValue_t result; + if(message->getReportId() % 2 == 0) { + result = generateFailureReport(message); + } else { + result = generateSuccessReport(message); + } + if(result != HasReturnvaluesIF::RETURN_OK){ + sif::error << "Service1TelecommandVerification::initialize: " + "Sending verification packet failed !" << std::endl; + } + return result; +} + +ReturnValue_t Service1TelecommandVerification::generateFailureReport( + PusVerificationMessage *message) { + FailureReport report( + message->getReportId(), message->getTcPacketId(), + message->getTcSequenceControl(), message->getStep(), + message->getErrorCode(), message->getParameter1(), + message->getParameter2()); + TmPacketStored tmPacket(apid, serviceId, message->getReportId(), + packetSubCounter++, &report); + ReturnValue_t result = tmPacket.sendPacket(tmQueue->getDefaultDestination(), + tmQueue->getId()); + return result; +} + +ReturnValue_t Service1TelecommandVerification::generateSuccessReport( + PusVerificationMessage *message) { + SuccessReport report(message->getReportId(),message->getTcPacketId(), + message->getTcSequenceControl(),message->getStep()); + TmPacketStored tmPacket(apid, serviceId, message->getReportId(), + packetSubCounter++, &report); + ReturnValue_t result = tmPacket.sendPacket(tmQueue->getDefaultDestination(), + tmQueue->getId()); + return result; +} + + +ReturnValue_t Service1TelecommandVerification::initialize() { + // Get target object for TC verification messages + AcceptsTelemetryIF* funnel = objectManager-> + get(targetDestination); + if(funnel == nullptr){ + sif::error << "Service1TelecommandVerification::initialize: Specified" + " TM funnel invalid. Make sure it is set up and implements" + " AcceptsTelemetryIF." << std::endl; + return ObjectManagerIF::CHILD_INIT_FAILED; + } + tmQueue->setDefaultDestination(funnel->getReportReceptionQueue()); + return SystemObject::initialize(); +} diff --git a/pus/Service1TelecommandVerification.h b/pus/Service1TelecommandVerification.h new file mode 100644 index 000000000..37562d1c9 --- /dev/null +++ b/pus/Service1TelecommandVerification.h @@ -0,0 +1,94 @@ +#ifndef MISSION_PUS_SERVICE1TELECOMMANDVERIFICATION_H_ +#define MISSION_PUS_SERVICE1TELECOMMANDVERIFICATION_H_ + +#include "../objectmanager/SystemObject.h" +#include "../returnvalues/HasReturnvaluesIF.h" +#include "../tasks/ExecutableObjectIF.h" +#include "../tmtcservices/AcceptsVerifyMessageIF.h" +#include "../tmtcservices/PusVerificationReport.h" +#include "../ipc/MessageQueueIF.h" + +/** + * @brief Verify TC acceptance, start, progress and execution. + * + * Full Documentation: ECSS-E70-41A p.51 + * + * The telecommand verification service provides the capability for + * explicit verification of each distinct stage of execution of a telecommand + * packet, from on-board acceptance through to completion of execution. + * + * Minimum capabilities of this service: + * + * - TM[1,1]: Telecommand Acceptance Report - Success. + * - TM[1,2]: Telecommand Acceptance Report - Failure. + * + * Additional capabilities of this service: + * + * - TM[1,3]: Telecommand Execution Started Report - Success (Req. 4). + * - TM[1,4]: Telecommand Execution Started Report - Failure (Req. 3). + * - TM[1,5]: Telecommand Execution Progress Report - Success (Req. 6). + * - TM[1,6]: Telecommand Execution Progress Report - Failure (Req. 5). + * - TM[1,7]: Telecommand Execution Completed Report - Success (Req. 8). + * - TM[1,8]: Telecommand Execution Completed Report - Failure (Req. 7). + * + * This Service is not inherited from PUSServiceBase unlike other PUS Services + * because all services implementing PUSServiceBase use this service to + * generate verification reports. + * @ingroup pus_services + */ +class Service1TelecommandVerification: public AcceptsVerifyMessageIF, + public SystemObject, + public ExecutableObjectIF, + public HasReturnvaluesIF { +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); + virtual ~Service1TelecommandVerification(); + + /** + * + * @return ID of Verification Queue + */ + virtual MessageQueueId_t getVerificationQueue(); + + /** + * Performs the service periodically as specified in init_mission(). + * Triggers the handlePacket function to send TC verification messages + * @param operationCode + * @return + */ + ReturnValue_t performOperation(uint8_t operationCode = 0) override; + + /** + * Initializes the destination for TC verification messages and initializes + * Service 1 as a system object + * @return + */ + ReturnValue_t initialize() override; +private: + uint16_t apid = 0; + uint8_t serviceId = 0; + + object_id_t targetDestination = objects::NO_OBJECT; + + ReturnValue_t sendVerificationReport(PusVerificationMessage* message); + ReturnValue_t generateFailureReport(PusVerificationMessage* message); + ReturnValue_t generateSuccessReport(PusVerificationMessage* message); + + uint16_t packetSubCounter = 0; + + MessageQueueIF* tmQueue = nullptr; + + enum class Subservice: uint8_t { + VERIFY_ACCEPTANCE_SUCCESS = 1, //!< [EXPORT] : [TM] + VERIFY_ACCEPTANCE_FAILED = 2, //!< [EXPORT] : [TM] + VERIFY_START_SUCCESS = 3, //!< [EXPORT] : [TM] + VERIFY_START_FAILED = 4, //!< [EXPORT] : [TM] + VERIFY_STEP_SUCCESS = 5, //!< [EXPORT] : [TM] + VERIFY_STEP_FAILED = 6 //!< [EXPORT] : [TM] + }; +}; + +#endif /* MISSION_PUS_SERVICE1TELECOMMANDVERIFICATION_H_ */ diff --git a/pus/Service2DeviceAccess.cpp b/pus/Service2DeviceAccess.cpp new file mode 100644 index 000000000..2093a617d --- /dev/null +++ b/pus/Service2DeviceAccess.cpp @@ -0,0 +1,167 @@ +#include "Service2DeviceAccess.h" +#include "servicepackets/Service2Packets.h" + +#include "../devicehandlers/DeviceHandlerIF.h" +#include "../storagemanager/StorageManagerIF.h" +#include "../devicehandlers/DeviceHandlerMessage.h" +#include "../serialize/EndianConverter.h" +#include "../action/ActionMessage.h" +#include "../serialize/SerializeAdapter.h" +#include "../serialize/SerialLinkedListAdapter.h" +#include "../serviceinterface/ServiceInterfaceStream.h" + +Service2DeviceAccess::Service2DeviceAccess(object_id_t objectId, + uint16_t apid, uint8_t serviceId, uint8_t numberOfParallelCommands, + uint16_t commandTimeoutSeconds): + CommandingServiceBase(objectId, apid, serviceId, + numberOfParallelCommands, commandTimeoutSeconds) {} + +Service2DeviceAccess::~Service2DeviceAccess() {} + + +ReturnValue_t Service2DeviceAccess::isValidSubservice(uint8_t subservice) { + switch(static_cast(subservice)){ + case Subservice::RAW_COMMANDING: + case Subservice::TOGGLE_WIRETAPPING: + return HasReturnvaluesIF::RETURN_OK; + default: + sif::error << "Invalid Subservice" << std::endl; + return AcceptsTelecommandsIF::INVALID_SUBSERVICE; + } +} + +ReturnValue_t Service2DeviceAccess::getMessageQueueAndObject( + uint8_t subservice, const uint8_t* tcData, size_t tcDataLen, + MessageQueueId_t* id, object_id_t* objectId) { + if(tcDataLen < sizeof(object_id_t)) { + return CommandingServiceBase::INVALID_TC; + } + SerializeAdapter::deSerialize(objectId, &tcData, + &tcDataLen, SerializeIF::Endianness::BIG); + + ReturnValue_t result = checkInterfaceAndAcquireMessageQueue(id,objectId); + return result; +} + +ReturnValue_t Service2DeviceAccess::checkInterfaceAndAcquireMessageQueue( + MessageQueueId_t * messageQueueToSet, object_id_t *objectId) { + DeviceHandlerIF* possibleTarget = + objectManager->get(*objectId); + if(possibleTarget == nullptr) { + return CommandingServiceBase::INVALID_OBJECT; + } + *messageQueueToSet = possibleTarget->getCommandQueue(); + return HasReturnvaluesIF::RETURN_OK; +} + + +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: { + return prepareRawCommand(dynamic_cast(message), + tcData, tcDataLen); + } + break; + case Subservice::TOGGLE_WIRETAPPING: { + return prepareWiretappingCommand(dynamic_cast(message), + tcData, tcDataLen); + } + break; + default: + return HasReturnvaluesIF::RETURN_FAILED; + } +} + +ReturnValue_t Service2DeviceAccess::prepareRawCommand( + CommandMessage* messageToSet, const uint8_t *tcData,size_t tcDataLen) { + RawCommand RawCommand(tcData,tcDataLen); + // store command into the Inter Process Communication Store + store_address_t storeAddress; + ReturnValue_t result = IPCStore->addData(&storeAddress, + RawCommand.getCommand(), RawCommand.getCommandSize()); + DeviceHandlerMessage::setDeviceHandlerRawCommandMessage(messageToSet, + storeAddress); + return result; +} + +ReturnValue_t Service2DeviceAccess::prepareWiretappingCommand( + CommandMessage *messageToSet, const uint8_t *tcData, + size_t tcDataLen) { + if(tcDataLen != WiretappingToggle::WIRETAPPING_COMMAND_SIZE) { + return CommandingServiceBase::INVALID_TC; + } + WiretappingToggle command; + ReturnValue_t result = command.deSerialize(&tcData, &tcDataLen, + SerializeIF::Endianness::BIG); + DeviceHandlerMessage::setDeviceHandlerWiretappingMessage(messageToSet, + command.getWiretappingMode()); + return result; +} + + +ReturnValue_t Service2DeviceAccess::handleReply(const CommandMessage* reply, + Command_t previousCommand, uint32_t* state, + CommandMessage* optionalNextCommand, object_id_t objectId, + bool* isStep) { + switch(reply->getCommand()) { + case CommandMessage::REPLY_COMMAND_OK: + return HasReturnvaluesIF::RETURN_OK; + case CommandMessage::REPLY_REJECTED: + return reply->getReplyRejectedReason(); + default: + return CommandingServiceBase::INVALID_REPLY; + } +} + +// All device handlers set service 2 as default raw receiver for wiretapping +// so we have to handle those unrequested messages. +void Service2DeviceAccess::handleUnrequestedReply(CommandMessage* reply) { + switch(reply->getCommand()) { + case DeviceHandlerMessage::REPLY_RAW_COMMAND: + sendWiretappingTm(reply, + static_cast(Subservice::WIRETAPPING_RAW_TC)); + break; + case DeviceHandlerMessage::REPLY_RAW_REPLY: + sendWiretappingTm(reply, + static_cast(Subservice::RAW_REPLY)); + break; + default: + sif::error << "Unknown message in Service2DeviceAccess::" + "handleUnrequestedReply with command ID " << + reply->getCommand() << std::endl; + break; + } + //Must be reached by all cases to clear message + reply->clear(); +} + +void Service2DeviceAccess::sendWiretappingTm(CommandMessage *reply, + uint8_t subservice) { + // Raw Wiretapping + // Get Address of Data from Message + store_address_t storeAddress = DeviceHandlerMessage::getStoreAddress(reply); + const uint8_t* data = nullptr; + size_t size = 0; + ReturnValue_t result = IPCStore->getData(storeAddress, &data, &size); + if(result != HasReturnvaluesIF::RETURN_OK){ + sif::error << "Service2DeviceAccess::sendWiretappingTm: Data Lost in " + "handleUnrequestedReply with failure ID "<< result + << std::endl; + return; + } + + // Init our dummy packet and correct endianness of object ID before + // sending it back. + WiretappingPacket TmPacket(DeviceHandlerMessage::getDeviceObjectId(reply), + data); + TmPacket.objectId = EndianConverter::convertBigEndian(TmPacket.objectId); + sendTmPacket(subservice, TmPacket.data,size, reinterpret_cast( + &TmPacket.objectId), sizeof(TmPacket.objectId)); +} + +MessageQueueId_t Service2DeviceAccess::getDeviceQueue() { + return commandQueue->getId(); +} + diff --git a/pus/Service2DeviceAccess.h b/pus/Service2DeviceAccess.h new file mode 100644 index 000000000..f6aa8b521 --- /dev/null +++ b/pus/Service2DeviceAccess.h @@ -0,0 +1,92 @@ +#ifndef FRAMEWORK_PUS_SERVICE2DEVICEACCESS_H_ +#define FRAMEWORK_PUS_SERVICE2DEVICEACCESS_H_ + +#include "../objectmanager/SystemObjectIF.h" +#include "../devicehandlers/AcceptsDeviceResponsesIF.h" +#include "../tmtcservices/CommandingServiceBase.h" + +/** + * @brief Raw Commanding and Wiretapping of devices. + * @details + * Full Documentation: ECSS-E-ST-70-41C or ECSS-E-70-41A + * Dissertation Baetz p. 115, 116, 165-167. + * + * This service provides the capability to communicate with devices in their + * native protocols with raw commands through the DeviceHandlerIF. + * + * This is a gateway service. It relays device commands to the software bus. + * This service is very closely tied to the CommandingServiceBase + * template class. + * + * There are 4 adaption points for component implementation through the + * CommandingServiceBase. + * + * This service employs custom subservices exclusively. This includes a + * wiretapping subservice to monitor all traffic between target devices and + * this service. + * + * - TC[2,128]: Raw Commanding + * - TC[2,129]: Toggle Wiretapping + * - TM[2,130]: Wiretapping Packet TM + * - TM[2,131]: Wiretapping Packet TC + * @ingroup pus_services + */ +class Service2DeviceAccess : public CommandingServiceBase, + public AcceptsDeviceResponsesIF +{ +public: + Service2DeviceAccess(object_id_t objectId, uint16_t apid, + uint8_t serviceId, uint8_t numberOfParallelCommands = 4, + uint16_t commandTimeoutSeconds = 60); + virtual ~Service2DeviceAccess(); + +protected: + //! CommandingServiceBase (CSB) abstract functions. 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; + + /** + * @brief Generates TM packets containing either the TC wiretapping + * packets or the TM wiretapping packets. + * Note that for service 2, all telemetry will be treated as an + * unrequested reply regardless of wiretapping mode. + * @param reply + */ + void handleUnrequestedReply(CommandMessage* reply) override; + + MessageQueueId_t getDeviceQueue() override; +private: + /** + * Generates TM packets for Wiretapping Service + * @param reply + * @param subservice + */ + void sendWiretappingTm(CommandMessage* reply,uint8_t subservice); + + ReturnValue_t checkInterfaceAndAcquireMessageQueue( + MessageQueueId_t* messageQueueToSet, object_id_t* objectId); + + ReturnValue_t prepareRawCommand(CommandMessage* messageToSet, + const uint8_t* tcData, size_t tcDataLen); + ReturnValue_t prepareWiretappingCommand(CommandMessage* messageToSet, + 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 + }; +}; + + +#endif /* MISSION_PUS_DEVICE2DEVICECOMMANDING_H_ */ diff --git a/pus/Service5EventReporting.cpp b/pus/Service5EventReporting.cpp new file mode 100644 index 000000000..829d04bde --- /dev/null +++ b/pus/Service5EventReporting.cpp @@ -0,0 +1,91 @@ +#include "Service5EventReporting.h" +#include "servicepackets/Service5Packets.h" + +#include "../serviceinterface/ServiceInterfaceStream.h" +#include "../events/EventManagerIF.h" +#include "../ipc/QueueFactory.h" +#include "../tmtcpacket/pus/TmPacketStored.h" + + +Service5EventReporting::Service5EventReporting(object_id_t objectId, + uint16_t apid, uint8_t serviceId, size_t maxNumberReportsPerCycle): + PusServiceBase(objectId, apid, serviceId), + maxNumberReportsPerCycle(maxNumberReportsPerCycle) { + eventQueue = QueueFactory::instance()->createMessageQueue(); +} + +Service5EventReporting::~Service5EventReporting(){} + +ReturnValue_t Service5EventReporting::performService() { + EventMessage message; + ReturnValue_t status = RETURN_OK; + for(uint8_t counter = 0; + counter < maxNumberReportsPerCycle; + counter++) + { + // Receive messages even if reporting is disabled for now. + status = eventQueue->receiveMessage(&message); + if(status == MessageQueueIF::EMPTY) { + return HasReturnvaluesIF::RETURN_OK; + } + + if(enableEventReport) { + status = generateEventReport(message); + if(status != HasReturnvaluesIF::RETURN_OK) { + return status; + } + } + } + sif::debug << "Service5EventReporting::generateEventReport:" + " Too many events" << std::endl; + return HasReturnvaluesIF::RETURN_OK; +} + + +ReturnValue_t Service5EventReporting::generateEventReport( + EventMessage message) +{ + EventReport report(message.getEventId(),message.getReporter(), + message.getParameter1(),message.getParameter2()); + TmPacketStored tmPacket(PusServiceBase::apid, PusServiceBase::serviceId, + message.getSeverity(), packetSubCounter++, &report); + ReturnValue_t result = tmPacket.sendPacket( + requestQueue->getDefaultDestination(),requestQueue->getId()); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::debug << "Service5EventReporting::generateEventReport:" + " Could not send TM packet" << std::endl; + } + return result; +} + +ReturnValue_t Service5EventReporting::handleRequest(uint8_t subservice) { + switch(subservice) { + case Subservice::ENABLE: { + enableEventReport = true; + return HasReturnvaluesIF::RETURN_OK; + } + case Subservice::DISABLE: { + enableEventReport = false; + return HasReturnvaluesIF::RETURN_OK; + } + default: + return AcceptsTelecommandsIF::INVALID_SUBSERVICE; + } +} + + +// In addition to the default PUSServiceBase initialization, this service needs +// to be registered to the event manager to listen for events. +ReturnValue_t Service5EventReporting::initialize() { + EventManagerIF* manager = objectManager->get( + objects::EVENT_MANAGER); + if (manager == NULL) { + return RETURN_FAILED; + } + // register Service 5 as listener for events + ReturnValue_t result = manager->registerListener(eventQueue->getId(),true); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + return PusServiceBase::initialize(); +} diff --git a/pus/Service5EventReporting.h b/pus/Service5EventReporting.h new file mode 100644 index 000000000..0b6ee9a8c --- /dev/null +++ b/pus/Service5EventReporting.h @@ -0,0 +1,86 @@ +#ifndef FRAMEWORK_PUS_SERVICE5EVENTREPORTING_H_ +#define FRAMEWORK_PUS_SERVICE5EVENTREPORTING_H_ + +#include "../tmtcservices/PusServiceBase.h" +#include "../events/EventMessage.h" + +/** + * @brief Report on-board events like information or errors + * @details + * Full Documentation: ECSS-E70-41A p.79 + * Implements the PusServiceBase template class. + * Documentation: Dissertation Baetz p.135,136 + * + * This service provides for the reporting to the service user of information of + * operational significance. + * 1. reporting of failures or anomalies detected on-board; + * 2. reporting of autonomous on-board actions; + * 3. reporting of normal progress of operations and activities, e.g. + * detection of events which are not anomalous (such as payload events), + * reaching of predefined steps in an operation. Some reports can combine + * more than one of these events. + * + * Minimum capabilities of this service: + * + * - TM[5,1]: Normal/Progress Report + * - TM[5,2]: Error/Anomaly Report - Low Severity + * - TM[5,3]: Error/Anomaly Report - Medium Severity + * - TM[5,4]: Error/Anomaly Report - High Severity + * + * Events can be translated by using translator files located in + * /config/objects/ and /config/events/. Description to events can be added by + * adding a comment behind the event definition with [//!<] as leading string + * + * Additional capabilities of this service: + * + * - TC[5,5]: Enable Event Report Generation (Req. 6) + * - TC[5,6]: Disable Event Report Generation (Req. 5) + * @author R. Mueller + * @ingroup pus_services + */ +class Service5EventReporting: public PusServiceBase { +public: + + Service5EventReporting(object_id_t objectId, uint16_t apid, + uint8_t serviceId, size_t maxNumberReportsPerCycle = 10); + virtual ~Service5EventReporting(); + + /*** + * Check for events and generate event reports if required. + * @return + */ + ReturnValue_t performService() override; + + /*** + * Turn event generation on or off. + * @return + */ + ReturnValue_t handleRequest(uint8_t subservice) override; + + /** + * The default PusServiceBase initialize has been overridden but is still + * executed. Registers this service as a listener for events at the + * EventManager. + * @return + */ + ReturnValue_t initialize() override; + + enum Subservice: uint8_t { + NORMAL_REPORT = 1, //!< [EXPORT] : [REPLY] Generate normal report + ERROR_LOW_SEVERITY = 2, //!< [EXPORT] : [REPLY] Generate error report with low severity + ERROR_MED_SEVERITY = 3, //!< [EXPORT] : [REPLY] Generate error report with medium severity + ERROR_HIGH_SEVERITY = 4, //!< [EXPORT] : [REPLY] Generate error report with high severity + ENABLE = 5, //!< [EXPORT] : [COMMAND] Enable report generation + DISABLE = 6 //!< [EXPORT] : [COMMAND] Disable report generation + }; + +private: + uint16_t packetSubCounter = 0; + MessageQueueIF* eventQueue = nullptr; + bool enableEventReport = true; + const uint8_t maxNumberReportsPerCycle; + + ReturnValue_t generateEventReport(EventMessage message); +}; + +#endif /* MISSION_PUS_SERVICE5EVENTREPORTING_H_ */ diff --git a/pus/Service8FunctionManagement.cpp b/pus/Service8FunctionManagement.cpp new file mode 100644 index 000000000..2c2e590b5 --- /dev/null +++ b/pus/Service8FunctionManagement.cpp @@ -0,0 +1,142 @@ +#include "Service8FunctionManagement.h" +#include "servicepackets/Service8Packets.h" + +#include "../objectmanager/SystemObjectIF.h" +#include "../action/HasActionsIF.h" +#include "../devicehandlers/DeviceHandlerIF.h" +#include "../serialize/SerializeAdapter.h" +#include "../serviceinterface/ServiceInterfaceStream.h" + +Service8FunctionManagement::Service8FunctionManagement(object_id_t object_id, + uint16_t apid, uint8_t serviceId, uint8_t numParallelCommands, + uint16_t commandTimeoutSeconds): + CommandingServiceBase(object_id, apid, serviceId, numParallelCommands, + commandTimeoutSeconds) {} + +Service8FunctionManagement::~Service8FunctionManagement() {} + + +ReturnValue_t Service8FunctionManagement::isValidSubservice( + uint8_t subservice) { + switch(static_cast(subservice)) { + case Subservice::DIRECT_COMMANDING: + return HasReturnvaluesIF::RETURN_OK; + default: + return AcceptsTelecommandsIF::INVALID_SUBSERVICE; + } +} + +ReturnValue_t Service8FunctionManagement::getMessageQueueAndObject( + uint8_t subservice, const uint8_t* tcData, size_t tcDataLen, + MessageQueueId_t* id, object_id_t* objectId) { + if(tcDataLen < sizeof(object_id_t)) { + return CommandingServiceBase::INVALID_TC; + } + SerializeAdapter::deSerialize(objectId, &tcData, + &tcDataLen, SerializeIF::Endianness::BIG); + + return checkInterfaceAndAcquireMessageQueue(id,objectId); +} + +ReturnValue_t Service8FunctionManagement::checkInterfaceAndAcquireMessageQueue( + MessageQueueId_t* messageQueueToSet, object_id_t* objectId) { + // check HasActionIF property of target + HasActionsIF* possibleTarget = objectManager->get(*objectId); + if(possibleTarget == nullptr){ + return CommandingServiceBase::INVALID_OBJECT; + } + *messageQueueToSet = possibleTarget->getCommandQueue(); + return HasReturnvaluesIF::RETURN_OK; +} + + +ReturnValue_t Service8FunctionManagement::prepareCommand( + CommandMessage* message, uint8_t subservice, const uint8_t* tcData, + size_t tcDataLen, uint32_t* state, object_id_t objectId) { + return prepareDirectCommand(dynamic_cast(message), + tcData, tcDataLen); +} + +ReturnValue_t Service8FunctionManagement::prepareDirectCommand( + CommandMessage *message, const uint8_t *tcData, size_t tcDataLen) { + if(tcDataLen < sizeof(object_id_t) + sizeof(ActionId_t)) { + sif::debug << "Service8FunctionManagement::prepareDirectCommand:" + << " TC size smaller thant minimum size of direct command." + << std::endl; + return CommandingServiceBase::INVALID_TC; + } + + // Create direct command instance by extracting data from Telecommand + DirectCommand command(tcData, tcDataLen); + + // store additional parameters into the IPC Store + store_address_t parameterAddress; + ReturnValue_t result = IPCStore->addData(¶meterAddress, + command.getParameters(),command.getParametersSize()); + + // setCommand expects a Command Message, an Action ID and a store adress + // pointing to additional parameters + ActionMessage::setCommand(message,command.getActionId(),parameterAddress); + return result; +} + + +ReturnValue_t Service8FunctionManagement::handleReply( + const CommandMessage* reply, Command_t previousCommand, + uint32_t* state, CommandMessage* optionalNextCommand, + object_id_t objectId, bool* isStep) { + Command_t replyId = reply->getCommand(); + ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED; + ActionId_t actionId = ActionMessage::getActionId(reply); + ReturnValue_t returnCode = ActionMessage::getReturnCode(reply); + + switch(replyId) { + case ActionMessage::COMPLETION_SUCCESS: { + DirectReply completionReply(objectId, actionId,returnCode); + result = CommandingServiceBase::EXECUTION_COMPLETE; + break; + } + case ActionMessage::STEP_SUCCESS: { + *isStep = true; + result = HasReturnvaluesIF::RETURN_OK; + break; + } + case ActionMessage::DATA_REPLY: { + result = handleDataReply(reply, objectId, actionId); + break; + } + case ActionMessage::STEP_FAILED: + *isStep = true; + /*No break, falls through*/ + case ActionMessage::COMPLETION_FAILED: + result = ActionMessage::getReturnCode(reply); + break; + default: + result = INVALID_REPLY; + } + return result; +} + +ReturnValue_t Service8FunctionManagement::handleDataReply( + const CommandMessage* reply, object_id_t objectId, + ActionId_t actionId) { + store_address_t storeId = ActionMessage::getStoreId(reply); + size_t size = 0; + const uint8_t * buffer = nullptr; + ReturnValue_t result = IPCStore->getData(storeId, &buffer, &size); + if(result != RETURN_OK) { + sif::error << "Service 8: Could not retrieve data for data reply" + << std::endl; + return result; + } + DataReply dataReply(objectId, actionId, buffer, size); + result = sendTmPacket(static_cast( + Subservice::DIRECT_COMMANDING_DATA_REPLY), &dataReply); + + auto deletionResult = IPCStore->deleteData(storeId); + if(deletionResult != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "Service8FunctionManagement::handleReply: Deletion" + << " of data in pool failed." << std::endl; + } + return result; +} diff --git a/pus/Service8FunctionManagement.h b/pus/Service8FunctionManagement.h new file mode 100644 index 000000000..b5ebcda8b --- /dev/null +++ b/pus/Service8FunctionManagement.h @@ -0,0 +1,67 @@ +#ifndef FRAMEWORK_PUS_SERVICE8FUNCTIONMANAGEMENT_H_ +#define FRAMEWORK_PUS_SERVICE8FUNCTIONMANAGEMENT_H_ + +#include "../action/ActionMessage.h" +#include "../tmtcservices/CommandingServiceBase.h" + +/** + * @brief Functional commanding. + * Full Documentation: ECSS-E-ST-70-41C p.64, p. 451 + * Dissertation Baetz p. 115, 116, 165-167 + * + * This service provides the capability to perform functions of an + * application process and provides high-level commanding as opposed to the + * Raw Access provided by Service 2. Examples for these functions can include + * control and operation of payload or the AOCS subsystem. + * This service will be the primary means to control the spacecraft as it is + * considered safer than the Raw Access provided + * by Service 2 and is generally sufficient for most tasks. + * + * This is a gateway service. It relays device commands using the software bus. + * This service is very closely tied to the Commanding Service Base template + * class. There is constant interaction between this Service Base und a + * subclass like this service. + * + * Service Capability: + * - TC[8,128]: Direct Commanding + * - TM[8,130]: Direct Commanding Data Reply + * + * @ingroup pus_services + */ +class Service8FunctionManagement : public CommandingServiceBase +{ +public: + Service8FunctionManagement(object_id_t objectId, uint16_t apid, + uint8_t serviceId, uint8_t numParallelCommands = 4, + uint16_t commandTimeoutSeconds = 60); + virtual ~Service8FunctionManagement(); + +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; + +private: + enum class Subservice { + DIRECT_COMMANDING = 128, //!< [EXPORT] : [COMMAND] Functional commanding + DIRECT_COMMANDING_DATA_REPLY = 130, //!< [EXPORT] : [REPLY] Data reply + }; + + ReturnValue_t checkInterfaceAndAcquireMessageQueue( + MessageQueueId_t* messageQueueToSet, object_id_t* objectId); + ReturnValue_t prepareDirectCommand(CommandMessage* message, + const uint8_t* tcData, size_t tcDataLen); + ReturnValue_t handleDataReply(const CommandMessage* reply, + object_id_t objectId, ActionId_t actionId); +}; + +#endif /* FRAMEWORK_PUS_SERVICE8FUNCTIONMANAGEMENT_H_ */ diff --git a/pus/servicepackets/Service1Packets.h b/pus/servicepackets/Service1Packets.h new file mode 100644 index 000000000..dbd31028c --- /dev/null +++ b/pus/servicepackets/Service1Packets.h @@ -0,0 +1,166 @@ +/** + * @defgroup spacepackets PUS Packet Definitions + * This group contains all implemented TM or TM packages that are sent to + * or sent by the OBC.They are exported later to display + * packet structures in Mission Information Base (MIB). + */ + +#ifndef MISSION_PUS_SERVICEPACKETS_SERVICE1PACKETS_H_ +#define MISSION_PUS_SERVICEPACKETS_SERVICE1PACKETS_H_ + +#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] 1, 3, 5, 7 +public: + FailureReport(uint8_t failureSubtype_, uint16_t packetId_, + uint16_t packetSequenceControl_, uint8_t stepNumber_, + ReturnValue_t errorCode_, uint32_t errorParameter1_, + uint32_t errorParameter2_) : + packetId(packetId_), packetSequenceControl(packetSequenceControl_), + stepNumber(stepNumber_), errorCode(errorCode_), + errorParameter1(errorParameter1_), errorParameter2(errorParameter2_), + failureSubtype(failureSubtype_) {} + + /** + * This function is called by the FSFW when calling the tm packet send + * function and supplying the SerializeIF* as parameter + * @param buffer Object content is serialized into the buffer + * @param size + * @param max_size + * @param bigEndian + * @return + */ + virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, SerializeIF::Endianness streamEndianness + ) const override { + ReturnValue_t result = SerializeAdapter::serialize(&packetId, buffer, + size, maxSize, streamEndianness); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = SerializeAdapter::serialize(&packetSequenceControl, buffer, + size, maxSize, streamEndianness); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + if (failureSubtype == TC_VERIFY::PROGRESS_FAILURE) { + result = SerializeAdapter::serialize(&stepNumber, buffer, size, + maxSize, streamEndianness); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + } + result = SerializeAdapter::serialize(&errorCode, buffer, size, + maxSize, streamEndianness); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = SerializeAdapter::serialize(&errorParameter1, buffer, size, + maxSize, streamEndianness); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + + result = SerializeAdapter::serialize(&errorParameter2, buffer, size, + maxSize, streamEndianness); + return result; + } + + + virtual size_t getSerializedSize() const { + size_t size = 0; + size += SerializeAdapter::getSerializedSize(&packetId); + size += sizeof(packetSequenceControl); + if(failureSubtype==TC_VERIFY::PROGRESS_FAILURE){ + size += SerializeAdapter::getSerializedSize(&stepNumber); + } + size += SerializeAdapter::getSerializedSize(&errorCode); + size += SerializeAdapter::getSerializedSize(&errorParameter1); + size += SerializeAdapter::getSerializedSize(&errorParameter2); + return size; + } + + /** + * Deserialization is not allowed for a report. + * @param buffer + * @param size + * @param bigEndian + * @return + */ + ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + SerializeIF::Endianness streamEndianness) override { + return HasReturnvaluesIF::RETURN_FAILED; + } +private: + uint16_t packetId; //!< [EXPORT] : [COMMENT] Packet ID of respective Telecommand + uint16_t packetSequenceControl; //!< [EXPORT] : [COMMENT] Packet SSC of respective Telecommand + uint8_t stepNumber; //!< [EXPORT] : [OPTIONAL][SUBSERVICE] 6 + ReturnValue_t errorCode; //!< [EXPORT] : [COMMENT] Error code which can be looked up in generated error code file + uint32_t errorParameter1; + uint32_t errorParameter2; + const uint8_t failureSubtype; //!< [EXPORT] : [IGNORE] +}; + +/** + * @brief Subservices 2, 4, 6, 8 + * @ingroup spacepackets + */ +class SuccessReport: public SerializeIF { //!< [EXPORT] : [SUBSERVICE] 2, 4, 6, 8 +public: + SuccessReport(uint8_t subtype_, uint16_t packetId_, + uint16_t packetSequenceControl_,uint8_t stepNumber_) : + packetId(packetId_), packetSequenceControl(packetSequenceControl_), + stepNumber(stepNumber_), subtype(subtype_) {} + + virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, SerializeIF::Endianness streamEndianness + ) const override { + ReturnValue_t result = SerializeAdapter::serialize(&packetId, buffer, + size, maxSize, streamEndianness); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = SerializeAdapter::serialize(&packetSequenceControl, buffer, + size, maxSize, streamEndianness); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + if (subtype == TC_VERIFY::PROGRESS_SUCCESS) { + result = SerializeAdapter::serialize(&stepNumber, buffer, size, + maxSize, streamEndianness); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + } + return result; + } + + virtual size_t getSerializedSize() const override { + size_t size = 0; + size += SerializeAdapter::getSerializedSize(&packetId); + size += sizeof(packetSequenceControl); + if(subtype == TC_VERIFY::PROGRESS_SUCCESS){ + size += SerializeAdapter::getSerializedSize(&stepNumber); + } + return size; + + } + + ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + SerializeIF::Endianness streamEndianness) override { + return HasReturnvaluesIF::RETURN_FAILED; + } +private: + uint16_t packetId; //!< [EXPORT] : [COMMENT] Packet ID of respective Telecommand + uint16_t packetSequenceControl; //!< [EXPORT] : [COMMENT] Packet SSC of respective Telecommand + uint8_t stepNumber; //!< [EXPORT] : [OPTIONAL][SUBSERVICE] 6 + const uint8_t subtype; //!< [EXPORT] : [IGNORE] +}; + +#endif /* MISSION_PUS_SERVICEPACKETS_SERVICE1PACKETS_H_ */ diff --git a/pus/servicepackets/Service200Packets.h b/pus/servicepackets/Service200Packets.h new file mode 100644 index 000000000..efcf65fcf --- /dev/null +++ b/pus/servicepackets/Service200Packets.h @@ -0,0 +1,63 @@ +#ifndef FRAMEWORK_PUS_SERVICEPACKETS_SERVICE200PACKETS_H_ +#define FRAMEWORK_PUS_SERVICEPACKETS_SERVICE200PACKETS_H_ + +#include "../../serialize/SerialLinkedListAdapter.h" +#include "../../modes/ModeMessage.h" +#include "../../serialize/SerializeIF.h" + +/** + * @brief Subservice 1, 2, 3, 4, 5 + * @ingroup spacepackets + */ +class ModePacket : public SerialLinkedListAdapter { //!< [EXPORT] : [SUBSERVICE] 1, 2, 6 +public: + + ModePacket() { + setLinks(); + } + + ModePacket(object_id_t objectId, Mode_t mode, Submode_t submode) : + objectId(objectId), mode(mode), submode(submode) { + setLinks(); + } + + Mode_t getMode() { + return mode.entry; + } + + Submode_t getSubmode() { + return submode.entry; + } + + // Forbid copying, pointers are used. + ModePacket(const ModePacket&) = delete; + ModePacket& operator=(const ModePacket&) = delete; +private: + + void setLinks() { + setStart(&objectId); + objectId.setNext(&mode); + mode.setNext(&submode); + } + SerializeElement objectId; //!< [EXPORT] : [COMMENT] Target or source object + SerializeElement mode; //!< [EXPORT] : [COMMENT] 0: MODE_OFF, 1: MODE_ON, 2: MODE_NORMAL, 3: MODE_RAW + SerializeElement submode; //!< [EXPORT] : [COMMENT] Usually 0, device specific submode possible +}; + +/** + * @brief Subservice 7 + * @ingroup spacepackets + */ +class CantReachModePacket: public SerialLinkedListAdapter { //!< [EXPORT] : [SUBSERVICE] 7 +public: + CantReachModePacket(object_id_t objectId, ReturnValue_t reason): + objectId(objectId), reason(reason) { + setStart(&this->objectId); + this->objectId.setNext(&this->reason); + } + + SerializeElement objectId; //!< [EXPORT] : [COMMENT] Reply source object + SerializeElement reason; //!< [EXPORT] : [COMMENT] Reason the mode could not be reached +}; + +#endif /* FRAMEWORK_PUS_SERVICEPACKETS_SERVICE200PACKETS_H_ */ diff --git a/pus/servicepackets/Service2Packets.h b/pus/servicepackets/Service2Packets.h new file mode 100644 index 000000000..d4f3fb170 --- /dev/null +++ b/pus/servicepackets/Service2Packets.h @@ -0,0 +1,76 @@ +#ifndef FRAMEWORK_PUS_SERVICEPACKETS_SERVICE2PACKETS_H_ +#define FRAMEWORK_PUS_SERVICEPACKETS_SERVICE2PACKETS_H_ + +#include "../../action/ActionMessage.h" +#include "../../objectmanager/SystemObjectIF.h" +#include "../../serialize/SerialLinkedListAdapter.h" +#include "../../serviceinterface/ServiceInterfaceStream.h" + +/** + * @brief Subservice 128 + * @ingroup spacepackets + */ +class RawCommand { //!< [EXPORT] : [SUBSERVICE] 128 +public: + RawCommand(const uint8_t* buffer, size_t size) { + // Deserialize Adapter to get correct endianness + SerializeAdapter::deSerialize(&objectId, &buffer, &size, + SerializeIF::Endianness::BIG); + commandBuffer = buffer; + // size is decremented by AutoSerializeAdapter, + // remaining size is data size + dataSize = size; + } + object_id_t getObjectId() const { + return objectId; + } + + const uint8_t* getCommand() { + return commandBuffer; + } + + size_t getCommandSize() const { + return dataSize; + } +private: + object_id_t objectId = 0; + const uint8_t* commandBuffer = nullptr; //!< [EXPORT] : [MAXSIZE] 256 Bytes + size_t dataSize = 0; //!< [EXPORT] : [IGNORE] +}; + + +/** + * @brief Subservice 129: Command packet to set wiretapping mode + * @ingroup spacepackets + */ +class WiretappingToggle: public SerialLinkedListAdapter{ //!< [EXPORT] : [SUBSERVICE] 129 +public: + static const size_t WIRETAPPING_COMMAND_SIZE = 5; + WiretappingToggle(){ + setStart(&objectId); + objectId.setNext(&wiretappingMode); + } + + uint8_t getWiretappingMode() const { + return wiretappingMode.entry; + } +private: + SerializeElement objectId; + SerializeElement wiretappingMode; //!< [EXPORT] : [INPUT] Mode 0: OFF, Mode 1: RAW +}; + + +/** + * @brief Subservices 130 and 131: TM packets + * @ingroup spacepackets + */ +class WiretappingPacket { //!< [EXPORT] : [SUBSERVICE] 130, 131 +public: + object_id_t objectId; //!< [EXPORT] : [COMMENT] Object ID of source object + const uint8_t* data; //!< [EXPORT] : [MAXSIZE] Raw Command Max. Size + WiretappingPacket(object_id_t objectId, const uint8_t* buffer): + objectId(objectId), data(buffer) { + } +}; + +#endif /* FRAMEWORK_PUS_SERVICEPACKETS_SERVICE2PACKETS_H_ */ diff --git a/pus/servicepackets/Service5Packets.h b/pus/servicepackets/Service5Packets.h new file mode 100644 index 000000000..9655608aa --- /dev/null +++ b/pus/servicepackets/Service5Packets.h @@ -0,0 +1,76 @@ +#ifndef MISSION_PUS_SERVICEPACKETS_SERVICE5PACKETS_H_ +#define MISSION_PUS_SERVICEPACKETS_SERVICE5PACKETS_H_ + +#include "../../serialize/SerializeAdapter.h" +#include "../../tmtcservices/VerificationCodes.h" + + +/** + * @brief Subservice 1, 2, 3, 4 + * Structure of Event Report. + * It consists of: + * 1. Report ID(RID). This is the Event ID in the FSFW + * 2. Object ID of the reporter (e.g. subsystem) + * 2. Parameter 1 + * 3. Parameter 2 + * + * @ingroup spacepackets + */ +class EventReport: public SerializeIF { //!< [EXPORT] : [SUBSERVICE] 1, 2, 3, 4 +public: + + EventReport(EventId_t reportId_, object_id_t objectId_, uint32_t parameter1_, + uint32_t parameter2_): + reportId(reportId_),objectId(objectId_), parameter1(parameter1_), + parameter2(parameter2_) {} + + virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, + SerializeIF::Endianness streamEndianness) const override + { + ReturnValue_t result = SerializeAdapter::serialize(&reportId, buffer, + size, maxSize, streamEndianness); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = SerializeAdapter::serialize(&objectId, buffer, size, + maxSize, streamEndianness); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = SerializeAdapter::serialize(¶meter1, buffer, size, + maxSize, streamEndianness); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = SerializeAdapter::serialize(¶meter2, buffer, size, + maxSize, streamEndianness); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + return result; + } + + virtual size_t getSerializedSize() const override { + uint32_t size = 0; + size += SerializeAdapter::getSerializedSize(&reportId); + size += SerializeAdapter::getSerializedSize(&objectId); + size += SerializeAdapter::getSerializedSize(¶meter1); + size += SerializeAdapter::getSerializedSize(¶meter2); + return size; + + } + + virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + SerializeIF::Endianness streamEndianness) override { + return HasReturnvaluesIF::RETURN_FAILED; + } +private: + EventId_t reportId; + object_id_t objectId; + uint32_t parameter1; + uint32_t parameter2; +}; + + +#endif /* MISSION_PUS_SERVICEPACKETS_SERVICE5PACKETS_H_ */ diff --git a/pus/servicepackets/Service8Packets.h b/pus/servicepackets/Service8Packets.h new file mode 100644 index 000000000..14f8b6e6e --- /dev/null +++ b/pus/servicepackets/Service8Packets.h @@ -0,0 +1,121 @@ +#ifndef FRAMEWORK_PUS_SERVICEPACKETS_SERVICE8PACKETS_H_ +#define FRAMEWORK_PUS_SERVICEPACKETS_SERVICE8PACKETS_H_ + +#include "../../action/ActionMessage.h" +#include "../../objectmanager/SystemObjectIF.h" +#include "../../serialize/SerialBufferAdapter.h" +#include "../../serialize/SerializeElement.h" +#include "../../serialize/SerialLinkedListAdapter.h" +#include "../../serialize/SerialFixedArrayListAdapter.h" + + +/** + * @brief Subservice 128 + * @ingroup spacepackets + */ +class DirectCommand: public SerialLinkedListAdapter { //!< [EXPORT] : [SUBSERVICE] 128 +public: + + DirectCommand(const uint8_t* tcData, size_t size) { + SerializeAdapter::deSerialize(&objectId, &tcData, &size, + SerializeIF::Endianness::BIG); + SerializeAdapter::deSerialize(&actionId, &tcData, &size, + SerializeIF::Endianness::BIG); + parameterBuffer = tcData; + parametersSize = size; + } + + ActionId_t getActionId() const { + return actionId; + } + + object_id_t getObjectId() const { + return objectId; + } + + const uint8_t* getParameters() { + return parameterBuffer; + } + + uint32_t getParametersSize() const { + return parametersSize; + } + +private: + DirectCommand(const DirectCommand &command); + object_id_t objectId; + ActionId_t actionId; + uint32_t parametersSize; //!< [EXPORT] : [IGNORE] + const uint8_t * parameterBuffer; //!< [EXPORT] : [MAXSIZE] 65535 Bytes + +}; + + +/** + * @brief Subservice 130 + * Data reply (subservice 130) consists of + * 1. Target Object ID + * 2. Action ID + * 3. Data + * @ingroup spacepackets + */ +class DataReply: public SerialLinkedListAdapter { //!< [EXPORT] : [SUBSERVICE] 130 +public: + typedef uint16_t typeOfMaxDataSize; + static const uint16_t MAX_DATA_LENGTH = sizeof(typeOfMaxDataSize); + DataReply(object_id_t objectId_, ActionId_t actionId_, + const uint8_t * replyDataBuffer_ = NULL, uint16_t replyDataSize_ = 0): + objectId(objectId_), actionId(actionId_), replyData(replyDataBuffer_,replyDataSize_){ + setLinks(); + } + +private: + DataReply(const DataReply &reply); + void setLinks() { + setStart(&objectId); + objectId.setNext(&actionId); + actionId.setNext(&replyData); + } + SerializeElement objectId; + SerializeElement actionId; + SerializeElement> replyData; +}; + + +/** + * @brief Subservice 132 + * @details + * Not used yet. Telecommand Verification takes care of this. + * @ingroup spacepackets + */ +class DirectReply: public SerialLinkedListAdapter { //!< [EXPORT] : [SUBSERVICE] 132 +public: + typedef uint16_t typeOfMaxDataSize; + static const uint16_t MAX_DATA_LENGTH = sizeof(typeOfMaxDataSize); + + DirectReply(object_id_t objectId_, ActionId_t actionId_, ReturnValue_t returnCode_, + bool isStep_ = false, uint8_t step_ = 0): + isStep(isStep_), objectId(objectId_), actionId(actionId_), + returnCode(returnCode_),step(step_) { + setLinks(); + } +private: + + void setLinks() { + setStart(&objectId); + objectId.setNext(&actionId); + actionId.setNext(&returnCode); + if(isStep) { + returnCode.setNext(&step); + } + } + + bool isStep; //!< [EXPORT] : [IGNORE] + SerializeElement objectId; //!< [EXPORT] : [IGNORE] + SerializeElement actionId; //!< [EXPORT] : [IGNORE] + SerializeElement returnCode; //!< [EXPORT] : [IGNORE] + SerializeElement step; //!< [EXPORT] : [OPTIONAL] [IGNORE] + +}; + +#endif /* FRAMEWORK_PUS_SERVICEPACKETS_SERVICE8PACKETS_H_ */ diff --git a/returnvalues/FwClassIds.h b/returnvalues/FwClassIds.h index d21861c08..ddee539e3 100644 --- a/returnvalues/FwClassIds.h +++ b/returnvalues/FwClassIds.h @@ -24,6 +24,7 @@ enum { MEMORY_HELPER, //MH SERIALIZE_IF, //SE FIXED_MAP, //FM + FIXED_MULTIMAP, //FMM HAS_HEALTH_IF, //HHI FIFO_CLASS, //FF MESSAGE_PROXY, //MQP @@ -54,11 +55,15 @@ enum { HAS_ACTIONS_IF, //HF DEVICE_COMMUNICATION_IF, //DC BSP, //BSP - TIME_STAMPER_IF, //TSI 52 + TIME_STAMPER_IF, //TSI 53 //TODO This will shift all IDs for FLP - SGP4PROPAGATOR_CLASS, //SGP4 53 - MUTEX_IF, //MUX 54 - MESSAGE_QUEUE_IF,//MQI 55 + SGP4PROPAGATOR_CLASS, //SGP4 54 + MUTEX_IF, //MUX 55 + MESSAGE_QUEUE_IF,//MQI 56 + SEMAPHORE_IF, //SPH 57 + LOCAL_POOL_OWNER_IF, //LPIF 58 + POOL_VARIABLE_IF, //PVA 59 + HOUSEKEEPING_MANAGER, //HKM 60 FW_CLASS_ID_COUNT //is actually count + 1 ! }; diff --git a/returnvalues/HasReturnvaluesIF.h b/returnvalues/HasReturnvaluesIF.h index 5adbca3fc..5fef91dd0 100644 --- a/returnvalues/HasReturnvaluesIF.h +++ b/returnvalues/HasReturnvaluesIF.h @@ -1,27 +1,23 @@ -#ifndef HASRETURNVALUESIF_H_ -#define HASRETURNVALUESIF_H_ +#ifndef FRAMEWORK_RETURNVALUES_HASRETURNVALUESIF_H_ +#define FRAMEWORK_RETURNVALUES_HASRETURNVALUESIF_H_ -#include -#include +#include "FwClassIds.h" #include +#include #define MAKE_RETURN_CODE( number ) ((INTERFACE_ID << 8) + (number)) typedef uint16_t ReturnValue_t; - - - - class HasReturnvaluesIF { public: static const ReturnValue_t RETURN_OK = 0; static const ReturnValue_t RETURN_FAILED = 1; - virtual ~HasReturnvaluesIF() { - } + virtual ~HasReturnvaluesIF() {} + static ReturnValue_t makeReturnCode(uint8_t interfaceId, uint8_t number) { + return (interfaceId << 8) + number; + } }; - - -#endif /* HASRETURNVALUESIF_H_ */ +#endif /* FRAMEWORK_RETURNVALUES_HASRETURNVALUESIF_H_ */ diff --git a/rmap/RMAP.cpp b/rmap/RMAP.cpp index 4c95f6c9e..4ab8b17ba 100644 --- a/rmap/RMAP.cpp +++ b/rmap/RMAP.cpp @@ -1,7 +1,7 @@ -#include -#include -#include -#include +#include "../devicehandlers/DeviceCommunicationIF.h" +#include "rmapStructs.h" +#include "RMAP.h" +#include "RMAPChannelIF.h" #include ReturnValue_t RMAP::reset(RMAPCookie* cookie) { diff --git a/rmap/RMAP.h b/rmap/RMAP.h index 195574f85..d14320cbc 100644 --- a/rmap/RMAP.h +++ b/rmap/RMAP.h @@ -1,8 +1,8 @@ #ifndef RMAPpp_H_ #define RMAPpp_H_ -#include -#include +#include "../returnvalues/HasReturnvaluesIF.h" +#include "RMAPCookie.h" //SHOULDTODO: clean up includes for RMAP, should be enough to include RMAP.h but right now it's quite chaotic... diff --git a/rmap/RMAPChannelIF.h b/rmap/RMAPChannelIF.h index 6549c8ef9..dac4a7220 100644 --- a/rmap/RMAPChannelIF.h +++ b/rmap/RMAPChannelIF.h @@ -1,8 +1,8 @@ #ifndef RMAPCHANNELIF_H_ #define RMAPCHANNELIF_H_ -#include -#include +#include "RMAPCookie.h" +#include "../returnvalues/HasReturnvaluesIF.h" class RMAPChannelIF { public: diff --git a/rmap/RMAPCookie.cpp b/rmap/RMAPCookie.cpp index 5bf2ba9f5..597f066c5 100644 --- a/rmap/RMAPCookie.cpp +++ b/rmap/RMAPCookie.cpp @@ -1,5 +1,5 @@ -#include -#include +#include "RMAPChannelIF.h" +#include "RMAPCookie.h" #include diff --git a/rmap/RMAPCookie.h b/rmap/RMAPCookie.h index c091ba182..4c6081bdd 100644 --- a/rmap/RMAPCookie.h +++ b/rmap/RMAPCookie.h @@ -1,12 +1,12 @@ #ifndef RMAPCOOKIE_H_ #define RMAPCOOKIE_H_ -#include -#include +#include "../devicehandlers/CookieIF.h" +#include "rmapStructs.h" class RMAPChannelIF; -class RMAPCookie : public Cookie{ +class RMAPCookie : public CookieIF { public: //To Uli: Sorry, I need an empty ctor to initialize an array of cookies. RMAPCookie(); diff --git a/rmap/RmapDeviceCommunicationIF.cpp b/rmap/RmapDeviceCommunicationIF.cpp index 4958b3ed7..db4a75b55 100644 --- a/rmap/RmapDeviceCommunicationIF.cpp +++ b/rmap/RmapDeviceCommunicationIF.cpp @@ -1,47 +1,47 @@ -#include -#include +#include "RmapDeviceCommunicationIF.h" +#include "RMAP.h" //TODO Cast here are all potential bugs RmapDeviceCommunicationIF::~RmapDeviceCommunicationIF() { } -ReturnValue_t RmapDeviceCommunicationIF::sendMessage(Cookie* cookie, +ReturnValue_t RmapDeviceCommunicationIF::sendMessage(CookieIF* cookie, uint8_t* data, uint32_t len) { return RMAP::sendWriteCommand((RMAPCookie *) cookie, data, len); } -ReturnValue_t RmapDeviceCommunicationIF::getSendSuccess(Cookie* cookie) { +ReturnValue_t RmapDeviceCommunicationIF::getSendSuccess(CookieIF* cookie) { return RMAP::getWriteReply((RMAPCookie *) cookie); } ReturnValue_t RmapDeviceCommunicationIF::requestReceiveMessage( - Cookie* cookie) { + CookieIF* cookie) { return RMAP::sendReadCommand((RMAPCookie *) cookie, ((RMAPCookie *) cookie)->getMaxReplyLen()); } -ReturnValue_t RmapDeviceCommunicationIF::readReceivedMessage(Cookie* cookie, +ReturnValue_t RmapDeviceCommunicationIF::readReceivedMessage(CookieIF* cookie, uint8_t** buffer, uint32_t* size) { return RMAP::getReadReply((RMAPCookie *) cookie, buffer, size); } -ReturnValue_t RmapDeviceCommunicationIF::setAddress(Cookie* cookie, +ReturnValue_t RmapDeviceCommunicationIF::setAddress(CookieIF* cookie, uint32_t address) { ((RMAPCookie *) cookie)->setAddress(address); return HasReturnvaluesIF::RETURN_OK; } -uint32_t RmapDeviceCommunicationIF::getAddress(Cookie* cookie) { +uint32_t RmapDeviceCommunicationIF::getAddress(CookieIF* cookie) { return ((RMAPCookie *) cookie)->getAddress(); } -ReturnValue_t RmapDeviceCommunicationIF::setParameter(Cookie* cookie, +ReturnValue_t RmapDeviceCommunicationIF::setParameter(CookieIF* cookie, uint32_t parameter) { //TODO Empty? return HasReturnvaluesIF::RETURN_FAILED; } -uint32_t RmapDeviceCommunicationIF::getParameter(Cookie* cookie) { +uint32_t RmapDeviceCommunicationIF::getParameter(CookieIF* cookie) { return 0; } diff --git a/rmap/RmapDeviceCommunicationIF.h b/rmap/RmapDeviceCommunicationIF.h index 12ae67e4a..dacc720b4 100644 --- a/rmap/RmapDeviceCommunicationIF.h +++ b/rmap/RmapDeviceCommunicationIF.h @@ -1,7 +1,7 @@ #ifndef MISSION_RMAP_RMAPDEVICECOMMUNICATIONINTERFACE_H_ #define MISSION_RMAP_RMAPDEVICECOMMUNICATIONINTERFACE_H_ -#include +#include "../devicehandlers/DeviceCommunicationIF.h" /** * @brief This class is a implementation of a DeviceCommunicationIF for RMAP calls. It expects RMAPCookies or a derived class of RMAPCookies @@ -25,7 +25,7 @@ public: * @param maxReplyLen Maximum length of expected reply * @return */ - virtual ReturnValue_t open(Cookie **cookie, uint32_t address, + virtual ReturnValue_t open(CookieIF **cookie, uint32_t address, uint32_t maxReplyLen) = 0; /** @@ -39,7 +39,7 @@ public: * @param maxReplyLen * @return */ - virtual ReturnValue_t reOpen(Cookie *cookie, uint32_t address, + virtual ReturnValue_t reOpen(CookieIF *cookie, uint32_t address, uint32_t maxReplyLen) = 0; @@ -47,7 +47,7 @@ public: * Closing call of connection and memory free of cookie. Mission dependent call * @param cookie */ - virtual void close(Cookie *cookie) = 0; + virtual void close(CookieIF *cookie) = 0; //SHOULDDO can data be const? /** @@ -58,23 +58,23 @@ public: * @param len Length of the data to be send * @return - Return codes of RMAP::sendWriteCommand() */ - virtual ReturnValue_t sendMessage(Cookie *cookie, uint8_t *data, + virtual ReturnValue_t sendMessage(CookieIF *cookie, uint8_t *data, uint32_t len); - virtual ReturnValue_t getSendSuccess(Cookie *cookie); + virtual ReturnValue_t getSendSuccess(CookieIF *cookie); - virtual ReturnValue_t requestReceiveMessage(Cookie *cookie); + virtual ReturnValue_t requestReceiveMessage(CookieIF *cookie); - virtual ReturnValue_t readReceivedMessage(Cookie *cookie, uint8_t **buffer, + virtual ReturnValue_t readReceivedMessage(CookieIF *cookie, uint8_t **buffer, uint32_t *size); - virtual ReturnValue_t setAddress(Cookie *cookie, uint32_t address); + virtual ReturnValue_t setAddress(CookieIF *cookie, uint32_t address); - virtual uint32_t getAddress(Cookie *cookie); + virtual uint32_t getAddress(CookieIF *cookie); - virtual ReturnValue_t setParameter(Cookie *cookie, uint32_t parameter); + virtual ReturnValue_t setParameter(CookieIF *cookie, uint32_t parameter); - virtual uint32_t getParameter(Cookie *cookie); + virtual uint32_t getParameter(CookieIF *cookie); }; #endif /* MISSION_RMAP_RMAPDEVICECOMMUNICATIONINTERFACE_H_ */ diff --git a/serialize/EndianConverter.h b/serialize/EndianConverter.h new file mode 100644 index 000000000..7461576dc --- /dev/null +++ b/serialize/EndianConverter.h @@ -0,0 +1,126 @@ +#ifndef ENDIANSWAPPER_H_ +#define ENDIANSWAPPER_H_ + +#include "../osal/Endiness.h" +#include +#include + +/** + * Helper class to convert variables or bitstreams between machine + * endian and either big or little endian. + * Machine endian is the endianness used by the machine running the + * program and is one of big or little endian. As this is portable + * code, it is not known at coding time which it is. At compile time + * it is however, which is why this is implemented using compiler + * macros and translates to a copy operation at runtime. + * + * This changes the layout of multi-byte variables in the machine's + * memory. In most cases, you should not need to use this class. + * Probably what you are looking for is the SerializeAdapter. + * If you still decide you need this class, please read and understand + * the code first. + * + * The order of the individual bytes of the multi-byte variable is + * reversed, the byte at the highest address is moved to the lowest + * address and vice versa, same for the bytes in between. + * + * Note that the conversion is also its inversion, that is converting + * from machine to a specified endianness is the same operation as + * converting from specified to machine (I looked it up, mathematicians + * would call it an involution): + * + * X == convertBigEndian(convertBigEndian(X)) + * + * Thus, there is only one function supplied to do the conversion. + */ +class EndianConverter { +private: + EndianConverter() { + } + ; +public: + /** + * Convert a typed variable between big endian and machine endian. + * Intended for plain old datatypes. + */ + template + static T convertBigEndian(T in) { +#ifndef BYTE_ORDER_SYSTEM +#error BYTE_ORDER_SYSTEM not defined +#elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN + T tmp; + uint8_t *pointerOut = (uint8_t*) &tmp; + uint8_t *pointerIn = (uint8_t*) ∈ + for (size_t count = 0; count < sizeof(T); count++) { + pointerOut[sizeof(T) - count - 1] = pointerIn[count]; + } + return tmp; +#elif BYTE_ORDER_SYSTEM == BIG_ENDIAN + return in; +#else +#error Unknown Byte Order +#endif + } + + /** + * convert a bytestream representing a single variable between big endian + * and machine endian. + */ + static void convertBigEndian(uint8_t *out, const uint8_t *in, + size_t size) { +#ifndef BYTE_ORDER_SYSTEM +#error BYTE_ORDER_SYSTEM not defined +#elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN + for (size_t count = 0; count < size; count++) { + out[size - count - 1] = in[count]; + } + return; +#elif BYTE_ORDER_SYSTEM == BIG_ENDIAN + memcpy(out, in, size); + return; +#endif + } + + /** + * Convert a typed variable between little endian and machine endian. + * Intended for plain old datatypes. + */ + template + static T convertLittleEndian(T in) { +#ifndef BYTE_ORDER_SYSTEM + #error BYTE_ORDER_SYSTEM not defined + #elif BYTE_ORDER_SYSTEM == BIG_ENDIAN + T tmp; + uint8_t *pointerOut = (uint8_t *) &tmp; + uint8_t *pointerIn = (uint8_t *) ∈ + for (size_t count = 0; count < sizeof(T); count++) { + pointerOut[sizeof(T) - count - 1] = pointerIn[count]; + } + return tmp; + #elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN + return in; +#else + #error Unknown Byte Order + #endif + } + /** + * convert a bytestream representing a single variable between little endian + * and machine endian. + */ + static void convertLittleEndian(uint8_t *out, const uint8_t *in, + size_t size) { +#ifndef BYTE_ORDER_SYSTEM + #error BYTE_ORDER_SYSTEM not defined + #elif BYTE_ORDER_SYSTEM == BIG_ENDIAN + for (size_t count = 0; count < size; count++) { + out[size - count - 1] = in[count]; + } + return; + #elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN + memcpy(out, in, size); + return; +#endif + } +}; + +#endif /* ENDIANSWAPPER_H_ */ diff --git a/serialize/EndianSwapper.h b/serialize/EndianSwapper.h deleted file mode 100644 index 6ff544447..000000000 --- a/serialize/EndianSwapper.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef ENDIANSWAPPER_H_ -#define ENDIANSWAPPER_H_ - -#include -#include -#include - -class EndianSwapper { -private: - EndianSwapper() { - } - ; -public: - template - static T swap(T in) { -#ifndef BYTE_ORDER_SYSTEM -#error BYTE_ORDER_SYSTEM not defined -#elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN - T tmp; - uint8_t *pointerOut = (uint8_t *) &tmp; - uint8_t *pointerIn = (uint8_t *) ∈ - for (uint8_t count = 0; count < sizeof(T); count++) { - pointerOut[sizeof(T) - count - 1] = pointerIn[count]; - } - return tmp; -#elif BYTE_ORDER_SYSTEM == BIG_ENDIAN - return in; -#else -#error Unknown Byte Order -#endif - } - static void swap(uint8_t* out, const uint8_t* in, uint32_t size) { -#ifndef BYTE_ORDER_SYSTEM -#error BYTE_ORDER_SYSTEM not defined -#elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN - for (uint8_t count = 0; count < size; count++) { - out[size - count - 1] = in[count]; - } - return; -#elif BYTE_ORDER_SYSTEM == BIG_ENDIAN - memcpy(out, in, size); - return; -#endif - } -}; - -#endif /* ENDIANSWAPPER_H_ */ diff --git a/serialize/SerialArrayListAdapter.h b/serialize/SerialArrayListAdapter.h index 5ffbc3757..7576505a7 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 FRAMEWORK_SERIALIZE_SERIALARRAYLISTADAPTER_H_ +#define FRAMEWORK_SERIALIZE_SERIALARRAYLISTADAPTER_H_ -#include -#include +#include "../container/ArrayList.h" +#include "SerializeIF.h" #include /** - * \ingroup serialize + * @ingroup serialize + * @author baetz */ template class SerialArrayListAdapter : public SerializeIF { @@ -20,25 +15,26 @@ public: SerialArrayListAdapter(ArrayList *adaptee) : adaptee(adaptee) { } - virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { - return serialize(adaptee, buffer, size, max_size, bigEndian); + virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const { + return serialize(adaptee, buffer, size, maxSize, streamEndianness); } - static ReturnValue_t serialize(const ArrayList* list, uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) { - ReturnValue_t result = SerializeAdapter::serialize(&list->size, - buffer, size, max_size, bigEndian); + 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; while ((result == HasReturnvaluesIF::RETURN_OK) && (i < list->size)) { - result = SerializeAdapter::serialize(&list->entries[i], buffer, size, - max_size, bigEndian); + result = SerializeAdapter::serialize(&list->entries[i], buffer, + size, maxSize, streamEndianness); ++i; } return result; } - virtual uint32_t getSerializedSize() const { + virtual size_t getSerializedSize() const { return getSerializedSize(adaptee); } @@ -47,31 +43,35 @@ public: count_t i = 0; for (i = 0; i < list->size; ++i) { - printSize += SerializeAdapter::getSerializedSize(&list->entries[i]); + printSize += SerializeAdapter::getSerializedSize(&list->entries[i]); } return printSize; } - virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) { - return deSerialize(adaptee, buffer, size, bigEndian); + virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) { + return deSerialize(adaptee, buffer, size, streamEndianness); } - static ReturnValue_t deSerialize(ArrayList* list, const uint8_t** buffer, int32_t* size, - bool bigEndian) { + 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, bigEndian); + 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)) { - result = SerializeAdapter::deSerialize( + result = SerializeAdapter::deSerialize( &list->front()[i], buffer, size, - bigEndian); + streamEndianness); ++i; } return result; @@ -82,4 +82,4 @@ private: -#endif /* SERIALARRAYLISTADAPTER_H_ */ +#endif /* FRAMEWORK_SERIALIZE_SERIALARRAYLISTADAPTER_H_ */ diff --git a/serialize/SerialBufferAdapter.cpp b/serialize/SerialBufferAdapter.cpp index 3ed083bf5..5dd01f54c 100644 --- a/serialize/SerialBufferAdapter.cpp +++ b/serialize/SerialBufferAdapter.cpp @@ -1,4 +1,4 @@ -#include +#include "SerialBufferAdapter.h" #include @@ -22,19 +22,19 @@ SerialBufferAdapter::~SerialBufferAdapter() { } template -ReturnValue_t SerialBufferAdapter::serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { +ReturnValue_t SerialBufferAdapter::serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const { uint32_t serializedLength = bufferLength; if (serializeLength) { - serializedLength += AutoSerializeAdapter::getSerializedSize( + serializedLength += SerializeAdapter::getSerializedSize( &bufferLength); } - if (*size + serializedLength > max_size) { + if (*size + serializedLength > maxSize) { return BUFFER_TOO_SHORT; } else { if (serializeLength) { - AutoSerializeAdapter::serialize(&bufferLength, buffer, size, - max_size, bigEndian); + SerializeAdapter::serialize(&bufferLength, buffer, size, + maxSize, streamEndianness); } if (this->constBuffer != NULL) { memcpy(*buffer, this->constBuffer, bufferLength); @@ -50,20 +50,20 @@ ReturnValue_t SerialBufferAdapter::serialize(uint8_t** buffer, uint32_t* size } template -uint32_t SerialBufferAdapter::getSerializedSize() const { +size_t SerialBufferAdapter::getSerializedSize() const { if (serializeLength) { - return bufferLength + AutoSerializeAdapter::getSerializedSize(&bufferLength); + return bufferLength + SerializeAdapter::getSerializedSize(&bufferLength); } else { return bufferLength; } } template ReturnValue_t SerialBufferAdapter::deSerialize(const uint8_t** buffer, - int32_t* size, bool bigEndian) { + size_t* size, Endianness streamEndianness) { //TODO Ignores Endian flag! if (buffer != NULL) { if(serializeLength){ - T serializedSize = AutoSerializeAdapter::getSerializedSize( + T serializedSize = SerializeAdapter::getSerializedSize( &bufferLength); if((*size - bufferLength - serializedSize) >= 0){ *buffer += serializedSize; diff --git a/serialize/SerialBufferAdapter.h b/serialize/SerialBufferAdapter.h index 7cd75d556..c27a5424e 100644 --- a/serialize/SerialBufferAdapter.h +++ b/serialize/SerialBufferAdapter.h @@ -1,8 +1,8 @@ #ifndef SERIALBUFFERADAPTER_H_ #define SERIALBUFFERADAPTER_H_ -#include -#include +#include "SerializeIF.h" +#include "SerializeAdapter.h" /** * \ingroup serialize @@ -16,13 +16,13 @@ public: virtual ~SerialBufferAdapter(); - virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const; + virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const override; - virtual uint32_t getSerializedSize() const; + virtual size_t getSerializedSize() const override; - virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian); + virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) override; private: bool serializeLength; const uint8_t *constBuffer; diff --git a/serialize/SerialFixedArrayListAdapter.h b/serialize/SerialFixedArrayListAdapter.h index 16919b623..38e0d4383 100644 --- a/serialize/SerialFixedArrayListAdapter.h +++ b/serialize/SerialFixedArrayListAdapter.h @@ -1,8 +1,8 @@ #ifndef SERIALFIXEDARRAYLISTADAPTER_H_ #define SERIALFIXEDARRAYLISTADAPTER_H_ -#include -#include +#include "../container/FixedArrayList.h" +#include "SerialArrayListAdapter.h" /** * \ingroup serialize @@ -13,16 +13,16 @@ public: template SerialFixedArrayListAdapter(Args... args) : FixedArrayList(std::forward(args)...) { } - ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { - return SerialArrayListAdapter::serialize(this, buffer, size, max_size, bigEndian); + ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const { + return SerialArrayListAdapter::serialize(this, buffer, size, maxSize, streamEndianness); } - uint32_t getSerializedSize() const { + size_t getSerializedSize() const { return SerialArrayListAdapter::getSerializedSize(this); } - ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) { - return SerialArrayListAdapter::deSerialize(this, buffer, size, bigEndian); + ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) { + return SerialArrayListAdapter::deSerialize(this, buffer, size, streamEndianness); } }; diff --git a/serialize/SerialLinkedListAdapter.h b/serialize/SerialLinkedListAdapter.h index 29952c4a3..5de8c2423 100644 --- a/serialize/SerialLinkedListAdapter.h +++ b/serialize/SerialLinkedListAdapter.h @@ -7,10 +7,10 @@ #ifndef SERIALLINKEDLISTADAPTER_H_ #define SERIALLINKEDLISTADAPTER_H_ -#include -#include -#include -#include +#include "../container/SinglyLinkedList.h" +#include "SerializeAdapter.h" +#include "SerializeElement.h" +#include "SerializeIF.h" //This is where we need the SerializeAdapter! /** @@ -31,32 +31,32 @@ public: SinglyLinkedList(), printCount(printCount) { } - virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { + virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const override { if (printCount) { count_t mySize = SinglyLinkedList::getSize(); - ReturnValue_t result = SerializeAdapter::serialize(&mySize, - buffer, size, max_size, bigEndian); + ReturnValue_t result = SerializeAdapter::serialize(&mySize, + buffer, size, maxSize, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } } - return serialize(SinglyLinkedList::start, buffer, size, max_size, - bigEndian); + return serialize(SinglyLinkedList::start, buffer, size, maxSize, + streamEndianness); } static ReturnValue_t serialize(const LinkedElement* element, - uint8_t** buffer, uint32_t* size, const uint32_t max_size, - bool bigEndian) { + uint8_t** buffer, size_t* size, size_t maxSize, + Endianness streamEndianness) { ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; while ((result == HasReturnvaluesIF::RETURN_OK) && (element != NULL)) { - result = element->value->serialize(buffer, size, max_size, - bigEndian); + result = element->value->serialize(buffer, size, maxSize, + streamEndianness); element = element->getNext(); } return result; } - virtual uint32_t getSerializedSize() const { + virtual size_t getSerializedSize() const override { if (printCount) { return SerialLinkedListAdapter::getSerializedSize() + sizeof(count_t); @@ -64,8 +64,8 @@ public: return getSerializedSize(SinglyLinkedList::start); } } - static uint32_t getSerializedSize(const LinkedElement *element) { - uint32_t size = 0; + static size_t getSerializedSize(const LinkedElement *element) { + size_t size = 0; while (element != NULL) { size += element->value->getSerializedSize(); element = element->getNext(); @@ -73,16 +73,16 @@ public: return size; } - virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) { - return deSerialize(SinglyLinkedList::start, buffer, size, bigEndian); + virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) override { + return deSerialize(SinglyLinkedList::start, buffer, size, streamEndianness); } static ReturnValue_t deSerialize(LinkedElement* element, - const uint8_t** buffer, int32_t* size, bool bigEndian) { + const uint8_t** buffer, size_t* size, Endianness streamEndianness) { ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; while ((result == HasReturnvaluesIF::RETURN_OK) && (element != NULL)) { - result = element->value->deSerialize(buffer, size, bigEndian); + result = element->value->deSerialize(buffer, size, streamEndianness); element = element->getNext(); } return result; diff --git a/serialize/SerializeAdapter.h b/serialize/SerializeAdapter.h index fd9e1b6af..af5ec116a 100644 --- a/serialize/SerializeAdapter.h +++ b/serialize/SerializeAdapter.h @@ -1,125 +1,123 @@ #ifndef SERIALIZEADAPTER_H_ #define SERIALIZEADAPTER_H_ -#include -#include -#include -#include +#include "../container/IsDerivedFrom.h" +#include "../returnvalues/HasReturnvaluesIF.h" +#include "EndianConverter.h" +#include "SerializeIF.h" #include /** * \ingroup serialize */ -template -class SerializeAdapter_ { -public: - static ReturnValue_t serialize(const T* object, uint8_t** buffer, - uint32_t* size, const uint32_t max_size, bool bigEndian) { - uint32_t ignoredSize = 0; - if (size == NULL) { - size = &ignoredSize; - } - if (sizeof(T) + *size <= max_size) { - T tmp; - if (bigEndian) { - tmp = EndianSwapper::swap(*object); - } else { - tmp = *object; - } - memcpy(*buffer, &tmp, sizeof(T)); - *size += sizeof(T); - (*buffer) += sizeof(T); - return HasReturnvaluesIF::RETURN_OK; - } else { - return SerializeIF::BUFFER_TOO_SHORT; - } - } - ReturnValue_t deSerialize(T* object, const uint8_t** buffer, int32_t* size, - bool bigEndian) { - T tmp; - *size -= sizeof(T); - if (*size >= 0) { - memcpy(&tmp, *buffer, sizeof(T)); - if (bigEndian) { - *object = EndianSwapper::swap(tmp); - } else { - *object = tmp; - } - *buffer += sizeof(T); - return HasReturnvaluesIF::RETURN_OK; - } else { - return SerializeIF::STREAM_TOO_SHORT; - } - } - - uint32_t getSerializedSize(const T * object) { - return sizeof(T); - } - -}; - -template -class SerializeAdapter_ { -public: - ReturnValue_t serialize(const T* object, uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { - uint32_t ignoredSize = 0; - if (size == NULL) { - size = &ignoredSize; - } - return object->serialize(buffer, size, max_size, bigEndian); - } - uint32_t getSerializedSize(const T* object) const { - return object->getSerializedSize(); - } - - ReturnValue_t deSerialize(T* object, const uint8_t** buffer, int32_t* size, - bool bigEndian) { - return object->deSerialize(buffer, size, bigEndian); - } -}; - -template class SerializeAdapter { -public: - static ReturnValue_t serialize(const T* object, uint8_t** buffer, - uint32_t* size, const uint32_t max_size, bool bigEndian) { - SerializeAdapter_::Is> adapter; - return adapter.serialize(object, buffer, size, max_size, bigEndian); - } - static uint32_t getSerializedSize(const T* object) { - SerializeAdapter_::Is> adapter; - return adapter.getSerializedSize(object); - } - - static ReturnValue_t deSerialize(T* object, const uint8_t** buffer, - int32_t* size, bool bigEndian) { - SerializeAdapter_::Is> adapter; - return adapter.deSerialize(object, buffer, size, bigEndian); - } -}; - - -class AutoSerializeAdapter { public: template - static ReturnValue_t serialize(const T* object, uint8_t** buffer, - uint32_t* size, const uint32_t max_size, bool bigEndian) { - SerializeAdapter_::Is> adapter; - return adapter.serialize(object, buffer, size, max_size, bigEndian); + static ReturnValue_t serialize(const T *object, uint8_t **buffer, + size_t *size, size_t maxSize, SerializeIF::Endianness streamEndianness) { + InternalSerializeAdapter::Is> adapter; + return adapter.serialize(object, buffer, size, maxSize, + streamEndianness); } template - static uint32_t getSerializedSize(const T* object) { - SerializeAdapter_::Is> adapter; + static uint32_t getSerializedSize(const T *object) { + InternalSerializeAdapter::Is> adapter; return adapter.getSerializedSize(object); } template - static ReturnValue_t deSerialize(T* object, const uint8_t** buffer, - int32_t* size, bool bigEndian) { - SerializeAdapter_::Is> adapter; - return adapter.deSerialize(object, buffer, size, bigEndian); + static ReturnValue_t deSerialize(T *object, const uint8_t **buffer, + size_t *size, SerializeIF::Endianness streamEndianness) { + InternalSerializeAdapter::Is> adapter; + return adapter.deSerialize(object, buffer, size, streamEndianness); } +private: + template + class InternalSerializeAdapter { + public: + static ReturnValue_t serialize(const T *object, uint8_t **buffer, + size_t *size, size_t max_size, SerializeIF::Endianness streamEndianness) { + size_t ignoredSize = 0; + if (size == NULL) { + size = &ignoredSize; + } + //TODO check integer overflow of *size + if (sizeof(T) + *size <= max_size) { + T tmp; + switch (streamEndianness) { + case SerializeIF::Endianness::BIG: + tmp = EndianConverter::convertBigEndian(*object); + break; + case SerializeIF::Endianness::LITTLE: + tmp = EndianConverter::convertLittleEndian(*object); + break; + default: + case SerializeIF::Endianness::MACHINE: + tmp = *object; + break; + } + memcpy(*buffer, &tmp, sizeof(T)); + *size += sizeof(T); + (*buffer) += sizeof(T); + return HasReturnvaluesIF::RETURN_OK; + } else { + return SerializeIF::BUFFER_TOO_SHORT; + } + } + + ReturnValue_t deSerialize(T *object, const uint8_t **buffer, + size_t *size, SerializeIF::Endianness streamEndianness) { + T tmp; + if (*size >= sizeof(T)) { + *size -= sizeof(T); + memcpy(&tmp, *buffer, sizeof(T)); + switch (streamEndianness) { + case SerializeIF::Endianness::BIG: + *object = EndianConverter::convertBigEndian(tmp); + break; + case SerializeIF::Endianness::LITTLE: + *object = EndianConverter::convertLittleEndian(tmp); + break; + default: + case SerializeIF::Endianness::MACHINE: + *object = tmp; + break; + } + + *buffer += sizeof(T); + return HasReturnvaluesIF::RETURN_OK; + } else { + return SerializeIF::STREAM_TOO_SHORT; + } + } + + uint32_t getSerializedSize(const T *object) { + return sizeof(T); + } + + }; + + template + class InternalSerializeAdapter { + public: + 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) { + size = &ignoredSize; + } + return object->serialize(buffer, size, max_size, streamEndianness); + } + uint32_t getSerializedSize(const T *object) const { + return object->getSerializedSize(); + } + + ReturnValue_t deSerialize(T *object, const uint8_t **buffer, + size_t *size, SerializeIF::Endianness streamEndianness) { + return object->deSerialize(buffer, size, streamEndianness); + } + }; }; #endif /* SERIALIZEADAPTER_H_ */ diff --git a/serialize/SerializeElement.h b/serialize/SerializeElement.h index db7db20a9..ffedeff95 100644 --- a/serialize/SerializeElement.h +++ b/serialize/SerializeElement.h @@ -1,49 +1,51 @@ #ifndef SERIALIZEELEMENT_H_ #define SERIALIZEELEMENT_H_ -#include -#include +#include "../container/SinglyLinkedList.h" +#include "SerializeAdapter.h" #include /** * \ingroup serialize */ template -class SerializeElement : public SerializeIF, public LinkedElement { +class SerializeElement: public SerializeIF, public LinkedElement { public: - template - SerializeElement(Args... args) : LinkedElement(this), entry(std::forward(args)...) { + template + SerializeElement(Args ... args) : + LinkedElement(this), entry(std::forward(args)...) { } - SerializeElement() : LinkedElement(this) { + SerializeElement() : + LinkedElement(this) { } T entry; - ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { - return SerializeAdapter::serialize(&entry, buffer, size, max_size, bigEndian); + ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize, + Endianness streamEndianness) const override { + return SerializeAdapter::serialize(&entry, buffer, size, maxSize, + streamEndianness); } - uint32_t getSerializedSize() const { - return SerializeAdapter::getSerializedSize(&entry); + size_t getSerializedSize() const override { + return SerializeAdapter::getSerializedSize(&entry); } - virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) { - return SerializeAdapter::deSerialize(&entry, buffer, size, bigEndian); + virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size, + Endianness streamEndianness) override { + return SerializeAdapter::deSerialize(&entry, buffer, size, + streamEndianness); } operator T() { return entry; } - SerializeElement &operator=(T newValue) { + SerializeElement& operator=(T newValue) { entry = newValue; return *this; } - T *operator->() { + T* operator->() { return &entry; } }; - - #endif /* SERIALIZEELEMENT_H_ */ diff --git a/serialize/SerializeIF.h b/serialize/SerializeIF.h index 701fbf563..9ed52d295 100644 --- a/serialize/SerializeIF.h +++ b/serialize/SerializeIF.h @@ -1,7 +1,8 @@ #ifndef SERIALIZEIF_H_ #define SERIALIZEIF_H_ -#include +#include "../returnvalues/HasReturnvaluesIF.h" +#include /** * \defgroup serialize Serialization @@ -14,6 +15,10 @@ */ class SerializeIF { public: + enum class Endianness : uint8_t { + BIG, LITTLE, MACHINE + }; + 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); @@ -22,13 +27,13 @@ public: virtual ~SerializeIF() { } - virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const = 0; + virtual ReturnValue_t serialize(uint8_t **buffer, size_t *size, + size_t maxSize, Endianness streamEndianness) const = 0; - virtual uint32_t getSerializedSize() const = 0; + virtual size_t getSerializedSize() const = 0; - virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) = 0; + virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size, + Endianness streamEndianness) = 0; }; diff --git a/serviceinterface/ServiceInterfaceBuffer.cpp b/serviceinterface/ServiceInterfaceBuffer.cpp index 58065994a..68fc4dec3 100644 --- a/serviceinterface/ServiceInterfaceBuffer.cpp +++ b/serviceinterface/ServiceInterfaceBuffer.cpp @@ -1,11 +1,58 @@ -#include -#include +#include "../timemanager/Clock.h" +#include "ServiceInterfaceBuffer.h" #include +#include // to be implemented by bsp -extern "C" void printChar(const char*); +extern "C" void printChar(const char*, bool errStream); + +#ifndef UT699 + +ServiceInterfaceBuffer::ServiceInterfaceBuffer(std::string setMessage, + bool addCrToPreamble, bool buffered , bool errStream, uint16_t port): + isActive(true), logMessage(setMessage), + addCrToPreamble(addCrToPreamble), buffered(buffered), + errStream(errStream) { + if(buffered) { + // Set pointers if the stream is buffered. + setp( buf, buf + BUF_SIZE ); + } + preamble.reserve(MAX_PREAMBLE_SIZE); + preamble.resize(MAX_PREAMBLE_SIZE); +} + +void ServiceInterfaceBuffer::putChars(char const* begin, char const* end) { + char array[BUF_SIZE]; + uint32_t length = end - begin; + if (length > sizeof(array)) { + length = sizeof(array); + } + memcpy(array, begin, length); + + for(; begin != end; begin++){ + if(errStream) { + printChar(begin, true); + } + else { + printChar(begin, false); + } + } +} + +#endif int ServiceInterfaceBuffer::overflow(int c) { + if(not buffered and this->isActive) { + if (c != Traits::eof()) { + if(errStream) { + printChar(reinterpret_cast(&c), true); + } + else { + printChar(reinterpret_cast(&c), false); + } + } + return 0; + } // Handle output putChars(pbase(), pptr()); if (c != Traits::eof()) { @@ -20,52 +67,70 @@ int ServiceInterfaceBuffer::overflow(int c) { } int ServiceInterfaceBuffer::sync(void) { - if (this->isActive) { - Clock::TimeOfDay_t loggerTime; - Clock::getDateAndTime(&loggerTime); - char preamble[96] = { 0 }; - sprintf(preamble, "%s: | %lu:%02lu:%02lu.%03lu | ", - this->log_message.c_str(), (unsigned long) loggerTime.hour, - (unsigned long) loggerTime.minute, - (unsigned long) loggerTime.second, - (unsigned long) loggerTime.usecond /1000); - // Write log_message and time - this->putChars(preamble, preamble + sizeof(preamble)); - // Handle output - this->putChars(pbase(), pptr()); + if(not this->isActive and not buffered) { + if(not buffered) { + setp(buf, buf + BUF_SIZE - 1); + } + return 0; } + if(not buffered) { + return 0; + } + + size_t preambleSize = 0; + std::string* preamble = getPreamble(&preambleSize); + // Write logMessage and time + this->putChars(preamble->data(), preamble->data() + preambleSize); + // Handle output + this->putChars(pbase(), pptr()); // This tells that buffer is empty again setp(buf, buf + BUF_SIZE - 1); return 0; } -#ifndef UT699 - -ServiceInterfaceBuffer::ServiceInterfaceBuffer(std::string set_message, uint16_t port) { - this->log_message = set_message; - this->isActive = true; - setp( buf, buf + BUF_SIZE ); +bool ServiceInterfaceBuffer::isBuffered() const { + return buffered; } -void ServiceInterfaceBuffer::putChars(char const* begin, char const* end) { - char array[BUF_SIZE]; - uint32_t length = end - begin; - if (length > sizeof(array)) { - length = sizeof(array); +std::string* ServiceInterfaceBuffer::getPreamble(size_t * preambleSize) { + Clock::TimeOfDay_t loggerTime; + Clock::getDateAndTime(&loggerTime); + size_t currentSize = 0; + char* parsePosition = &preamble[0]; + if(addCrToPreamble) { + preamble[0] = '\r'; + currentSize += 1; + parsePosition += 1; } - memcpy(array, begin, length); - - for( ; begin != end; begin++){ - printChar(begin); + int32_t charCount = sprintf(parsePosition, + "%s: | %02" SCNu32 ":%02" SCNu32 ":%02" SCNu32 ".%03" SCNu32 " | ", + this->logMessage.c_str(), loggerTime.hour, + loggerTime.minute, + loggerTime.second, + loggerTime.usecond /1000); + if(charCount < 0) { + printf("ServiceInterfaceBuffer: Failure parsing preamble\r\n"); + return &preamble; } - + if(charCount > MAX_PREAMBLE_SIZE) { + printf("ServiceInterfaceBuffer: Char count too large for maximum " + "preamble size"); + return &preamble; + } + currentSize += charCount; + if(preambleSize != nullptr) { + *preambleSize = currentSize; + } + return &preamble; } -#endif + + #ifdef UT699 -#include +#include "../osal/rtems/Interrupt.h" -ServiceInterfaceBuffer::ServiceInterfaceBuffer(std::string set_message, uint16_t port) { +ServiceInterfaceBuffer::ServiceInterfaceBuffer(std::string set_message, + uint16_t port) { this->log_message = set_message; this->isActive = true; setp( buf, buf + BUF_SIZE ); diff --git a/serviceinterface/ServiceInterfaceBuffer.h b/serviceinterface/ServiceInterfaceBuffer.h index b42c8a197..c5d5b2584 100644 --- a/serviceinterface/ServiceInterfaceBuffer.h +++ b/serviceinterface/ServiceInterfaceBuffer.h @@ -1,51 +1,71 @@ #ifndef FRAMEWORK_SERVICEINTERFACE_SERVICEINTERFACEBUFFER_H_ #define FRAMEWORK_SERVICEINTERFACE_SERVICEINTERFACEBUFFER_H_ +#include "../returnvalues/HasReturnvaluesIF.h" #include -#include #include -#include +#include #ifndef UT699 -class ServiceInterfaceBuffer: public std::basic_streambuf > { + +/** + * @brief This is the underlying stream buffer which implements the + * streambuf class and overloads the overflow() and sync() methods + * @details + * This class is used to modify the output of the stream, for example by adding. + * It also calls the char printing function which is implemented in the + * board supply package (BSP). + */ +class ServiceInterfaceBuffer: + public std::streambuf { friend class ServiceInterfaceStream; public: - ServiceInterfaceBuffer(std::string set_message, uint16_t port); + static constexpr uint8_t MAX_PREAMBLE_SIZE = 40; + + ServiceInterfaceBuffer(std::string setMessage, bool addCrToPreamble, + bool buffered, bool errStream, uint16_t port); + protected: bool isActive; - // This is called when buffer becomes full. If - // buffer is not used, then this is called every - // time when characters are put to stream. - virtual int overflow(int c = Traits::eof()); + //! This is called when buffer becomes full. If + //! buffer is not used, then this is called every + //! time when characters are put to stream. + int overflow(int c = Traits::eof()) override; - // This function is called when stream is flushed, - // for example when std::endl is put to stream. - virtual int sync(void); + //! This function is called when stream is flushed, + //! for example when std::endl is put to stream. + int sync(void) override; + bool isBuffered() const; private: - // For additional message information - std::string log_message; + //! For additional message information + std::string logMessage; + std::string preamble; // For EOF detection typedef std::char_traits Traits; - // Work in buffer mode. It is also possible to work without buffer. + //! This is useful for some terminal programs which do not have + //! implicit carriage return with newline characters. + bool addCrToPreamble; + + //! Specifies whether the stream operates in buffered or unbuffered mode. + bool buffered; + //! This specifies to print to stderr and work in unbuffered mode. + bool errStream; + + //! Needed for buffered mode. static size_t const BUF_SIZE = 128; char buf[BUF_SIZE]; - // In this function, the characters are parsed. + //! In this function, the characters are parsed. void putChars(char const* begin, char const* end); + + std::string* getPreamble(size_t * preambleSize = nullptr); }; + #endif - - - - - - - #ifdef UT699 class ServiceInterfaceBuffer: public std::basic_streambuf > { diff --git a/serviceinterface/ServiceInterfaceStream.cpp b/serviceinterface/ServiceInterfaceStream.cpp index c2979f369..5b7b9f004 100644 --- a/serviceinterface/ServiceInterfaceStream.cpp +++ b/serviceinterface/ServiceInterfaceStream.cpp @@ -1,11 +1,32 @@ -#include +#include "ServiceInterfaceStream.h" + +ServiceInterfaceStream::ServiceInterfaceStream(std::string setMessage, + bool addCrToPreamble, bool buffered, bool errStream, uint16_t port) : + std::ostream(&streambuf), + streambuf(setMessage, addCrToPreamble, buffered, errStream, port) {} void ServiceInterfaceStream::setActive( bool myActive) { - this->buf.isActive = myActive; + this->streambuf.isActive = myActive; } -ServiceInterfaceStream::ServiceInterfaceStream(std::string set_message, - uint16_t port) : - std::basic_ostream >(&buf), buf( - set_message, port) { +std::string* ServiceInterfaceStream::getPreamble() { + return streambuf.getPreamble(); +} + +void ServiceInterfaceStream::print(std::string error, + bool withPreamble, bool withNewline, bool flush) { + if(not streambuf.isBuffered() and withPreamble) { + *this << getPreamble() << error; + } + else { + *this << error; + } + + if(withNewline) { + *this << "\n"; + } + // if mode is non-buffered, no need to flush. + if(flush and streambuf.isBuffered()) { + this->flush(); + } } diff --git a/serviceinterface/ServiceInterfaceStream.h b/serviceinterface/ServiceInterfaceStream.h index df736a1b6..76fa1bf23 100644 --- a/serviceinterface/ServiceInterfaceStream.h +++ b/serviceinterface/ServiceInterfaceStream.h @@ -1,30 +1,58 @@ #ifndef FRAMEWORK_SERVICEINTERFACE_SERVICEINTERFACESTREAM_H_ #define FRAMEWORK_SERVICEINTERFACE_SERVICEINTERFACESTREAM_H_ -#include +#include "ServiceInterfaceBuffer.h" #include -#include -#include #include -// Unfortunately, there must be a forward declaration of log_fe -// (MUST be defined in main), to let the system know where to write to. -namespace sif { -extern std::ostream debug; -extern std::ostream info; -extern std::ostream warning; -extern std::ostream error; -} - - -class ServiceInterfaceStream : public std::basic_ostream< char, std::char_traits< char > > { -protected: - ServiceInterfaceBuffer buf; +/** + * Generic service interface stream which can be used like std::cout or + * std::cerr but has additional capability. Add preamble and timestamp + * to output. Can be run in buffered or unbuffered mode. + */ +class ServiceInterfaceStream : public std::ostream { public: - ServiceInterfaceStream( std::string set_message, uint16_t port = 1234 ); + /** + * This constructor is used by specifying the preamble message. + * Optionally, the output can be directed to stderr and a CR character + * can be prepended to the preamble. + * @param setMessage message of preamble. + * @param addCrToPreamble Useful for applications like Puttty. + * @param buffered specify whether to use buffered mode. + * @param errStream specify which output stream to use (stderr or stdout). + */ + ServiceInterfaceStream(std::string setMessage, + bool addCrToPreamble = false, bool buffered = true, + bool errStream = false, uint16_t port = 1234); + + //! An inactive stream will not print anything. void setActive( bool ); + + /** + * This can be used to retrieve the preamble in case it should be printed in + * the unbuffered mode. + * @return Preamle consisting of log message and timestamp. + */ + std::string* getPreamble(); + + /** + * This prints an error with a preamble. Useful if using the unbuffered + * mode. Flushes in default mode (prints immediately). + */ + void print(std::string error, bool withPreamble = true, + bool withNewline = true, bool flush = true); + +protected: + ServiceInterfaceBuffer streambuf; }; - +// Forward declaration of interface streams. These should be instantiated in +// main. They can then be used like std::cout or std::cerr. +namespace sif { +extern ServiceInterfaceStream debug; +extern ServiceInterfaceStream info; +extern ServiceInterfaceStream warning; +extern ServiceInterfaceStream error; +} #endif /* FRAMEWORK_SERVICEINTERFACE_SERVICEINTERFACESTREAM_H_ */ diff --git a/storagemanager/LocalPool.h b/storagemanager/LocalPool.h index 3ddcc4918..ad3deee13 100644 --- a/storagemanager/LocalPool.h +++ b/storagemanager/LocalPool.h @@ -7,11 +7,11 @@ #ifndef FRAMEWORK_STORAGEMANAGER_LOCALPOOL_H_ #define FRAMEWORK_STORAGEMANAGER_LOCALPOOL_H_ -#include -#include -#include -#include -#include +#include "../objectmanager/SystemObject.h" +#include "../serviceinterface/ServiceInterfaceStream.h" +#include "StorageManagerIF.h" +#include "../objectmanager/ObjectManagerIF.h" +#include "../internalError/InternalErrorReporterIF.h" #include /** @@ -178,6 +178,6 @@ private: ReturnValue_t findEmpty(uint16_t pool_index, uint16_t* element); }; -#include +#include "LocalPool.tpp" #endif /* FRAMEWORK_STORAGEMANAGER_LOCALPOOL_H_ */ diff --git a/storagemanager/PoolManager.h b/storagemanager/PoolManager.h index 67534cc5e..0b101d665 100644 --- a/storagemanager/PoolManager.h +++ b/storagemanager/PoolManager.h @@ -2,8 +2,8 @@ #define POOLMANAGER_H_ -#include -#include +#include "LocalPool.h" +#include "../ipc/MutexHelper.h" /** * @brief The PoolManager class provides an intermediate data storage with diff --git a/storagemanager/PoolManager.tpp b/storagemanager/PoolManager.tpp index 26eb22707..0e946b66b 100644 --- a/storagemanager/PoolManager.tpp +++ b/storagemanager/PoolManager.tpp @@ -17,7 +17,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::NO_TIMEOUT); + MutexHelper mutexHelper(mutex,MutexIF::BLOCKING); ReturnValue_t status = LocalPool::reserveSpace(size, address,ignoreFault); return status; @@ -29,7 +29,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::NO_TIMEOUT); + MutexHelper mutexHelper(mutex,MutexIF::BLOCKING); ReturnValue_t status = LocalPool::deleteData(packet_id); return status; } @@ -37,7 +37,7 @@ 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::NO_TIMEOUT); + MutexHelper mutexHelper(mutex,MutexIF::BLOCKING); ReturnValue_t status = LocalPool::deleteData(buffer, size, storeId); return status; @@ -46,7 +46,7 @@ inline ReturnValue_t PoolManager::deleteData(uint8_t* buffer, template inline ReturnValue_t PoolManager::modifyData( store_address_t packet_id, uint8_t** packet_ptr, size_t* size) { - MutexHelper mutexHelper(mutex,MutexIF::NO_TIMEOUT); + MutexHelper mutexHelper(mutex,MutexIF::BLOCKING); ReturnValue_t status = LocalPool::modifyData(packet_id, packet_ptr, size); return status; diff --git a/storagemanager/StorageManagerIF.h b/storagemanager/StorageManagerIF.h index 101e0dcdb..7c194d724 100644 --- a/storagemanager/StorageManagerIF.h +++ b/storagemanager/StorageManagerIF.h @@ -1,8 +1,8 @@ #ifndef STORAGEMANAGERIF_H_H #define STORAGEMANAGERIF_H_H -#include -#include +#include "../events/Event.h" +#include "../returnvalues/HasReturnvaluesIF.h" #include /** diff --git a/subsystem/Subsystem.cpp b/subsystem/Subsystem.cpp index 2d7d9c443..ff3ef634a 100644 --- a/subsystem/Subsystem.cpp +++ b/subsystem/Subsystem.cpp @@ -1,10 +1,10 @@ -#include -#include -#include -#include -#include -#include -#include +#include "../health/HealthMessage.h" +#include "../objectmanager/ObjectManagerIF.h" +#include "../serialize/SerialArrayListAdapter.h" +#include "../serialize/SerialFixedArrayListAdapter.h" +#include "../serialize/SerializeElement.h" +#include "../serialize/SerialLinkedListAdapter.h" +#include "Subsystem.h" #include Subsystem::Subsystem(object_id_t setObjectId, object_id_t parent, @@ -13,7 +13,7 @@ Subsystem::Subsystem(object_id_t setObjectId, object_id_t parent, false), uptimeStartTable(0), currentTargetTable(), targetMode( 0), targetSubmode(SUBMODE_NONE), initialMode(0), currentSequenceIterator(), modeTables( maxNumberOfTables), modeSequences(maxNumberOfSequences), IPCStore( - NULL) + NULL) #ifdef USE_MODESTORE ,modeStore(NULL) #endif @@ -75,7 +75,8 @@ void Subsystem::performChildOperation() { if (isInTransition) { if (commandsOutstanding <= 0) { //all children of the current table were commanded and replied if (currentSequenceIterator.value == NULL) { //we're through with this sequence - if (checkStateAgainstTable(currentTargetTable, targetSubmode) == RETURN_OK) { + if (checkStateAgainstTable(currentTargetTable, targetSubmode) + == RETURN_OK) { setMode(targetMode, targetSubmode); isInTransition = false; return; @@ -86,7 +87,8 @@ void Subsystem::performChildOperation() { } } if (currentSequenceIterator->checkSuccess()) { - if (checkStateAgainstTable(getCurrentTable(), targetSubmode) != RETURN_OK) { + if (checkStateAgainstTable(getCurrentTable(), targetSubmode) + != RETURN_OK) { transitionFailed(TABLE_CHECK_FAILED, currentSequenceIterator->getTableId()); return; @@ -117,7 +119,8 @@ void Subsystem::performChildOperation() { childrenChangedHealth = false; startTransition(mode, submode); } else if (childrenChangedMode) { - if (checkStateAgainstTable(currentTargetTable, submode) != RETURN_OK) { + if (checkStateAgainstTable(currentTargetTable, submode) + != RETURN_OK) { triggerEvent(CANT_KEEP_MODE, mode, submode); cantKeepMode(); } @@ -147,7 +150,7 @@ HybridIterator Subsystem::getTable(Mode_t id) { } } -ReturnValue_t Subsystem::handleCommandMessage(CommandMessage* message) { +ReturnValue_t Subsystem::handleCommandMessage(CommandMessage *message) { ReturnValue_t result; switch (message->getCommand()) { case HealthMessage::HEALTH_INFO: { @@ -168,12 +171,13 @@ ReturnValue_t Subsystem::handleCommandMessage(CommandMessage* message) { &sizeRead); if (result == RETURN_OK) { Mode_t fallbackId; - int32_t size = sizeRead; - result = SerializeAdapter::deSerialize(&fallbackId, - &pointer, &size, true); + size_t size = sizeRead; + result = SerializeAdapter::deSerialize(&fallbackId, &pointer, &size, + SerializeIF::Endianness::BIG); if (result == RETURN_OK) { result = SerialArrayListAdapter::deSerialize( - &sequence, &pointer, &size, true); + &sequence, &pointer, &size, + SerializeIF::Endianness::BIG); if (result == RETURN_OK) { result = addSequence(&sequence, ModeSequenceMessage::getSequenceId(message), @@ -193,9 +197,9 @@ ReturnValue_t Subsystem::handleCommandMessage(CommandMessage* message) { ModeSequenceMessage::getStoreAddress(message), &pointer, &sizeRead); if (result == RETURN_OK) { - int32_t size = sizeRead; + size_t size = sizeRead; result = SerialArrayListAdapter::deSerialize(&table, - &pointer, &size, true); + &pointer, &size, SerializeIF::Endianness::BIG); if (result == RETURN_OK) { result = addTable(&table, ModeSequenceMessage::getSequenceId(message)); @@ -339,7 +343,7 @@ void Subsystem::replyToCommand(ReturnValue_t status, uint32_t parameter) { } } -ReturnValue_t Subsystem::addSequence(ArrayList* sequence, +ReturnValue_t Subsystem::addSequence(ArrayList *sequence, Mode_t id, Mode_t fallbackSequence, bool inStore, bool preInit) { ReturnValue_t result; @@ -507,7 +511,7 @@ MessageQueueId_t Subsystem::getSequenceCommandQueue() const { } ReturnValue_t Subsystem::checkModeCommand(Mode_t mode, Submode_t submode, - uint32_t* msToReachTheMode) { + uint32_t *msToReachTheMode) { //Need to accept all submodes to be able to inherit submodes // if (submode != SUBMODE_NONE) { // return INVALID_SUBMODE; @@ -599,15 +603,15 @@ void Subsystem::transitionFailed(ReturnValue_t failureCode, } void Subsystem::sendSerializablesAsCommandMessage(Command_t command, - SerializeIF** elements, uint8_t count) { + SerializeIF **elements, uint8_t count) { ReturnValue_t result; - uint32_t maxSize = 0; + size_t maxSize = 0; for (uint8_t i = 0; i < count; i++) { maxSize += elements[i]->getSerializedSize(); } uint8_t *storeBuffer; store_address_t address; - uint32_t size = 0; + size_t size = 0; result = IPCStore->getFreeElement(&address, maxSize, &storeBuffer); if (result != HasReturnvaluesIF::RETURN_OK) { @@ -615,7 +619,8 @@ void Subsystem::sendSerializablesAsCommandMessage(Command_t command, return; } for (uint8_t i = 0; i < count; i++) { - elements[i]->serialize(&storeBuffer, &size, maxSize, true); + elements[i]->serialize(&storeBuffer, &size, maxSize, + SerializeIF::Endianness::BIG); } CommandMessage reply; ModeSequenceMessage::setModeSequenceMessage(&reply, command, address); diff --git a/subsystem/Subsystem.h b/subsystem/Subsystem.h index ca1020b94..a40b8028d 100644 --- a/subsystem/Subsystem.h +++ b/subsystem/Subsystem.h @@ -1,13 +1,13 @@ #ifndef SUBSYSTEM_H_ #define SUBSYSTEM_H_ -#include -#include -#include -#include -#include -#include -#include +#include "../container/FixedArrayList.h" +#include "../container/FixedMap.h" +#include "../container/HybridIterator.h" +#include "../container/SinglyLinkedList.h" +#include "../serialize/SerialArrayListAdapter.h" +#include "modes/ModeDefinitions.h" +#include "SubsystemBase.h" class Subsystem: public SubsystemBase, public HasModeSequenceIF { public: diff --git a/subsystem/SubsystemBase.cpp b/subsystem/SubsystemBase.cpp index 6df0b64f6..56ae10628 100644 --- a/subsystem/SubsystemBase.cpp +++ b/subsystem/SubsystemBase.cpp @@ -1,7 +1,7 @@ -#include -#include -#include -#include +#include "../serviceinterface/ServiceInterfaceStream.h" +#include "../serviceinterface/ServiceInterfaceStream.h" +#include "SubsystemBase.h" +#include "../ipc/QueueFactory.h" SubsystemBase::SubsystemBase(object_id_t setObjectId, object_id_t parent, Mode_t initialMode, uint16_t commandQueueDepth) : @@ -329,7 +329,7 @@ void SubsystemBase::checkCommandQueue() { result = handleCommandMessage(&message); if (result != RETURN_OK) { CommandMessage reply; - reply.setReplyRejected(CommandMessage::UNKNOW_COMMAND, + reply.setReplyRejected(CommandMessage::UNKNOWN_COMMAND, message.getCommand()); replyToCommand(&reply); } diff --git a/subsystem/SubsystemBase.h b/subsystem/SubsystemBase.h index 3294c46d7..61a7eaef1 100644 --- a/subsystem/SubsystemBase.h +++ b/subsystem/SubsystemBase.h @@ -1,15 +1,15 @@ #ifndef SUBSYSTEMBASE_H_ #define SUBSYSTEMBASE_H_ -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "../container/HybridIterator.h" +#include "../health/HasHealthIF.h" +#include "../health/HealthHelper.h" +#include "../modes/HasModesIF.h" +#include "../objectmanager/SystemObject.h" +#include "../returnvalues/HasReturnvaluesIF.h" +#include "modes/HasModeSequenceIF.h" +#include "../tasks/ExecutableObjectIF.h" +#include "../ipc/MessageQueueIF.h" #include class SubsystemBase: public SystemObject, diff --git a/subsystem/modes/HasModeSequenceIF.h b/subsystem/modes/HasModeSequenceIF.h index e03de4102..70b1667e9 100644 --- a/subsystem/modes/HasModeSequenceIF.h +++ b/subsystem/modes/HasModeSequenceIF.h @@ -1,9 +1,9 @@ #ifndef HASMODESEQUENCEIF_H_ #define HASMODESEQUENCEIF_H_ -#include -#include -#include +#include "ModeDefinitions.h" +#include "ModeSequenceMessage.h" +#include "ModeStoreIF.h" class HasModeSequenceIF { diff --git a/subsystem/modes/ModeDefinitions.h b/subsystem/modes/ModeDefinitions.h index 8e7531f3d..a865ab0cf 100644 --- a/subsystem/modes/ModeDefinitions.h +++ b/subsystem/modes/ModeDefinitions.h @@ -1,10 +1,10 @@ #ifndef MODEDEFINITIONS_H_ #define MODEDEFINITIONS_H_ -#include -#include -#include -#include +#include "../../modes/HasModesIF.h" +#include "../../objectmanager/SystemObjectIF.h" +#include "../../serialize/SerializeIF.h" +#include "../../serialize/SerialLinkedListAdapter.h" class ModeListEntry: public SerializeIF, public LinkedElement { public: ModeListEntry() : @@ -18,65 +18,65 @@ public: uint8_t value3; uint8_t value4; - virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { + virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const { ReturnValue_t result; - result = SerializeAdapter::serialize(&value1, buffer, size, - max_size, bigEndian); + result = SerializeAdapter::serialize(&value1, buffer, size, + maxSize, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::serialize(&value2, buffer, size, - max_size, bigEndian); + result = SerializeAdapter::serialize(&value2, buffer, size, + maxSize, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::serialize(&value3, buffer, size, - max_size, bigEndian); + result = SerializeAdapter::serialize(&value3, buffer, size, + maxSize, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::serialize(&value4, buffer, size, - max_size, bigEndian); + result = SerializeAdapter::serialize(&value4, buffer, size, + maxSize, streamEndianness); return result; } - virtual uint32_t getSerializedSize() const { + virtual size_t getSerializedSize() const { return sizeof(value1) + sizeof(value2) + sizeof(value3) + sizeof(value4); } - virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) { + virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) { ReturnValue_t result; - result = SerializeAdapter::deSerialize(&value1, buffer, size, - bigEndian); + result = SerializeAdapter::deSerialize(&value1, buffer, size, + streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::deSerialize(&value2, buffer, size, - bigEndian); + result = SerializeAdapter::deSerialize(&value2, buffer, size, + streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::deSerialize(&value3, buffer, size, - bigEndian); + result = SerializeAdapter::deSerialize(&value3, buffer, size, + streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::deSerialize(&value4, buffer, size, - bigEndian); + result = SerializeAdapter::deSerialize(&value4, buffer, size, + streamEndianness); return result; } diff --git a/subsystem/modes/ModeSequenceMessage.cpp b/subsystem/modes/ModeSequenceMessage.cpp index 31661739e..33019f58f 100644 --- a/subsystem/modes/ModeSequenceMessage.cpp +++ b/subsystem/modes/ModeSequenceMessage.cpp @@ -1,8 +1,8 @@ -#include -#include -#include -#include -#include +#include "../../objectmanager/ObjectManagerIF.h" +#include "../../objectmanager/ObjectManagerIF.h" +#include "../../objectmanager/ObjectManagerIF.h" +#include "../../storagemanager/StorageManagerIF.h" +#include "ModeSequenceMessage.h" void ModeSequenceMessage::setModeSequenceMessage(CommandMessage* message, Command_t command, Mode_t sequence, store_address_t storeAddress) { diff --git a/subsystem/modes/ModeSequenceMessage.h b/subsystem/modes/ModeSequenceMessage.h index 61d1b6285..bbf747f14 100644 --- a/subsystem/modes/ModeSequenceMessage.h +++ b/subsystem/modes/ModeSequenceMessage.h @@ -1,9 +1,9 @@ #ifndef MODESEQUENCEMESSAGE_H_ #define MODESEQUENCEMESSAGE_H_ -#include -#include -#include +#include "../../ipc/CommandMessage.h" +#include "../../storagemanager/StorageManagerIF.h" +#include "ModeDefinitions.h" class ModeSequenceMessage { public: diff --git a/subsystem/modes/ModeStore.cpp b/subsystem/modes/ModeStore.cpp index 2aa02087e..217e177c8 100644 --- a/subsystem/modes/ModeStore.cpp +++ b/subsystem/modes/ModeStore.cpp @@ -1,4 +1,4 @@ -#include +#include "ModeStore.h" #ifdef USE_MODESTORE diff --git a/subsystem/modes/ModeStore.h b/subsystem/modes/ModeStore.h index cbc45b5af..0bf856a3e 100644 --- a/subsystem/modes/ModeStore.h +++ b/subsystem/modes/ModeStore.h @@ -3,10 +3,10 @@ #ifdef USE_MODESTORE -#include -#include -#include -#include +#include "../../container/ArrayList.h" +#include "../../container/SinglyLinkedList.h" +#include "../../objectmanager/SystemObject.h" +#include "ModeStoreIF.h" class ModeStore: public ModeStoreIF, public SystemObject { public: diff --git a/subsystem/modes/ModeStoreIF.h b/subsystem/modes/ModeStoreIF.h index 7be7a5a7d..e5cac3b2e 100644 --- a/subsystem/modes/ModeStoreIF.h +++ b/subsystem/modes/ModeStoreIF.h @@ -3,10 +3,10 @@ #ifdef USE_MODESTORE -#include -#include -#include -#include +#include "../../container/ArrayList.h" +#include "../../container/SinglyLinkedList.h" +#include "../../returnvalues/HasReturnvaluesIF.h" +#include "ModeDefinitions.h" class ModeStoreIF { public: diff --git a/tasks/ExecutableObjectIF.h b/tasks/ExecutableObjectIF.h index 5c5955c1c..06b837db8 100644 --- a/tasks/ExecutableObjectIF.h +++ b/tasks/ExecutableObjectIF.h @@ -1,25 +1,16 @@ -/** - * @file ExecutableObjectIF.h - * - * @brief This file contains the definition for the ExecutableObjectIF interface. - * - * @author Bastian Baetz - * - * @date 12.03.2012 - */ - -#ifndef EXECUTABLEOBJECTIF_H_ -#define EXECUTABLEOBJECTIF_H_ +#ifndef FRAMEWORK_TASKS_EXECUTABLEOBJECTIF_H_ +#define FRAMEWORK_TASKS_EXECUTABLEOBJECTIF_H_ class PeriodicTaskIF; -#include +#include "../returnvalues/HasReturnvaluesIF.h" #include /** * @brief The interface provides a method to execute objects within a task. * @details The performOperation method, that is required by the interface is * executed cyclically within a task context. + * @author Bastian Baetz */ class ExecutableObjectIF { public: @@ -37,13 +28,26 @@ public: /** * @brief Function called during setup assignment of object to task - * @details Has to be called from the function that assigns the object to a task and - * enables the object implementation to overwrite this function and get a reference to the executing task + * @details + * Has to be called from the function that assigns the object to a task and + * enables the object implementation to overwrite this function and get + * a reference to the executing task * @param task_ Pointer to the taskIF of this task */ - virtual void setTaskIF(PeriodicTaskIF* task_) { + virtual void setTaskIF(PeriodicTaskIF* task_) {}; + /** + * This function should be called after the object was assigned to a + * specific task. + * + * Example: Can be used to get task execution frequency. + * The task is created after initialize() and the object ctors have been + * called so the execution frequency can't be cached in initialize() + * @return + */ + virtual ReturnValue_t initializeAfterTaskCreation() { + return HasReturnvaluesIF::RETURN_OK; } }; -#endif /* EXECUTABLEOBJECTIF_H_ */ +#endif /* FRAMEWORK_TASKS_EXECUTABLEOBJECTIF_H_ */ diff --git a/tasks/FixedTimeslotTaskIF.h b/tasks/FixedTimeslotTaskIF.h index 3a3582fbc..421978f0d 100644 --- a/tasks/FixedTimeslotTaskIF.h +++ b/tasks/FixedTimeslotTaskIF.h @@ -1,8 +1,8 @@ #ifndef FRAMEWORK_TASKS_FIXEDTIMESLOTTASKIF_H_ #define FRAMEWORK_TASKS_FIXEDTIMESLOTTASKIF_H_ -#include -#include +#include "../objectmanager/ObjectManagerIF.h" +#include "PeriodicTaskIF.h" /** * Following the same principle as the base class IF. This is the interface for a Fixed timeslot task diff --git a/tasks/PeriodicTaskIF.h b/tasks/PeriodicTaskIF.h index 304a7de60..4df376450 100644 --- a/tasks/PeriodicTaskIF.h +++ b/tasks/PeriodicTaskIF.h @@ -1,9 +1,11 @@ -#ifndef PERIODICTASKIF_H_ -#define PERIODICTASKIF_H_ +#ifndef FRAMEWORK_TASK_PERIODICTASKIF_H_ +#define FRAMEWORK_TASK_PERIODICTASKIF_H_ -#include +#include "../objectmanager/SystemObjectIF.h" +#include "../timemanager/Clock.h" #include class ExecutableObjectIF; + /** * New version of TaskIF * Follows RAII principles, i.e. there's no create or delete method. @@ -17,11 +19,26 @@ public: */ virtual ~PeriodicTaskIF() { } /** - * @brief With the startTask method, a created task can be started for the first time. + * @brief With the startTask method, a created task can be started + * for the first time. */ virtual ReturnValue_t startTask() = 0; - virtual ReturnValue_t addComponent(object_id_t object) {return HasReturnvaluesIF::RETURN_FAILED;}; + /** + * Add a component (object) to a periodic task. The pointer to the + * task can be set optionally + * @param object + * Add an object to the task. The most important case is to add an + * executable object with a function which will be called regularly + * (see ExecutableObjectIF) + * @param setTaskIF + * Can be used to specify whether the task object pointer is passed + * to the component. + * @return + */ + virtual ReturnValue_t addComponent(object_id_t object) { + return HasReturnvaluesIF::RETURN_FAILED; + }; virtual ReturnValue_t sleepFor(uint32_t ms) = 0; diff --git a/tasks/TaskFactory.h b/tasks/TaskFactory.h index 8a59adf1c..cbf2272c3 100644 --- a/tasks/TaskFactory.h +++ b/tasks/TaskFactory.h @@ -2,8 +2,8 @@ #define FRAMEWORK_TASKS_TASKFACTORY_H_ #include -#include -#include +#include "FixedTimeslotTaskIF.h" +#include "Typedef.h" /** * Singleton Class that produces Tasks. diff --git a/tcdistribution/CCSDSDistributor.cpp b/tcdistribution/CCSDSDistributor.cpp index 878b8f7d5..1ebb3185e 100644 --- a/tcdistribution/CCSDSDistributor.cpp +++ b/tcdistribution/CCSDSDistributor.cpp @@ -1,6 +1,6 @@ -#include -#include -#include +#include "../serviceinterface/ServiceInterfaceStream.h" +#include "CCSDSDistributor.h" +#include "../tmtcpacket/SpacePacketBase.h" CCSDSDistributor::CCSDSDistributor( uint16_t setDefaultApid, object_id_t setObjectId ) : TcDistributor( setObjectId ), default_apid( setDefaultApid ), tcStore(NULL) { diff --git a/tcdistribution/CCSDSDistributor.h b/tcdistribution/CCSDSDistributor.h index 9dce34f2b..bff720928 100644 --- a/tcdistribution/CCSDSDistributor.h +++ b/tcdistribution/CCSDSDistributor.h @@ -1,11 +1,11 @@ #ifndef CCSDSDISTRIBUTOR_H_ #define CCSDSDISTRIBUTOR_H_ -#include -#include -#include -#include -#include +#include "../objectmanager/ObjectManagerIF.h" +#include "../storagemanager/StorageManagerIF.h" +#include "CCSDSDistributorIF.h" +#include "TcDistributor.h" +#include "../tmtcservices/AcceptsTelecommandsIF.h" /** * An instantiation of the CCSDSDistributorIF. * It receives Space Packets, and selects a destination depending on the APID of the telecommands. diff --git a/tcdistribution/CCSDSDistributorIF.h b/tcdistribution/CCSDSDistributorIF.h index dc1263a97..be3c28114 100644 --- a/tcdistribution/CCSDSDistributorIF.h +++ b/tcdistribution/CCSDSDistributorIF.h @@ -1,8 +1,8 @@ #ifndef CCSDSDISTRIBUTORIF_H_ #define CCSDSDISTRIBUTORIF_H_ -#include -#include +#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, diff --git a/tcdistribution/PUSDistributor.cpp b/tcdistribution/PUSDistributor.cpp index c214f6746..f77eb99d8 100644 --- a/tcdistribution/PUSDistributor.cpp +++ b/tcdistribution/PUSDistributor.cpp @@ -1,8 +1,8 @@ -#include -#include -#include -#include -#include +#include "../serviceinterface/ServiceInterfaceStream.h" +#include "CCSDSDistributorIF.h" +#include "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( diff --git a/tcdistribution/PUSDistributor.h b/tcdistribution/PUSDistributor.h index 8d7746626..e9d4be8ca 100644 --- a/tcdistribution/PUSDistributor.h +++ b/tcdistribution/PUSDistributor.h @@ -1,12 +1,12 @@ #ifndef PUSDISTRIBUTOR_H_ #define PUSDISTRIBUTOR_H_ -#include -#include -#include -#include -#include -#include +#include "../returnvalues/HasReturnvaluesIF.h" +#include "PUSDistributorIF.h" +#include "TcDistributor.h" +#include "TcPacketCheck.h" +#include "../tmtcservices/AcceptsTelecommandsIF.h" +#include "../tmtcservices/VerificationReporter.h" /** * This class accepts PUS Telecommands and forwards them to Application services. diff --git a/tcdistribution/PUSDistributorIF.h b/tcdistribution/PUSDistributorIF.h index bb1011374..5e27b35c5 100644 --- a/tcdistribution/PUSDistributorIF.h +++ b/tcdistribution/PUSDistributorIF.h @@ -1,8 +1,8 @@ #ifndef PUSDISTRIBUTORIF_H_ #define PUSDISTRIBUTORIF_H_ -#include -#include +#include "../tmtcservices/AcceptsTelecommandsIF.h" +#include "../ipc/MessageQueueSenderIF.h" /** * This interface allows PUS Services to register themselves at a PUS Distributor. * \ingroup tc_distribution diff --git a/tcdistribution/TcDistributor.cpp b/tcdistribution/TcDistributor.cpp index 579214593..49a996d90 100644 --- a/tcdistribution/TcDistributor.cpp +++ b/tcdistribution/TcDistributor.cpp @@ -1,8 +1,8 @@ -#include -#include -#include -#include -#include +#include "../serviceinterface/ServiceInterfaceStream.h" +#include "../serviceinterface/ServiceInterfaceStream.h" +#include "TcDistributor.h" +#include "../tmtcservices/TmTcMessage.h" +#include "../ipc/QueueFactory.h" TcDistributor::TcDistributor(object_id_t set_object_id) : SystemObject(set_object_id), tcQueue(NULL) { diff --git a/tcdistribution/TcDistributor.h b/tcdistribution/TcDistributor.h index b80f08e68..fed1cb3e0 100644 --- a/tcdistribution/TcDistributor.h +++ b/tcdistribution/TcDistributor.h @@ -1,12 +1,12 @@ #ifndef TCDISTRIBUTOR_H_ #define TCDISTRIBUTOR_H_ -#include -#include -#include -#include -#include -#include -#include +#include "../objectmanager/ObjectManagerIF.h" +#include "../objectmanager/SystemObject.h" +#include "../returnvalues/HasReturnvaluesIF.h" +#include "../storagemanager/StorageManagerIF.h" +#include "../tasks/ExecutableObjectIF.h" +#include "../tmtcservices/TmTcMessage.h" +#include "../ipc/MessageQueueIF.h" #include diff --git a/tcdistribution/TcPacketCheck.cpp b/tcdistribution/TcPacketCheck.cpp index 90a1167fa..b5881083f 100644 --- a/tcdistribution/TcPacketCheck.cpp +++ b/tcdistribution/TcPacketCheck.cpp @@ -1,8 +1,8 @@ -#include -#include -#include -#include -#include +#include "../globalfunctions/CRC.h" +#include "../serviceinterface/ServiceInterfaceStream.h" +#include "../storagemanager/StorageManagerIF.h" +#include "TcPacketCheck.h" +#include "../tmtcservices/VerificationCodes.h" TcPacketCheck::TcPacketCheck( uint16_t set_apid ) : apid(set_apid) { } diff --git a/tcdistribution/TcPacketCheck.h b/tcdistribution/TcPacketCheck.h index 88810ed7e..4ba269f5e 100644 --- a/tcdistribution/TcPacketCheck.h +++ b/tcdistribution/TcPacketCheck.h @@ -1,9 +1,9 @@ #ifndef TCPACKETCHECK_H_ #define TCPACKETCHECK_H_ -#include -#include -#include +#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. diff --git a/thermal/AbstractTemperatureSensor.cpp b/thermal/AbstractTemperatureSensor.cpp index be143410a..45ebe4a2a 100644 --- a/thermal/AbstractTemperatureSensor.cpp +++ b/thermal/AbstractTemperatureSensor.cpp @@ -1,5 +1,5 @@ #include "AbstractTemperatureSensor.h" -#include +#include "../ipc/QueueFactory.h" AbstractTemperatureSensor::AbstractTemperatureSensor(object_id_t setObjectid, ThermalModuleIF *thermalModule) : diff --git a/thermal/AbstractTemperatureSensor.h b/thermal/AbstractTemperatureSensor.h index 75437dca8..726ab9f4c 100644 --- a/thermal/AbstractTemperatureSensor.h +++ b/thermal/AbstractTemperatureSensor.h @@ -1,12 +1,12 @@ #ifndef ABSTRACTSENSOR_H_ #define ABSTRACTSENSOR_H_ -#include -#include -#include -#include -#include -#include +#include "../health/HasHealthIF.h" +#include "../health/HealthHelper.h" +#include "../objectmanager/SystemObject.h" +#include "../tasks/ExecutableObjectIF.h" +#include "../parameters/ParameterHelper.h" +#include "../ipc/MessageQueueIF.h" #include "ThermalModuleIF.h" #include "tcsDefinitions.h" diff --git a/thermal/CoreComponent.h b/thermal/CoreComponent.h index f7e7aff8d..48a49f7d0 100644 --- a/thermal/CoreComponent.h +++ b/thermal/CoreComponent.h @@ -1,12 +1,12 @@ #ifndef MISSION_CONTROLLERS_TCS_CORECOMPONENT_H_ #define MISSION_CONTROLLERS_TCS_CORECOMPONENT_H_ -#include -#include -#include -#include -#include -#include +#include "../datapool/DataSet.h" +#include "../datapool/PoolVariable.h" +#include "ThermalComponentIF.h" +#include "AbstractTemperatureSensor.h" +#include "ThermalModule.h" +#include "ThermalMonitor.h" class CoreComponent: public ThermalComponentIF { public: diff --git a/thermal/Heater.cpp b/thermal/Heater.cpp index 29daa15df..1301e2e01 100644 --- a/thermal/Heater.cpp +++ b/thermal/Heater.cpp @@ -1,8 +1,8 @@ -#include +#include "../devicehandlers/DeviceHandlerFailureIsolation.h" #include "Heater.h" -#include -#include +#include "../power/Fuse.h" +#include "../ipc/QueueFactory.h" Heater::Heater(uint32_t objectId, uint8_t switch0, uint8_t switch1) : HealthDevice(objectId, 0), internalState(STATE_OFF), powerSwitcher( diff --git a/thermal/Heater.h b/thermal/Heater.h index 41004e039..63fe20667 100644 --- a/thermal/Heater.h +++ b/thermal/Heater.h @@ -1,11 +1,11 @@ #ifndef FRAMEWORK_THERMAL_HEATER_H_ #define FRAMEWORK_THERMAL_HEATER_H_ -#include -#include -#include -#include -#include +#include "../devicehandlers/HealthDevice.h" +#include "../parameters/ParameterHelper.h" +#include "../power/PowerSwitchIF.h" +#include "../returnvalues/HasReturnvaluesIF.h" +#include "../timemanager/Countdown.h" #include //class RedundantHeater; diff --git a/thermal/RedundantHeater.h b/thermal/RedundantHeater.h index 29791a9a1..ab745a698 100644 --- a/thermal/RedundantHeater.h +++ b/thermal/RedundantHeater.h @@ -1,7 +1,7 @@ #ifndef REDUNDANTHEATER_H_ #define REDUNDANTHEATER_H_ -#include +#include "Heater.h" class RedundantHeater { public: diff --git a/thermal/TemperatureSensor.h b/thermal/TemperatureSensor.h index de280d877..356ca7220 100644 --- a/thermal/TemperatureSensor.h +++ b/thermal/TemperatureSensor.h @@ -1,9 +1,9 @@ #ifndef TEMPERATURESENSOR_H_ #define TEMPERATURESENSOR_H_ -#include +#include "../datapool/DataSet.h" #include "AbstractTemperatureSensor.h" -#include +#include "../monitoring/LimitMonitor.h" template class TemperatureSensor: public AbstractTemperatureSensor { diff --git a/thermal/ThermalComponent.cpp b/thermal/ThermalComponent.cpp index bf6f73986..5dcd0bc64 100644 --- a/thermal/ThermalComponent.cpp +++ b/thermal/ThermalComponent.cpp @@ -46,15 +46,15 @@ ReturnValue_t ThermalComponent::setLimits(const uint8_t* data, uint32_t size) { if (size != 4 * sizeof(parameters.lowerOpLimit)) { return MonitoringIF::INVALID_SIZE; } - int32_t readSize = size; - SerializeAdapter::deSerialize(&nopParameters.lowerNopLimit, &data, - &readSize, true); - SerializeAdapter::deSerialize(¶meters.lowerOpLimit, &data, - &readSize, true); - SerializeAdapter::deSerialize(¶meters.upperOpLimit, &data, - &readSize, true); - SerializeAdapter::deSerialize(&nopParameters.upperNopLimit, &data, - &readSize, true); + size_t readSize = size; + SerializeAdapter::deSerialize(&nopParameters.lowerNopLimit, &data, + &readSize, SerializeIF::Endianness::BIG); + SerializeAdapter::deSerialize(¶meters.lowerOpLimit, &data, + &readSize, SerializeIF::Endianness::BIG); + SerializeAdapter::deSerialize(¶meters.upperOpLimit, &data, + &readSize, SerializeIF::Endianness::BIG); + SerializeAdapter::deSerialize(&nopParameters.upperNopLimit, &data, + &readSize, SerializeIF::Endianness::BIG); return HasReturnvaluesIF::RETURN_OK; } diff --git a/thermal/ThermalComponentIF.h b/thermal/ThermalComponentIF.h index ad8dbd0a8..522d4e443 100644 --- a/thermal/ThermalComponentIF.h +++ b/thermal/ThermalComponentIF.h @@ -1,10 +1,10 @@ #ifndef THERMALCOMPONENTIF_H_ #define THERMALCOMPONENTIF_H_ -#include -#include -#include -#include +#include "../events/Event.h" +#include "../parameters/HasParametersIF.h" +#include "../returnvalues/HasReturnvaluesIF.h" +#include "../objectmanager/SystemObjectIF.h" class ThermalComponentIF : public HasParametersIF { public: diff --git a/thermal/ThermalModule.cpp b/thermal/ThermalModule.cpp index 24a4c90d9..c573008e6 100644 --- a/thermal/ThermalModule.cpp +++ b/thermal/ThermalModule.cpp @@ -1,5 +1,5 @@ -#include -#include +#include "../monitoring/LimitViolationReporter.h" +#include "../monitoring/MonitoringMessageContent.h" #include "ThermalModule.h" #include "AbstractTemperatureSensor.h" diff --git a/thermal/ThermalModule.h b/thermal/ThermalModule.h index d8ac7d732..19ab9a549 100644 --- a/thermal/ThermalModule.h +++ b/thermal/ThermalModule.h @@ -1,10 +1,10 @@ #ifndef THERMALMODULE_H_ #define THERMALMODULE_H_ -#include -#include -#include -#include +#include "../datapool/DataSet.h" +#include "../datapool/PoolVariable.h" +#include "../devicehandlers/HealthDevice.h" +#include "../events/EventReportingProxyIF.h" #include "ThermalModuleIF.h" #include #include "tcsDefinitions.h" diff --git a/thermal/ThermalMonitor.cpp b/thermal/ThermalMonitor.cpp index 773fa084f..11abfbe54 100644 --- a/thermal/ThermalMonitor.cpp +++ b/thermal/ThermalMonitor.cpp @@ -1,6 +1,6 @@ -#include -#include -#include +#include "ThermalMonitor.h" +#include "ThermalComponentIF.h" +#include "../monitoring/MonitoringIF.h" ThermalMonitor::~ThermalMonitor() { } diff --git a/thermal/ThermalMonitor.h b/thermal/ThermalMonitor.h index 6aca55abc..5c6806c1d 100644 --- a/thermal/ThermalMonitor.h +++ b/thermal/ThermalMonitor.h @@ -1,8 +1,8 @@ #ifndef FRAMEWORK_THERMAL_THERMALMONITOR_H_ #define FRAMEWORK_THERMAL_THERMALMONITOR_H_ -#include -#include +#include "../monitoring/MonitorReporter.h" +#include "ThermalComponentIF.h" class ThermalMonitor: public MonitorReporter { public: diff --git a/timemanager/CCSDSTime.cpp b/timemanager/CCSDSTime.cpp index 320327161..eddbb97b5 100644 --- a/timemanager/CCSDSTime.cpp +++ b/timemanager/CCSDSTime.cpp @@ -1,5 +1,6 @@ -#include +#include "CCSDSTime.h" #include +#include #include CCSDSTime::CCSDSTime() { @@ -154,15 +155,17 @@ ReturnValue_t CCSDSTime::convertFromASCII(Clock::TimeOfDay_t* to, const uint8_t* if (length < 19) { return RETURN_FAILED; } +// 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 uint16_t year; - uint8_t month; + uint16_t month; uint16_t day; - uint8_t hour; - uint8_t minute; + uint16_t hour; + uint16_t minute; float second; -//try Code A (yyyy-mm-dd) - int count = sscanf((char *) from, "%4hi-%2hhi-%2hiT%2hhi:%2hhi:%fZ", &year, - &month, &day, &hour, &minute, &second); + int count = sscanf((char *) from, "%4" SCNu16 "-%2" SCNu16 "-%2" SCNu16 "T%2" SCNu16 ":%2" SCNu16 ":%fZ", &year, + &month, &day, &hour, &minute, &second); if (count == 6) { to->year = year; to->month = month; @@ -174,9 +177,52 @@ ReturnValue_t CCSDSTime::convertFromASCII(Clock::TimeOfDay_t* to, const uint8_t* return RETURN_OK; } - //try Code B (yyyy-ddd) - count = sscanf((char *) from, "%4hi-%3hiT%2hhi:%2hhi:%fZ", &year, &day, + // try Code B (yyyy-ddd) + count = sscanf((char *) from, "%4" SCNu16 "-%3" SCNu16 "T%2" SCNu16 ":%2" SCNu16 ":%fZ", &year, &day, &hour, &minute, &second); + if (count == 5) { + uint8_t tempDay; + ReturnValue_t result = CCSDSTime::convertDaysOfYear(day, year, + reinterpret_cast(&month), reinterpret_cast(&tempDay)); + if (result != RETURN_OK) { + return RETURN_FAILED; + } + to->year = year; + to->month = month; + to->day = tempDay; + to->hour = hour; + to->minute = minute; + to->second = second; + to->usecond = (second - floor(second)) * 1000000; + return RETURN_OK; + } +// Warning: Compiler/Linker fails ambiguously if library does not implement +// C99 I/O +#else + uint16_t year; + uint8_t month; + uint16_t day; + uint8_t hour; + uint8_t minute; + float second; + //try Code A (yyyy-mm-dd) + int count = sscanf((char *) from, "%4" SCNu16 "-%2" SCNu8 "-%2" SCNu16 + "T%2" SCNu8 ":%2" SCNu8 ":%fZ", &year, &month, &day, + &hour, &minute, &second); + if (count == 6) { + to->year = year; + to->month = month; + to->day = day; + to->hour = hour; + to->minute = minute; + to->second = second; + to->usecond = (second - floor(second)) * 1000000; + return RETURN_OK; + } + + //try Code B (yyyy-ddd) + count = sscanf((char *) from, "%4" SCNu16 "-%3" SCNu16 "T%2" SCNu8 + ":%2" SCNu8 ":%fZ", &year, &day, &hour, &minute, &second); if (count == 5) { uint8_t tempDay; ReturnValue_t result = CCSDSTime::convertDaysOfYear(day, year, &month, @@ -193,6 +239,7 @@ ReturnValue_t CCSDSTime::convertFromASCII(Clock::TimeOfDay_t* to, const uint8_t* to->usecond = (second - floor(second)) * 1000000; return RETURN_OK; } +#endif return UNSUPPORTED_TIME_FORMAT; } diff --git a/timemanager/CCSDSTime.h b/timemanager/CCSDSTime.h index 92060d5d7..8563cf0fd 100644 --- a/timemanager/CCSDSTime.h +++ b/timemanager/CCSDSTime.h @@ -3,8 +3,8 @@ // COULDDO: have calls in Clock.h which return time quality and use timespec accordingly -#include -#include +#include "Clock.h" +#include "../returnvalues/HasReturnvaluesIF.h" #include bool operator<(const timeval& lhs, const timeval& rhs); diff --git a/timemanager/Clock.h b/timemanager/Clock.h index af6572472..6f6a97daf 100644 --- a/timemanager/Clock.h +++ b/timemanager/Clock.h @@ -1,13 +1,16 @@ #ifndef FRAMEWORK_TIMEMANAGER_CLOCK_H_ #define FRAMEWORK_TIMEMANAGER_CLOCK_H_ -#include -#include +#include "../returnvalues/HasReturnvaluesIF.h" +#include "../ipc/MutexFactory.h" +#include "../globalfunctions/timevalOperations.h" + +#include #include -#include -#include - +//! Don't use these for time points, type is not large enough for UNIX epoch. +typedef uint32_t dur_millis_t; +typedef double dur_seconds_t; class Clock { public: @@ -21,7 +24,7 @@ public: uint32_t usecond; //!< Microseconds, 0 .. 999999 } TimeOfDay_t; - /**static Clock* TimeOfDay_t(); + /** * This method returns the number of clock ticks per second. * In RTEMS, this is typically 1000. * @return The number of ticks. @@ -33,22 +36,23 @@ public: * This system call sets the system time. * To set the time, it uses a TimeOfDay_t struct. * @param time The struct with the time settings to set. - * @return \c RETURN_OK on success. Otherwise, the OS failure code is returned. + * @return -@c RETURN_OK on success. Otherwise, the OS failure code + * is returned. */ static ReturnValue_t setClock(const TimeOfDay_t* time); /** * This system call sets the system time. * To set the time, it uses a timeval struct. * @param time The struct with the time settings to set. - * @return \c RETURN_OK on success. Otherwise, the OS failure code is returned. + * @return -@c RETURN_OK on success. Otherwise, the OS failure code is returned. */ static ReturnValue_t setClock(const timeval* time); /** * This system call returns the current system clock in timeval format. - * The timval format has the fields \c tv_sec with seconds and \c tv_usec with + * The timval format has the fields @c tv_sec with seconds and @c tv_usec with * microseconds since an OS-defined epoch. * @param time A pointer to a timeval struct where the current time is stored. - * @return \c RETURN_OK on success. Otherwise, the OS failure code is returned. + * @return @c RETURN_OK on success. Otherwise, the OS failure code is returned. */ static ReturnValue_t getClock_timeval(timeval* time); @@ -56,7 +60,7 @@ public: * Get the time since boot in a timeval struct * * @param[out] time A pointer to a timeval struct where the uptime is stored. - * @return\c RETURN_OK on success. Otherwise, the OS failure code is returned. + * @return @c RETURN_OK on success. Otherwise, the OS failure code is returned. * * @deprecated, I do not think this should be able to fail, use timeval getUptime() */ diff --git a/timemanager/Countdown.cpp b/timemanager/Countdown.cpp index e65659149..d56957301 100644 --- a/timemanager/Countdown.cpp +++ b/timemanager/Countdown.cpp @@ -6,7 +6,7 @@ */ -#include +#include "Countdown.h" Countdown::Countdown(uint32_t initialTimeout) : startTime(0), timeout(initialTimeout) { } diff --git a/timemanager/Countdown.h b/timemanager/Countdown.h index 57a11f911..b86d9fe0b 100644 --- a/timemanager/Countdown.h +++ b/timemanager/Countdown.h @@ -8,7 +8,7 @@ #ifndef COUNTDOWN_H_ #define COUNTDOWN_H_ -#include +#include "Clock.h" class Countdown { private: diff --git a/timemanager/Stopwatch.cpp b/timemanager/Stopwatch.cpp new file mode 100644 index 000000000..00373bd7e --- /dev/null +++ b/timemanager/Stopwatch.cpp @@ -0,0 +1,57 @@ +#include "Stopwatch.h" +#include "../serviceinterface/ServiceInterfaceStream.h" +#include + +Stopwatch::Stopwatch(bool displayOnDestruction, + StopwatchDisplayMode displayMode): displayOnDestruction( + displayOnDestruction), displayMode(displayMode) { + // Measures start time on initialization. + Clock::getClock_timeval(&startTime); +} + +void Stopwatch::start() { + Clock::getClock_timeval(&startTime); +} + +dur_millis_t Stopwatch::stop() { + stopInternal(); + return elapsedTime.tv_sec * 1000 + elapsedTime.tv_usec / 1000; +} + +dur_seconds_t Stopwatch::stopSeconds() { + stopInternal(); + return timevalOperations::toDouble(elapsedTime); +} + +void Stopwatch::display() { + if(displayMode == StopwatchDisplayMode::MILLIS) { + sif::info << "Stopwatch: Operation took " << (elapsedTime.tv_sec * 1000 + + elapsedTime.tv_usec / 1000) << " milliseconds" << std::endl; + } + else if(displayMode == StopwatchDisplayMode::SECONDS) { + sif::info <<"Stopwatch: Operation took " << std::setprecision(3) + << std::fixed << timevalOperations::toDouble(elapsedTime) + << " seconds" << std::endl; + } +} + +Stopwatch::~Stopwatch() { + if(displayOnDestruction) { + stopInternal(); + display(); + } +} + +void Stopwatch::setDisplayMode(StopwatchDisplayMode displayMode) { + this->displayMode = displayMode; +} + +StopwatchDisplayMode Stopwatch::getDisplayMode() const { + return displayMode; +} + +void Stopwatch::stopInternal() { + timeval endTime; + Clock::getClock_timeval(&endTime); + elapsedTime = endTime - startTime; +} diff --git a/timemanager/Stopwatch.h b/timemanager/Stopwatch.h new file mode 100644 index 000000000..f216b7e10 --- /dev/null +++ b/timemanager/Stopwatch.h @@ -0,0 +1,71 @@ +#ifndef FRAMEWORK_TIMEMANAGER_STOPWATCH_H_ +#define FRAMEWORK_TIMEMANAGER_STOPWATCH_H_ +#include "Clock.h" + +enum class StopwatchDisplayMode { + MILLIS, + SECONDS +}; + +/** + * @brief Simple Stopwatch implementation to measure elapsed time + * @details + * This class can be used to measure elapsed times. It also displays elapsed + * times automatically on destruction if not explicitely deactivated in the + * constructor. The default time format is the elapsed time in miliseconds + * in seconds as a double. + * @author R. Mueller + */ +class Stopwatch { +public: + /** + * Default constructor. Call "Stopwatch stopwatch" without brackets if + * no parameters are required! + * @param displayOnDestruction If set to true, displays measured time on + * object destruction + * @param displayMode Display format is either MS rounded or MS as double + * format + * @param outputPrecision If using double format, specify precision here. + */ + Stopwatch(bool displayOnDestruction = true, StopwatchDisplayMode displayMode + = StopwatchDisplayMode::MILLIS); + virtual~ Stopwatch(); + + /** + * Caches the start time + */ + void start(); + + /** + * Calculates the elapsed time since start and returns it + * @return elapsed time in milliseconds (rounded) + */ + dur_millis_t stop(); + /** + * Calculates the elapsed time since start and returns it + * @return elapsed time in seconds (double precision) + */ + dur_seconds_t stopSeconds(); + + /** + * Displays the elapsed times on the osstream, depending on internal display + * mode. + */ + void display(); + + StopwatchDisplayMode getDisplayMode() const; + void setDisplayMode(StopwatchDisplayMode displayMode); + bool displayOnDestruction = true; +private: + timeval startTime {0, 0}; + timeval elapsedTime {0, 0}; + + StopwatchDisplayMode displayMode = StopwatchDisplayMode::MILLIS; + + void stopInternal(); +}; + + + + +#endif /* FRAMEWORK_TIMEMANAGER_STOPWATCH_H_ */ diff --git a/timemanager/TimeMessage.cpp b/timemanager/TimeMessage.cpp index bf514317f..5a9a416b5 100644 --- a/timemanager/TimeMessage.cpp +++ b/timemanager/TimeMessage.cpp @@ -5,7 +5,7 @@ * @author baetz */ -#include +#include "TimeMessage.h" TimeMessage::TimeMessage() { this->messageSize += sizeof(timeval) + sizeof(uint32_t); diff --git a/timemanager/TimeMessage.h b/timemanager/TimeMessage.h index 95685fec2..116002e6d 100644 --- a/timemanager/TimeMessage.h +++ b/timemanager/TimeMessage.h @@ -8,8 +8,8 @@ #ifndef TIMEMESSAGE_H_ #define TIMEMESSAGE_H_ -#include -#include +#include "../ipc/MessageQueueMessage.h" +#include "Clock.h" #include class TimeMessage : public MessageQueueMessage { diff --git a/timemanager/TimeStamperIF.h b/timemanager/TimeStamperIF.h index 7ed453716..bdc5e7e37 100644 --- a/timemanager/TimeStamperIF.h +++ b/timemanager/TimeStamperIF.h @@ -1,7 +1,7 @@ #ifndef FRAMEWORK_TIMEMANAGER_TIMESTAMPERIF_H_ #define FRAMEWORK_TIMEMANAGER_TIMESTAMPERIF_H_ -#include +#include "../returnvalues/HasReturnvaluesIF.h" /** * A class implementing this IF provides facilities to add a time stamp to the diff --git a/tmstorage/TmStoreBackendIF.h b/tmstorage/TmStoreBackendIF.h index 162bd7665..a441808e4 100644 --- a/tmstorage/TmStoreBackendIF.h +++ b/tmstorage/TmStoreBackendIF.h @@ -1,11 +1,11 @@ #ifndef PLATFORM_TMTCSERVICES_TMSTOREBACKENDIF_H_ #define PLATFORM_TMTCSERVICES_TMSTOREBACKENDIF_H_ -#include -#include -#include -#include -#include +#include "../returnvalues/HasReturnvaluesIF.h" +#include "../objectmanager/SystemObjectIF.h" +#include "../parameters/HasParametersIF.h" +#include "../storagemanager/StorageManagerIF.h" +#include "../timemanager/Clock.h" class TmPacketInformation; class TmPacketMinimal; class SpacePacketBase; diff --git a/tmstorage/TmStoreFrontendIF.h b/tmstorage/TmStoreFrontendIF.h index 787c35972..e1bc3a148 100644 --- a/tmstorage/TmStoreFrontendIF.h +++ b/tmstorage/TmStoreFrontendIF.h @@ -1,9 +1,9 @@ #ifndef PLATFORM_TMTCSERVICES_TMSTOREFRONTENDIF_H_ #define PLATFORM_TMTCSERVICES_TMSTOREFRONTENDIF_H_ -#include -#include -#include +#include "../returnvalues/HasReturnvaluesIF.h" +#include "TmStorePackets.h" +#include "../ipc/MessageQueueSenderIF.h" class TmPacketMinimal; class SpacePacketBase; class TmStoreBackendIF; diff --git a/tmstorage/TmStoreMessage.cpp b/tmstorage/TmStoreMessage.cpp index 4509ba912..d2efd4033 100644 --- a/tmstorage/TmStoreMessage.cpp +++ b/tmstorage/TmStoreMessage.cpp @@ -1,5 +1,5 @@ -#include -#include +#include "../objectmanager/ObjectManagerIF.h" +#include "TmStoreMessage.h" TmStoreMessage::~TmStoreMessage() { @@ -74,7 +74,7 @@ void TmStoreMessage::clear(CommandMessage* cmd) { case DELETE_STORE_CONTENT_BLOCKS: case DOWNLINK_STORE_CONTENT_BLOCKS: case REPORT_INDEX_REQUEST: - cmd->setCommand(UNKNOW_COMMAND); + cmd->setCommand(UNKNOWN_COMMAND); cmd->setParameter(0); cmd->setParameter2(0); break; diff --git a/tmstorage/TmStoreMessage.h b/tmstorage/TmStoreMessage.h index bd6b2def9..5b928569d 100644 --- a/tmstorage/TmStoreMessage.h +++ b/tmstorage/TmStoreMessage.h @@ -1,10 +1,10 @@ #ifndef FRAMEWORK_TMSTORAGE_TMSTOREMESSAGE_H_ #define FRAMEWORK_TMSTORAGE_TMSTOREMESSAGE_H_ -#include -#include -#include -#include +#include "../ipc/CommandMessage.h" +#include "../storagemanager/StorageManagerIF.h" +#include "TmStorePackets.h" +#include "../objectmanager/SystemObjectIF.h" class TmStoreMessage: public CommandMessage { public: static ReturnValue_t setEnableStoringMessage(CommandMessage* cmd, diff --git a/tmstorage/TmStorePackets.h b/tmstorage/TmStorePackets.h index 6eea6f586..e88e741a8 100644 --- a/tmstorage/TmStorePackets.h +++ b/tmstorage/TmStorePackets.h @@ -1,14 +1,14 @@ #ifndef FRAMEWORK_TMSTORAGE_TMSTOREPACKETS_H_ #define FRAMEWORK_TMSTORAGE_TMSTOREPACKETS_H_ -#include -#include -#include -#include -#include -#include -#include -#include +#include "../serialize/SerialFixedArrayListAdapter.h" +#include "../serialize/SerializeElement.h" +#include "../serialize/SerialLinkedListAdapter.h" +#include "../serialize/SerialBufferAdapter.h" +#include "../tmtcpacket/pus/TmPacketMinimal.h" +#include "../timemanager/TimeStamperIF.h" +#include "../timemanager/CCSDSTime.h" +#include "../globalfunctions/timevalOperations.h" class ServiceSubservice: public SerialLinkedListAdapter { public: @@ -32,31 +32,31 @@ public: } uint16_t apid; uint16_t ssc; - ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { - ReturnValue_t result = SerializeAdapter::serialize(&apid, - buffer, size, max_size, bigEndian); + ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const { + ReturnValue_t result = SerializeAdapter::serialize(&apid, + buffer, size, maxSize, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - return SerializeAdapter::serialize(&ssc, buffer, size, - max_size, bigEndian); + return SerializeAdapter::serialize(&ssc, buffer, size, + maxSize, streamEndianness); } - uint32_t getSerializedSize() const { + size_t getSerializedSize() const { return sizeof(apid) + sizeof(ssc); } - ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) { - ReturnValue_t result = SerializeAdapter::deSerialize(&apid, - buffer, size, bigEndian); + ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) { + ReturnValue_t result = SerializeAdapter::deSerialize(&apid, + buffer, size, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - return SerializeAdapter::deSerialize(&ssc, buffer, size, - bigEndian); + return SerializeAdapter::deSerialize(&ssc, buffer, size, + streamEndianness); } }; @@ -218,74 +218,74 @@ public: } - ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { - ReturnValue_t result = AutoSerializeAdapter::serialize(&apid,buffer,size,max_size,bigEndian); + ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const { + ReturnValue_t result = SerializeAdapter::serialize(&apid,buffer,size,maxSize,streamEndianness); if(result!=HasReturnvaluesIF::RETURN_OK){ return result; } - result = AutoSerializeAdapter::serialize(&sourceSequenceCount,buffer,size,max_size,bigEndian); + result = SerializeAdapter::serialize(&sourceSequenceCount,buffer,size,maxSize,streamEndianness); if(result!=HasReturnvaluesIF::RETURN_OK){ return result; } - result = AutoSerializeAdapter::serialize(&serviceType,buffer,size,max_size,bigEndian); + result = SerializeAdapter::serialize(&serviceType,buffer,size,maxSize,streamEndianness); if(result!=HasReturnvaluesIF::RETURN_OK){ return result; } - result = AutoSerializeAdapter::serialize(&serviceSubtype,buffer,size,max_size,bigEndian); + result = SerializeAdapter::serialize(&serviceSubtype,buffer,size,maxSize,streamEndianness); if(result!=HasReturnvaluesIF::RETURN_OK){ return result; } - result = AutoSerializeAdapter::serialize(&subCounter,buffer,size,max_size,bigEndian); + result = SerializeAdapter::serialize(&subCounter,buffer,size,maxSize,streamEndianness); if(result!=HasReturnvaluesIF::RETURN_OK){ return result; } SerialBufferAdapter adapter(rawTimestamp,sizeof(rawTimestamp)); - return adapter.serialize(buffer,size,max_size,bigEndian); + return adapter.serialize(buffer,size,maxSize,streamEndianness); } - uint32_t getSerializedSize() const { + size_t getSerializedSize() const { uint32_t size = 0; - size += AutoSerializeAdapter::getSerializedSize(&apid); - size += AutoSerializeAdapter::getSerializedSize(&sourceSequenceCount); - size += AutoSerializeAdapter::getSerializedSize(&serviceType); - size += AutoSerializeAdapter::getSerializedSize(&serviceSubtype); - size += AutoSerializeAdapter::getSerializedSize(&subCounter); + size += SerializeAdapter::getSerializedSize(&apid); + size += SerializeAdapter::getSerializedSize(&sourceSequenceCount); + size += SerializeAdapter::getSerializedSize(&serviceType); + size += SerializeAdapter::getSerializedSize(&serviceSubtype); + size += SerializeAdapter::getSerializedSize(&subCounter); SerialBufferAdapter adapter(rawTimestamp,sizeof(rawTimestamp)); size += adapter.getSerializedSize(); return size; }; - ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) { - ReturnValue_t result = AutoSerializeAdapter::deSerialize(&apid, buffer, - size, bigEndian); + ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) { + ReturnValue_t result = SerializeAdapter::deSerialize(&apid, buffer, + size, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = AutoSerializeAdapter::deSerialize(&sourceSequenceCount, buffer, - size, bigEndian); + result = SerializeAdapter::deSerialize(&sourceSequenceCount, buffer, + size, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = AutoSerializeAdapter::deSerialize(&serviceType, buffer, size, - bigEndian); + result = SerializeAdapter::deSerialize(&serviceType, buffer, size, + streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = AutoSerializeAdapter::deSerialize(&serviceSubtype, buffer, - size, bigEndian); + result = SerializeAdapter::deSerialize(&serviceSubtype, buffer, + size, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = AutoSerializeAdapter::deSerialize(&subCounter, buffer, size, - bigEndian); + result = SerializeAdapter::deSerialize(&subCounter, buffer, size, + streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } SerialBufferAdapter adapter(rawTimestamp,sizeof(rawTimestamp)); - return adapter.deSerialize(buffer,size,bigEndian); + return adapter.deSerialize(buffer,size,streamEndianness); } private: diff --git a/tmtcpacket/SpacePacket.cpp b/tmtcpacket/SpacePacket.cpp index d9bc08fa6..b8ba27e9a 100644 --- a/tmtcpacket/SpacePacket.cpp +++ b/tmtcpacket/SpacePacket.cpp @@ -1,6 +1,6 @@ -#include -#include -#include +#include "../serviceinterface/ServiceInterfaceStream.h" +#include "ccsds_header.h" +#include "SpacePacket.h" #include SpacePacket::SpacePacket( uint16_t packetDataLength, bool isTelecommand, uint16_t apid, uint16_t sequenceCount ): diff --git a/tmtcpacket/SpacePacket.h b/tmtcpacket/SpacePacket.h index f2d457528..49dd5ae52 100644 --- a/tmtcpacket/SpacePacket.h +++ b/tmtcpacket/SpacePacket.h @@ -1,7 +1,7 @@ #ifndef SPACEPACKET_H_ #define SPACEPACKET_H_ -#include +#include "SpacePacketBase.h" /** * The SpacePacket class is a representation of a simple CCSDS Space Packet diff --git a/tmtcpacket/SpacePacketBase.cpp b/tmtcpacket/SpacePacketBase.cpp index 13c062d8f..a37e024b6 100644 --- a/tmtcpacket/SpacePacketBase.cpp +++ b/tmtcpacket/SpacePacketBase.cpp @@ -1,5 +1,5 @@ -#include -#include +#include "../serviceinterface/ServiceInterfaceStream.h" +#include "SpacePacketBase.h" #include SpacePacketBase::SpacePacketBase( const uint8_t* set_address ) { diff --git a/tmtcpacket/SpacePacketBase.h b/tmtcpacket/SpacePacketBase.h index cc68f714b..ef3ad79d3 100644 --- a/tmtcpacket/SpacePacketBase.h +++ b/tmtcpacket/SpacePacketBase.h @@ -1,7 +1,7 @@ #ifndef SPACEPACKETBASE_H_ #define SPACEPACKETBASE_H_ -#include +#include "ccsds_header.h" /** * \defgroup tmtcpackets Space Packets diff --git a/tmtcpacket/packetmatcher/ApidMatcher.h b/tmtcpacket/packetmatcher/ApidMatcher.h index 1f1949682..4f196ac97 100644 --- a/tmtcpacket/packetmatcher/ApidMatcher.h +++ b/tmtcpacket/packetmatcher/ApidMatcher.h @@ -1,9 +1,9 @@ #ifndef FRAMEWORK_TMTCPACKET_PACKETMATCHER_APIDMATCHER_H_ #define FRAMEWORK_TMTCPACKET_PACKETMATCHER_APIDMATCHER_H_ -#include -#include -#include +#include "../../globalfunctions/matching/SerializeableMatcherIF.h" +#include "../../serialize/SerializeAdapter.h" +#include "../../tmtcpacket/pus/TmPacketMinimal.h" class ApidMatcher: public SerializeableMatcherIF { private: @@ -22,16 +22,16 @@ public: return false; } } - ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { - return SerializeAdapter::serialize(&apid, buffer, size, max_size, bigEndian); + ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const { + return SerializeAdapter::serialize(&apid, buffer, size, maxSize, streamEndianness); } - uint32_t getSerializedSize() const { - return SerializeAdapter::getSerializedSize(&apid); + size_t getSerializedSize() const { + return SerializeAdapter::getSerializedSize(&apid); } - ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) { - return SerializeAdapter::deSerialize(&apid, buffer, size, bigEndian); + ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) { + return SerializeAdapter::deSerialize(&apid, buffer, size, streamEndianness); } }; diff --git a/tmtcpacket/packetmatcher/PacketMatchTree.cpp b/tmtcpacket/packetmatcher/PacketMatchTree.cpp index d8f61ffb8..a45796576 100644 --- a/tmtcpacket/packetmatcher/PacketMatchTree.cpp +++ b/tmtcpacket/packetmatcher/PacketMatchTree.cpp @@ -1,7 +1,7 @@ -#include -#include -#include -#include +#include "ApidMatcher.h" +#include "PacketMatchTree.h" +#include "ServiceMatcher.h" +#include "SubserviceMatcher.h" PacketMatchTree::PacketMatchTree(Node* root) : MatchTree(root, 2), factoryBackend(0, POOL_SIZES, diff --git a/tmtcpacket/packetmatcher/PacketMatchTree.h b/tmtcpacket/packetmatcher/PacketMatchTree.h index a6c0c61e9..86fb087ed 100644 --- a/tmtcpacket/packetmatcher/PacketMatchTree.h +++ b/tmtcpacket/packetmatcher/PacketMatchTree.h @@ -1,10 +1,10 @@ #ifndef FRAMEWORK_TMTCPACKET_PACKETMATCHER_PACKETMATCHTREE_H_ #define FRAMEWORK_TMTCPACKET_PACKETMATCHER_PACKETMATCHTREE_H_ -#include -#include -#include -#include +#include "../../container/PlacementFactory.h" +#include "../../globalfunctions/matching/MatchTree.h" +#include "../../storagemanager/LocalPool.h" +#include "../../tmtcpacket/pus/TmPacketMinimal.h" class PacketMatchTree: public MatchTree, public HasReturnvaluesIF { public: diff --git a/tmtcpacket/packetmatcher/ServiceMatcher.h b/tmtcpacket/packetmatcher/ServiceMatcher.h index 1a6781b40..eba23d755 100644 --- a/tmtcpacket/packetmatcher/ServiceMatcher.h +++ b/tmtcpacket/packetmatcher/ServiceMatcher.h @@ -1,9 +1,9 @@ #ifndef FRAMEWORK_TMTCPACKET_PACKETMATCHER_SERVICEMATCHER_H_ #define FRAMEWORK_TMTCPACKET_PACKETMATCHER_SERVICEMATCHER_H_ -#include -#include -#include +#include "../../globalfunctions/matching/SerializeableMatcherIF.h" +#include "../../serialize/SerializeAdapter.h" +#include "../../tmtcpacket/pus/TmPacketMinimal.h" class ServiceMatcher: public SerializeableMatcherIF { private: @@ -22,16 +22,16 @@ public: return false; } } - ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { - return SerializeAdapter::serialize(&service, buffer, size, max_size, bigEndian); + ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const { + return SerializeAdapter::serialize(&service, buffer, size, maxSize, streamEndianness); } - uint32_t getSerializedSize() const { - return SerializeAdapter::getSerializedSize(&service); + size_t getSerializedSize() const { + return SerializeAdapter::getSerializedSize(&service); } - ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) { - return SerializeAdapter::deSerialize(&service, buffer, size, bigEndian); + ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) { + return SerializeAdapter::deSerialize(&service, buffer, size, streamEndianness); } }; diff --git a/tmtcpacket/packetmatcher/SubserviceMatcher.h b/tmtcpacket/packetmatcher/SubserviceMatcher.h index 1b589b201..a9b6def89 100644 --- a/tmtcpacket/packetmatcher/SubserviceMatcher.h +++ b/tmtcpacket/packetmatcher/SubserviceMatcher.h @@ -1,9 +1,9 @@ #ifndef FRAMEWORK_TMTCPACKET_PACKETMATCHER_SUBSERVICEMATCHER_H_ #define FRAMEWORK_TMTCPACKET_PACKETMATCHER_SUBSERVICEMATCHER_H_ -#include -#include -#include +#include "../../globalfunctions/matching/SerializeableMatcherIF.h" +#include "../../serialize/SerializeAdapter.h" +#include "../../tmtcpacket/pus/TmPacketMinimal.h" class SubServiceMatcher: public SerializeableMatcherIF { public: @@ -20,16 +20,16 @@ public: return false; } } - ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { - return SerializeAdapter::serialize(&subService, buffer, size, max_size, bigEndian); + ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const { + return SerializeAdapter::serialize(&subService, buffer, size, maxSize, streamEndianness); } - uint32_t getSerializedSize() const { - return SerializeAdapter::getSerializedSize(&subService); + size_t getSerializedSize() const { + return SerializeAdapter::getSerializedSize(&subService); } - ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) { - return SerializeAdapter::deSerialize(&subService, buffer, size, bigEndian); + ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) { + return SerializeAdapter::deSerialize(&subService, buffer, size, streamEndianness); } private: uint8_t subService; diff --git a/tmtcpacket/pus/PacketTimestampInterpreterIF.h b/tmtcpacket/pus/PacketTimestampInterpreterIF.h index 6e19381ac..dd0c03285 100644 --- a/tmtcpacket/pus/PacketTimestampInterpreterIF.h +++ b/tmtcpacket/pus/PacketTimestampInterpreterIF.h @@ -1,7 +1,7 @@ #ifndef FRAMEWORK_TMTCPACKET_PUS_PACKETTIMESTAMPINTERPRETERIF_H_ #define FRAMEWORK_TMTCPACKET_PUS_PACKETTIMESTAMPINTERPRETERIF_H_ -#include +#include "../../returnvalues/HasReturnvaluesIF.h" class TmPacketMinimal; class PacketTimestampInterpreterIF { diff --git a/tmtcpacket/pus/TcPacketBase.cpp b/tmtcpacket/pus/TcPacketBase.cpp index 0f3bd52e1..3815eb204 100644 --- a/tmtcpacket/pus/TcPacketBase.cpp +++ b/tmtcpacket/pus/TcPacketBase.cpp @@ -1,6 +1,6 @@ -#include -#include -#include +#include "../../globalfunctions/CRC.h" +#include "../../serviceinterface/ServiceInterfaceStream.h" +#include "TcPacketBase.h" #include TcPacketBase::TcPacketBase(const uint8_t* set_data) : diff --git a/tmtcpacket/pus/TcPacketBase.h b/tmtcpacket/pus/TcPacketBase.h index e6e6bdad4..dd63d2beb 100644 --- a/tmtcpacket/pus/TcPacketBase.h +++ b/tmtcpacket/pus/TcPacketBase.h @@ -1,7 +1,7 @@ #ifndef TCPACKETBASE_H_ #define TCPACKETBASE_H_ -#include +#include "../../tmtcpacket/SpacePacketBase.h" /** * This struct defines a byte-wise structured PUS TC Data Field Header. diff --git a/tmtcpacket/pus/TcPacketStored.cpp b/tmtcpacket/pus/TcPacketStored.cpp index 0187b08f4..216f89c9e 100644 --- a/tmtcpacket/pus/TcPacketStored.cpp +++ b/tmtcpacket/pus/TcPacketStored.cpp @@ -1,6 +1,6 @@ -#include -#include -#include +#include "../../objectmanager/ObjectManagerIF.h" +#include "../../serviceinterface/ServiceInterfaceStream.h" +#include "TcPacketStored.h" #include TcPacketStored::TcPacketStored(store_address_t setAddress) : diff --git a/tmtcpacket/pus/TcPacketStored.h b/tmtcpacket/pus/TcPacketStored.h index c57f0e0fd..2d86f89bf 100644 --- a/tmtcpacket/pus/TcPacketStored.h +++ b/tmtcpacket/pus/TcPacketStored.h @@ -1,8 +1,8 @@ #ifndef TCPACKETSTORED_H_ #define TCPACKETSTORED_H_ -#include -#include +#include "../../storagemanager/StorageManagerIF.h" +#include "TcPacketBase.h" /** * This class generates a ECSS PUS Telecommand packet within a given diff --git a/tmtcpacket/pus/TmPacketBase.cpp b/tmtcpacket/pus/TmPacketBase.cpp index a7bda5afc..3c1a8ca4f 100644 --- a/tmtcpacket/pus/TmPacketBase.cpp +++ b/tmtcpacket/pus/TmPacketBase.cpp @@ -1,8 +1,8 @@ -#include -#include -#include -#include -#include +#include "../../globalfunctions/CRC.h" +#include "../../objectmanager/ObjectManagerIF.h" +#include "../../serviceinterface/ServiceInterfaceStream.h" +#include "TmPacketBase.h" +#include "../../timemanager/CCSDSTime.h" #include TmPacketBase::TmPacketBase(uint8_t* set_data) : diff --git a/tmtcpacket/pus/TmPacketBase.h b/tmtcpacket/pus/TmPacketBase.h index d03beba52..85ae4dacf 100644 --- a/tmtcpacket/pus/TmPacketBase.h +++ b/tmtcpacket/pus/TmPacketBase.h @@ -1,10 +1,10 @@ #ifndef TMPACKETBASE_H_ #define TMPACKETBASE_H_ -#include -#include -#include -#include +#include "../../timemanager/TimeStamperIF.h" +#include "../../tmtcpacket/SpacePacketBase.h" +#include "../../timemanager/Clock.h" +#include "../../objectmanager/SystemObjectIF.h" namespace Factory{ void setStaticFrameworkObjectIds(); diff --git a/tmtcpacket/pus/TmPacketMinimal.cpp b/tmtcpacket/pus/TmPacketMinimal.cpp index 9df0fe5db..18e9dda1e 100644 --- a/tmtcpacket/pus/TmPacketMinimal.cpp +++ b/tmtcpacket/pus/TmPacketMinimal.cpp @@ -1,7 +1,7 @@ -#include +#include "TmPacketMinimal.h" #include #include -#include +#include "PacketTimestampInterpreterIF.h" TmPacketMinimal::TmPacketMinimal(const uint8_t* set_data) : SpacePacketBase( set_data ) { this->tm_data = (TmPacketMinimalPointer*)set_data; diff --git a/tmtcpacket/pus/TmPacketMinimal.h b/tmtcpacket/pus/TmPacketMinimal.h index 7bfe0883c..728acb154 100644 --- a/tmtcpacket/pus/TmPacketMinimal.h +++ b/tmtcpacket/pus/TmPacketMinimal.h @@ -2,8 +2,8 @@ #define FRAMEWORK_TMTCPACKET_PUS_TMPACKETMINIMAL_H_ -#include -#include +#include "../../tmtcpacket/SpacePacketBase.h" +#include "../../returnvalues/HasReturnvaluesIF.h" struct timeval; class PacketTimestampInterpreterIF; diff --git a/tmtcpacket/pus/TmPacketStored.cpp b/tmtcpacket/pus/TmPacketStored.cpp index 0add30a5c..4e4c9434c 100644 --- a/tmtcpacket/pus/TmPacketStored.cpp +++ b/tmtcpacket/pus/TmPacketStored.cpp @@ -1,7 +1,7 @@ -#include -#include -#include -#include +#include "../../objectmanager/ObjectManagerIF.h" +#include "../../serviceinterface/ServiceInterfaceStream.h" +#include "TmPacketStored.h" +#include "../../tmtcservices/TmTcMessage.h" #include TmPacketStored::TmPacketStored(store_address_t setAddress) : @@ -10,14 +10,14 @@ 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) : + uint8_t subservice, uint8_t packetSubcounter, const uint8_t *data, + uint32_t size, const uint8_t *headerData, uint32_t headerSize) : TmPacketBase(NULL) { storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; if (!checkAndSetStore()) { return; } - uint8_t* pData = NULL; + uint8_t *pData = NULL; ReturnValue_t returnValue = store->getFreeElement(&storeAddress, (TmPacketBase::TM_PACKET_MIN_SIZE + size + headerSize), &pData); @@ -34,21 +34,21 @@ TmPacketStored::TmPacketStored(uint16_t apid, uint8_t service, } TmPacketStored::TmPacketStored(uint16_t apid, uint8_t service, - uint8_t subservice, uint8_t packetSubcounter, SerializeIF* content, - SerializeIF* header) : + uint8_t subservice, uint8_t packetSubcounter, SerializeIF *content, + SerializeIF *header) : TmPacketBase(NULL) { storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; if (!checkAndSetStore()) { return; } - uint32_t sourceDataSize = 0; + size_t sourceDataSize = 0; if (content != NULL) { sourceDataSize += content->getSerializedSize(); } if (header != NULL) { sourceDataSize += header->getSerializedSize(); } - uint8_t* p_data = NULL; + uint8_t *p_data = NULL; ReturnValue_t returnValue = store->getFreeElement(&storeAddress, (TmPacketBase::TM_PACKET_MIN_SIZE + sourceDataSize), &p_data); if (returnValue != store->RETURN_OK) { @@ -56,13 +56,15 @@ TmPacketStored::TmPacketStored(uint16_t apid, uint8_t service, } setData(p_data); initializeTmPacket(apid, service, subservice, packetSubcounter); - uint8_t* putDataHere = getSourceData(); - uint32_t size = 0; + uint8_t *putDataHere = getSourceData(); + size_t size = 0; if (header != NULL) { - header->serialize(&putDataHere, &size, sourceDataSize, true); + header->serialize(&putDataHere, &size, sourceDataSize, + SerializeIF::Endianness::BIG); } if (content != NULL) { - content->serialize(&putDataHere, &size, sourceDataSize, true); + content->serialize(&putDataHere, &size, sourceDataSize, + SerializeIF::Endianness::BIG); } setPacketDataLength( sourceDataSize + sizeof(PUSTmDataFieldHeader) + CRC_SIZE - 1); @@ -106,8 +108,8 @@ bool TmPacketStored::checkAndSetStore() { return true; } -StorageManagerIF* TmPacketStored::store = NULL; -InternalErrorReporterIF* TmPacketStored::internalErrorReporter = NULL; +StorageManagerIF *TmPacketStored::store = NULL; +InternalErrorReporterIF *TmPacketStored::internalErrorReporter = NULL; ReturnValue_t TmPacketStored::sendPacket(MessageQueueId_t destination, MessageQueueId_t sentFrom, bool doErrorReporting) { @@ -116,7 +118,8 @@ ReturnValue_t TmPacketStored::sendPacket(MessageQueueId_t destination, return HasReturnvaluesIF::RETURN_FAILED; } TmTcMessage tmMessage(getStoreAddress()); - ReturnValue_t result = MessageQueueSenderIF::sendMessage(destination, &tmMessage, sentFrom); + ReturnValue_t result = MessageQueueSenderIF::sendMessage(destination, + &tmMessage, sentFrom); if (result != HasReturnvaluesIF::RETURN_OK) { deletePacket(); if (doErrorReporting) { diff --git a/tmtcpacket/pus/TmPacketStored.h b/tmtcpacket/pus/TmPacketStored.h index eaa26ce75..8962d343a 100644 --- a/tmtcpacket/pus/TmPacketStored.h +++ b/tmtcpacket/pus/TmPacketStored.h @@ -1,11 +1,11 @@ #ifndef TMPACKETSTORED_H_ #define TMPACKETSTORED_H_ -#include -#include -#include -#include -#include +#include "../../serialize/SerializeIF.h" +#include "../../storagemanager/StorageManagerIF.h" +#include "TmPacketBase.h" +#include "../../internalError/InternalErrorReporterIF.h" +#include "../../ipc/MessageQueueSenderIF.h" /** * This class generates a ECSS PUS Telemetry packet within a given diff --git a/tmtcservices/AcceptsTelecommandsIF.h b/tmtcservices/AcceptsTelecommandsIF.h index 03a57aaeb..76d10a592 100644 --- a/tmtcservices/AcceptsTelecommandsIF.h +++ b/tmtcservices/AcceptsTelecommandsIF.h @@ -1,7 +1,7 @@ #ifndef ACCEPTSTELECOMMANDSIF_H_ #define ACCEPTSTELECOMMANDSIF_H_ -#include +#include "../ipc/MessageQueueSenderIF.h" /** * @brief This interface is implemented by classes that are sinks for diff --git a/tmtcservices/AcceptsTelemetryIF.h b/tmtcservices/AcceptsTelemetryIF.h index 8c00b5c60..2325dbe08 100644 --- a/tmtcservices/AcceptsTelemetryIF.h +++ b/tmtcservices/AcceptsTelemetryIF.h @@ -1,7 +1,7 @@ #ifndef ACCEPTSTELEMETRYIF_H_ #define ACCEPTSTELEMETRYIF_H_ -#include +#include "../ipc/MessageQueueSenderIF.h" /** * @brief This interface is implemented by classes that are sinks for * Telemetry. diff --git a/tmtcservices/AcceptsVerifyMessageIF.h b/tmtcservices/AcceptsVerifyMessageIF.h index fe8bb2886..c9318ab01 100644 --- a/tmtcservices/AcceptsVerifyMessageIF.h +++ b/tmtcservices/AcceptsVerifyMessageIF.h @@ -1,7 +1,7 @@ #ifndef ACCEPTSVERIFICATIONMESSAGEIF_H_ #define ACCEPTSVERIFICATIONMESSAGEIF_H_ -#include +#include "../ipc/MessageQueueSenderIF.h" class AcceptsVerifyMessageIF { public: diff --git a/tmtcservices/CommandingServiceBase.cpp b/tmtcservices/CommandingServiceBase.cpp index d70b90428..0b33e3aad 100644 --- a/tmtcservices/CommandingServiceBase.cpp +++ b/tmtcservices/CommandingServiceBase.cpp @@ -1,26 +1,35 @@ -/* - * CommandingServiceBase.cpp - * - * Created on: 28.08.2019 - * Author: gaisser - */ +#include "../tcdistribution/PUSDistributorIF.h" +#include "AcceptsTelemetryIF.h" +#include "../objectmanager/ObjectManagerIF.h" -#include +#include "CommandingServiceBase.h" +#include "TmTcMessage.h" +#include "../ipc/QueueFactory.h" +#include "../tmtcpacket/pus/TcPacketStored.h" +#include "../tmtcpacket/pus/TmPacketStored.h" + +object_id_t CommandingServiceBase::defaultPacketSource = objects::NO_OBJECT; +object_id_t CommandingServiceBase::defaultPacketDestination = objects::NO_OBJECT; CommandingServiceBase::CommandingServiceBase(object_id_t setObjectId, uint16_t apid, uint8_t service, uint8_t numberOfParallelCommands, - uint16_t commandTimeout_seconds, object_id_t setPacketSource, - object_id_t setPacketDestination, size_t queueDepth) : - SystemObject(setObjectId), apid(apid), service(service), timeout_seconds( - commandTimeout_seconds), tmPacketCounter(0), IPCStore(NULL), TCStore( - NULL), commandQueue(NULL), requestQueue(NULL), commandMap( - numberOfParallelCommands), failureParameter1(0), failureParameter2( - 0), packetSource(setPacketSource), packetDestination( - setPacketDestination),executingTask(NULL) { + uint16_t commandTimeoutSeconds, size_t queueDepth) : + SystemObject(setObjectId), apid(apid), service(service), + timeoutSeconds(commandTimeoutSeconds), + commandMap(numberOfParallelCommands) { commandQueue = QueueFactory::instance()->createMessageQueue(queueDepth); requestQueue = QueueFactory::instance()->createMessageQueue(queueDepth); } +void CommandingServiceBase::setPacketSource(object_id_t packetSource) { + this->packetSource = packetSource; +} + +void CommandingServiceBase::setPacketDestination( + object_id_t packetDestination) { + this->packetDestination = packetDestination; +} + CommandingServiceBase::~CommandingServiceBase() { QueueFactory::instance()->deleteMessageQueue(commandQueue); @@ -53,12 +62,22 @@ ReturnValue_t CommandingServiceBase::initialize() { return result; } + if(packetDestination == objects::NO_OBJECT) { + packetDestination = defaultPacketDestination; + } AcceptsTelemetryIF* packetForwarding = objectManager->get(packetDestination); + + if(packetSource == objects::NO_OBJECT) { + packetSource = defaultPacketSource; + } PUSDistributorIF* distributor = objectManager->get( packetSource); - if ((packetForwarding == NULL) && (distributor == NULL)) { - return RETURN_FAILED; + + if (packetForwarding == nullptr or distributor == nullptr) { + sif::error << "CommandingServiceBase::intialize: Packet source or " + "packet destination invalid!" << std::endl; + return ObjectManagerIF::CHILD_INIT_FAILED; } distributor->registerService(this); @@ -68,8 +87,10 @@ ReturnValue_t CommandingServiceBase::initialize() { IPCStore = objectManager->get(objects::IPC_STORE); TCStore = objectManager->get(objects::TC_STORE); - if ((IPCStore == NULL) || (TCStore == NULL)) { - return RETURN_FAILED; + if (IPCStore == nullptr or TCStore == nullptr) { + sif::error << "CommandingServiceBase::intialize: IPC store or TC store " + "not initialized yet!" << std::endl; + return ObjectManagerIF::CHILD_INIT_FAILED; } return RETURN_OK; @@ -77,97 +98,126 @@ ReturnValue_t CommandingServiceBase::initialize() { } void CommandingServiceBase::handleCommandQueue() { - CommandMessage reply, nextCommand; - ReturnValue_t result, sendResult = RETURN_OK; - bool isStep = false; + CommandMessage reply; + ReturnValue_t result = RETURN_FAILED; for (result = commandQueue->receiveMessage(&reply); result == RETURN_OK; result = commandQueue->receiveMessage(&reply)) { - isStep = false; - typename FixedMap::Iterator iter; - if (reply.getSender() == MessageQueueIF::NO_QUEUE) { - handleUnrequestedReply(&reply); - continue; - } - if ((iter = commandMap.find(reply.getSender())) == commandMap.end()) { - handleUnrequestedReply(&reply); - continue; - } - nextCommand.setCommand(CommandMessage::CMD_NONE); - result = handleReply(&reply, iter->command, &iter->state, &nextCommand, - iter->objectId, &isStep); - switch (result) { - case EXECUTION_COMPLETE: - case RETURN_OK: - case NO_STEP_MESSAGE: - iter->command = nextCommand.getCommand(); - if (nextCommand.getCommand() != CommandMessage::CMD_NONE) { - sendResult = commandQueue->sendMessage(reply.getSender(), - &nextCommand); - } - if (sendResult == RETURN_OK) { - if (isStep) { - if (result != NO_STEP_MESSAGE) { - verificationReporter.sendSuccessReport( - TC_VERIFY::PROGRESS_SUCCESS, - iter->tcInfo.ackFlags, iter->tcInfo.tcPacketId, - iter->tcInfo.tcSequenceControl, ++iter->step); - } - } else { - verificationReporter.sendSuccessReport( - TC_VERIFY::COMPLETION_SUCCESS, - iter->tcInfo.ackFlags, iter->tcInfo.tcPacketId, - iter->tcInfo.tcSequenceControl, 0); - checkAndExecuteFifo(&iter); - } - } else { - if (isStep) { - nextCommand.clearCommandMessage(); - verificationReporter.sendFailureReport( - TC_VERIFY::PROGRESS_FAILURE, iter->tcInfo.ackFlags, - iter->tcInfo.tcPacketId, - iter->tcInfo.tcSequenceControl, sendResult, - ++iter->step, failureParameter1, failureParameter2); - } else { - nextCommand.clearCommandMessage(); - verificationReporter.sendFailureReport( - TC_VERIFY::COMPLETION_FAILURE, - iter->tcInfo.ackFlags, iter->tcInfo.tcPacketId, - iter->tcInfo.tcSequenceControl, sendResult, 0, - failureParameter1, failureParameter2); - } - failureParameter1 = 0; - failureParameter2 = 0; - checkAndExecuteFifo(&iter); - } - break; - case INVALID_REPLY: - //might be just an unrequested reply at a bad moment - handleUnrequestedReply(&reply); - break; - default: - if (isStep) { - verificationReporter.sendFailureReport( - TC_VERIFY::PROGRESS_FAILURE, iter->tcInfo.ackFlags, - iter->tcInfo.tcPacketId, iter->tcInfo.tcSequenceControl, - result, ++iter->step, failureParameter1, - failureParameter2); - } else { - verificationReporter.sendFailureReport( - TC_VERIFY::COMPLETION_FAILURE, iter->tcInfo.ackFlags, - iter->tcInfo.tcPacketId, iter->tcInfo.tcSequenceControl, - result, 0, failureParameter1, failureParameter2); - } - failureParameter1 = 0; - failureParameter2 = 0; - checkAndExecuteFifo(&iter); - break; - } - + handleCommandMessage(&reply); } } +void CommandingServiceBase::handleCommandMessage(CommandMessage* reply) { + bool isStep = false; + CommandMessage nextCommand; + CommandMapIter iter = commandMap.find(reply->getSender()); + + // handle unrequested reply first + if (reply->getSender() == MessageQueueIF::NO_QUEUE or + iter == commandMap.end()) { + handleUnrequestedReply(reply); + return; + } + nextCommand.setCommand(CommandMessage::CMD_NONE); + + + // Implemented by child class, specifies what to do with reply. + ReturnValue_t result = handleReply(reply, iter->command, &iter->state, + &nextCommand, iter->objectId, &isStep); + + /* If the child implementation does not implement special handling for + * rejected replies (RETURN_FAILED or INVALID_REPLY is returned), a + * failure verification will be generated with the reason as the + * return code and the initial command as failure parameter 1 */ + if((reply->getCommand() == CommandMessage::REPLY_REJECTED) and + (result == RETURN_FAILED or result == INVALID_REPLY)) { + result = reply->getReplyRejectedReason(); + failureParameter1 = iter->command; + } + + switch (result) { + case EXECUTION_COMPLETE: + case RETURN_OK: + case NO_STEP_MESSAGE: + // handle result of reply handler implemented by developer. + handleReplyHandlerResult(result, iter, &nextCommand, reply, isStep); + break; + case INVALID_REPLY: + //might be just an unrequested reply at a bad moment + handleUnrequestedReply(reply); + break; + default: + if (isStep) { + verificationReporter.sendFailureReport( + TC_VERIFY::PROGRESS_FAILURE, iter->tcInfo.ackFlags, + iter->tcInfo.tcPacketId, iter->tcInfo.tcSequenceControl, + result, ++iter->step, failureParameter1, + failureParameter2); + } else { + verificationReporter.sendFailureReport( + TC_VERIFY::COMPLETION_FAILURE, iter->tcInfo.ackFlags, + iter->tcInfo.tcPacketId, iter->tcInfo.tcSequenceControl, + result, 0, failureParameter1, failureParameter2); + } + failureParameter1 = 0; + failureParameter2 = 0; + checkAndExecuteFifo(iter); + break; + } + +} + +void CommandingServiceBase::handleReplyHandlerResult(ReturnValue_t result, + CommandMapIter iter, CommandMessage* nextCommand, + CommandMessage* reply, bool& isStep) { + iter->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 + // sendResult as RETURN_OK + ReturnValue_t sendResult = RETURN_OK; + if (nextCommand->getCommand() != CommandMessage::CMD_NONE) { + sendResult = commandQueue->sendMessage(reply->getSender(), + nextCommand); + } + + if (sendResult == RETURN_OK) { + if (isStep and result != NO_STEP_MESSAGE) { + verificationReporter.sendSuccessReport( + TC_VERIFY::PROGRESS_SUCCESS, + iter->tcInfo.ackFlags, iter->tcInfo.tcPacketId, + iter->tcInfo.tcSequenceControl, ++iter->step); + } + else { + verificationReporter.sendSuccessReport( + TC_VERIFY::COMPLETION_SUCCESS, + iter->tcInfo.ackFlags, iter->tcInfo.tcPacketId, + iter->tcInfo.tcSequenceControl, 0); + checkAndExecuteFifo(iter); + } + } + else { + if (isStep) { + nextCommand->clearCommandMessage(); + verificationReporter.sendFailureReport( + TC_VERIFY::PROGRESS_FAILURE, iter->tcInfo.ackFlags, + iter->tcInfo.tcPacketId, + iter->tcInfo.tcSequenceControl, sendResult, + ++iter->step, failureParameter1, failureParameter2); + } else { + nextCommand->clearCommandMessage(); + verificationReporter.sendFailureReport( + TC_VERIFY::COMPLETION_FAILURE, + iter->tcInfo.ackFlags, iter->tcInfo.tcPacketId, + iter->tcInfo.tcSequenceControl, sendResult, 0, + failureParameter1, failureParameter2); + } + failureParameter1 = 0; + failureParameter2 = 0; + checkAndExecuteFifo(iter); + } +} + void CommandingServiceBase::handleRequestQueue() { TmTcMessage message; ReturnValue_t result; @@ -181,7 +231,7 @@ void CommandingServiceBase::handleRequestQueue() { packet.setStoreAddress(address); if ((packet.getSubService() == 0) - || (isValidSubservice(packet.getSubService()) != RETURN_OK)) { + or (isValidSubservice(packet.getSubService()) != RETURN_OK)) { rejectPacket(TC_VERIFY::START_FAILURE, &packet, INVALID_SUBSERVICE); continue; } @@ -194,8 +244,7 @@ void CommandingServiceBase::handleRequestQueue() { } //Is a command already active for the target object? - typename FixedMap::Iterator iter; + CommandMapIter iter; iter = commandMap.find(queue); if (iter != commandMap.end()) { @@ -210,7 +259,7 @@ void CommandingServiceBase::handleRequestQueue() { if (result != RETURN_OK) { rejectPacket(TC_VERIFY::START_FAILURE, &packet, BUSY); } else { - startExecution(&packet, &iter); + startExecution(&packet, iter); } } @@ -218,9 +267,9 @@ void CommandingServiceBase::handleRequestQueue() { } -void CommandingServiceBase::sendTmPacket(uint8_t subservice, - const uint8_t* data, uint32_t dataLen, const uint8_t* headerData, - uint32_t headerSize) { +ReturnValue_t CommandingServiceBase::sendTmPacket(uint8_t subservice, + const uint8_t* data, size_t dataLen, const uint8_t* headerData, + size_t headerSize) { TmPacketStored tmPacketStored(this->apid, this->service, subservice, this->tmPacketCounter, data, dataLen, headerData, headerSize); ReturnValue_t result = tmPacketStored.sendPacket( @@ -228,79 +277,79 @@ void CommandingServiceBase::sendTmPacket(uint8_t subservice, if (result == HasReturnvaluesIF::RETURN_OK) { this->tmPacketCounter++; } + return result; } -void CommandingServiceBase::sendTmPacket(uint8_t subservice, - object_id_t objectId, const uint8_t *data, uint32_t dataLen) { - uint8_t buffer[sizeof(object_id_t)]; - uint8_t* pBuffer = buffer; - uint32_t size = 0; - SerializeAdapter::serialize(&objectId, &pBuffer, &size, - sizeof(object_id_t), true); - TmPacketStored tmPacketStored(this->apid, this->service, subservice, - this->tmPacketCounter, data, dataLen, buffer, size); - ReturnValue_t result = tmPacketStored.sendPacket( - requestQueue->getDefaultDestination(), requestQueue->getId()); - if (result == HasReturnvaluesIF::RETURN_OK) { - this->tmPacketCounter++; - } - +ReturnValue_t CommandingServiceBase::sendTmPacket(uint8_t subservice, + object_id_t objectId, const uint8_t *data, size_t dataLen) { + uint8_t buffer[sizeof(object_id_t)]; + uint8_t* pBuffer = buffer; + size_t size = 0; + SerializeAdapter::serialize(&objectId, &pBuffer, &size, + sizeof(object_id_t), SerializeIF::Endianness::BIG); + TmPacketStored tmPacketStored(this->apid, this->service, subservice, + this->tmPacketCounter, data, dataLen, buffer, size); + ReturnValue_t result = tmPacketStored.sendPacket( + requestQueue->getDefaultDestination(), requestQueue->getId()); + if (result == HasReturnvaluesIF::RETURN_OK) { + this->tmPacketCounter++; + } + return result; } -void CommandingServiceBase::sendTmPacket(uint8_t subservice, - SerializeIF* content, SerializeIF* header) { - TmPacketStored tmPacketStored(this->apid, this->service, subservice, - this->tmPacketCounter, content, header); - ReturnValue_t result = tmPacketStored.sendPacket( - requestQueue->getDefaultDestination(), requestQueue->getId()); - if (result == HasReturnvaluesIF::RETURN_OK) { - this->tmPacketCounter++; - } +ReturnValue_t CommandingServiceBase::sendTmPacket(uint8_t subservice, + SerializeIF* content, SerializeIF* header) { + TmPacketStored tmPacketStored(this->apid, this->service, subservice, + this->tmPacketCounter, content, header); + ReturnValue_t result = tmPacketStored.sendPacket( + requestQueue->getDefaultDestination(), requestQueue->getId()); + if (result == HasReturnvaluesIF::RETURN_OK) { + this->tmPacketCounter++; + } + return result; } -void CommandingServiceBase::startExecution( - TcPacketStored *storedPacket, - typename FixedMap::Iterator *iter) { - ReturnValue_t result, sendResult = RETURN_OK; - CommandMessage message; - (*iter)->subservice = storedPacket->getSubService(); - result = prepareCommand(&message, (*iter)->subservice, - storedPacket->getApplicationData(), - storedPacket->getApplicationDataSize(), &(*iter)->state, - (*iter)->objectId); +void CommandingServiceBase::startExecution(TcPacketStored *storedPacket, + CommandMapIter iter) { + ReturnValue_t result = RETURN_OK; + CommandMessage command; + iter->subservice = storedPacket->getSubService(); + result = prepareCommand(&command, iter->subservice, + storedPacket->getApplicationData(), + storedPacket->getApplicationDataSize(), &iter->state, + iter->objectId); + ReturnValue_t sendResult = RETURN_OK; switch (result) { case RETURN_OK: - if (message.getCommand() != CommandMessage::CMD_NONE) { - sendResult = commandQueue->sendMessage((*iter).value->first, - &message); + if (command.getCommand() != CommandMessage::CMD_NONE) { + sendResult = commandQueue->sendMessage(iter.value->first, + &command); } if (sendResult == RETURN_OK) { - Clock::getUptime(&(*iter)->uptimeOfStart); - (*iter)->step = 0; -// (*iter)->state = 0; - (*iter)->subservice = storedPacket->getSubService(); - (*iter)->command = message.getCommand(); - (*iter)->tcInfo.ackFlags = storedPacket->getAcknowledgeFlags(); - (*iter)->tcInfo.tcPacketId = storedPacket->getPacketId(); - (*iter)->tcInfo.tcSequenceControl = + 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 = storedPacket->getPacketSequenceControl(); acceptPacket(TC_VERIFY::START_SUCCESS, storedPacket); } else { - message.clearCommandMessage(); + command.clearCommandMessage(); rejectPacket(TC_VERIFY::START_FAILURE, storedPacket, sendResult); checkAndExecuteFifo(iter); } break; case EXECUTION_COMPLETE: - if (message.getCommand() != CommandMessage::CMD_NONE) { + if (command.getCommand() != CommandMessage::CMD_NONE) { //Fire-and-forget command. - sendResult = commandQueue->sendMessage((*iter).value->first, - &message); + sendResult = commandQueue->sendMessage(iter.value->first, + &command); } if (sendResult == RETURN_OK) { verificationReporter.sendSuccessReport(TC_VERIFY::START_SUCCESS, @@ -308,7 +357,7 @@ void CommandingServiceBase::startExecution( acceptPacket(TC_VERIFY::COMPLETION_SUCCESS, storedPacket); checkAndExecuteFifo(iter); } else { - message.clearCommandMessage(); + command.clearCommandMessage(); rejectPacket(TC_VERIFY::START_FAILURE, storedPacket, sendResult); checkAndExecuteFifo(iter); } @@ -335,12 +384,10 @@ void CommandingServiceBase::acceptPacket(uint8_t reportId, } -void CommandingServiceBase::checkAndExecuteFifo( - typename FixedMap::Iterator *iter) { +void CommandingServiceBase::checkAndExecuteFifo(CommandMapIter iter) { store_address_t address; - if ((*iter)->fifo.retrieve(&address) != RETURN_OK) { - commandMap.erase(iter); + if (iter->fifo.retrieve(&address) != RETURN_OK) { + commandMap.erase(&iter); } else { TcPacketStored newPacket(address); startExecution(&newPacket, iter); @@ -348,8 +395,7 @@ void CommandingServiceBase::checkAndExecuteFifo( } -void CommandingServiceBase::handleUnrequestedReply( - CommandMessage* reply) { +void CommandingServiceBase::handleUnrequestedReply(CommandMessage* reply) { reply->clearCommandMessage(); } @@ -364,18 +410,18 @@ MessageQueueId_t CommandingServiceBase::getCommandQueue() { void CommandingServiceBase::checkTimeout() { uint32_t uptime; Clock::getUptime(&uptime); - typename FixedMap::Iterator iter; + CommandMapIter iter; for (iter = commandMap.begin(); iter != commandMap.end(); ++iter) { - if ((iter->uptimeOfStart + (timeout_seconds * 1000)) < uptime) { + if ((iter->uptimeOfStart + (timeoutSeconds * 1000)) < uptime) { verificationReporter.sendFailureReport( TC_VERIFY::COMPLETION_FAILURE, iter->tcInfo.ackFlags, iter->tcInfo.tcPacketId, iter->tcInfo.tcSequenceControl, TIMEOUT); - checkAndExecuteFifo(&iter); + checkAndExecuteFifo(iter); } } } - - +void CommandingServiceBase::setTaskIF(PeriodicTaskIF* task_) { + executingTask = task_; +} diff --git a/tmtcservices/CommandingServiceBase.h b/tmtcservices/CommandingServiceBase.h index bf2e82423..c0453f2f2 100644 --- a/tmtcservices/CommandingServiceBase.h +++ b/tmtcservices/CommandingServiceBase.h @@ -1,40 +1,43 @@ -#ifndef COMMANDINGSERVICEBASE_H_ -#define COMMANDINGSERVICEBASE_H_ +#ifndef FRAMEWORK_TMTCSERVICES_COMMANDINGSERVICEBASE_H_ +#define FRAMEWORK_TMTCSERVICES_COMMANDINGSERVICEBASE_H_ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "../objectmanager/SystemObject.h" +#include "../storagemanager/StorageManagerIF.h" +#include "../tasks/ExecutableObjectIF.h" +#include "../ipc/MessageQueueIF.h" +#include "AcceptsTelecommandsIF.h" + +#include "VerificationReporter.h" +#include "../ipc/CommandMessage.h" +#include "../container/FixedMap.h" +#include "../container/FIFO.h" +#include "../serialize/SerializeIF.h" + +class TcPacketStored; + +namespace Factory{ +void setStaticFrameworkObjectIds(); +} /** - * \brief This class is the basis for all PUS Services, which have to relay Telecommands to software bus. + * @brief This class is the basis for all PUS Services, which have to + * relay Telecommands to software bus. * - * It manages Telecommand reception and the generation of Verification Reports like PUSServiceBase. - * Every class that inherits from this abstract class has to implement four adaption points: + * It manages Telecommand reception and the generation of Verification Reports + * similar to PusServiceBase. This class is used if a telecommand can't be + * handled immediately and must be relayed to the internal software bus. * - isValidSubservice * - getMessageQueueAndObject * - prepareCommand * - handleReply - * \ingroup pus_services + * @author gaisser + * @ingroup pus_services */ class CommandingServiceBase: public SystemObject, public AcceptsTelecommandsIF, public ExecutableObjectIF, public HasReturnvaluesIF { + friend void (Factory::setStaticFrameworkObjectIds)(); public: static const uint8_t INTERFACE_ID = CLASS_ID::COMMAND_SERVICE_BASE; static const ReturnValue_t EXECUTION_COMPLETE = MAKE_RETURN_CODE(1); @@ -59,10 +62,24 @@ public: */ CommandingServiceBase(object_id_t setObjectId, uint16_t apid, uint8_t service, uint8_t numberOfParallelCommands, - uint16_t commandTimeout_seconds, object_id_t setPacketSource, - object_id_t setPacketDestination, size_t queueDepth = 20); + uint16_t commandTimeoutSeconds, size_t queueDepth = 20); virtual ~CommandingServiceBase(); + /** + * This setter can be used to set the packet source individually instead + * of using the default static framework ID set in the factory. + * This should be called at object initialization and not during run-time! + * @param packetSource + */ + void setPacketSource(object_id_t packetSource); + /** + * This setter can be used to set the packet destination individually + * instead of using the default static framework ID set in the factory. + * This should be called at object initialization and not during run-time! + * @param packetDestination + */ + void setPacketDestination(object_id_t packetDestination); + /*** * This is the periodically called function. * Handle request queue for external commands. @@ -70,7 +87,7 @@ public: * @param opCode is unused here at the moment * @return RETURN_OK */ - virtual ReturnValue_t performOperation(uint8_t opCode); + virtual ReturnValue_t performOperation(uint8_t opCode) override; virtual uint16_t getIdentifier(); @@ -91,82 +108,110 @@ public: */ virtual MessageQueueId_t getCommandQueue(); - virtual ReturnValue_t initialize(); + virtual ReturnValue_t initialize() 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 + * @param task Pointer to the taskIF of this task */ - virtual void setTaskIF(PeriodicTaskIF* task_){ - executingTask = task_; - }; + virtual void setTaskIF(PeriodicTaskIF* task) override; protected: /** * Check the target subservice * @param subservice[in] - * @return -@c RETURN_OK on success - * -@c INVALID_SUBSERVICE if service is not known + * @return + * -@c RETURN_OK Subservice valid, continue message handling + * -@c INVALID_SUBSERVICE if service is not known, rejects packet. */ virtual ReturnValue_t isValidSubservice(uint8_t subservice) = 0; /** - * Once a TC Request is valid, the existence of the destination and its target interface is checked and retrieved. - * The target message queue ID can then be acquired by using the target interface. + * Once a TC Request is valid, the existence of the destination and its + * target interface is checked and retrieved. The target message queue ID + * can then be acquired by using the target interface. * @param subservice * @param tcData Application Data of TC Packet * @param tcDataLen * @param id MessageQueue ID is stored here * @param objectId Object ID is extracted and stored here - * @return - @c RETURN_OK on success - * - @c RETURN_FAILED - * - @c CSB or implementation specific return codes + * @return + * - @c RETURN_OK Cotinue message handling + * - @c RETURN_FAILED Reject the packet and generates a start failure + * verification */ virtual ReturnValue_t getMessageQueueAndObject(uint8_t subservice, - const uint8_t *tcData, uint32_t tcDataLen, MessageQueueId_t *id, + const uint8_t *tcData, size_t tcDataLen, MessageQueueId_t *id, object_id_t *objectId) = 0; /** - * After the Message Queue and Object ID are determined, - * the command is prepared by using an implementation specific CommandMessage type - * which is sent to the target object. - * It contains all necessary information for the device to execute telecommands. - * @param message[out] message to be sent to the object - * @param subservice[in] Subservice of the current communication - * @param tcData Additional data of the command - * @param tcDataLen Length of the additional data - * @param state[out] Setable state of the communication + * After the Message Queue and Object ID are determined, the command is + * prepared by using an implementation specific CommandMessage type + * which is sent to the target object. It contains all necessary information + * for the device to execute telecommands. + * @param message [out] message which can be set and is sent to the object + * @param subservice Subservice of the current communication + * @param tcData Application data of command + * @param tcDataLen Application data length + * @param state [out/in] Setable state of the communication. + * communication * @param objectId Target object ID - * @return - @c RETURN_OK on success - * - @c EXECUTION_COMPLETE if exectuin is finished - * - any other return code will be part of (1,4) start failure + * @return + * - @c RETURN_OK to generate a verification start message + * - @c EXECUTION_COMPELTE Fire-and-forget command. Generate a completion + * verification message. + * - @c Anything else rejects the packets and generates a start failure + * verification. */ - virtual ReturnValue_t prepareCommand(CommandMessage *message, - uint8_t subservice, const uint8_t *tcData, uint32_t tcDataLen, + virtual ReturnValue_t prepareCommand(CommandMessage* message, + uint8_t subservice, const uint8_t *tcData, size_t tcDataLen, uint32_t *state, object_id_t objectId) = 0; /** - * This function is responsible for the communication between the Command Service Base - * and the respective PUS Commanding Service once the execution has started. - * The PUS Commanding Service receives replies from the target device and forwards them by calling this function. - * There are different translations of these replies to specify how the Command Service proceeds. - * @param reply Command Message which contains information about the command - * @param previousCommand Command_t of last command - * @param state state of the communication - * @param optionalNextCommand[out] An optional next command which can be set in this function + * This function is implemented by child services to specify how replies + * to a command from another software component are handled. + * @param reply + * This is the reply in form of a generic read-only command message. + * @param previousCommand + * Command_t of related command + * @param state [out/in] + * Additional parameter which can be used to pass state information. + * State of the communication + * @param optionalNextCommand [out] + * An optional next command which can be set in this function * @param objectId Source object ID * @param isStep Flag value to mark steps of command execution - * @return - @c RETURN_OK, @c EXECUTION_COMPLETE or @c NO_STEP_MESSAGE to generate TC verification success - * - @c INVALID_REPLY can handle unrequested replies - * - Anything else triggers a TC verification failure + * @return + * - @c RETURN_OK, @c EXECUTION_COMPLETE or @c NO_STEP_MESSAGE to + * generate TC verification success + * - @c INVALID_REPLY Calls handleUnrequestedReply + * - Anything else triggers a TC verification failure. If RETURN_FAILED or + * INVALID_REPLY is returned and the command ID is + * CommandMessage::REPLY_REJECTED, a failure verification message with + * the reason as the error parameter and the initial command as + * failure parameter 1 is generated. */ - virtual ReturnValue_t handleReply(const CommandMessage *reply, + virtual ReturnValue_t handleReply(const CommandMessage* reply, Command_t previousCommand, uint32_t *state, - CommandMessage *optionalNextCommand, object_id_t objectId, + CommandMessage* optionalNextCommand, object_id_t objectId, bool *isStep) = 0; + /** + * This function can be overidden to handle unrequested reply, + * when the reply sender ID is unknown or is not found is the command map. + * The default implementation will clear the command message and all + * its contents. + * @param reply + * Reply which is non-const so the default implementation can clear the + * message. + */ + virtual void handleUnrequestedReply(CommandMessage* reply); + + virtual void doPeriodicOperation(); + + struct CommandInfo { struct tcInfo { uint8_t ackFlags; @@ -182,84 +227,92 @@ protected: FIFO fifo; }; + using CommandMapIter = FixedMap::Iterator; + const uint16_t apid; const uint8_t service; - const uint16_t timeout_seconds; + const uint16_t timeoutSeconds; - uint8_t tmPacketCounter; + uint8_t tmPacketCounter = 0; - StorageManagerIF *IPCStore; + StorageManagerIF *IPCStore = nullptr; - StorageManagerIF *TCStore; + StorageManagerIF *TCStore = nullptr; - MessageQueueIF* commandQueue; + MessageQueueIF* commandQueue = nullptr; - MessageQueueIF* requestQueue; + MessageQueueIF* requestQueue = nullptr; VerificationReporter verificationReporter; FixedMap commandMap; - uint32_t failureParameter1; //!< May be set be children to return a more precise failure condition. - uint32_t failureParameter2; //!< May be set be children to return a more precise failure condition. + /* May be set be children to return a more precise failure condition. */ + uint32_t failureParameter1 = 0; + uint32_t failureParameter2 = 0; - object_id_t packetSource; - - object_id_t packetDestination; + static object_id_t defaultPacketSource; + object_id_t packetSource = objects::NO_OBJECT; + static object_id_t defaultPacketDestination; + object_id_t packetDestination = objects::NO_OBJECT; /** - * Pointer to the task which executes this component, is invalid before setTaskIF was called. + * Pointer to the task which executes this component, + * is invalid before setTaskIF was called. */ - PeriodicTaskIF* executingTask; + PeriodicTaskIF* executingTask = nullptr; /** - * Send TM data from pointer to data. If a header is supplied it is added before data + * @brief Send TM data from pointer to data. + * If a header is supplied it is added before data * @param subservice Number of subservice * @param data Pointer to the data in the Packet * @param dataLen Lenght of data in the Packet * @param headerData HeaderData will be placed before data * @param headerSize Size of HeaderData */ - void sendTmPacket(uint8_t subservice, const uint8_t *data, uint32_t dataLen, - const uint8_t* headerData = NULL, uint32_t headerSize = 0); + ReturnValue_t sendTmPacket(uint8_t subservice, const uint8_t *data, + size_t dataLen, const uint8_t* headerData = nullptr, + size_t headerSize = 0); /** - * To send TM packets of objects that still need to be serialized and consist of an object ID with appended data + * @brief To send TM packets of objects that still need to be serialized + * and consist of an object ID with appended data. * @param subservice Number of subservice * @param objectId ObjectId is placed before data * @param data Data to append to the packet * @param dataLen Length of Data */ - void sendTmPacket(uint8_t subservice, object_id_t objectId, - const uint8_t *data, uint32_t dataLen); + ReturnValue_t sendTmPacket(uint8_t subservice, object_id_t objectId, + const uint8_t *data, size_t dataLen); /** - * To send packets has data which is in form of a SerializeIF or Adapters implementing it + * @brief To send packets which are contained inside a class implementing + * SerializeIF. * @param subservice Number of subservice * @param content This is a pointer to the serialized packet * @param header Serialize IF header which will be placed before content */ - void sendTmPacket(uint8_t subservice, SerializeIF* content, - SerializeIF* header = NULL); + ReturnValue_t sendTmPacket(uint8_t subservice, SerializeIF* content, + SerializeIF* header = nullptr); - virtual void handleUnrequestedReply(CommandMessage *reply); - - virtual void doPeriodicOperation(); - - void checkAndExecuteFifo( - typename FixedMap::Iterator *iter); + void checkAndExecuteFifo(CommandMapIter iter); private: /** * This method handles internal execution of a command, - * once it has been started by @sa{startExecution()} in the Request Queue handler. - * It handles replies generated by the devices and relayed by the specific service implementation. - * This means that it determines further course of action depending on the return values specified - * in the service implementation. + * once it has been started by @sa{startExecution()} in the request + * queue handler. + * It handles replies generated by the devices and relayed by the specific + * service implementation. This means that it determines further course of + * action depending on the return values specified in the service + * implementation. * This includes the generation of TC verification messages. Note that - * the static framework object ID @c VerificationReporter::messageReceiver needs to be set. + * the static framework object ID @c VerificationReporter::messageReceiver + * needs to be set. * - TM[1,5] Step Successs * - TM[1,6] Step Failure * - TM[1,7] Completion Success @@ -268,10 +321,13 @@ private: void handleCommandQueue(); /** + * @brief Handler function for request queue + * @details * Sequence of request queue handling: * isValidSubservice -> getMessageQueueAndObject -> startExecution - * Generates Start Success Reports TM[1,3] in subfunction @sa{startExecution()} - * or Start Failure Report TM[1,4] by using the TC Verification Service + * Generates a Start Success Reports TM[1,3] in subfunction + * @sa{startExecution()} or a Start Failure Report TM[1,4] by using the + * TC Verification Service. */ void handleRequestQueue(); @@ -280,8 +336,11 @@ private: void acceptPacket(uint8_t reportId, TcPacketStored* packet); - void startExecution(TcPacketStored *storedPacket, - typename FixedMap::Iterator *iter); + void startExecution(TcPacketStored *storedPacket, CommandMapIter iter); + + void handleCommandMessage(CommandMessage* reply); + void handleReplyHandlerResult(ReturnValue_t result, CommandMapIter iter, + CommandMessage* nextCommand, CommandMessage* reply, bool& isStep); void checkTimeout(); }; diff --git a/tmtcservices/PusServiceBase.cpp b/tmtcservices/PusServiceBase.cpp index b1d972933..d35944a46 100644 --- a/tmtcservices/PusServiceBase.cpp +++ b/tmtcservices/PusServiceBase.cpp @@ -1,18 +1,19 @@ -#include -#include -#include -#include -#include -#include -#include +#include "../serviceinterface/ServiceInterfaceStream.h" +#include "../tcdistribution/PUSDistributorIF.h" +#include "AcceptsTelemetryIF.h" +#include "PusServiceBase.h" +#include "PusVerificationReport.h" +#include "TmTcMessage.h" +#include "../ipc/QueueFactory.h" object_id_t PusServiceBase::packetSource = 0; object_id_t PusServiceBase::packetDestination = 0; -PusServiceBase::PusServiceBase(object_id_t setObjectId, uint16_t setApid, uint8_t setServiceId) : - SystemObject(setObjectId), apid(setApid), serviceId(setServiceId), errorParameter1( - 0), errorParameter2(0), requestQueue(NULL) { - requestQueue = QueueFactory::instance()->createMessageQueue(PUS_SERVICE_MAX_RECEPTION); +PusServiceBase::PusServiceBase(object_id_t setObjectId, uint16_t setApid, + uint8_t setServiceId) : + SystemObject(setObjectId), apid(setApid), serviceId(setServiceId) { + requestQueue = QueueFactory::instance()-> + createMessageQueue(PUS_SERVICE_MAX_RECEPTION); } PusServiceBase::~PusServiceBase() { @@ -20,50 +21,64 @@ PusServiceBase::~PusServiceBase() { } ReturnValue_t PusServiceBase::performOperation(uint8_t opCode) { + handleRequestQueue(); + ReturnValue_t result = this->performService(); + if (result != RETURN_OK) { + sif::error << "PusService " << (uint16_t) this->serviceId + << ": performService returned with " << (int16_t) result + << std::endl; + return RETURN_FAILED; + } + return RETURN_OK; +} + +void PusServiceBase::setTaskIF(PeriodicTaskIF* taskHandle) { + this->taskHandle = taskHandle; +} + +void PusServiceBase::handleRequestQueue() { TmTcMessage message; + ReturnValue_t result = RETURN_FAILED; for (uint8_t count = 0; count < PUS_SERVICE_MAX_RECEPTION; count++) { ReturnValue_t status = this->requestQueue->receiveMessage(&message); - // debug << "PusServiceBase::performOperation: Receiving from MQ ID: " << std::hex << this->requestQueue.getId() - // << std::dec << " returned: " << status << std::endl; + // debug << "PusServiceBase::performOperation: Receiving from MQ ID: " + // << std::hex << this->requestQueue.getId() + // << std::dec << " returned: " << status << std::endl; if (status == RETURN_OK) { this->currentPacket.setStoreAddress(message.getStorageId()); - // info << "Service " << (uint16_t) this->serviceId << ": new packet!" << std::endl; + //info << "Service " << (uint16_t) this->serviceId << + // ": new packet!" << std::endl; - ReturnValue_t return_code = this->handleRequest(); - // debug << "Service " << (uint16_t)this->serviceId << ": handleRequest returned: " << (int)return_code << std::endl; - if (return_code == RETURN_OK) { + result = this->handleRequest(currentPacket.getSubService()); + + // debug << "Service " << (uint16_t)this->serviceId << + // ": handleRequest returned: " << (int)return_code << std::endl; + if (result == RETURN_OK) { this->verifyReporter.sendSuccessReport( TC_VERIFY::COMPLETION_SUCCESS, &this->currentPacket); - } else { + } + else { this->verifyReporter.sendFailureReport( TC_VERIFY::COMPLETION_FAILURE, &this->currentPacket, - return_code, 0, errorParameter1, errorParameter2); + result, 0, errorParameter1, errorParameter2); } this->currentPacket.deletePacket(); errorParameter1 = 0; errorParameter2 = 0; - } else if (status == MessageQueueIF::EMPTY) { + } + else if (status == MessageQueueIF::EMPTY) { status = RETURN_OK; - // debug << "PusService " << (uint16_t)this->serviceId << ": no new packet." << std::endl; + // debug << "PusService " << (uint16_t)this->serviceId << + // ": no new packet." << std::endl; break; - } else { - + } + else { sif::error << "PusServiceBase::performOperation: Service " << (uint16_t) this->serviceId << ": Error receiving packet. Code: " << std::hex << status << std::dec << std::endl; } } - ReturnValue_t return_code = this->performService(); - if (return_code == RETURN_OK) { - return RETURN_OK; - } else { - - sif::error << "PusService " << (uint16_t) this->serviceId - << ": performService returned with " << (int16_t) return_code - << std::endl; - return RETURN_FAILED; - } } uint16_t PusServiceBase::getIdentifier() { @@ -79,19 +94,28 @@ ReturnValue_t PusServiceBase::initialize() { if (result != RETURN_OK) { return result; } - AcceptsTelemetryIF* dest_service = objectManager->get( + AcceptsTelemetryIF* destService = objectManager->get( packetDestination); PUSDistributorIF* distributor = objectManager->get( packetSource); - if ((dest_service != NULL) && (distributor != NULL)) { + if ((destService != nullptr) && (distributor != nullptr)) { this->requestQueue->setDefaultDestination( - dest_service->getReportReceptionQueue()); + destService->getReportReceptionQueue()); distributor->registerService(this); return RETURN_OK; - } else { + } + else { sif::error << "PusServiceBase::PusServiceBase: Service " << (uint32_t) this->serviceId << ": Configuration error." - << " Make sure packetSource and packetDestination are defined correctly" << std::endl; + << " Make sure packetSource and packetDestination are defined " + "correctly" << std::endl; return RETURN_FAILED; } } + +ReturnValue_t PusServiceBase::initializeAfterTaskCreation() { + // If task parameters, for example task frequency are required, this + // function should be overriden and the system object task IF can + // be used to get those parameters. + return HasReturnvaluesIF::RETURN_OK; +} diff --git a/tmtcservices/PusServiceBase.h b/tmtcservices/PusServiceBase.h index d318ff1e0..98d65efbb 100644 --- a/tmtcservices/PusServiceBase.h +++ b/tmtcservices/PusServiceBase.h @@ -1,88 +1,115 @@ -#ifndef PUSSERVICEBASE_H_ -#define PUSSERVICEBASE_H_ +#ifndef FRAMEWORK_TMTCSERVICES_PUSSERVICEBASE_H_ +#define FRAMEWORK_TMTCSERVICES_PUSSERVICEBASE_H_ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "../objectmanager/ObjectManagerIF.h" +#include "../objectmanager/SystemObject.h" +#include "../returnvalues/HasReturnvaluesIF.h" +#include "../tasks/ExecutableObjectIF.h" +#include "../tmtcpacket/pus/TcPacketStored.h" +#include "AcceptsTelecommandsIF.h" +#include "VerificationCodes.h" +#include "VerificationReporter.h" +#include "../ipc/MessageQueueIF.h" namespace Factory{ void setStaticFrameworkObjectIds(); } /** - * \defgroup pus_services PUS Service Framework + * @defgroup pus_services PUS Service Framework * These group contains all implementations of PUS Services in the OBSW. * Most of the Services are directly taken from the ECSS PUS Standard. */ /** - * \brief This class is the basis for all PUS Services, which can immediately process Telecommand Packets. - * It manages Telecommand reception and the generation of Verification Reports. Every class that inherits - * from this abstract class has to implement handleRequest and performService. Services that are created with this + * @brief This class is the basis for all PUS Services, + * which can immediately process Telecommand Packets. + * @details + * It manages Telecommand reception and the generation of Verification Reports. + * Every class that inherits from this abstract class has to implement + * handleRequest and performService. Services that are created with this * Base class have to handle any kind of request immediately on reception. - * All PUS Services are System Objects, so an Object ID needs to be specified on construction. - * \ingroup pus_services + * All PUS Services are System Objects, so an Object ID needs to be specified + * on construction. + * @ingroup pus_services */ -class PusServiceBase : public ExecutableObjectIF, public AcceptsTelecommandsIF, public SystemObject, public HasReturnvaluesIF { +class PusServiceBase : public ExecutableObjectIF, + public AcceptsTelecommandsIF, + public SystemObject, + public HasReturnvaluesIF { friend void (Factory::setStaticFrameworkObjectIds)(); public: /** - * The constructor for the class. - * The passed values are set, but inter-object initialization is done in the initialize method. - * @param setObjectId The system object identifier of this Service instance. - * @param set_apid The APID the Service is instantiated for. - * @param set_service_id The Service Identifier as specified in ECSS PUS. + * @brief The passed values are set, but inter-object initialization is + * done in the initialize method. + * @param setObjectId + * The system object identifier of this Service instance. + * @param setApid + * The APID the Service is instantiated for. + * @param setServiceId + * The Service Identifier as specified in ECSS PUS. */ - PusServiceBase( object_id_t setObjectId, uint16_t setApid, uint8_t setServiceId); + PusServiceBase( object_id_t setObjectId, uint16_t setApid, + uint8_t setServiceId); /** * The destructor is empty. */ virtual ~PusServiceBase(); /** - * @brief The handleRequest method shall handle any kind of Telecommand Request immediately. + * @brief The handleRequest method shall handle any kind of Telecommand + * Request immediately. * @details - * Implemetations can take the Telecommand in currentPacket and perform any kind of operation. - * They may send additional "Start Success (1,3)" messages with the verifyReporter, but Completion - * Success or Failure Reports are generated automatically after execution of this method. + * Implemetations can take the Telecommand in currentPacket and perform + * any kind of operation. + * They may send additional "Start Success (1,3)" messages with the + * verifyReporter, but Completion Success or Failure Reports are generated + * automatically after execution of this method. * * If a Telecommand can not be executed within one call cycle, * this Base class is not the right parent. * - * The child class may add additional error information by setting #errorParameters which are - * attached to the generated verification message. + * The child class may add additional error information by setting + * #errorParameters which aren attached to the generated verification + * message. * * Subservice checking should be implemented in this method. * - * @return The returned status_code is directly taken as main error code in the Verification Report. + * @return The returned status_code is directly taken as main error code + * in the Verification Report. * On success, RETURN_OK shall be returned. */ - virtual ReturnValue_t handleRequest() = 0; + virtual ReturnValue_t handleRequest(uint8_t subservice) = 0; /** - * In performService, implementations can handle periodic, non-TC-triggered activities. + * In performService, implementations can handle periodic, + * non-TC-triggered activities. * The performService method is always called. - * @return A success or failure code that does not trigger any kind of verification message. + * @return Currently, everything other that RETURN_OK only triggers + * diagnostic output. */ virtual ReturnValue_t performService() = 0; /** * This method implements the typical activity of a simple PUS Service. - * It checks for new requests, and, if found, calls handleRequest, sends completion verification messages and deletes + * It checks for new requests, and, if found, calls handleRequest, sends + * completion verification messages and deletes * the TC requests afterwards. * performService is always executed afterwards. - * @return \c RETURN_OK if the periodic performService was successful. - * \c RETURN_FAILED else. + * @return @c RETURN_OK if the periodic performService was successful. + * @c RETURN_FAILED else. */ - ReturnValue_t performOperation(uint8_t opCode); - virtual uint16_t getIdentifier(); - MessageQueueId_t getRequestQueue(); - virtual ReturnValue_t initialize(); + ReturnValue_t performOperation(uint8_t opCode) override; + virtual uint16_t getIdentifier() override; + MessageQueueId_t getRequestQueue() override; + virtual ReturnValue_t initialize() override; + + virtual void setTaskIF(PeriodicTaskIF* taskHandle) override; + virtual ReturnValue_t initializeAfterTaskCreation() override; protected: + /** + * @brief Handle to the underlying task + * @details + * Will be set by setTaskIF(), which is called on task creation. + */ + PeriodicTaskIF* taskHandle = nullptr; /** * The APID of this instance of the Service. */ @@ -94,19 +121,19 @@ protected: /** * One of two error parameters for additional error information. */ - uint32_t errorParameter1; + uint32_t errorParameter1 = 0; /** * One of two error parameters for additional error information. */ - uint32_t errorParameter2; + uint32_t errorParameter2 = 0; /** - * This is a complete instance of the Telecommand reception queue of the class. - * It is initialized on construction of the class. + * This is a complete instance of the telecommand reception queue + * of the class. It is initialized on construction of the class. */ - MessageQueueIF* requestQueue; + MessageQueueIF* requestQueue = nullptr; /** - * An instance of the VerificationReporter class, that simplifies sending any kind of - * Verification Message to the TC Verification Service. + * An instance of the VerificationReporter class, that simplifies + * sending any kind of verification message to the TC Verification Service. */ VerificationReporter verifyReporter; /** @@ -121,9 +148,12 @@ protected: private: /** * This constant sets the maximum number of packets accepted per call. - * Remember that one packet must be completely handled in one #handleRequest call. + * Remember that one packet must be completely handled in one + * #handleRequest call. */ static const uint8_t PUS_SERVICE_MAX_RECEPTION = 10; + + void handleRequestQueue(); }; #endif /* PUSSERVICEBASE_H_ */ diff --git a/tmtcservices/PusVerificationReport.cpp b/tmtcservices/PusVerificationReport.cpp index 1bc53c2a8..b047576bd 100644 --- a/tmtcservices/PusVerificationReport.cpp +++ b/tmtcservices/PusVerificationReport.cpp @@ -1,5 +1,5 @@ -#include -#include +#include "../serialize/SerializeAdapter.h" +#include "PusVerificationReport.h" PusVerificationMessage::PusVerificationMessage() { } @@ -33,7 +33,7 @@ PusVerificationMessage::PusVerificationMessage(uint8_t set_report_id, uint8_t ackFlags, uint16_t tcPacketId, uint16_t tcSequenceControl, ReturnValue_t set_error_code, uint8_t set_step, uint32_t parameter1, uint32_t parameter2) { - uint8_t* data = this->getBuffer(); + uint8_t *data = this->getBuffer(); data[messageSize] = set_report_id; messageSize += sizeof(set_report_id); data[messageSize] = ackFlags; @@ -108,13 +108,13 @@ PusSuccessReport::PusSuccessReport(uint16_t setPacketId, uint16_t setSequenceControl, uint8_t setStep) : reportSize(0), pBuffer(reportBuffer) { //Serialization won't fail, because we know the necessary max-size of the buffer. - SerializeAdapter::serialize(&setPacketId, &pBuffer, &reportSize, - sizeof(reportBuffer), true); - SerializeAdapter::serialize(&setSequenceControl, &pBuffer, - &reportSize, sizeof(reportBuffer), true); + SerializeAdapter::serialize(&setPacketId, &pBuffer, &reportSize, + sizeof(reportBuffer), SerializeIF::Endianness::BIG); + SerializeAdapter::serialize(&setSequenceControl, &pBuffer, &reportSize, + sizeof(reportBuffer), SerializeIF::Endianness::BIG); if (setStep != 0) { - SerializeAdapter::serialize(&setStep, &pBuffer, &reportSize, - sizeof(reportBuffer), true); + SerializeAdapter::serialize(&setStep, &pBuffer, &reportSize, + sizeof(reportBuffer), SerializeIF::Endianness::BIG); } } @@ -135,26 +135,26 @@ PusFailureReport::PusFailureReport(uint16_t setPacketId, uint8_t setStep, uint32_t parameter1, uint32_t parameter2) : reportSize(0), pBuffer(reportBuffer) { //Serialization won't fail, because we know the necessary max-size of the buffer. - SerializeAdapter::serialize(&setPacketId, &pBuffer, &reportSize, - sizeof(reportBuffer), true); - SerializeAdapter::serialize(&setSequenceControl, &pBuffer, - &reportSize, sizeof(reportBuffer), true); + SerializeAdapter::serialize(&setPacketId, &pBuffer, &reportSize, + sizeof(reportBuffer), SerializeIF::Endianness::BIG); + SerializeAdapter::serialize(&setSequenceControl, &pBuffer, &reportSize, + sizeof(reportBuffer), SerializeIF::Endianness::BIG); if (setStep != 0) { - SerializeAdapter::serialize(&setStep, &pBuffer, &reportSize, - sizeof(reportBuffer), true); + SerializeAdapter::serialize(&setStep, &pBuffer, &reportSize, + sizeof(reportBuffer), SerializeIF::Endianness::BIG); } - SerializeAdapter::serialize(&setErrorCode, &pBuffer, - &reportSize, sizeof(reportBuffer), true); - SerializeAdapter::serialize(¶meter1, &pBuffer, &reportSize, - sizeof(reportBuffer), true); - SerializeAdapter::serialize(¶meter2, &pBuffer, &reportSize, - sizeof(reportBuffer), true); + SerializeAdapter::serialize(&setErrorCode, &pBuffer, &reportSize, + sizeof(reportBuffer), SerializeIF::Endianness::BIG); + SerializeAdapter::serialize(¶meter1, &pBuffer, &reportSize, + sizeof(reportBuffer), SerializeIF::Endianness::BIG); + SerializeAdapter::serialize(¶meter2, &pBuffer, &reportSize, + sizeof(reportBuffer), SerializeIF::Endianness::BIG); } PusFailureReport::~PusFailureReport() { } -uint32_t PusFailureReport::getSize() { +size_t PusFailureReport::getSize() { return reportSize; } diff --git a/tmtcservices/PusVerificationReport.h b/tmtcservices/PusVerificationReport.h index 7a173be9f..b47395774 100644 --- a/tmtcservices/PusVerificationReport.h +++ b/tmtcservices/PusVerificationReport.h @@ -1,9 +1,9 @@ #ifndef PUSVERIFICATIONREPORT_H_ #define PUSVERIFICATIONREPORT_H_ -#include -#include -#include +#include "../ipc/MessageQueueMessage.h" +#include "../tmtcpacket/pus/TcPacketBase.h" +#include "VerificationCodes.h" class PusVerificationMessage: public MessageQueueMessage { private: @@ -49,7 +49,7 @@ class PusSuccessReport { private: static const uint16_t MAX_SIZE = 7; uint8_t reportBuffer[MAX_SIZE]; - uint32_t reportSize; + size_t reportSize; uint8_t * pBuffer; public: PusSuccessReport(uint16_t setPacketId, uint16_t setSequenceControl, @@ -63,14 +63,14 @@ class PusFailureReport { private: static const uint16_t MAX_SIZE = 16; uint8_t reportBuffer[MAX_SIZE]; - uint32_t reportSize; + size_t reportSize; uint8_t * pBuffer; public: PusFailureReport(uint16_t setPacketId, uint16_t setSequenceControl, ReturnValue_t setErrorCode, uint8_t setStep = 0, uint32_t parameter1 = 0, uint32_t parameter2 = 0); ~PusFailureReport(); - uint32_t getSize(); + size_t getSize(); uint8_t* getReport(); }; diff --git a/tmtcservices/SourceSequenceCounter.h b/tmtcservices/SourceSequenceCounter.h index b92a5c84c..1cc587587 100644 --- a/tmtcservices/SourceSequenceCounter.h +++ b/tmtcservices/SourceSequenceCounter.h @@ -7,7 +7,7 @@ #ifndef SOURCESEQUENCECOUNTER_H_ #define SOURCESEQUENCECOUNTER_H_ -#include +#include "../tmtcpacket/SpacePacketBase.h" class SourceSequenceCounter { private: diff --git a/tmtcservices/TmTcBridge.cpp b/tmtcservices/TmTcBridge.cpp new file mode 100644 index 000000000..021b0d7b3 --- /dev/null +++ b/tmtcservices/TmTcBridge.cpp @@ -0,0 +1,211 @@ +#include "TmTcBridge.h" + +#include "../ipc/QueueFactory.h" +#include "AcceptsTelecommandsIF.h" +#include "../serviceinterface/ServiceInterfaceStream.h" +#include "../globalfunctions/arrayprinter.h" + +TmTcBridge::TmTcBridge(object_id_t objectId, object_id_t tcDestination, + object_id_t tmStoreId, object_id_t tcStoreId): + SystemObject(objectId),tmStoreId(tmStoreId), tcStoreId(tcStoreId), + tcDestination(tcDestination) + +{ + tmTcReceptionQueue = QueueFactory::instance()-> + createMessageQueue(TMTC_RECEPTION_QUEUE_DEPTH); +} + +TmTcBridge::~TmTcBridge() {} + +ReturnValue_t TmTcBridge::setNumberOfSentPacketsPerCycle( + uint8_t sentPacketsPerCycle) { + if(sentPacketsPerCycle <= LIMIT_STORED_DATA_SENT_PER_CYCLE) { + this->sentPacketsPerCycle = sentPacketsPerCycle; + return RETURN_OK; + } + else { + sif::warning << "TmTcBridge::setNumberOfSentPacketsPerCycle: Number of " + << "packets sent per cycle exceeds limits. " + << "Keeping default value." << std::endl; + return RETURN_FAILED; + } +} + +ReturnValue_t TmTcBridge::setMaxNumberOfPacketsStored( + uint8_t maxNumberOfPacketsStored) { + if(maxNumberOfPacketsStored <= LIMIT_DOWNLINK_PACKETS_STORED) { + this->maxNumberOfPacketsStored = maxNumberOfPacketsStored; + return RETURN_OK; + } + else { + sif::warning << "TmTcBridge::setMaxNumberOfPacketsStored: Number of " + << "packets stored exceeds limits. " + << "Keeping default value." << std::endl; + return RETURN_FAILED; + } +} + +ReturnValue_t TmTcBridge::initialize() { + tcStore = objectManager->get(tcStoreId); + if (tcStore == nullptr) { + sif::error << "TmTcBridge::initialize: TC store invalid. Make sure" + "it is created and set up properly." << std::endl; + return ObjectManagerIF::CHILD_INIT_FAILED; + } + tmStore = objectManager->get(tmStoreId); + if (tmStore == nullptr) { + sif::error << "TmTcBridge::initialize: TM store invalid. Make sure" + "it is created and set up properly." << std::endl; + return ObjectManagerIF::CHILD_INIT_FAILED; + } + AcceptsTelecommandsIF* tcDistributor = + objectManager->get(tcDestination); + if (tcDistributor == nullptr) { + sif::error << "TmTcBridge::initialize: TC Distributor invalid" + << std::endl; + return ObjectManagerIF::CHILD_INIT_FAILED; + } + + tmTcReceptionQueue->setDefaultDestination(tcDistributor->getRequestQueue()); + return RETURN_OK; +} + +ReturnValue_t TmTcBridge::performOperation(uint8_t operationCode) { + ReturnValue_t result; + result = handleTc(); + if(result != RETURN_OK) { + sif::debug << "TmTcBridge::performOperation: " + << "Error handling TCs" << std::endl; + } + result = handleTm(); + if (result != RETURN_OK) { + sif::debug << "TmTcBridge::performOperation: " + << "Error handling TMs" << std::endl; + } + return result; +} + +ReturnValue_t TmTcBridge::handleTc() { + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t TmTcBridge::handleTm() { + ReturnValue_t result = handleTmQueue(); + if(result != RETURN_OK) { + sif::warning << "TmTcBridge: Reading TM Queue failed" << std::endl; + return RETURN_FAILED; + } + + if(tmStored and communicationLinkUp) { + result = handleStoredTm(); + } + return result; + +} + +ReturnValue_t TmTcBridge::handleTmQueue() { + TmTcMessage message; + const uint8_t* data = nullptr; + size_t size = 0; + for (ReturnValue_t result = tmTcReceptionQueue->receiveMessage(&message); + result == RETURN_OK; result = tmTcReceptionQueue->receiveMessage(&message)) + { + if(communicationLinkUp == false) { + result = storeDownlinkData(&message); + return result; + } + + result = tmStore->getData(message.getStorageId(), &data, &size); + if (result != HasReturnvaluesIF::RETURN_OK) { + continue; + } + + result = sendTm(data, size); + if (result != RETURN_OK) { + sif::warning << "TmTcBridge: Could not send TM packet" << std::endl; + tmStore->deleteData(message.getStorageId()); + return result; + + } + tmStore->deleteData(message.getStorageId()); + } + return RETURN_OK; +} + +ReturnValue_t TmTcBridge::storeDownlinkData(TmTcMessage *message) { + store_address_t storeId = 0; + + if(tmFifo.full()) { + sif::error << "TmTcBridge::storeDownlinkData: TM downlink max. number " + << "of stored packet IDs reached! " + << "Overwriting old data" << std::endl; + tmFifo.retrieve(&storeId); + tmStore->deleteData(storeId); + } + storeId = message->getStorageId(); + tmFifo.insert(storeId); + tmStored = true; + return RETURN_OK; +} + +ReturnValue_t TmTcBridge::handleStoredTm() { + uint8_t counter = 0; + ReturnValue_t result = RETURN_OK; + while(not tmFifo.empty() and counter < sentPacketsPerCycle) { + //info << "TMTC Bridge: Sending stored TM data. There are " + // << (int) fifo.size() << " left to send\r\n" << std::flush; + store_address_t storeId; + const uint8_t* data = nullptr; + size_t size = 0; + tmFifo.retrieve(&storeId); + result = tmStore->getData(storeId, &data, &size); + + sendTm(data,size); + + if(result != RETURN_OK) { + sif::error << "TMTC Bridge: Could not send stored downlink data" + << std::endl; + result = RETURN_FAILED; + } + counter ++; + + if(tmFifo.empty()) { + tmStored = false; + } + tmStore->deleteData(storeId); + } + return result; +} + +void TmTcBridge::registerCommConnect() { + if(not communicationLinkUp) { + //info << "TMTC Bridge: Registered Comm Link Connect" << std::endl; + communicationLinkUp = true; + } +} + +void TmTcBridge::registerCommDisconnect() { + //info << "TMTC Bridge: Registered Comm Link Disconnect" << std::endl; + if(communicationLinkUp) { + communicationLinkUp = false; + } +} + +MessageQueueId_t TmTcBridge::getReportReceptionQueue(uint8_t virtualChannel) { + return tmTcReceptionQueue->getId(); +} + + +void TmTcBridge::printData(uint8_t * data, size_t dataLen) { + arrayprinter::print(data, dataLen); +} + +uint16_t TmTcBridge::getIdentifier() { + // This is no PUS service, so we just return 0 + return 0; +} + +MessageQueueId_t TmTcBridge::getRequestQueue() { + // Default implementation: Relay TC messages to TC distributor directly. + return tmTcReceptionQueue->getDefaultDestination(); +} diff --git a/tmtcservices/TmTcBridge.h b/tmtcservices/TmTcBridge.h new file mode 100644 index 000000000..32eaf7f20 --- /dev/null +++ b/tmtcservices/TmTcBridge.h @@ -0,0 +1,154 @@ +#ifndef FRAMEWORK_TMTCSERVICES_TMTCBRIDGE_H_ +#define FRAMEWORK_TMTCSERVICES_TMTCBRIDGE_H_ + +#include "../objectmanager/SystemObject.h" +#include "AcceptsTelemetryIF.h" +#include "../tasks/ExecutableObjectIF.h" +#include "../ipc/MessageQueueIF.h" +#include "../storagemanager/StorageManagerIF.h" +#include "AcceptsTelecommandsIF.h" + +#include "../container/FIFO.h" +#include "TmTcMessage.h" + +class TmTcBridge : public AcceptsTelemetryIF, + public AcceptsTelecommandsIF, + public ExecutableObjectIF, + public HasReturnvaluesIF, + public SystemObject { +public: + static constexpr uint8_t TMTC_RECEPTION_QUEUE_DEPTH = 20; + static constexpr uint8_t LIMIT_STORED_DATA_SENT_PER_CYCLE = 15; + static constexpr uint8_t LIMIT_DOWNLINK_PACKETS_STORED = 20; + + static constexpr uint8_t DEFAULT_STORED_DATA_SENT_PER_CYCLE = 5; + static constexpr uint8_t DEFAULT_DOWNLINK_PACKETS_STORED = 10; + + TmTcBridge(object_id_t objectId, object_id_t tcDestination, + object_id_t tmStoreId, object_id_t tcStoreId); + virtual ~TmTcBridge(); + + /** + * Set number of packets sent per performOperation().Please note that this + * value must be smaller than MAX_STORED_DATA_SENT_PER_CYCLE + * @param sentPacketsPerCycle + * @return -@c RETURN_OK if value was set successfully + * -@c RETURN_FAILED otherwise, stored value stays the same + */ + ReturnValue_t setNumberOfSentPacketsPerCycle(uint8_t sentPacketsPerCycle); + + /** + * Set number of packets sent per performOperation().Please note that this + * value must be smaller than MAX_DOWNLINK_PACKETS_STORED + * @param sentPacketsPerCycle + * @return -@c RETURN_OK if value was set successfully + * -@c RETURN_FAILED otherwise, stored value stays the same + */ + ReturnValue_t setMaxNumberOfPacketsStored(uint8_t maxNumberOfPacketsStored); + + virtual void registerCommConnect(); + virtual void registerCommDisconnect(); + + /** + * Initializes necessary FSFW components for the TMTC Bridge + * @return + */ + virtual ReturnValue_t initialize() override; + + /** + * @brief Handles TMTC reception + */ + virtual ReturnValue_t performOperation(uint8_t operationCode = 0) override; + + + /** AcceptsTelemetryIF override */ + virtual MessageQueueId_t getReportReceptionQueue( + uint8_t virtualChannel = 0) override; + + /** AcceptsTelecommandsIF override */ + virtual uint16_t getIdentifier() override; + virtual MessageQueueId_t getRequestQueue() override; + +protected: + //! Cached for initialize function. + object_id_t tmStoreId = objects::NO_OBJECT; + object_id_t tcStoreId = objects::NO_OBJECT; + object_id_t tcDestination = objects::NO_OBJECT; + + //! Used to send and receive TMTC messages. + //! The TmTcMessage class is used to transport messages between tasks. + MessageQueueIF* tmTcReceptionQueue = nullptr; + + StorageManagerIF* tmStore = nullptr; + StorageManagerIF* tcStore = nullptr; + + //! Used to specify whether communication link is up. Will be true + //! by default, so telemetry will be handled immediately. + bool communicationLinkUp = true; + bool tmStored = false; + + /** + * @brief Handle TC reception + * @details + * Default implementation provided, but is empty. + * In most cases, TC reception will be handled in a separate task anyway. + * @return + */ + virtual ReturnValue_t handleTc(); + + /** + * Handle Telemetry. Default implementation provided. + * Calls sendTm() + * @return + */ + virtual ReturnValue_t handleTm(); + + /** + * Read the TM Queue and send TM if necessary. + * Default implementation provided + * @return + */ + virtual ReturnValue_t handleTmQueue(); + + /** + * Send stored data if communication link is active + * @return + */ + virtual ReturnValue_t handleStoredTm(); + + /** + * Implemented by child class. Perform sending of Telemetry by implementing + * communication drivers or wrappers, e.g. serial communication or a socket + * call. + * @param data + * @param dataLen + * @return + */ + virtual ReturnValue_t sendTm(const uint8_t * data, size_t dataLen) = 0; + + /** + * Store data to be sent later if communication link is not up. + * @param message + * @return + */ + virtual ReturnValue_t storeDownlinkData(TmTcMessage * message); + + + /** + * Print data as hexidecimal array + * @param data + * @param dataLen + */ + void printData(uint8_t * data, size_t dataLen); + + /** + * This fifo can be used to store downlink data + * which can not be sent at the moment. + */ + FIFO tmFifo; + uint8_t sentPacketsPerCycle = DEFAULT_STORED_DATA_SENT_PER_CYCLE; + uint8_t maxNumberOfPacketsStored = DEFAULT_DOWNLINK_PACKETS_STORED; +}; + + +#endif /* FRAMEWORK_TMTCSERVICES_TMTCBRIDGE_H_ */ diff --git a/tmtcservices/TmTcMessage.cpp b/tmtcservices/TmTcMessage.cpp index d437b41ea..987bd2321 100644 --- a/tmtcservices/TmTcMessage.cpp +++ b/tmtcservices/TmTcMessage.cpp @@ -1,4 +1,4 @@ -#include +#include "TmTcMessage.h" #include diff --git a/tmtcservices/TmTcMessage.h b/tmtcservices/TmTcMessage.h index 73f741fb6..b5e1ff8d4 100644 --- a/tmtcservices/TmTcMessage.h +++ b/tmtcservices/TmTcMessage.h @@ -1,8 +1,8 @@ #ifndef TMTCMESSAGE_H_ #define TMTCMESSAGE_H_ -#include -#include +#include "../ipc/MessageQueueMessage.h" +#include "../storagemanager/StorageManagerIF.h" /** * @brief This message class is used to pass Telecommand and Telemetry * packets between tasks. diff --git a/tmtcservices/VerificationReporter.cpp b/tmtcservices/VerificationReporter.cpp index 4484fb9b2..43e712a25 100644 --- a/tmtcservices/VerificationReporter.cpp +++ b/tmtcservices/VerificationReporter.cpp @@ -1,7 +1,7 @@ -#include -#include -#include -#include +#include "../serviceinterface/ServiceInterfaceStream.h" +#include "AcceptsVerifyMessageIF.h" +#include "PusVerificationReport.h" +#include "VerificationReporter.h" object_id_t VerificationReporter::messageReceiver = 0; diff --git a/tmtcservices/VerificationReporter.h b/tmtcservices/VerificationReporter.h index 370c44c8c..29a273c5a 100644 --- a/tmtcservices/VerificationReporter.h +++ b/tmtcservices/VerificationReporter.h @@ -1,8 +1,8 @@ #ifndef VERIFICATIONREPORTER_H_ #define VERIFICATIONREPORTER_H_ -#include -#include +#include "../objectmanager/ObjectManagerIF.h" +#include "PusVerificationReport.h" namespace Factory{ void setStaticFrameworkObjectIds();