# Changelog
All notable changes to espnow_mqtt will be documented here.
Format: [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
Versioning: [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
---
## [0.4.0] — Wi-Fi setup trigger and power save
### Added
- `wifi_mgr_reboot_into_setup()`: reboot straight into BLE provisioning
("setup mode"), keeping stored networks. The call to wire to a product's
setup trigger (button, app command, power-cycle gesture). Uses a magic
value in RTC no-init memory, read and cleared by `wifi_mgr_init()` on
every boot and honoured only after a software reset (not after power-on,
a crash or deep-sleep wakeup). Does not return.
- `wifi_mgr_forget_all_and_reboot_into_setup()`: forget every network,
commit the empty store to NVS, then reboot into setup mode. On a commit
failure it restores RAM from NVS, returns the error and does not reboot.
- Setup-mode deadline when credentials are stored:
`CONFIG_WIFI_SETUP_DEADLINE_MS` (300 s), extended by
`CONFIG_WIFI_SETUP_GRACE_MS` (60 s) while a phone is connected over BLE
or received credentials are pending, capped by `CONFIG_WIFI_SETUP_MAX_MS`
(15 min). Failed attempts restart in place inside the deadline. At the
end: session stopped, held credentials discarded, station confirmed
disconnected, driver copy wiped, back to scanning. Nothing from a session
ended this way is saved, even if it connects at that moment. With no
credentials stored, setup mode lasts until provisioning succeeds, as
before.
- `ps_mode` (`CONFIG_WIFI_PS_MODE`, `wifi_mgr_config_t.ps_mode`,
`wifi_mgr_ps_mode_t`): applied after `esp_wifi_start()` and after every
provisioning session.
- Once-per-boot log hint, when no stored network is reachable, that the
application must provide a setup trigger. README "Integration checklist".
- Example: Wi-Fi setup button in `examples/basic_provisioning`, built on
`espressif/button` (example-only dependency): BOOT button by default; hold
3 s = setup, 10 s = forget all, decided on release; callbacks hand the
action to a task because they run in the `esp_timer` task.
- Example README: the Bluetooth memory section described the release as
automatic; it only happens under `FREE_ON_SUCCESS` (not the default).
### Fixed
- **`FREE_ON_SUCCESS` never rebooted when BLE was needed again.** The
`bt_mem_freed` check ran only when `network_prov_mgr_init()` failed,
which it never does; the failure surfaces in
`network_prov_mgr_start_provisioning()`. The check now runs before either
call, and the reboot goes through the setup flag — a plain
`esp_restart()` would have come back connected (a provisioned device
never provisions by itself since 0.3.0), silently dropping the request.
- **`wifi_mgr_start_ble_provisioning()` from CONNECTED broke setup mode.**
The resulting disconnect made `on_disconnect()` overwrite PROVISIONING
with SCANNING, so the manager scanned while BLE provisioning ran and
ignored its result. `on_disconnect()` now leaves PROVISIONING alone.
- A setup-mode start that failed in the caller's task could leave the
manager task blocked in a wait for the old state. It is now woken.
- In SCANNING and RESCAN_ONCE, an unrelated notification during a scan
could be taken for the scan watchdog (aborting the scan, or overwriting
a state set by another task). Both now keep waiting or re-dispatch.
- The manager task could briefly observe the IDLE state at start-up.
### Changed
- Bluetooth lifecycle help text and code comments corrected: the BLE
controller is torn down at every session stop under both options; only
`esp_bt_mem_release()` is irreversible. `KEEP_ALIVE` keeps memory
reserved, not the controller running. Behaviour unchanged.
- `WIFI_PROV_TIMEOUT_MS` now limits each attempt; with credentials stored
the setup deadline limits the whole setup mode (whichever ends first).
- `auto_provision = ALWAYS` with `FREE_ON_SUCCESS` logs a start-up warning
(one reboot per automatic setup mode during an outage).
### Migration
- Recompile: `wifi_mgr_config_t` grew `ps_mode`.
- Wire `wifi_mgr_reboot_into_setup()` to a trigger (see the Integration
checklist).
- If you called `esp_wifi_set_ps()` yourself, use `ps_mode` instead —
the component re-applies its own setting after provisioning.
- A manually started setup on a provisioned device now ends after the
deadline instead of retrying forever.
---
## [0.3.1] — Review fixes for 0.3.0
### Fixed
- **The driver-config wipe after a failed session could fail silently**,
leaving an unverified password in the driver's NVS (`nvs.net80211`).
`esp_wifi_disconnect()` is asynchronous, so `esp_wifi_set_config()` could
return `ESP_ERR_WIFI_STATE`. In addition, while its state is ≥ CRED_RECV
(including STOPPING), network_provisioning reconnects on unexpected
disconnect reasons when `wifi_conn_attempts == 0` — including
`WIFI_REASON_ASSOC_LEAVE` from our own disconnect — which matters if the
`NETWORK_PROV_END` wait timed out. The wipe now retries for up to 1 s;
if it still fails it is deferred and retried before the next connection
attempt (normally seconds later, and the only early safe point on a
device that then resumes normal operation for weeks), at the next
session end and at start-up.
- `KNOWN_AP_UNREACHABLE` could be reported as `NO_KNOWN_AP_IN_TW`: after a
re-armed window, attempts continuing from the existing connect list
without a fresh scan did not count as "known AP seen". Attempts now count.
- When the window expired in the same wakeup as an attempt's failure, the
failure was recorded in the new window. The failure is now recorded
first, so the event reports it and the new window starts clean.
---
## [0.3.0] — Provisioning safety
### Fixed
- **A provisioned device could fall into BLE provisioning permanently.** A
router that took longer than the tw window to come back, with any
neighbour's AP in range, sent the device to PROVISIONING, where it
retried forever and never scanned again — until power-cycled, and
advertising to anyone in BLE range meanwhile. tw expiry is now governed
by `auto_provision` (new Kconfig choice `CONFIG_WIFI_AUTO_PROVISION`,
runtime field `wifi_mgr_config_t.auto_provision`). The default,
`WHEN_UNPROVISIONED`, provisions only when no credentials are stored,
checked at expiry time.
- **Unverified credentials were stored with top priority.** The CRED_RECV
handler called `ap_records_add()` (use_count = max + 1, evicting the
lowest entry when full) before the connection was tried. Credentials
are now held in RAM and saved only after CRED_SUCCESS; the held
password is wiped on success, failure, timeout and shutdown.
- **The driver's own NVS kept provisioned passwords.** network_provisioning
leaves the driver in `WIFI_STORAGE_FLASH` after every
`start_provisioning()` and writes received (unverified) credentials to
`nvs.net80211`. As a result later reconnects wrote to flash whenever
the config changed, and `wifi_mgr_reset_provisioning()` left the last
password behind. RAM storage is now re-applied after every
`start_provisioning()` and at the end of every session; the driver
config is overwritten after a failed session and at every
`wifi_mgr_start()` (before `esp_wifi_start()`, only if something is
stored), which also cleans units provisioned with 0.1.x / 0.2.x.
- A stale tw expiry (timer fired just as the last live AP disappeared)
could start provisioning with no APs in range, contrary to R7. It is
now ignored outside TW_ACTIVE.
- If `esp_wifi_set_config()` failed, `wifi_mgr_connect_attempt()` never
armed `connect_timer`, leaving the manager waiting forever. The timer is
now always armed.
- In TW_ACTIVE, an unrelated notification during a connect attempt
started a second attempt on top of the first. The task now keeps
waiting for the attempt's outcome.
- `conn_info.channel` was 0 in the CONNECTED event after provisioning.
### Changed
- When tw expires and provisioning is not allowed, the component posts an
event, re-arms the window and keeps scanning/connecting. It does not
disconnect, does not abort a scan, and a connection completing at the
same moment wins.
- `WIFI_MGR_EVENT_NO_KNOWN_AP_IN_TW` now means "no stored AP was visible
during the window" and no longer implies provisioning is starting —
watch `WIFI_MGR_EVENT_PROVISIONING_STARTED` for that.
- The stored BSSID is used as a first-attempt lock only when that BSSID
appears in the current scan; otherwise the first attempt is SSID-only
(avoids a wasted attempt in mesh / multi-AP homes). The BSSID of the
AP joined during provisioning is now stored.
- `wifi_mgr_start()` order: init → STA mode → wipe stored driver config →
RAM storage → start.
### Added
- `WIFI_MGR_EVENT_KNOWN_AP_UNREACHABLE` (id 11, appended) with
`wifi_mgr_known_ap_unreachable_t {ssid, last_reason, attempts}`: a stored
AP was visible during the window but every attempt failed. Never
triggers provisioning by itself — a look-alike AP produces the same
failures.
- `wifi_mgr_auto_prov_t` and `wifi_mgr_config_t.auto_provision` (appended
to the struct; zero = Kconfig default).
### Migration
- Recompile: `wifi_mgr_config_t` grew a field. Designated initialisers
and `NULL` config are unaffected.
- A provisioned device no longer re-provisions automatically after a
router password change. Provide a manual trigger that calls
`wifi_mgr_start_ble_provisioning()`, or set `auto_provision` to
`ALWAYS` to keep the old behaviour (not recommended).
- Not yet changed (planned): `FREE_ON_SUCCESS` reboot path, time-limited
manual sessions, `ps_mode`, runtime PoP, design-doc corrections.
---
## [0.2.0] — ESP-IDF v6.0 port
### Changed (breaking)
- Requires ESP-IDF v6.0 or later (`idf: ">=6.0.0"`). Stay on 0.1.x for v5.x.
- Provisioning now uses `espressif/network_provisioning` (declared in
`idf_component.yml`) instead of the built-in `wifi_provisioning`
component, which ESP-IDF v6.0 removed. Internal API is a 1:1 rename
(`wifi_prov_*` → `network_prov_*`, `WIFI_PROV_CRED_*` →
`NETWORK_PROV_WIFI_CRED_*`, `WIFI_PROV_END` → `NETWORK_PROV_END`).
The public `wifi_manager.h` API is unchanged.
- `network_provisioning` and `bt` moved from `REQUIRES` to `PRIV_REQUIRES`;
no public header exposes their types.
### Fixed
- ESP-IDF v6.0 disables protocomm security versions 0 and 1 by default,
which made provisioning fail at runtime with `ESP_ERR_NOT_SUPPORTED` and
no log line. Each `CONFIG_WIFI_PROV_AUTH_MODE_*` option now selects the
matching `CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_x`, and
`wifi_mgr_prov.c` has an `#error` guard as a backstop.
- Provisioning console banner said "SRP6a" for Security 1. Security 1 is
X25519 + AES-CTR (SRP6a is Security 2); label corrected.
### Removed
- IDF v4.x `esp_wifi_set_auto_connect()` compatibility branch.
---
## [0.1.0] — Initial release
1st Release