Hi,
I built a Wi-Fi manager component for ESP-IDF and looking for feedback on the architecture and component registry guidelines:
https://components.espressif.com/compon ... ons/1.0.0/
https://github.com/aluiziotomazelli/wifi_manager
The component wraps esp_wifi with a state machine and runs Wi-Fi operations in a dedicated task.
Key points:
- state machine based on a freertos task
- reconnection with exponencial backoff
- credentials persistence via esp_wifi driver itself NVS, and a valid flag in a class NVS
- C++ API, usable from C
Known limitations:
- no provisioning
- no RSSI evaluation
- WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT currently treated only as auth failure
Appreciate thoughts on overall design, edge cases, and better handling of failures.
Thanks.
Wi-Fi state manager component for ESP-IDF (C++): architecture feedback
-
aluiziotomazelli
- Posts: 3
- Joined: Tue Feb 03, 2026 4:06 am
-
MicroController
- Posts: 2669
- Joined: Mon Oct 17, 2022 7:38 pm
- Location: Europe, Germany
Re: Wi-Fi state manager component for ESP-IDF (C++): architecture feedback
I made something pretty similar. Also C++, also tracking WiFi state and managing state transitions, timed reconnect, an EventGroup for optional blocking/waiting...
I did not use a dedicated task but relied only on the WiFi event callbacks, and a timer for the reconnects. Turned out to work well without any crutches.
One class does the "basic" WiFi operations/"state tracking" and allows hooking up custom event callbacks (at compile time) for events such as "network up" or "network down", which the reconnect logic, in a separate class, leverages to do its thing.
One thing that got me at first was not realizing that the LOST_IP event can appear delayed after the DISCONNECT event, i.e. you can still have an IP after a disconnect/before (re-)connecting.
Your error handling looks better/more complete than mine. I don't return any detail about asynchronous WiFi errors to the caller.
These are the states I used:
Btw:
I use a std::atomic to hold the current state (more concise (and efficient) than a mutex). Then:
I did not use a dedicated task but relied only on the WiFi event callbacks, and a timer for the reconnects. Turned out to work well without any crutches.
One class does the "basic" WiFi operations/"state tracking" and allows hooking up custom event callbacks (at compile time) for events such as "network up" or "network down", which the reconnect logic, in a separate class, leverages to do its thing.
One thing that got me at first was not realizing that the LOST_IP event can appear delayed after the DISCONNECT event, i.e. you can still have an IP after a disconnect/before (re-)connecting.
Your error handling looks better/more complete than mine. I don't return any detail about asynchronous WiFi errors to the caller.
These are the states I used:
Code: Select all
enum class StaState {
STOPPED,
STARTING,
DISCONNECTED,
CONNECTING,
CONNECTED, // but no IP (yet)
HAVE_IP, // fully connected
DISCONNECTING,
STOPPING
};
Code: Select all
static constexpr bool transitionAllowed(const StaState& oldState, const StaState& newState) noexcept {
switch(newState) {
case StaState::STARTING : return anyOf<StaState::STOPPED>(oldState);
case StaState::CONNECTING : return anyOf<StaState::DISCONNECTED>(oldState);
case StaState::CONNECTED : return anyOf<StaState::CONNECTING,StaState::HAVE_IP>(oldState);
case StaState::HAVE_IP : return anyOf<StaState::CONNECTED,StaState::HAVE_IP>(oldState);
case StaState::DISCONNECTING : return anyOf<StaState::CONNECTED,StaState::HAVE_IP>(oldState);
case StaState::DISCONNECTED : return noneOf<StaState::STOPPED>(oldState);
case StaState::STOPPING : return noneOf<StaState::STOPPED,StaState::STARTING>(oldState);
case StaState::STOPPED : return anyOf<StaState::STOPPING>(oldState);
default: { [[unlikely]]; return false; }
};
}
Btw:
I use a std::atomic to hold the current state (more concise (and efficient) than a mutex). Then:
Code: Select all
bool transitionState(const StaState newState) noexcept {
StaState oldState = this->m_state.load(std::memory_order::relaxed);
while(transitionAllowed(oldState,newState)) {
if(this->m_state.compare_exchange_weak(oldState, newState, std::memory_order::acq_rel)) [[likely]] {
return true;
}
}
return false;
}
Code: Select all
esp_result_t start() noexcept {
if( !transitionState(StaState::STARTING) ) [[unlikely]] {
return ESP_ERR_WIFI_STATE;
}
...
}
-
aluiziotomazelli
- Posts: 3
- Joined: Tue Feb 03, 2026 4:06 am
Re: Wi-Fi state manager component for ESP-IDF (C++): architecture feedback
MicroController, your code is a beautiful example of modern C++; I’d love to see the whole project if it’s public and available on GitHub.
My own code is pretty much just 'C with classes.' I program strictly as a hobby and out of necessity, without any formal background in the field, so I still struggle with modern C++ features.
Your response made me realize my task-related code was a total 'spaghetti mess.' I’m finishing a refactor into more classes with specific responsibilities, and I’ve switched to using LUTs (Look-Up Tables) to improve readability and reduce complexity.
These new classes allow for more targeted testing.
I’m currently trying to implement mocks and host-based testing on Linux, leaving only a final set of tests to run on the chip to verify real hardware connections.
Tank you for your feedback.
My own code is pretty much just 'C with classes.' I program strictly as a hobby and out of necessity, without any formal background in the field, so I still struggle with modern C++ features.
Your response made me realize my task-related code was a total 'spaghetti mess.' I’m finishing a refactor into more classes with specific responsibilities, and I’ve switched to using LUTs (Look-Up Tables) to improve readability and reduce complexity.
These new classes allow for more targeted testing.
I’m currently trying to implement mocks and host-based testing on Linux, leaving only a final set of tests to run on the chip to verify real hardware connections.
Tank you for your feedback.
-
MicroController
- Posts: 2669
- Joined: Mon Oct 17, 2022 7:38 pm
- Location: Europe, Germany
Re: Wi-Fi state manager component for ESP-IDF (C++): architecture feedback
Not too sure about that. But I do use templatesMicroController, your code is a beautiful example of modern C++;
Ok. It's somewhat unfinished work, nothing I'd release for others to use as-is. But maybe you can find some useful bits in it:I’d love to see the whole project if it’s public and available on GitHub.
https://gist.github.com/BitsForPeople/e ... 07a2eba3da
Understandably. There is much more complexity in C++ than in C, or most other languages, both on the syntactical and conceptual level.so I still struggle with modern C++ features.
Yeah, I saw that you have provisions for unit testing in your codeThese new classes allow for more targeted testing.
I’m currently trying to implement mocks and host-based testing on Linux, leaving only a final set of tests to run on the chip to verify real hardware connections.
-
MicroController
- Posts: 2669
- Joined: Mon Oct 17, 2022 7:38 pm
- Location: Europe, Germany
Re: Wi-Fi state manager component for ESP-IDF (C++): architecture feedback
Btw,
You may want to look into using std::chrono, specifically std::chrono::milliseconds to represent and handle durations with various resolutions. This allows you to, among other things, write cool things like
Code: Select all
esp_err_t stop(uint32_t timeout_ms);
Code: Select all
WifiManager::get_instance().stop(1s+500ms);
Who is online
Users browsing this forum: Amazon [Bot], Bytespider, PetalBot and 4 guests