Native BLE local control¶
Current BLE security/host/bulk-transfer contract: bonded BLE transport. LE Secure Connections with numeric comparison and bonding supersedes the Security 2 firmware requirement in older sections below. Apps retain Security 2 only for older installed firmware; no fixed device passkeys are used.
ESP-IDF v6.1 NimBLE and pinned espressif/ble_conn_mgr provide one peripheral
host. esp_local_ctrl uses a transport adapter over that host, with link-encrypted
protobuf framing. Numeric comparison requires a headset click, and bond security
records persist through the render flash gate. No fixed passkey or private
credential header is required. Phone/watch bonds are independent; one connection
still owns control.
Standard OTS from espressif/ble_services supplies metadata and control points.
The bounded CoC worker handles firmware staging and immutable catalogue reads;
GATT FF01 remains the update fallback and FF02 remains INFO/paging/log/audio access.
New clients subscribe to update completion indications. GATT callbacks do no flash
work. CoC credits are replenished after bounded handoff consumption. Dedicated OTA
mode remains latched across abort/failure, allowing explicit retry without reset.
OTA is omitted by menuconfig, with capability bit 10 cleared; BLE itself can also
be compiled out. See the security/bulk contract.
When BLE is enabled, it is the boot default; Wi-Fi starts only after a five-second hold or boot-held recovery. Holding five seconds toggles BLE/Wi-Fi; a restrained base-to-tip wave shows blue/green through the render owner and normal brightness/current limits. Triple press selects BLE. Radio owners claim an exclusive startup/active token and release it after stopping, so mode changes cannot overlap their radio startup. Wi-Fi inactivity returns to BLE; BLE advertising itself does not expire.
Firmware 0.5.6 removes the ambient BLE activity effect, passive scanning and the app-owned scan-only host. The radio owner now has only idle/local-control modes; Bonded link security, comparison timeout, exclusive radio ownership, render-owned flash pauses and authenticated OTA retain their existing lifecycles. Bluetooth memory is never permanently released. Numeric-comparison pairing replaces the private credential prerequisite; LEDs/button/motion remain independently available. Repeated handovers and minimum runtime heap still need hardware acceptance.
Fresh Kconfig defaults disable the NimBLE observer role. Existing generated configs are preserved and may still compile the unused SDK observer support; there are no application scan calls. Peripheral/broadcaster support and one connection remain. Central operation stays disabled; SMP and guarded bond storage are enabled. Unsecured connections are terminated after 45 seconds. NimBLE logs stay at Warning; application session/heap/transition diagnostics remain enabled.
The control host installs a small Service Changed listener through its own event
queue. A subscribed peer gets one full-range cache invalidation per connection;
bond keys and local identity persist, while subscription/cache state does not. Stop suppresses it immediately, unregisters on
the host task, and releases both events after acknowledgement, before SDK teardown.
If that acknowledgement times out, teardown is refused until a later stop can
finish safely. Keep CONFIG_BT_NIMBLE_GATT_CACHING=n: the SDK's general cache has
an NVS backend independent of CONFIG_BT_NIMBLE_NVS_PERSIST.
Application protocol 2 adds authenticated espurr/catalogue (FF02) alongside
OTA. INFO/PAGE replies share the same serialised application exchange owner; immutable
bytes and their precomputed hash stay in flash. PAGE allocates at most 496 plaintext
bytes. There is no effect-mask property or protocol-1 fallback. See
catalogue wire contract.
Older Security 2 firmware¶
Current firmware doesn't read generated Security 2 verifiers. Rebuilding older firmware needs its matching source tag and provisioning tools. Native apps retain the authenticated Security 2 path for installed older revisions; it isn't a plaintext fallback for current firmware.
Commands and results¶
Property-value encoding and names: ../../docs/local-control.md. Discover names/indices every session; read at most four properties per request so metadata, values and encryption fit the stock 512-byte payload limit.
Every set batch includes a nonzero, increasing command.id. Actions are exclusive
with settings fields; duplicate/conflicting properties and malformed values are
rejected. GATT callbacks validate and enqueue nonblocking work; all LEDs, settings,
calibration and NVS saves remain render-owned. Settings saves coalesce for ten idle seconds.
Set success means accepted. command.result reports generation, ID, ESP error,
applied revision and queued/applied/failed state. Eight result records retain retry
identity; repeating a retained ID cannot execute the action again. Old evicted IDs
are rejected. Disconnect/host transition invalidates queued tickets. The app must
serialize writes, poll its exact result and refresh confirmed state. status exposes
motion, estimated current, output rate, dithering, pending save and save error.
The early migration record preserves the original authentication/control measurements. Current pairing, handover and loaded output timing need their own hardware acceptance.
Dedicated recovery¶
Recovery can run Wi-Fi and bonded BLE together without wearable services. It starts
only the primary user button to confirm new numeric-comparison requests; the boot
hold must be released before a fresh click can confirm. Existing bonds may reconnect.
Button startup failure leaves Wi-Fi and bonded BLE available. Settings
and control mutations are rejected. OTA still uses the shared bounded worker.
Both phones recognise authenticated firmware.recovery and
firmware.upload_project metadata and open the file-based updater. The running
firmware.project remains the recovery identity; OTA preflight uses the explicit
normal upload family. BLE AP provisioning is available as described below; phone release downloads remain deferred.
During update mode, new numeric comparisons are rejected and pending comparisons are cancelled. Bond writes/deletes and other non-OTA flash holds are rejected by the runtime; update entry excludes outstanding flash holds. Existing secured links and bond restoration remain available for OTA/retry.
BLE Wi-Fi password setup¶
Bonded phone clients can configure the ears' own AP password in normal Settings → Wi-Fi or recovery's Set up recovery Wi-Fi route. The firmware reports the actual SSID and credential-storage state; 8–63 printable ASCII characters are accepted. Generate/reveal/copy/save use transient fields, never password readback. Saving is blocked during OTA, in demo/disconnected sessions and for newer credential schemas. Recovery starts the AP after first setup; an already running AP uses the changed password after restart. Normal firmware retains its physical radio mode switch. Watch setup remains on the phone. See the provisioning wire/storage contract and recovery/reset guide.