#pragma once #include #include #include #include "saved_networks.h" namespace roro { struct ScanResult { std::string ssid; int rssi; }; // Decides what the Wi-Fi radio should do next. The Wi-Fi Service feeds it what happened (scan // results, connected, disconnected, Monitoring requests) and carries out the returned Action. // Stays Connected to the strongest Saved Network in range while enabled (radio off when there are // no Saved Networks); Monitoring overrides. class WifiController { public: enum class State { Off, Scanning, Connecting, Connected, Waiting, Monitoring }; enum class Action { None, StartScan, Connect, Disconnect, RadioOff, StartMonitor, StopMonitorAndScan, StopMonitorAndOff }; struct Step { Action action = Action::None; std::string ssid; std::string password; }; static constexpr uint32_t kConnectTimeoutMs = 15000; explicit WifiController(const SavedNetworks& saved) : saved_(saved) {} Step update(uint32_t nowMs, bool enabled); Step scanDone(const std::vector& results, uint32_t nowMs); Step connected(uint32_t nowMs); Step disconnected(uint32_t nowMs); // A Saved Network was just added: stop waiting and scan now. void retryNow(uint32_t nowMs) { if (state_ == State::Waiting) retryAtMs_ = nowMs; retries_ = 0; } Step requestMonitor(); Step releaseMonitor(bool enabled); State state() const { return state_; } const std::string& ssid() const { return ssid_; } // network joined or being joined private: Step wait(uint32_t nowMs); static Step act(Action a) { return Step{a, "", ""}; } const SavedNetworks& saved_; State state_ = State::Off; std::string ssid_; uint32_t sinceMs_ = 0; // when Connecting started uint32_t retryAtMs_ = 0; // when Waiting ends int retries_ = 0; int nextHidden_ = 0; // round-robin over hidden Saved Networks }; } // namespace roro