diff --git a/PayfritBeacon/Provisioners/DXSmartProvisioner.swift b/PayfritBeacon/Provisioners/DXSmartProvisioner.swift index 25214f2..ff3e66e 100644 --- a/PayfritBeacon/Provisioners/DXSmartProvisioner.swift +++ b/PayfritBeacon/Provisioners/DXSmartProvisioner.swift @@ -174,9 +174,12 @@ final class DXSmartProvisioner: NSObject, BeaconProvisioner { await diagnosticLog?.log("write", "[\(index + 1)/\(commands.count)] \(name) (\(packet.count) bytes)") // SaveConfig (last command) causes beacon MCU to reboot — it never sends an ACK. - // Fire the BLE write and return immediately; the disconnect is expected. + // Use .withoutResponse so CoreBluetooth fires the bytes immediately into the + // BLE radio buffer without waiting for a GATT round-trip. With .withResponse, + // the beacon reboots before the ACK arrives, and CoreBluetooth may silently + // drop the write — leaving the config unsaved and the beacon still flashing. if name == "SaveConfig" { - peripheral.writeValue(packet, for: writeChar, type: .withResponse) + peripheral.writeValue(packet, for: writeChar, type: .withoutResponse) await diagnosticLog?.log("write", "✅ [\(index + 1)/\(commands.count)] SaveConfig sent — beacon will reboot") await diagnosticLog?.log("write", "✅ All commands written successfully") return