#pragma once #include namespace roro { // Decides when new firmware on Probation (see CONTEXT.md) has proven healthy, or has failed in a // way that would leave no means to push a fix (Wi-Fi configured but never connecting). class Probation { public: enum class Verdict { Wait, Confirm, RollBack }; static constexpr uint32_t kHealthyAfterMs = 30000; static constexpr uint32_t kWifiDeadlineMs = 180000; // Checked first thing at boot, before anything that could crash. `attemptsBefore` counts earlier // boots of this image on Probation; a second start means the first one died before confirming. // (A second line behind the bootloader's own rollback, which aborts an image still pending.) static bool rollBackAtBoot(bool onProbation, int attemptsBefore) { return onProbation && attemptsBefore >= 1; } static Verdict judge(uint32_t uptimeMs, bool firstFrameDrawn, bool wifiConfigured, bool wifiConnected) { if (wifiConfigured && !wifiConnected && uptimeMs >= kWifiDeadlineMs) return Verdict::RollBack; if (uptimeMs < kHealthyAfterMs || !firstFrameDrawn) return Verdict::Wait; if (wifiConfigured && !wifiConnected) return Verdict::Wait; return Verdict::Confirm; } }; } // namespace roro