fix: resolve FFE2 characteristic lost during write #18

Closed
schwifty wants to merge 0 commits from schwifty/fix-ffe2-characteristic-lost into main
Collaborator

Summary

  • Root cause: CoreBluetooth invalidates cached CBCharacteristic references during BLE connection parameter renegotiation (common at edge-of-range), causing our characteristics[] dictionary to return nil mid-write
  • Fix: Added resolveCharacteristic() method that falls back to walking the peripheral's live service list when the cache misses, plus didModifyServices delegate to proactively clear stale cache entries and re-discover
  • Replaces all direct characteristics[] lookups with resolveCharacteristic() — also eliminates a force-unwrap on FFE1 subscribe

Test plan

  • Happy path: Provision a beacon at normal range — full command queue completes without issues
  • Edge-of-range: Provision at weak signal to trigger connection parameter renegotiation mid-write — should no longer crash with "FFE2 characteristic lost"
  • Service invalidation recovery: Confirm live service resolution fallback grabs a valid characteristic when the dictionary entry is stale
  • Read config flow: Verify beacon check still reads UUID/major/minor/name correctly

🤖 Generated with Claude Code

## Summary - **Root cause**: CoreBluetooth invalidates cached `CBCharacteristic` references during BLE connection parameter renegotiation (common at edge-of-range), causing our `characteristics[]` dictionary to return nil mid-write - **Fix**: Added `resolveCharacteristic()` method that falls back to walking the peripheral's live service list when the cache misses, plus `didModifyServices` delegate to proactively clear stale cache entries and re-discover - Replaces all direct `characteristics[]` lookups with `resolveCharacteristic()` — also eliminates a force-unwrap on FFE1 subscribe ## Test plan - [ ] Happy path: Provision a beacon at normal range — full command queue completes without issues - [ ] Edge-of-range: Provision at weak signal to trigger connection parameter renegotiation mid-write — should no longer crash with "FFE2 characteristic lost" - [ ] Service invalidation recovery: Confirm live service resolution fallback grabs a valid characteristic when the dictionary entry is stale - [ ] Read config flow: Verify beacon check still reads UUID/major/minor/name correctly 🤖 Generated with [Claude Code](https://claude.com/claude-code)
schwifty added 1 commit 2026-03-22 04:48:21 +00:00
When CoreBluetooth renegotiates connection parameters (common at edge-of-range),
it can invalidate cached CBCharacteristic references, causing the characteristics
dictionary to return nil mid-write. This resulted in "FFE2 characteristic lost
during write" failures.

Changes:
- Add resolveCharacteristic() with live service fallback when cache misses
- Implement peripheral(_:didModifyServices:) to handle service invalidation
- Replace all direct characteristics[] lookups with resolveCharacteristic()
- Eliminates force-unwrap on FFE1 notification subscribe

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
schwifty closed this pull request 2026-03-22 18:43:36 +00:00

Pull request closed

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#18
No description provided.