Merge remote-tracking branch 'origin/schwifty/fix-device-info-disconnect-retry'
This commit is contained in:
commit
07c5a22315
1 changed files with 46 additions and 8 deletions
|
|
@ -157,6 +157,7 @@ class BeaconProvisioner: NSObject, ObservableObject {
|
|||
private var dxSmartWriteIndex = 0
|
||||
private var provisioningMacAddress: String?
|
||||
private var awaitingDeviceInfoForProvisioning = false
|
||||
private var skipDeviceInfoRead = false // set after disconnect during device info — skip MAC read on reconnect
|
||||
private var isTerminating = false // guards against re-entrant disconnect handling
|
||||
|
||||
// Read config mode
|
||||
|
|
@ -215,6 +216,7 @@ class BeaconProvisioner: NSObject, ObservableObject {
|
|||
self.dxSmartWriteIndex = 0
|
||||
self.provisioningMacAddress = nil
|
||||
self.awaitingDeviceInfoForProvisioning = false
|
||||
self.skipDeviceInfoRead = false
|
||||
self.isTerminating = false
|
||||
self.connectionRetryCount = 0
|
||||
self.currentBeacon = beacon
|
||||
|
|
@ -298,6 +300,7 @@ class BeaconProvisioner: NSObject, ObservableObject {
|
|||
dxSmartWriteIndex = 0
|
||||
provisioningMacAddress = nil
|
||||
awaitingDeviceInfoForProvisioning = false
|
||||
skipDeviceInfoRead = false
|
||||
isTerminating = false
|
||||
connectionRetryCount = 0
|
||||
currentBeacon = nil
|
||||
|
|
@ -406,6 +409,14 @@ class BeaconProvisioner: NSObject, ObservableObject {
|
|||
|
||||
/// Read device info (MAC address) before writing config
|
||||
private func dxSmartReadDeviceInfoBeforeWrite() {
|
||||
// If we previously disconnected during device info read, skip it entirely
|
||||
if skipDeviceInfoRead {
|
||||
DebugLog.shared.log("BLE: Skipping device info read (reconnect after previous disconnect)")
|
||||
skipDeviceInfoRead = false
|
||||
dxSmartWriteConfig()
|
||||
return
|
||||
}
|
||||
|
||||
guard let commandChar = characteristics[BeaconProvisioner.DXSMART_COMMAND_CHAR] else {
|
||||
DebugLog.shared.log("BLE: FFE2 not found, proceeding without MAC")
|
||||
dxSmartWriteConfig()
|
||||
|
|
@ -1012,16 +1023,43 @@ extension BeaconProvisioner: CBCentralManagerDelegate {
|
|||
return
|
||||
}
|
||||
|
||||
// Disconnect during device info read (post-auth, pre-write) — beacon may have
|
||||
// dropped the connection during the MAC address query. We authenticated but
|
||||
// lost connection before writing config, so this is a failure — but a known
|
||||
// one with a clear retry path, not an unexplained "Unexpected disconnect".
|
||||
// Disconnect during device info read (post-auth, pre-write) — beacon dropped
|
||||
// connection during the optional MAC address query. Instead of failing, reconnect
|
||||
// and skip the device info step (MAC is nice-to-have, not required).
|
||||
if state == .authenticating && awaitingDeviceInfoForProvisioning && dxSmartAuthenticated {
|
||||
DebugLog.shared.log("BLE: Disconnect during device info read (post-auth) — connection lost before config write, failing with retry prompt")
|
||||
awaitingDeviceInfoForProvisioning = false
|
||||
// Connection lost — can't write config without it, fail with specific message
|
||||
fail("Disconnected after auth during device info read — please retry", code: .disconnected)
|
||||
return
|
||||
skipDeviceInfoRead = true // on reconnect, go straight to config write
|
||||
|
||||
if connectionRetryCount < BeaconProvisioner.MAX_CONNECTION_RETRIES {
|
||||
connectionRetryCount += 1
|
||||
let delay = Double(connectionRetryCount)
|
||||
progress = "Reconnecting (skip MAC read)..."
|
||||
DebugLog.shared.log("BLE: Disconnect during device info read — reconnecting (\(connectionRetryCount)/\(BeaconProvisioner.MAX_CONNECTION_RETRIES)), will skip MAC read")
|
||||
|
||||
// Reset BLE state for reconnect
|
||||
dxSmartAuthenticated = false
|
||||
dxSmartNotifySubscribed = false
|
||||
dxSmartCommandQueue.removeAll()
|
||||
dxSmartWriteIndex = 0
|
||||
characteristics.removeAll()
|
||||
responseBuffer.removeAll()
|
||||
state = .connecting
|
||||
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + delay) { [weak self] in
|
||||
guard let self = self, let beacon = self.currentBeacon else { return }
|
||||
guard self.state == .connecting else { return }
|
||||
|
||||
let resolvedPeripheral = self.resolvePeripheral(beacon)
|
||||
self.peripheral = resolvedPeripheral
|
||||
resolvedPeripheral.delegate = self
|
||||
self.centralManager.connect(resolvedPeripheral, options: nil)
|
||||
}
|
||||
return
|
||||
} else {
|
||||
DebugLog.shared.log("BLE: Disconnect during device info read — max retries exhausted")
|
||||
fail("Disconnected while reading device information (retries exhausted)", code: .disconnected)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// All other disconnects are unexpected
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue