Skip to content

Commit

Permalink
BLE - Communication with Android devices improvements (#948)
Browse files Browse the repository at this point in the history
- Peripheral manager will now can return data with offset in BLE read requests.
  • Loading branch information
TruszczynskiA authored Jun 27, 2023
1 parent 7304443 commit 7baa942
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 14 deletions.
2 changes: 1 addition & 1 deletion MobileWallet/Common/Managers/BLE/BLEConstants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
import CoreBluetooth

enum BLEConstants {
static var chunkSize = 200
static var chunkSize = 150
static var contactBookService: BLEContactBookService.Type { BLEContactBookService.self }
}

Expand Down
50 changes: 37 additions & 13 deletions MobileWallet/Common/Managers/BLE/BLEPeripheralManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down Expand Up @@ -250,14 +252,36 @@ 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 [] }
let model = UserProfileDeeplink(alias: alias, tariAddress: address)
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..<chunk.count)
}
}

extension BLEPeripheralManager: CBPeripheralManagerDelegate {
Expand Down

0 comments on commit 7baa942

Please sign in to comment.