Handle slot indices out of range correctly at top level

Besides Unload Filament, which only operates on active slot, all other
top level state machines check the validity of the command's parameter.
If the parameter is out of range for available slots, they return
ErrorCode::INVALID_TOOL now.
pull/83/head
D.R.racer 2021-08-11 08:11:54 +02:00 committed by DRracer
parent c14c79f3ac
commit 9ba116e06e
12 changed files with 71 additions and 0 deletions

View File

@ -76,4 +76,12 @@ bool CommandBase::Step() {
return StepInner();
}
bool CommandBase::CheckToolIndex(uint8_t index) {
if (index >= config::toolCount) {
error = ErrorCode::INVALID_TOOL;
return false;
}
return true;
}
} // namespace logic

View File

@ -62,6 +62,10 @@ public:
virtual ErrorCode Error() const { return error; }
protected:
/// @returns true if the slot/tool index is within specified range (0 - config::toolCount)
/// If not, it returns false and sets the error to ErrorCode::INVALID_TOOL
bool CheckToolIndex(uint8_t index);
ProgressCode state; ///< current progress state of the state machine
ErrorCode error; ///< current error code
};

View File

@ -13,6 +13,10 @@ namespace logic {
CutFilament cutFilament;
void CutFilament::Reset(uint8_t param) {
if (!CheckToolIndex(param)) {
return;
}
error = ErrorCode::OK;
cutSlot = param;

View File

@ -13,6 +13,10 @@ namespace logic {
EjectFilament ejectFilament;
void EjectFilament::Reset(uint8_t param) {
if (!CheckToolIndex(param)) {
return;
}
error = ErrorCode::OK;
slot = param;

View File

@ -26,6 +26,8 @@ enum class ErrorCode : uint_fast16_t {
FILAMENT_ALREADY_LOADED = 0x8005, ///< cannot perform operation LoadFilament or move the selector as the filament is already loaded
INVALID_TOOL = 0x8006, ///< tool/slot index out of range (typically issuing T5 into an MMU with just 5 slots - valid range 0-4)
MMU_NOT_RESPONDING = 0x802e, ///< internal error of the printer - communication with the MMU is not working
INTERNAL = 0x802f, ///< internal runtime error (software)

View File

@ -13,6 +13,10 @@ namespace logic {
LoadFilament loadFilament;
void LoadFilament::Reset(uint8_t param) {
if (!CheckToolIndex(param)) {
return;
}
state = ProgressCode::EngagingIdler;
error = ErrorCode::OK;
mg::globals.SetActiveSlot(param);

View File

@ -13,6 +13,10 @@ namespace logic {
ToolChange toolChange;
void ToolChange::Reset(uint8_t param) {
if (!CheckToolIndex(param)) {
return;
}
if (param == mg::globals.ActiveSlot())
return;

View File

@ -90,3 +90,9 @@ TEST_CASE("cut_filament::cut0", "[cut_filament]") {
CutSlot(cutSlot);
}
}
TEST_CASE("cut_filament::invalid_slot", "[cut_filament]") {
for (uint8_t cutSlot = 0; cutSlot < config::toolCount; ++cutSlot) {
InvalidSlot<logic::CutFilament>(config::toolCount, cutSlot);
}
}

View File

@ -19,6 +19,8 @@
using Catch::Matchers::Equals;
#include "../helpers/helpers.ipp"
// temporarily disabled
TEST_CASE("eject_filament::eject0", "[eject_filament][.]") {
using namespace logic;
@ -67,6 +69,12 @@ TEST_CASE("eject_filament::eject0", "[eject_filament][.]") {
// the next states are still @@TODO
}
TEST_CASE("eject_filament::invalid_slot", "[eject_filament]") {
for (uint8_t cutSlot = 0; cutSlot < config::toolCount; ++cutSlot) {
InvalidSlot<logic::EjectFilament>(config::toolCount, cutSlot);
}
}
// comments:
// The tricky part of the whole state machine are the edge cases - filament not loaded, stall guards etc.
// ... all the external influence we can get on the real HW

View File

@ -51,3 +51,16 @@ bool VerifyState2(SM &uf, bool filamentLoaded, uint8_t idlerSlotIndex, uint8_t s
CHECKED_ELSE(uf.TopLevelState() == topLevelProgress) { return false; }
return true;
}
template<typename SM>
void InvalidSlot(uint8_t invSlot, uint8_t activeSlot){
ForceReinitAllAutomata();
SM logicSM;
REQUIRE(VerifyState(logicSM, false, mi::Idler::IdleSlotIndex(), 0, false, ml::off, ml::off, ErrorCode::OK, ProgressCode::OK));
EnsureActiveSlotIndex(activeSlot);
logicSM.Reset(invSlot);
REQUIRE(VerifyState(logicSM, false, mi::Idler::IdleSlotIndex(), activeSlot, false, ml::off, ml::off, ErrorCode::INVALID_TOOL, ProgressCode::OK));
}

View File

@ -159,3 +159,9 @@ TEST_CASE("load_filament::failed_load_to_finda_0-4_resolve_help_second_fail", "[
FailedLoadToFindaResolveHelpFindaDidntTrigger(slot, lf);
}
}
TEST_CASE("load_filament::invalid_slot", "[load_filament]") {
for (uint8_t cutSlot = 0; cutSlot < config::toolCount; ++cutSlot) {
InvalidSlot<logic::LoadFilament>(config::toolCount, cutSlot);
}
}

View File

@ -19,6 +19,8 @@
using Catch::Matchers::Equals;
#include "../helpers/helpers.ipp"
void ToolChange(uint8_t fromSlot, uint8_t toSlot) {
ForceReinitAllAutomata();
@ -79,3 +81,9 @@ TEST_CASE("tool_change::test0", "[tool_change]") {
}
}
}
TEST_CASE("tool_change::invalid_slot", "[tool_change]") {
for (uint8_t cutSlot = 0; cutSlot < config::toolCount; ++cutSlot) {
InvalidSlot<logic::ToolChange>(config::toolCount, cutSlot);
}
}