@@ -91,7 +91,7 @@ class BluetoothManager: NSObject, ObservableObject, CBCentralManagerDelegate, CB
91
91
}
92
92
93
93
func isConnected( ) -> Bool {
94
- return isPaired && connectedPeripheral != nil && pReader != nil && pWriter != nil ;
94
+ return isPaired && connectedPeripheral != nil && pReader != nil && pWriter != nil
95
95
}
96
96
97
97
func connect( to peripheralID: UUID ) {
@@ -110,14 +110,15 @@ class BluetoothManager: NSObject, ObservableObject, CBCentralManagerDelegate, CB
110
110
111
111
private func restartScan( ) {
112
112
guard centralManager. state == . poweredOn,
113
- !centralManager. isScanning,
114
- connectedPeripheral == nil else { return }
113
+ !centralManager. isScanning,
114
+ connectedPeripheral == nil
115
+ else { return }
115
116
state. discoveredPeripherals. removeAll ( )
116
117
state. scanning = true
117
118
updateBackendState ( )
118
119
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
121
122
)
122
123
}
123
124
@@ -137,7 +138,10 @@ class BluetoothManager: NSObject, ObservableObject, CBCentralManagerDelegate, CB
137
138
}
138
139
}
139
140
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
+ ) {
141
145
let identifier = peripheral. identifier
142
146
print ( " BLE: discovered \( peripheral. name ?? " unknown device " ) " )
143
147
if state. discoveredPeripherals [ identifier] == nil {
@@ -184,7 +188,9 @@ class BluetoothManager: NSObject, ObservableObject, CBCentralManagerDelegate, CB
184
188
updateBackendState ( )
185
189
}
186
190
187
- func centralManager( _ central: CBCentralManager , didFailToConnect peripheral: CBPeripheral , error: Error ? ) {
191
+ func centralManager(
192
+ _ central: CBCentralManager , didFailToConnect peripheral: CBPeripheral , error: Error ?
193
+ ) {
188
194
let errorMessage = error? . localizedDescription ?? " unknown error "
189
195
state. discoveredPeripherals [ peripheral. identifier] ? . connectionState = . error
190
196
state. discoveredPeripherals [ peripheral. identifier] ? . connectionError = errorMessage
@@ -246,7 +252,7 @@ class BluetoothManager: NSObject, ObservableObject, CBCentralManagerDelegate, CB
246
252
print ( " BLE: Error writing data: \( error) " )
247
253
return
248
254
}
249
- print ( " BLE: write ok " )
255
+ // print("BLE: write ok")
250
256
}
251
257
252
258
func peripheral(
@@ -317,15 +323,17 @@ class BluetoothManager: NSObject, ObservableObject, CBCentralManagerDelegate, CB
317
323
}
318
324
319
325
// 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
+ ) {
321
329
print ( " BLE: peripheral disconnected " )
322
330
handleDisconnect ( )
323
331
}
324
332
325
333
struct ReadError : Error {
326
334
let message : String
327
335
}
328
-
336
+
329
337
func readBlocking( length: Int ) throws -> Data {
330
338
if !isConnected( ) {
331
339
throw ReadError ( message: " not connected " )
@@ -338,16 +346,16 @@ class BluetoothManager: NSObject, ObservableObject, CBCentralManagerDelegate, CB
338
346
throw ReadError ( message: " no connection context " )
339
347
}
340
348
currentContextLock. unlock ( )
341
-
342
- let currentID = ctx. identifier;
349
+
350
+ let currentID = ctx. identifier
343
351
344
352
var data = Data ( )
345
353
346
354
// Loop until we've read the required amount of data
347
355
while data. count < length {
348
356
// Block until BLE reader callback notifies us or the peripheral is disconnected.
349
357
ctx. semaphore. wait ( )
350
-
358
+
351
359
if !isConnected( ) {
352
360
throw ReadError ( message: " the peripheral has disconnected while reading " )
353
361
}
@@ -357,10 +365,10 @@ class BluetoothManager: NSObject, ObservableObject, CBCentralManagerDelegate, CB
357
365
if exit {
358
366
throw ReadError ( message: " the peripheral has disconnected while reading " )
359
367
}
360
-
368
+
361
369
ctx. readBufferLock. lock ( )
362
370
data. append ( ctx. readBuffer. prefix ( 64 ) )
363
- ctx. readBuffer = ctx . readBuffer . advanced ( by : 64 )
371
+ ctx. readBuffer. removeSubrange ( ..< 64 )
364
372
ctx. readBufferLock. unlock ( )
365
373
}
366
374
print ( " BLE: got \( data. count) " )
@@ -370,7 +378,8 @@ class BluetoothManager: NSObject, ObservableObject, CBCentralManagerDelegate, CB
370
378
371
379
func parseProduct( ) -> ProductInfo ? {
372
380
guard let pProduct = self . pProduct,
373
- let value = pProduct. value else {
381
+ let value = pProduct. value
382
+ else {
374
383
return nil
375
384
}
376
385
@@ -438,7 +447,9 @@ class BluetoothManager: NSObject, ObservableObject, CBCentralManagerDelegate, CB
438
447
var error : NSError ?
439
448
let success = MobileserverBluetoothSetState ( jsonStr, & error)
440
449
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
+ )
442
453
}
443
454
}
444
455
}
@@ -497,9 +508,18 @@ class BluetoothDeviceInfo: NSObject, MobileserverGoDeviceInfoInterfaceProtocol {
497
508
498
509
class BluetoothReadWriteCloser : NSObject , MobileserverGoReadWriteCloserInterfaceProtocol {
499
510
private let bluetoothManager : BluetoothManager
511
+ private var max_mtu_len : Int
500
512
501
513
init ( bluetoothManager: BluetoothManager ) {
502
514
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
503
523
}
504
524
505
525
func close( ) throws {
@@ -510,14 +530,23 @@ class BluetoothReadWriteCloser: NSObject, MobileserverGoReadWriteCloserInterface
510
530
}
511
531
512
532
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
514
537
return
515
538
}
516
539
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)
518
545
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 ( ) ) ... " )
521
550
}
522
551
}
523
552
0 commit comments