The beacon reboots instantly on SaveConfig (0x60). Using .withResponse
meant CoreBluetooth expected a GATT ACK that never arrived, potentially
causing the write to be silently dropped — leaving the config unsaved
and the beacon LED still flashing after provisioning.
Switching to .withoutResponse fires the bytes directly into the BLE
radio buffer without requiring a round-trip ACK. The beacon firmware
processes the save command from its buffer before rebooting.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
SaveConfig (0x60) causes the beacon MCU to reboot and save to flash.
It never sends an ACK, so writeToCharAndWaitACK would wait for the
5s timeout, during which the beacon disconnects. The disconnect
handler fires while writesCompleted is still false, causing a false
"Unexpected disconnect: beacon timed out" error.
Fix: fire-and-forget the SaveConfig write and return immediately.
The BLE-level write (.withResponse) confirms delivery. writeConfig()
returns before the disconnect callback runs, so writesCompleted gets
set to true in time.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Shaves ~4.6s off the 23-command provisioning sequence while keeping
a safe margin for the beacon's BLE stack to process each write.
Next step: if stable, we can go more aggressive (200ms or 150ms).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove BlueCharmProvisioner, KBeaconProvisioner, and FallbackProvisioner.
Simplify BeaconType enum to DX-Smart only. Simplify BLE detection to only
show CP-28 beacons. Remove multi-type provisioner factory from ScanView.
-989 lines of dead code removed. Other beacon types will be re-added
when we start using different hardware.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1. Minor allocation: reject minor=0 from API instead of silently using it.
API returning null/0 means the service point isn't configured right.
2. DXSmart write reliability:
- Add per-command retry (1 retry with 500ms backoff)
- Increase inter-command delay from 200ms to 500ms
- Increase post-auth settle from 100ms to 500ms
- Add 2s cooldown in FallbackProvisioner between provisioner attempts
The beacon's BLE stack gets hammered by KBeacon's 15 failed auth
attempts before DXSmart even gets a chance. These timings give it
breathing room.
3. KBeacon passwords: password 5 was a duplicate of password 3
(both "1234567890123456"). Replaced with "000000" (6-char variant).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Frame1_DevInfo (cmd 0x61) and potentially other commands don't send a
separate FFE1 notification after being written. The code was waiting for
didUpdateValueFor (notification) to resolve responseContinuation, but it
never came — causing a 5s timeout on every such command.
The .withResponse write type already guarantees the BLE stack confirmed
delivery. Now didWriteValueFor resolves responseContinuation on success,
so commands that don't trigger notifications still complete immediately.
If a notification also arrives later, responseContinuation is already nil
so it's harmlessly ignored.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- DXSmartProvisioner now reports each phase (connecting, discovering
services, authenticating, retrying) via onStatusUpdate callback
- ScanView shows live diagnostic log during connecting/writing states,
not just on failure — so you can see exactly where it stalls
- Unexpected BLE disconnects now properly update provisioningState to
.failed instead of silently logging
- Added cancel button to connecting progress view
- "Connected" screen title changed to "Connected — Beacon is Flashing"
for clearer status indication
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
BIG FIX: Provisioners were calling centralManager.connect() but
BLEManager is the CBCentralManagerDelegate — provisioners never
received didConnect/didFailToConnect callbacks, so connections
ALWAYS timed out after 5s regardless. This is why provisioning
kept failing. Fixed by:
1. Adding didConnect/didFailToConnect/didDisconnect to BLEManager
2. Provisioners register connection callbacks via bleManager
3. Increased connection timeout from 5s to 10s
DIAGNOSTICS: Added ProvisionLog system so failures show a timestamped
step-by-step log of what happened (with Share button). Every phase
is logged: init, API calls, connect attempts, service discovery,
auth, write commands, and errors.