From b88dded928cbcaac83215c4363d99824a358573d Mon Sep 17 00:00:00 2001 From: Schwifty Date: Mon, 23 Mar 2026 02:16:24 +0000 Subject: [PATCH] fix: resolve write ACK on didWriteValueFor instead of waiting for notification MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Frame1_DevInfo (cmd 0x61) and potentially other commands don't send a separate FFE1 notification after being written. The code was waiting for didUpdateValueFor (notification) to resolve responseContinuation, but it never came — causing a 5s timeout on every such command. The .withResponse write type already guarantees the BLE stack confirmed delivery. Now didWriteValueFor resolves responseContinuation on success, so commands that don't trigger notifications still complete immediately. If a notification also arrives later, responseContinuation is already nil so it's harmlessly ignored. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../Provisioners/DXSmartProvisioner.swift | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/PayfritBeacon/Provisioners/DXSmartProvisioner.swift b/PayfritBeacon/Provisioners/DXSmartProvisioner.swift index b6aa21b..02a5d95 100644 --- a/PayfritBeacon/Provisioners/DXSmartProvisioner.swift +++ b/PayfritBeacon/Provisioners/DXSmartProvisioner.swift @@ -448,10 +448,18 @@ extension DXSmartProvisioner: CBPeripheralDelegate { return } - // Handle write errors for command writes - if let error, let cont = responseContinuation { + // For command writes (FFE1/FFE2): the .withResponse write confirmation + // IS the ACK. Some commands (e.g. 0x61 Frame1_DevInfo) don't send a + // separate FFE1 notification, so we must resolve here on success too. + // If a notification also arrives later, responseContinuation will already + // be nil — harmless. + if let cont = responseContinuation { responseContinuation = nil - cont.resume(throwing: error) + if let error { + cont.resume(throwing: error) + } else { + cont.resume(returning: Data()) + } } } }