Skip to content

feat: BLE provisioning for WiFi and MQTT credentials - #10

Merged
JMTamayo merged 4 commits into
mainfrom
feat/ble-provisioning
Jun 20, 2026
Merged

feat: BLE provisioning for WiFi and MQTT credentials#10
JMTamayo merged 4 commits into
mainfrom
feat/ble-provisioning

Conversation

@JMTamayo

Copy link
Copy Markdown
Owner

Summary

Adds a BLE provisioning capability so a deployed ESP32-C3 can be configured in the field over BLE, complementing the host provisioner (which still seeds device_id into NVS). A NimBLE GATT server exposes the device identity plus the WiFi and MQTT settings, persisting every change to flash.

New connectivity/ layer (hexagonal: domain ports → application → infrastructure adapters):

  • connectivity/config — shared configuration stores reused by the future WiFi/MQTT modules:
    • IDeviceConfig / IWifiConfig / IMqttConfig ports with flash-backed adapters.
    • Read-through / write-through to NVS; no in-RAM cache. NVS keys injected at construction.
  • connectivity/provisioning — NimBLE GATT server (plaintext, peripheral-only):
    • Characteristics: device_id (read-only), wifi_ssid (rw), wifi_password (write-only), mqtt_host/mqtt_port/mqtt_user (rw), mqtt_password (write-only). Each carries a 0x2901 user description.
    • start() reads device_id and advertises as <project_name>-<first device_id section>; fails if the device is not provisioned. stop() halts advertising.

Notes

  • BLE host: NimBLE, peripheral-only, enabled in sdkconfig.
  • The NVS contract with the host provisioner is unchanged (namespace config).
  • No security on the BLE link yet (plaintext) — intended for a first MVP.
  • setup.{hpp,cpp} renamed to build.{hpp,cpp} (beginPeripherals()); config.hpp is imported only by main.cpp.

Verification

  • make -C firmware builds cleanly (flash ~53.6%, fits the default app partition).
  • Manual: provision device_id, connect with a BLE app, read/write the characteristics, reboot and confirm values persist from flash.

JMTamayo added 4 commits June 20, 2026 14:54
DigitalActuatorService had a virtual setLevel and a virtual destructor that
were never overridden. The substitution seam is the IDigitalActuator port, not
the service, so drop the speculative polymorphism.
Turn on Bluetooth with the NimBLE host in peripheral-only mode for the BLE
provisioning module, and add the bt requirement to the app component.
Introduce a connectivity layer following the hexagonal structure:
- config: device/wifi/mqtt configuration ports with flash-backed adapters
  (read-through/write-through to NVS, with NVS keys injected at construction).
- provisioning: a NimBLE GATT server exposing device_id (read-only), WiFi and
  MQTT settings as characteristics and persisting writes to flash; passwords
  are write-only. Exposes start()/stop() for flexible availability.

Add the NVS keys, project name and BLE UUIDs to the central config header.
Rename setup.{hpp,cpp} to build.{hpp,cpp} with beginPeripherals(). Instantiate
the connectivity config stores and the provisioning server in main, starting
BLE provisioning after the peripheral begin() sequence.
@JMTamayo
JMTamayo merged commit e2b1111 into main Jun 20, 2026
2 checks passed
@JMTamayo
JMTamayo deleted the feat/ble-provisioning branch June 20, 2026 20:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant