Compare commits
2 commits
cabb2825d8
...
292821622e
| Author | SHA1 | Date | |
|---|---|---|---|
| 292821622e | |||
| cb3e8107fc |
2 changed files with 10 additions and 7 deletions
|
|
@ -182,7 +182,7 @@ class BeaconProvisioner: NSObject, ObservableObject {
|
|||
private var disconnectRetryCount = 0
|
||||
private static let MAX_CONNECTION_RETRIES = 3
|
||||
private static let MAX_DEVICE_INFO_RETRIES = 2
|
||||
private static let MAX_DISCONNECT_RETRIES = 2
|
||||
private static let MAX_DISCONNECT_RETRIES = 3
|
||||
private var currentBeacon: DiscoveredBeacon?
|
||||
|
||||
// Per-write timeout (matches Android's 5-second per-write timeout)
|
||||
|
|
@ -241,8 +241,8 @@ class BeaconProvisioner: NSObject, ObservableObject {
|
|||
|
||||
centralManager.connect(resolvedPeripheral, options: nil)
|
||||
|
||||
// Timeout after 30 seconds
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 30) { [weak self] in
|
||||
// Timeout after 45 seconds (increased from 30s to accommodate 3 disconnect retries with backoff)
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 45) { [weak self] in
|
||||
if self?.state != .success && self?.state != .idle {
|
||||
self?.fail("Connection timeout", code: .connectionTimeout)
|
||||
}
|
||||
|
|
@ -1114,6 +1114,9 @@ extension BeaconProvisioner: CBCentralManagerDelegate {
|
|||
return
|
||||
}
|
||||
|
||||
// Cancel any pending write timeout — disconnect supersedes it
|
||||
cancelWriteTimeout()
|
||||
|
||||
// Unexpected disconnect during any active provisioning phase — retry with full reconnect
|
||||
let isActivePhase = (state == .discoveringServices || state == .authenticating || state == .writing || state == .verifying)
|
||||
if isActivePhase && disconnectRetryCount < BeaconProvisioner.MAX_DISCONNECT_RETRIES {
|
||||
|
|
@ -1131,7 +1134,7 @@ extension BeaconProvisioner: CBCentralManagerDelegate {
|
|||
responseBuffer.removeAll()
|
||||
state = .connecting
|
||||
|
||||
let delay = Double(disconnectRetryCount) + 1.0 // 2s, 3s backoff
|
||||
let delay = Double(disconnectRetryCount) + 2.0 // 3s, 4s, 5s backoff — give BLE time to settle
|
||||
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 }
|
||||
|
|
@ -1145,7 +1148,7 @@ extension BeaconProvisioner: CBCentralManagerDelegate {
|
|||
|
||||
// All retries exhausted or disconnect in unexpected state — fail
|
||||
DebugLog.shared.log("BLE: UNEXPECTED disconnect — state=\(state) writeIdx=\(dxSmartWriteIndex) queueCount=\(dxSmartCommandQueue.count) authenticated=\(dxSmartAuthenticated) disconnectRetries=\(disconnectRetryCount)")
|
||||
fail("Unexpected disconnect (state: \(state))", code: .disconnected)
|
||||
fail("Beacon disconnected \(disconnectRetryCount + 1) times during \(state). Move closer to the beacon and try again.", code: .disconnected)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -385,11 +385,11 @@ struct ScanView: View {
|
|||
.font(.title3)
|
||||
}
|
||||
|
||||
// Provisioning progress
|
||||
// Provisioning progress — show live updates from provisioner
|
||||
if isProvisioning {
|
||||
HStack {
|
||||
ProgressView()
|
||||
Text(provisioningProgress)
|
||||
Text(provisioner.progress.isEmpty ? provisioningProgress : provisioner.progress)
|
||||
.font(.callout)
|
||||
}
|
||||
.padding()
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue