#include "logic/boot_policy.h" #include "config.h" BootDecision decideBoot(ResetKind reset, uint8_t crash_count) { switch (reset) { case ResetKind::PowerOn: return {BootMode::Normal, 0}; case ResetKind::Crash: if (crash_count < 255) crash_count++; if (crash_count >= SAFE_MODE_CRASHES) return {BootMode::SafeMode, crash_count}; return {BootMode::PanicWindow, crash_count}; case ResetKind::Software: case ResetKind::Other: default: return {BootMode::Normal, crash_count}; } } uint8_t crashCountAfterSafeMode() { return SAFE_MODE_CRASHES - 1; } bool shouldMarkFirmwareValid(uint32_t running_ms, bool wifi_connected) { return running_ms >= FIRMWARE_VALID_TIME && wifi_connected; } bool shouldClearCrashCount(uint32_t running_ms) { return running_ms >= CRASH_FREE_TIME; } const char *recoveryReasonText(RecoveryReason reason) { switch (reason) { case RecoveryReason::Wifi: return "the clock firmware could not connect to WiFi"; case RecoveryReason::Crash: return "the clock firmware crashed repeatedly"; case RecoveryReason::Manual: return "requested from Home Assistant"; case RecoveryReason::PowerCycle: return "the power was switched on and off quickly"; case RecoveryReason::None: default: return "no working clock firmware"; } } const char *recoveryReasonShort(RecoveryReason reason) { switch (reason) { case RecoveryReason::Wifi: return "no WiFi"; case RecoveryReason::Crash: return "crashed"; case RecoveryReason::Manual: return "requested"; case RecoveryReason::PowerCycle: return "power cycled"; case RecoveryReason::None: default: return "no firmware"; } } bool powerCyclesRequestRecovery(uint8_t power_on_count) { return power_on_count >= POWER_CYCLES_FOR_RECOVERY; } bool recoveryShouldStartMain(RecoveryReason reason, uint32_t running_ms, bool wifi_connected, bool main_available) { if (!main_available) return false; if (reason == RecoveryReason::Wifi) return wifi_connected && running_ms >= RECOVERY_MIN_TIME; return running_ms >= RECOVERY_TIME; }