Skip to content

Commit fddc515

Browse files
authored
Merge pull request #3307 from NickeZ/nickez/improve-ble-tx-speed
ble: Add support for larger ble packets
2 parents 2c87545 + 8b67de1 commit fddc515

File tree

1 file changed

+50
-21
lines changed

1 file changed

+50
-21
lines changed

frontends/ios/BitBoxApp/BitBoxApp/Bluetooth.swift

Lines changed: 50 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ class BluetoothManager: NSObject, ObservableObject, CBCentralManagerDelegate, CB
9191
}
9292

9393
func isConnected() -> Bool {
94-
return isPaired && connectedPeripheral != nil && pReader != nil && pWriter != nil;
94+
return isPaired && connectedPeripheral != nil && pReader != nil && pWriter != nil
9595
}
9696

9797
func connect(to peripheralID: UUID) {
@@ -110,14 +110,15 @@ class BluetoothManager: NSObject, ObservableObject, CBCentralManagerDelegate, CB
110110

111111
private func restartScan() {
112112
guard centralManager.state == .poweredOn,
113-
!centralManager.isScanning,
114-
connectedPeripheral == nil else { return }
113+
!centralManager.isScanning,
114+
connectedPeripheral == nil
115+
else { return }
115116
state.discoveredPeripherals.removeAll()
116117
state.scanning = true
117118
updateBackendState()
118119
centralManager.scanForPeripherals(
119-
withServices: [CBUUID(string: "e1511a45-f3db-44c0-82b8-6c880790d1f1")],
120-
options: nil
120+
withServices: [CBUUID(string: "e1511a45-f3db-44c0-82b8-6c880790d1f1")],
121+
options: nil
121122
)
122123
}
123124

@@ -137,7 +138,10 @@ class BluetoothManager: NSObject, ObservableObject, CBCentralManagerDelegate, CB
137138
}
138139
}
139140

140-
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String: Any], rssi RSSI: NSNumber) {
141+
func centralManager(
142+
_ central: CBCentralManager, didDiscover peripheral: CBPeripheral,
143+
advertisementData: [String: Any], rssi RSSI: NSNumber
144+
) {
141145
let identifier = peripheral.identifier
142146
print("BLE: discovered \(peripheral.name ?? "unknown device")")
143147
if state.discoveredPeripherals[identifier] == nil {
@@ -184,7 +188,9 @@ class BluetoothManager: NSObject, ObservableObject, CBCentralManagerDelegate, CB
184188
updateBackendState()
185189
}
186190

187-
func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) {
191+
func centralManager(
192+
_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?
193+
) {
188194
let errorMessage = error?.localizedDescription ?? "unknown error"
189195
state.discoveredPeripherals[peripheral.identifier]?.connectionState = .error
190196
state.discoveredPeripherals[peripheral.identifier]?.connectionError = errorMessage
@@ -246,7 +252,7 @@ class BluetoothManager: NSObject, ObservableObject, CBCentralManagerDelegate, CB
246252
print("BLE: Error writing data: \(error)")
247253
return
248254
}
249-
print("BLE: write ok")
255+
//print("BLE: write ok")
250256
}
251257

252258
func peripheral(
@@ -317,15 +323,17 @@ class BluetoothManager: NSObject, ObservableObject, CBCentralManagerDelegate, CB
317323
}
318324

319325
// This method gets called if the peripheral disconnects
320-
func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
326+
func centralManager(
327+
_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?
328+
) {
321329
print("BLE: peripheral disconnected")
322330
handleDisconnect()
323331
}
324332

325333
struct ReadError: Error {
326334
let message: String
327335
}
328-
336+
329337
func readBlocking(length: Int) throws -> Data {
330338
if !isConnected() {
331339
throw ReadError(message: "not connected")
@@ -338,16 +346,16 @@ class BluetoothManager: NSObject, ObservableObject, CBCentralManagerDelegate, CB
338346
throw ReadError(message: "no connection context")
339347
}
340348
currentContextLock.unlock()
341-
342-
let currentID = ctx.identifier;
349+
350+
let currentID = ctx.identifier
343351

344352
var data = Data()
345353

346354
// Loop until we've read the required amount of data
347355
while data.count < length {
348356
// Block until BLE reader callback notifies us or the peripheral is disconnected.
349357
ctx.semaphore.wait()
350-
358+
351359
if !isConnected() {
352360
throw ReadError(message: "the peripheral has disconnected while reading")
353361
}
@@ -357,10 +365,10 @@ class BluetoothManager: NSObject, ObservableObject, CBCentralManagerDelegate, CB
357365
if exit {
358366
throw ReadError(message: "the peripheral has disconnected while reading")
359367
}
360-
368+
361369
ctx.readBufferLock.lock()
362370
data.append(ctx.readBuffer.prefix(64))
363-
ctx.readBuffer = ctx.readBuffer.advanced(by: 64)
371+
ctx.readBuffer.removeSubrange(..<64)
364372
ctx.readBufferLock.unlock()
365373
}
366374
print("BLE: got \(data.count)")
@@ -370,7 +378,8 @@ class BluetoothManager: NSObject, ObservableObject, CBCentralManagerDelegate, CB
370378

371379
func parseProduct() -> ProductInfo? {
372380
guard let pProduct = self.pProduct,
373-
let value = pProduct.value else {
381+
let value = pProduct.value
382+
else {
374383
return nil
375384
}
376385

@@ -438,7 +447,9 @@ class BluetoothManager: NSObject, ObservableObject, CBCentralManagerDelegate, CB
438447
var error: NSError?
439448
let success = MobileserverBluetoothSetState(jsonStr, &error)
440449
if !success {
441-
print("Failed to set Bluetooth backend state: \(error?.localizedDescription ?? "Unknown error")")
450+
print(
451+
"Failed to set Bluetooth backend state: \(error?.localizedDescription ?? "Unknown error")"
452+
)
442453
}
443454
}
444455
}
@@ -497,9 +508,18 @@ class BluetoothDeviceInfo: NSObject, MobileserverGoDeviceInfoInterfaceProtocol {
497508

498509
class BluetoothReadWriteCloser: NSObject, MobileserverGoReadWriteCloserInterfaceProtocol {
499510
private let bluetoothManager: BluetoothManager
511+
private var max_mtu_len: Int
500512

501513
init(bluetoothManager: BluetoothManager) {
502514
self.bluetoothManager = bluetoothManager
515+
self.max_mtu_len = 64
516+
// Maximum number of bytes that fit based on MTU
517+
guard let p = bluetoothManager.connectedPeripheral else {
518+
return
519+
}
520+
self.max_mtu_len =
521+
((p.maximumWriteValueLength(for: CBCharacteristicWriteType.withoutResponse)) / 64)
522+
* 64
503523
}
504524

505525
func close() throws {
@@ -510,14 +530,23 @@ class BluetoothReadWriteCloser: NSObject, MobileserverGoReadWriteCloserInterface
510530
}
511531

512532
func write(_ data: Data?, n: UnsafeMutablePointer<Int>?) throws {
513-
guard let pWriter = bluetoothManager.pWriter else {
533+
guard let data = data, let p = bluetoothManager.connectedPeripheral,
534+
let pWriter = bluetoothManager.pWriter
535+
else {
536+
n!.pointee = 0
514537
return
515538
}
516539

517-
print("BLE: write data: \(data!.hexEncodedString())")
540+
// This is the max char len according to BLE firmware
541+
// only multiples of 64 are allowed
542+
let max_char_len = 5 * 64
543+
544+
let len = min(max_char_len, max_mtu_len, data.count)
518545

519-
bluetoothManager.connectedPeripheral!.writeValue(data!, for: pWriter, type: .withResponse)
520-
n!.pointee = data!.count
546+
bluetoothManager.connectedPeripheral!.writeValue(
547+
data[..<len], for: pWriter, type: .withResponse)
548+
n!.pointee = len
549+
print("BLE: write data (\(len) bytes): \(data[..<8].hexEncodedString())...")
521550
}
522551
}
523552

0 commit comments

Comments
 (0)