Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions Strand/BLE/BLEManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5603,6 +5603,22 @@ extension BLEManager: @preconcurrency CBCentralManagerDelegate {
}
state.append(log: "reconnect n=\(connReconnectCount) failedConnect reason=\(reason)", domain: .connection)
}
// PARITY (#1790): Android can now CLEAR this pairing itself, behind a default-off Test Centre
// switch, once, after five of these failures — the step guide-line 2 asks the user to take. This
// side deliberately cannot, and the blocker is identity rather than a missing call:
//
// - iOS: the same identity problem, with nothing else to reach for. The guide below already
// tells the user to do it themselves, which is the honest answer rather than a claim about
// Apple's intent.
// - macOS ships IOBluetooth, a separate classic-Bluetooth framework, and whether its device
// removal works on a BLE pairing is a question that never arises for us: it addresses devices
// by MAC, and we never have one. `epitaphLine`'s doc already says why — the peripheral UUID is
// "per-install, not the hardware address". The only bridge left is matching
// `IOBluetoothDevice.pairedDevices()` by NAME, and deleting a pairing on a name match removes
// the wrong device the moment there are two straps or one has been renamed.
//
// So both platforms detect this and both give the same advice; only Android can act on it. Do not
// close the gap with a name match. Kotlin twin: `StaleBondRemoval.kt`.
if let cbErr = error as? CBError, cbErr.code == .peerRemovedPairingInformation {
state.reconnectGuide = """
Your strap's Bluetooth pairing was reset - usually by a WHOOP firmware update, or the official WHOOP app reconnecting. NOOP works fine on the new firmware; you just need to re-pair:
Expand Down
22 changes: 22 additions & 0 deletions android/app/src/main/java/com/noop/ble/StaleBondRemoval.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,28 @@ package com.noop.ble
* Independently arrived at by OpenStrap/edge, whose gen5 bootstrap removes the platform bond once after
* five consecutive exchange failures and clears the counter only when a connect reaches READY. The
* threshold and the once-only shape are taken from that behaviour as a fact; none of its code is.
*
* PARITY: Android-only, and the reason is IDENTITY rather than a missing API — worth stating precisely,
* because "CoreBluetooth has no bond-removal call" is true but is not the whole blocker and invites
* someone to go looking for a way round it.
*
* Apple DETECTS the same condition and gives the same advice: `BLEManager`'s `didFailToConnect` handles
* `CBError.peerRemovedPairingInformation` and publishes a forget-and-re-pair guide naming the strap. It
* simply cannot perform the step.
*
* - iOS: the same identity problem, with nothing else to reach for. The app's own guide already tells
* the user to do it in Settings, which is the honest answer rather than a claim about Apple's intent.
* - macOS ships `IOBluetooth`, a separate classic-Bluetooth framework. Whether its device removal
* works on a BLE pairing is a question that never arises: it addresses devices by MAC, and Apple's
* side never has one — `BLEManager.epitaphLine`'s doc already states it, the peripheral UUID being
* "per-install, not the hardware address". The only bridge left is matching
* `IOBluetoothDevice.pairedDevices()` by NAME, and deleting a pairing on a name match is precisely the
* mistake this file's guards exist to prevent: two straps, or a renamed device, and it removes the
* wrong one.
*
* So the gap is real and stays: both platforms detect and ask, only this one can act. If CoreBluetooth
* ever exposes the hardware address, or grows a removal call of its own, revisit it — do not close it
* with a name match.
*/

/**
Expand Down
Loading