Void Sentry
An AI-driven, real-time Sentry Turret platform leveraging asynchronous I/O and computer vision to deliver high-precision autonomous motion tracking on resource-constrained embedded hardware.
Loading...
Searching...
No Matches
wifi_manager.h
Go to the documentation of this file.
1
6#pragma once
7
8#include "choose.h"
9#include "form.h"
10#include "network_list.h"
11#include "pin_guard.h"
12#include "prov_types.h"
13#include "sync.h"
14#include "wifi_plan.h"
15#include "wifi_store.h"
16#include <Arduino.h>
17#include <DNSServer.h>
18#include <WiFi.h>
19#include <atomic>
20#include <freertos/FreeRTOS.h>
21#include <freertos/semphr.h>
22
40{
41public:
43 struct Status {
44 const char* mode = "joining";
45 char ssid[prov::kSsidMax + 1] = {};
46 char ip[16] = {};
47 bool pin_set = false;
48 const char* failure = "";
49 };
50
52 enum class Result { Ok, BadInput, WrongPin, LockedOut };
53
55 struct Outcome {
56 Result result = Result::BadInput;
57 uint32_t seconds_left = 0;
58 };
59 using AddOutcome = Outcome;
60 using ForgetOutcome = Outcome;
61
63 static constexpr size_t kScanCap = 24;
64
65 WifiManager() = default;
66 WifiManager(const WifiManager&) = delete;
67 WifiManager& operator=(const WifiManager&) = delete;
68
73 void begin();
74
78 void maintain();
79
86 Status status();
87
89 const char* mode_name();
90
92 bool setup_mode() const { return this->_hotspot_flag.load(); }
93
95 prov::PlanState plan_state();
96
103 size_t scan(prov::ScanResult* out, size_t cap);
104
106 size_t saved(char (*ssids)[prov::kSsidMax + 1], size_t cap);
107
113 AddOutcome add(const char* ssid, size_t ssid_len, const char* pass, size_t pass_len, const char* pin,
114 size_t pin_len, uint32_t now_ms);
115
117 ForgetOutcome forget(const char* ssid, size_t ssid_len, const char* pin, size_t pin_len, uint32_t now_ms);
118
119private:
120 static void on_wifi_event(arduino_event_id_t event, arduino_event_info_t info);
121
122 void process_events(uint32_t now);
123 void poll_scan(uint32_t now);
124 void collect_scan(int count, uint32_t now);
125 void apply(prov::Action a, uint32_t now);
126 void do_join(const prov::NetworkEntry& e);
127 void start_hotspot();
128 void stop_hotspot();
129 void poll_serial();
130 void factory_reset();
131 const char* mode_name_locked() const;
133 Status build_status_locked() const;
135 void publish_status_locked();
136
137 static WifiManager* _instance;
138
139 SemaphoreHandle_t _mutex = nullptr;
140 WifiStore _store;
141 prov::NetworkList _list;
142 prov::PinGuard _pin;
143 prov::WifiPlan _plan;
144 DNSServer _dns;
145
146 // Event flags written by the arduino_events task.
147 std::atomic<bool> _ev_got_ip{false};
148 std::atomic<bool> _ev_disc{false};
149 std::atomic<bool> _ev_leave{false}; // ASSOC_LEAVE: kept apart from _ev_reason, see on_wifi_event()
150 std::atomic<uint8_t> _ev_reason{0};
151 std::atomic<bool> _hotspot_flag{false};
152
154 vsync::SpinGuarded<Status> _status_snap;
155
156 // Shared with the HTTP layer (guarded by _mutex).
158 size_t _scan_n = 0;
159 bool _scan_valid = false;
160 uint32_t _scan_time_ms = 0;
161 bool _ui_scan_wanted = false;
162 bool _added_pending = false;
163 char _cur_ssid[prov::kSsidMax + 1] = {};
164 char _cur_ip[16] = {};
165 char _joining_ssid[prov::kSsidMax + 1] = {};
166
167 // Used by the loop() side only.
168 bool _scan_running = false;
169 bool _plan_scan_pending = false;
170 uint32_t _scan_start_ms = 0;
171 prov::PlanState _prev_state = prov::PlanState::Boot;
172 char _cand_ssid[prov::kMaxNetworks][prov::kSsidMax + 1] = {}; // list SSIDs at the last scan, by list index
173 bool _hotspot_failed = false;
174 uint32_t _hotspot_retry_ms = 0;
175 bool _hotspot_running = false;
176 bool _stop_pending = false;
177 uint32_t _stop_at_ms = 0;
178 char _hotspot_ssid[20] = {};
179 char _line[24] = {};
180 size_t _line_len = 0;
181 bool _line_overflow = false;
182};
Picks which saved networks to try, given a scan (pure C++20, no heap).
Glue between the pure prov::WifiPlan and the Arduino WiFi stack.
Definition wifi_manager.h:40
size_t saved(char(*ssids)[prov::kSsidMax+1], size_t cap)
Copies the saved SSIDs.
Definition wifi_manager.cpp:551
void maintain()
Call from loop(): WiFi events, scan polling, plan timers, hotspot DNS and the serial wifi-reset.
Definition wifi_manager.cpp:114
ForgetOutcome forget(const char *ssid, size_t ssid_len, const char *pin, size_t pin_len, uint32_t now_ms)
Forgets a saved network after checking the PIN (same PinGuard as add, so lockouts are shared).
Definition wifi_manager.cpp:624
static constexpr size_t kScanCap
Capacity of the scan cache (strongest networks beyond it are not guaranteed to be kept).
Definition wifi_manager.h:63
AddOutcome add(const char *ssid, size_t ssid_len, const char *pass, size_t pass_len, const char *pin, size_t pin_len, uint32_t now_ms)
Adds (or replaces) a network after checking the PIN; the first add with no PIN set defines the PIN.
Definition wifi_manager.cpp:562
prov::PlanState plan_state()
Current plan state (thread-safe; for tests and diagnostics).
Definition wifi_manager.cpp:467
Status status()
Snapshot of mode, SSID, IP, whether a PIN is set and the last failure.
Definition wifi_manager.cpp:473
Result
Result of add()/forget(); the HTTP layer maps it to 200 / 400 / 403 / 429.
Definition wifi_manager.h:52
void begin()
Loads NVS, brings up the WiFi stack and starts the connection plan. Returns at once.
Definition wifi_manager.cpp:89
size_t scan(prov::ScanResult *out, size_t cap)
Copies the cached scan (strongest entry per SSID, hidden networks skipped).
Definition wifi_manager.cpp:519
const char * mode_name()
Short mode name for logs ("sta" | "setup" | "joining" | "lost").
Definition wifi_manager.cpp:461
bool setup_mode() const
true while the setup hotspot is running (atomic, no lock).
Definition wifi_manager.h:92
Reads and writes the wifi NVS namespace (keys nets, pin, appw) using the pure blob formats.
Definition wifi_store.h:18
Up to kMaxNetworks saved networks; the least recently added or joined one is evicted when full.
Definition network_list.h:14
Guards the PIN. The 5th consecutive wrong PIN starts a lockout of min(60 s * 2^k, 3600 s),...
Definition pin_guard.h:24
Decides what the WiFi glue should do next. Events that do not apply to the current state return Actio...
Definition wifi_plan.h:27
A value of type T that owns its own spinlock; every access is one short critical section.
Definition sync.h:54
x-www-form-urlencoded decoding and input validation for the WiFi page (pure C++20,...
Fixed-capacity list of saved WiFi networks with recency-based eviction (pure C++20,...
PIN storage (salted SHA-256) with constant-time check and escalating lockout (pure C++20,...
Plain value types shared by the WiFi provisioning logic (pure C++20, no heap).
Outcome with the lockout time for Result::LockedOut.
Definition wifi_manager.h:55
Snapshot for /api/wifi/status.
Definition wifi_manager.h:43
const char * mode
"sta" | "setup" | "joining" | "lost" (string literal)
Definition wifi_manager.h:44
const char * failure
"wrong password" | "not found" | "timeout" | "failed" | "" (string literal)
Definition wifi_manager.h:48
Definition wifi_plan.h:17
One saved network. Strings are NUL-terminated.
Definition prov_types.h:31
One access point seen by a scan.
Definition prov_types.h:45
Small RAII wrappers for the two locking patterns the firmware uses (device only).
WiFi connection state machine: events in, actions out (pure C++20, no heap).
NVS persistence for the saved WiFi networks, the PIN record and the setup hotspot password.