Page 1 of 1

Wi-Fi state manager component for ESP-IDF (C++): architecture feedback

Posted: Tue Feb 03, 2026 4:19 am
by aluiziotomazelli
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.

Re: Wi-Fi state manager component for ESP-IDF (C++): architecture feedback

Posted: Wed Feb 04, 2026 8:41 pm
by MicroController
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:

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;
  }
  ...
}

Re: Wi-Fi state manager component for ESP-IDF (C++): architecture feedback

Posted: Mon Feb 09, 2026 4:38 pm
by aluiziotomazelli
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.

Re: Wi-Fi state manager component for ESP-IDF (C++): architecture feedback

Posted: Tue Feb 10, 2026 8:05 pm
by MicroController
MicroController, your code is a beautiful example of modern C++;
Not too sure about that. But I do use templates ;-)
I’d love to see the whole project if it’s public and available on GitHub.
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:
https://gist.github.com/BitsForPeople/e ... 07a2eba3da
so I still struggle with modern C++ features.
Understandably. There is much more complexity in C++ than in C, or most other languages, both on the syntactical and conceptual level.
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.
Yeah, I saw that you have provisions for unit testing in your code :+1: (I strongly hate writing unit tests - though I really like having them...)

Re: Wi-Fi state manager component for ESP-IDF (C++): architecture feedback

Posted: Tue Feb 10, 2026 8:16 pm
by MicroController
Btw,

Code: Select all

esp_err_t stop(uint32_t timeout_ms);
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

WifiManager::get_instance().stop(1s+500ms);