#ifndef FSFW_SUBSYSTEM_MODES_MODEDEFINITIONS_H_ #define FSFW_SUBSYSTEM_MODES_MODEDEFINITIONS_H_ #include "fsfw/modes/HasModesIF.h" #include "fsfw/objectmanager/SystemObjectIF.h" #include "fsfw/serialize/SerialLinkedListAdapter.h" #include "fsfw/serialize/SerializeIF.h" namespace mode { enum SpecialSubmodeFlags : uint8_t { INHERIT = 1 << 0, ALLOWED_MASK = 1 << 1 }; } class ModeListEntry : public SerialLinkedListAdapter, public LinkedElement { public: static constexpr uint8_t ALL_SUBMODES_ALLOWED_MASK = 0xff; ModeListEntry() : SerialLinkedListAdapter(), LinkedElement(this) { setLinks(); } SerializeElement value1 = 0; SerializeElement value2 = 0; SerializeElement value3 = 0; SerializeElement value4 = 0; SerializeElement value5 = 0; ModeListEntry(const ModeListEntry& other) : SerialLinkedListAdapter(), LinkedElement(this) { value1.entry = other.value1.entry; value2.entry = other.value2.entry; value3.entry = other.value3.entry; value4.entry = other.value4.entry; value5.entry = other.value5.entry; setLinks(); } ModeListEntry& operator=(const ModeListEntry& other) { this->value1.entry = other.value1.entry; this->value2.entry = other.value2.entry; this->value3.entry = other.value3.entry; this->value4.entry = other.value4.entry; this->value5.entry = other.value5.entry; return *this; } void setLinks() { setStart(&value1); value1.setNext(&value2); value2.setNext(&value3); value3.setNext(&value4); value4.setNext(&value5); } // for Sequences Mode_t getTableId() const { return value1.entry; } void setTableId(Mode_t tableId) { this->value1.entry = tableId; } uint8_t getWaitSeconds() const { return value2.entry; } void setWaitSeconds(uint8_t waitSeconds) { this->value2.entry = waitSeconds; } bool checkSuccess() const { return value3.entry == 1; } void setCheckSuccess(bool checkSuccess) { this->value3.entry = checkSuccess; } // for Tables object_id_t getObject() const { return value1.entry; } void setObject(object_id_t object) { this->value1.entry = object; } Mode_t getMode() const { return value2.entry; } void setMode(Mode_t mode) { this->value2.entry = mode; } Submode_t getSubmode() const { return value3.entry; } void setSubmode(Submode_t submode) { this->value3.entry = submode; } bool inheritSubmode() const { return (value4.entry & mode::SpecialSubmodeFlags::INHERIT) == mode::SpecialSubmodeFlags::INHERIT; } bool submodesAllowed(uint8_t* mask) const { bool submodesAllowed = (value4.entry & mode::SpecialSubmodeFlags::ALLOWED_MASK) == mode::SpecialSubmodeFlags::ALLOWED_MASK; if (submodesAllowed and mask != nullptr) { *mask = value5.entry; } return submodesAllowed; } /** * Enable the inheritance of submodes. This is relevant for both the execution * of mode tables and for mode checking. */ void enableInheritSubmode() { value4.entry |= mode::SpecialSubmodeFlags::INHERIT; } /** * Disable the inheritance of submodes. This is relevant for both the execution * of mode tables and for mode checking. */ void disableInheritSubmode() { value4.entry &= ~mode::SpecialSubmodeFlags::INHERIT; } /** * Specialization of @enableSubmodeAllowed which allows all submodes. */ void allowAllSubmodes() { enableSubmodeAllowed(ALL_SUBMODES_ALLOWED_MASK); } /** * Enable an allowed submode mask for mode checks. Any submode which contains bits * outside of the mask will be declined. * * For example, for a mask of 0b11, only the modes 0b00, 0b01 and 0b11 will be accepted. */ void enableSubmodeAllowed(uint8_t mask) { value4.entry |= mode::SpecialSubmodeFlags::ALLOWED_MASK; value5.entry = mask; } /** * Enforce the equality of submodes for mode checks. This is the default. */ void disableSubmodeAllowed() { value4.entry &= ~mode::SpecialSubmodeFlags::ALLOWED_MASK; value5.entry = 0; } }; #endif /* FSFW_SUBSYSTEM_MODES_MODEDEFINITIONS_H_ */