akilaid/blifi

0.3.2

Latest
uploaded 16 hours ago
blifi: BLE-based Wi-Fi provisioning for ESP32. Provision Wi-Fi credentials over an encrypted BLE session (X25519 + AES-256-GCM, gated by a Proof-of-Possession) instead of a hotspot/captive portal. Includes a NimBLE GATT transport, Wi-Fi station manager with NVS persistence and retry/backoff, and an optional reset-pin factory reset. Companion Flutter package: `blifi` on pub.dev.

Changelog

# Changelog - blifi (ESP-IDF component)

All notable changes to the firmware component are documented here. Format based
on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this component is
versioned independently under [Semantic Versioning](https://semver.org/).

## [Unreleased]

Nothing yet.

## [0.3.2] - 2026-07-27

### Fixed
- Examples now require the component version they actually build against. All
  three examples use `cfg.manage_nvs` (added in 0.3.0), but their
  `main/idf_component.yml` pinned `>=0.1.0`; a registry extract could resolve a
  pre-0.3.0 component that fails to compile. Raised the floor to `>=0.3.0`.
  (Monorepo/CI builds were unaffected, since they build via `override_path`.)

### Changed
- Refreshed stale documentation comments: the `blifi.h` file header no longer
  describes a "Phase 2, Wi-Fi only" state that no longer exists, and the leftover
  `(Phase 3)` markers and internal `docs/plan.md` references were removed from the
  public headers, Kconfig help, and source comments. No code or API change.

## [0.3.1] - 2026-07-27

### Added
- The `BLIFI_EVENT` loop now posts the full provisioning lifecycle:
  `BLIFI_EVENT_STARTED`, `BLIFI_EVENT_BLE_CONNECTED`, and
  `BLIFI_EVENT_CREDENTIALS_RECEIVED` were declared but never fired; they are now
  emitted at their call sites, so an on-device consumer (e.g. a status LED) can
  follow the handshake, not just the Wi-Fi phase.
- `blifi_config_t.prov_timeout_ms` is now enforced (it was previously ignored).
  When set to a non-zero value, blifi stops advertising and posts
  `BLIFI_EVENT_PROV_TIMEOUT` if no BLE central connects within the window. Opt-in;
  default `0` keeps the previous "no timeout" behaviour.

### Removed
- `BLIFI_EVENT_REPROVISIONING_TRIGGERED` (a local `esp_event` id). It was posted
  immediately after `BLIFI_EVENT_WIFI_FAILED` with an identical payload; its one
  internal action (return to provisioning) now happens inside the `WIFI_FAILED`
  handler. Subscribe to `BLIFI_EVENT_WIFI_FAILED` instead. No wire-protocol change
  (these ids are local); no consumer in this repo referenced the removed event.

### Fixed
- After Wi-Fi is given up on, the device now ensures BLE advertising is running and
  waits for new credentials, instead of immediately re-attempting the same stored
  credentials. Previously the give-up path re-armed Wi-Fi, which retried the
  unchanged (often wrong) credentials in a tight loop; a boot that was already
  provisioned but could not connect could also be left unreachable for
  re-provisioning. Credentials are unchanged until the app submits new ones.

## [0.3.0] - 2026-07-27

### Added
- `blifi_config_t.manage_nvs` (default `true`): `blifi_init()` now initialises the
  default NVS partition itself (erasing and retrying once on
  `ESP_ERR_NVS_NO_FREE_PAGES` / `ESP_ERR_NVS_NEW_VERSION_FOUND`), so applications no
  longer need to call `nvs_flash_init()`. Set `manage_nvs = false` to keep managing
  NVS in the application.
- New [`examples/very-minimal`](examples/very-minimal): the shortest integration -
  three calls in `app_main()`, no `nvs_flash_init()`.

### Changed
- The `minimal` and `interactive` examples now set `manage_nvs = false` and keep
  their own `nvs_flash_init()`, to demonstrate the opt-out.
- Renamed the `esp-idf-example` example to `interactive`.

## [0.2.0] - 2026-07-25

### Added
- Fixed (user-defined) Proof-of-Possession. Set an exact 8-character Crockford
  base32 PoP instead of auto-generating one, two ways:
  - `CONFIG_BLIFI_FIXED_POP` (menuconfig / `sdkconfig.defaults`), **validated at
    build time** - a wrong length or an invalid character fails the build.
  - `blifi_config_t.fixed_pop` at runtime, validated in `blifi_init()` (returns an
    error on a malformed value).
  A fixed PoP overrides any NVS-stored value and is not persisted; leaving both
  unset keeps the auto-generated, NVS-backed PoP (unchanged default).
- Public `blifi_pop_validate()` and a self-test covering the format rules.

## [0.1.3] - 2026-07-25

### Changed
- Example manifests: removed the non-standard `description` field that 0.1.2 had
  added to each example's `main/idf_component.yml` (no well-maintained component
  ships one) and pinned the back-dependency `akilaid/blifi: "^0.1"` instead of
  `"*"`, matching espressif/led_strip and esp-iot-solution/button.

### Notes
- The registry auto-generates (and badges "Generated by LLM") the short example
  descriptions from each example's README/code; there is no author override via
  the manifest. The example READMEs are the place to shape that text.
- Publishing is slow server-side: blifi's NimBLE + mbedTLS/PSA dependency graph
  makes the registry's "Processing examples" step take minutes, so the upload
  action can report a timeout even though the version does publish (0.1.2 and
  0.1.3 both landed after "failed" runs). CI now confirms the outcome against the
  registry API instead of trusting the action's exit code.

## [0.1.2] - 2026-07-25

### Changed
- Docs only: removed em-dashes throughout the README, headers, and code comments
  (hyphens/colons instead). No code or API changes.
- Both example manifests now carry an author-written `description` field, so the
  ESP Component Registry shows those instead of an auto-generated summary.
- README links the hard-reset ADR by absolute GitHub URL; the old relative path
  pointed outside the packaged component and broke on the registry.

## [0.1.1] - 2026-07-25

### Added
- Minimal example (`examples/minimal`): the smallest useful integration -
  provisioning plus the reset pin and reset-indicator LED via pure
  configuration, without the serial-console commands of `esp-idf-example`.

## [0.1.0] - 2026-07-24

First public release on the ESP Component Registry (`akilaid/blifi`).

### Added
- Wi-Fi station manager (`blifi_wifi_manager`): active scan, connect using
  supplied or NVS-stored credentials, credential persistence, and a
  retry/backoff connection state machine with a per-attempt connect timeout and
  fast-fail on auth errors.
- Public headers `blifi.h`, `blifi_status.h`, `blifi_wifi_manager.h`; the
  `BLIFI_EVENT` esp_event base (Wi-Fi events live; BLE/provisioning events
  declared for later phases); status/error codes mirroring `docs/protocol-spec.md`.
- Component manifest (`idf_component.yml`) and build (`CMakeLists.txt`).
- Serial-console example (`examples/esp-idf-example`) exercising the manager
  with no BLE.
- Wire protocol: 8-byte big-endian framing with chunking/reassembly and a
  self-contained JSON payload codec (no external cJSON dependency).
- Session security over the PSA Crypto API (mbedTLS 4.x / TF-PSA-Crypto):
  X25519 key agreement, HKDF-SHA256 key schedule with PoP mixing, HMAC-SHA256
  key confirmation, and AES-256-GCM records with per-direction counters and
  replay protection. Proof-of-Possession generation (8-char Crockford base32).
- NimBLE GATT transport (`ble_transport`): the provisioning service with its five
  characteristics, advertising as `blifi-XXXX`, MTU-aware chunked notifications.
- Provisioning manager (`provisioning_manager`): state machine tying BLE ↔
  handshake ↔ Wi-Fi, PoP lifecycle + confirmation lockout, encrypted status
  notifications, and the public API (`blifi_init/start/stop/is_provisioned/
  reset_credentials/get_pop`).
- On-device self-tests (`blifi_selftest`, `selftest` command) with RFC 7748 /
  RFC 5869 / AES-GCM known-answer vectors plus session and framing round-trips.
- Hard reset via reset pin (ADR 0005): the ESP-IDF bootloader
  factory reset erases a dedicated `blifi_nvs` partition (Wi-Fi credentials only)
  when a GPIO is held at boot. New public API `blifi_register_data_reset_callback()`
  and `blifi_was_hard_reset()`, plus the `BLIFI_EVENT_HARD_RESET_TRIGGERED` event,
  let the app erase its own data on the next boot. Ships `partitions.example.csv`;
  the reset GPIO/level/hold-time and erase target are set via bootloader Kconfig in
  the app's `sdkconfig.defaults` (see README). The PoP stays in the default `nvs`
  partition, so it survives a hard reset (printed QR/sticker keeps working).

- Optional hard-reset indicator pin: a `Kconfig.projbuild`
  "Blifi Provisioning → Hard Reset Indicator" menu
  (`CONFIG_BLIFI_RESET_INDICATOR_ENABLE`/`_GPIO`/`_ACTIVE_LEVEL`/`_PULSE_MS`) drives
  a GPIO active when a hard reset is detected, driven from the `hard_reset` module.
  `PULSE_MS=0` holds until re-provisioned (`CONNECTED`). Pin/level/pulse are also
  runtime-overridable via `blifi_config_t.reset_indicator`. Fully opt-in - the whole
  feature compiles out when disabled (default).

### Changed
- Wi-Fi credentials now persist in the dedicated `blifi_nvs` partition (via
  `blifi_wifi_manager_config_t.nvs_partition`) instead of the default `nvs`
  partition, scoping the hard reset to credentials. When `blifi_nvs` is absent,
  blifi logs a loud warning and falls back to the default `nvs` partition.
  **Migration:** existing boards read empty on first boot of this firmware and
  re-provision once.

### Fixed
- NimBLE host-task stack overflow when handling a scan request: moved the
  encrypted-record buffer off the stack (it is lock-guarded) and raised
  `CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE`. Found via live phone interop.

Links

Supports all targets

To add this component to your project, run:

idf.py add-dependency "akilaid/blifi^0.3.2"

download archive

Stats

  • Archive size
    Archive size ~ 64.66 KB
  • Downloaded in total
    Downloaded in total 4 times
  • Weekly Downloads Weekly Downloads (All Versions)
  • Downloaded this version
    This version: 0 times

Badge

akilaid/blifi version: 0.3.2
|