#ifndef FSFW_SUBSYSTEM_SUBSYSTEM_H_ #define FSFW_SUBSYSTEM_SUBSYSTEM_H_ #include "../container/FixedArrayList.h" #include "../container/FixedMap.h" #include "../container/HybridIterator.h" #include "../container/SinglyLinkedList.h" #include "../serialize/SerialArrayListAdapter.h" #include "SubsystemBase.h" #include "fsfw/FSFW.h" #include "modes/ModeDefinitions.h" struct TableSequenceBase { public: TableSequenceBase(Mode_t mode, ArrayList *table) : mode(mode), table(table){}; Mode_t mode; ArrayList *table; bool inStore = false; bool preInit = true; }; struct TableEntry : public TableSequenceBase { public: TableEntry(Mode_t mode, ArrayList *table) : TableSequenceBase(mode, table){}; }; struct SequenceEntry : public TableSequenceBase { public: SequenceEntry(Mode_t mode, ArrayList *table, Mode_t fallbackMode) : TableSequenceBase(mode, table), fallbackMode(fallbackMode) {} Mode_t fallbackMode; }; /** * @brief TODO: documentation missing * @details */ class Subsystem : public SubsystemBase, public HasModeSequenceIF { public: static const uint8_t INTERFACE_ID = CLASS_ID::SUBSYSTEM; static const ReturnValue_t SEQUENCE_ALREADY_EXISTS = MAKE_RETURN_CODE(0x01); static const ReturnValue_t TABLE_ALREADY_EXISTS = MAKE_RETURN_CODE(0x02); static const ReturnValue_t TABLE_DOES_NOT_EXIST = MAKE_RETURN_CODE(0x03); static const ReturnValue_t TABLE_OR_SEQUENCE_LENGTH_INVALID = MAKE_RETURN_CODE(0x04); static const ReturnValue_t SEQUENCE_DOES_NOT_EXIST = MAKE_RETURN_CODE(0x05); static const ReturnValue_t TABLE_CONTAINS_INVALID_OBJECT_ID = MAKE_RETURN_CODE(0x06); static const ReturnValue_t FALLBACK_SEQUENCE_DOES_NOT_EXIST = MAKE_RETURN_CODE(0x07); static const ReturnValue_t NO_TARGET_TABLE = MAKE_RETURN_CODE(0x08); static const ReturnValue_t SEQUENCE_OR_TABLE_TOO_LONG = MAKE_RETURN_CODE(0x09); static const ReturnValue_t IS_FALLBACK_SEQUENCE = MAKE_RETURN_CODE(0x0B); static const ReturnValue_t ACCESS_DENIED = MAKE_RETURN_CODE(0x0C); static const ReturnValue_t TABLE_IN_USE = MAKE_RETURN_CODE(0x0E); static const ReturnValue_t TARGET_TABLE_NOT_REACHED = MAKE_RETURN_CODE(0xA1); static const ReturnValue_t TABLE_CHECK_FAILED = MAKE_RETURN_CODE(0xA2); /** * TODO: Doc for constructor * @param setObjectId * @param parent * @param maxNumberOfSequences * @param maxNumberOfTables */ Subsystem(object_id_t setObjectId, object_id_t parent, uint32_t maxNumberOfSequences, uint32_t maxNumberOfTables); virtual ~Subsystem(); ReturnValue_t addSequence(SequenceEntry sequence); ReturnValue_t addSequence(ArrayList *sequence, Mode_t id, Mode_t fallbackSequence, bool inStore = true, bool preInit = true); ReturnValue_t addTable(TableEntry table); ReturnValue_t addTable(ArrayList *table, Mode_t id, bool inStore = true, bool preInit = true); void setInitialMode(Mode_t mode, Submode_t submode = SUBMODE_NONE); virtual ReturnValue_t initialize() override; virtual ReturnValue_t checkObjectConnections() override; virtual MessageQueueId_t getSequenceCommandQueue() const override; protected: struct EntryPointer { bool islinked; union { ModeListEntry *firstLinkedElement; ArrayList *array; }; }; struct SequenceInfo { Mode_t fallbackSequence; EntryPointer entries; }; static const uint8_t MAX_NUMBER_OF_TABLES_OR_SEQUENCES = 70; static const uint8_t MAX_LENGTH_OF_TABLE_OR_SEQUENCE = 20; bool isInTransition; bool childrenChangedHealth; uint32_t uptimeStartTable = 0; HybridIterator currentTargetTable; Mode_t targetMode = 0; Submode_t targetSubmode; Mode_t initialMode = 0; Submode_t initSubmode = SUBMODE_NONE; HybridIterator currentSequenceIterator; FixedMap modeTables; FixedMap modeSequences; StorageManagerIF *IPCStore = nullptr; #if FSFW_USE_MODESTORE == 1 ModeStoreIF *modeStore = nullptr; #endif bool existsModeSequence(Mode_t id); HybridIterator getSequence(Mode_t id); bool existsModeTable(Mode_t id); HybridIterator getTable(Mode_t id); HybridIterator getCurrentTable(); /** * DO NOT USE ON NON EXISTING SEQUENCE * * @param a sequence * @return the fallback sequence's Id */ Mode_t getFallbackSequence(Mode_t sequence); void replyToCommand(ReturnValue_t status, uint32_t parameter); ReturnValue_t deleteSequence(Mode_t id); ReturnValue_t deleteTable(Mode_t id); virtual void performChildOperation() override; virtual ReturnValue_t handleCommandMessage(CommandMessage *message) override; bool isFallbackSequence(Mode_t SequenceId); bool isTableUsed(Mode_t tableId); virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, uint32_t *msToReachTheMode) override; virtual void startTransition(Mode_t mode, Submode_t submode) override; void sendSerializablesAsCommandMessage(Command_t command, SerializeIF **elements, uint8_t count); void transitionFailed(ReturnValue_t failureCode, uint32_t parameter); void cantKeepMode(); /** * @brief Checks whether a sequence, identified by a mode. * @param sequence * @return */ ReturnValue_t checkSequence(Mode_t sequence); /** * @brief Checks whether a sequence, identified by a mode list iterator * and a fallback sequence. Iterator needs to point to a valid * sequence. * @param iter * @return */ ReturnValue_t checkSequence(HybridIterator iter, Mode_t fallbackSequence); }; #endif /* FSFW_SUBSYSTEM_SUBSYSTEM_H_ */