fix: handle expected BLE disconnect after SaveConfig #3

Merged
schwifty merged 2 commits from schwifty/fix-saveconfig-disconnect into main 2026-03-21 22:49:05 +00:00
Collaborator

Bug

The DX-Smart CP28 beacon reboots after receiving SaveConfig (0x60) to persist config to flash. This drops the BLE connection before the write callback fires, causing the app to report "Unexpected disconnect" even though provisioning succeeded.

Fix

In didDisconnectPeripheral, check if we're on the last command (SaveConfig) when disconnect occurs. If so, call succeed() instead of fail().

Root cause analysis

Credit to @luna for tracing the full flow — the Android stack handles this gracefully via coroutine timeout, but the iOS delegate-based BLE stack was treating all mid-write disconnects as failures.

Test plan

  • Re-provision a DX-Smart CP28 beacon — should report success instead of "Unexpected disconnect"
  • Provision a fresh beacon — should still work normally
  • Verify disconnect mid-provisioning (before SaveConfig) still reports failure correctly
## Bug The DX-Smart CP28 beacon reboots after receiving `SaveConfig` (0x60) to persist config to flash. This drops the BLE connection before the write callback fires, causing the app to report "Unexpected disconnect" even though provisioning succeeded. ## Fix In `didDisconnectPeripheral`, check if we're on the last command (SaveConfig) when disconnect occurs. If so, call `succeed()` instead of `fail()`. ## Root cause analysis Credit to @luna for tracing the full flow — the Android stack handles this gracefully via coroutine timeout, but the iOS delegate-based BLE stack was treating all mid-write disconnects as failures. ## Test plan - [ ] Re-provision a DX-Smart CP28 beacon — should report success instead of "Unexpected disconnect" - [ ] Provision a fresh beacon — should still work normally - [ ] Verify disconnect mid-provisioning (before SaveConfig) still reports failure correctly
schwifty added 1 commit 2026-03-21 22:29:01 +00:00
The DX-Smart CP28 beacon reboots after receiving SaveConfig (0x60) to
persist config to flash. This drops the BLE connection before the write
callback fires, causing the app to report "Unexpected disconnect" even
though the config was successfully saved.

Now we check if we're on the last command (SaveConfig) when disconnect
occurs — if so, treat it as success instead of failure.

Co-Authored-By: Luna <luna@payfrit.com>
schwifty added 1 commit 2026-03-21 22:47:24 +00:00
The previous fix only caught the disconnect callback path. But CoreBluetooth
can also fire didWriteValueFor with an error when the beacon reboots mid-ATT
response. This was hitting fail() at the isNonFatalCommand check instead of
being treated as success.

Now handles both paths:
1. didDisconnectPeripheral with state=.writing at last command → succeed()
2. didWriteValueFor error for SaveConfig (last command) → succeed()

Also added detailed state/index logging to disconnect handler for diagnostics.
schwifty merged commit f7a554e282 into main 2026-03-21 22:49:05 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: payfrit/payfrit-beacon-ios#3
No description provided.