diff --git a/PayfritBeacon/Views/ScanView.swift b/PayfritBeacon/Views/ScanView.swift index 6a02741..416e0ec 100644 --- a/PayfritBeacon/Views/ScanView.swift +++ b/PayfritBeacon/Views/ScanView.swift @@ -634,9 +634,15 @@ struct ScanView: View { Task { @MainActor [weak self] in let reason = error?.localizedDescription ?? "beacon timed out" provisionLog?.log("disconnect", "Unexpected disconnect: \(reason)", isError: true) - // If we're in any active provisioning state, show failure - if let self = self, - self.provisioningState == .connecting || self.provisioningState == .connected || + guard let self = self else { return } + // DXSmart: disconnect during .connected is expected — beacon keeps + // flashing after BLE drops. We'll reconnect when user taps Write Config. + if self.provisioningState == .connected && beacon.type == .dxsmart { + provisionLog?.log("disconnect", "DXSmart idle disconnect — beacon still flashing, ignoring") + return + } + // For all other active states, treat disconnect as failure + if self.provisioningState == .connecting || self.provisioningState == .connected || self.provisioningState == .writing || self.provisioningState == .verifying { self.provisioningState = .failed self.errorMessage = "Beacon disconnected: \(reason)" @@ -718,6 +724,15 @@ struct ScanView: View { statusMessage = "Writing config to DX-Smart…" do { + // Reconnect if the beacon dropped BLE during the "confirm flashing" wait + if !provisioner.isConnected { + provisionLog.log("write", "Beacon disconnected while waiting — reconnecting…") + statusMessage = "Reconnecting to beacon…" + try await provisioner.connect() + provisionLog.log("write", "Reconnected — writing config…") + statusMessage = "Writing config to DX-Smart…" + } + try await provisioner.writeConfig(config) provisioner.disconnect()