From 7baa942d2902bcf58d7b95fd249bf17c236af9ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20Truszczy=C5=84ski?= Date: Tue, 27 Jun 2023 17:34:46 +0200 Subject: [PATCH] BLE - Communication with Android devices improvements (#948) - Peripheral manager will now can return data with offset in BLE read requests. --- .../Common/Managers/BLE/BLEConstants.swift | 2 +- .../Managers/BLE/BLEPeripheralManager.swift | 50 ++++++++++++++----- 2 files changed, 38 insertions(+), 14 deletions(-) diff --git a/MobileWallet/Common/Managers/BLE/BLEConstants.swift b/MobileWallet/Common/Managers/BLE/BLEConstants.swift index 1bfc02f4..2eb256ca 100644 --- a/MobileWallet/Common/Managers/BLE/BLEConstants.swift +++ b/MobileWallet/Common/Managers/BLE/BLEConstants.swift @@ -41,7 +41,7 @@ import CoreBluetooth enum BLEConstants { - static var chunkSize = 200 + static var chunkSize = 150 static var contactBookService: BLEContactBookService.Type { BLEContactBookService.self } } diff --git a/MobileWallet/Common/Managers/BLE/BLEPeripheralManager.swift b/MobileWallet/Common/Managers/BLE/BLEPeripheralManager.swift index 91cdc621..7a79ae1f 100644 --- a/MobileWallet/Common/Managers/BLE/BLEPeripheralManager.swift +++ b/MobileWallet/Common/Managers/BLE/BLEPeripheralManager.swift @@ -157,20 +157,22 @@ final class BLEPeripheralManager: NSObject { private func handle(readRequest: CBATTRequest) { - var chunks: [Data] = cache[readRequest.characteristic.uuid] ?? [] - - if chunks.isEmpty { - chunks = makeUserProfileDeeplinkChunks() - } - - guard !chunks.isEmpty else { - manager.respond(to: readRequest, withResult: .invalidHandle) - return + let chunk: Data + + if readRequest.offset == 0 { + guard let nextChunk = nextChunk(characteristicUUID: readRequest.characteristic.uuid) else { + manager.respond(to: readRequest, withResult: .invalidHandle) + return + } + chunk = nextChunk + } else { + guard let currentChunk = currentChunk(characteristicUUID: readRequest.characteristic.uuid, offset: readRequest.offset) else { + manager.respond(to: readRequest, withResult: .invalidHandle) + return + } + chunk = currentChunk } - let chunk = chunks.removeFirst() - - cache[readRequest.characteristic.uuid] = chunks readRequest.value = chunk manager.respond(to: readRequest, withResult: .success) } @@ -250,7 +252,7 @@ final class BLEPeripheralManager: NSObject { } } - // MARK: - Factories + // MARK: - Helpers private func makeUserProfileDeeplinkChunks() -> [Data] { guard let alias = UserSettingsManager.name, let address = try? Tari.shared.walletAddress.byteVector.hex else { return [] } @@ -258,6 +260,28 @@ final class BLEPeripheralManager: NSObject { guard let url = try? DeepLinkFormatter.deeplink(model: model) else { return [] } return url.absoluteString.data(using: .utf8)?.bleDataChunks ?? [] } + + private func nextChunk(characteristicUUID: CBUUID) -> Data? { + + var chunks: [Data] = cache[characteristicUUID] ?? [] + + if !chunks.isEmpty { + chunks.removeFirst() + } + + if chunks.isEmpty { + chunks = makeUserProfileDeeplinkChunks() + } + + cache[characteristicUUID] = chunks + return chunks.first + } + + private func currentChunk(characteristicUUID: CBUUID, offset: Int) -> Data? { + var chunks: [Data] = cache[characteristicUUID] ?? [] + guard let chunk = chunks.first, chunk.count > offset else { return nil } + return chunk.subdata(in: offset..