8
8
import CoreBluetooth
9
9
import Mobileserver
10
10
11
-
12
11
class BluetoothManager : NSObject , ObservableObject , CBCentralManagerDelegate , CBPeripheralDelegate {
13
12
var centralManager : CBCentralManager !
14
13
var discoveredPeripheral : CBPeripheral ?
@@ -17,7 +16,7 @@ class BluetoothManager: NSObject, ObservableObject, CBCentralManagerDelegate, CB
17
16
var pProduct : CBCharacteristic ?
18
17
19
18
private var readBuffer = Data ( )
20
- private let readBufferLock = NSLock ( ) // Ensure thread-safe buffer access
19
+ private let readBufferLock = NSLock ( ) // Ensure thread-safe buffer access
21
20
private let semaphore = DispatchSemaphore ( value: 0 )
22
21
23
22
override init ( ) {
@@ -26,95 +25,118 @@ class BluetoothManager: NSObject, ObservableObject, CBCentralManagerDelegate, CB
26
25
}
27
26
28
27
func isConnected( ) -> Bool {
29
- return discoveredPeripheral != nil && pReader != nil && pWriter != nil ;
28
+ return discoveredPeripheral != nil && pReader != nil && pWriter != nil
30
29
}
31
30
32
31
func centralManagerDidUpdateState( _ central: CBCentralManager ) {
33
32
switch central. state {
34
33
case . poweredOn:
35
- print ( " Bluetooth on" )
34
+ print ( " BLE: on" )
36
35
centralManager. scanForPeripherals (
37
36
withServices: [ CBUUID ( string: " e1511a45-f3db-44c0-82b8-6c880790d1f1 " ) ] ,
38
37
options: nil )
39
38
case . poweredOff, . unauthorized, . unsupported, . resetting, . unknown:
40
- print ( " Bluetooth unavailable or not supported " )
39
+ print ( " BLE: Bluetooth Unavailable or not supported" )
41
40
discoveredPeripheral = nil
42
41
pReader = nil
43
42
pWriter = nil
44
43
@unknown default :
45
- print ( " Unknown Bluetooth state " )
44
+ print ( " BLE: Unknown Bluetooth state" )
46
45
}
47
46
}
48
47
49
- func centralManager( _ central: CBCentralManager , didDiscover peripheral: CBPeripheral , advertisementData: [ String : Any ] , rssi RSSI: NSNumber ) {
50
- print ( " Bluetooth: discovered \( peripheral. name ?? " unknown device " ) " )
48
+ func centralManager(
49
+ _ central: CBCentralManager , didDiscover peripheral: CBPeripheral ,
50
+ advertisementData: [ String : Any ] , rssi RSSI: NSNumber
51
+ ) {
52
+ print ( " BLE: discovered \( peripheral. name ?? " unknown device " ) " )
53
+
54
+ if let data = advertisementData [ " kCBAdvDataManufacturerData " ] as? Data {
55
+ let data = data. advanced ( by: 2 ) // 2 bytes for manufacturer ID
56
+ print ( " BLE: manufacturer data: \( data. hexEncodedString ( ) ) " )
57
+ }
58
+
51
59
discoveredPeripheral = peripheral
52
60
centralManager. stopScan ( )
53
61
centralManager. connect ( peripheral, options: nil )
54
62
}
55
63
56
64
func centralManager( _ central: CBCentralManager , didConnect peripheral: CBPeripheral ) {
57
- print ( " Connected to \( peripheral. name ?? " unknown device " ) " )
65
+ print ( " BLE: Connected to \( peripheral. name ?? " unknown device " ) " )
58
66
59
67
peripheral. delegate = self
60
68
peripheral. discoverServices ( nil )
61
69
}
62
70
63
71
func peripheral( _ peripheral: CBPeripheral , didDiscoverServices error: Error ? ) {
64
72
if let error = error {
65
- print ( " Error discovering services: \( error. localizedDescription) " )
73
+ print ( " BLE: Error discovering services: \( error. localizedDescription) " )
66
74
return
67
75
}
68
76
69
77
if let services = peripheral. services {
70
78
for service in services {
71
- print ( " Discovered service: \( service. uuid) " )
79
+ print ( " BLE: Discovered service: \( service. uuid) " )
72
80
peripheral. discoverCharacteristics ( nil , for: service)
73
81
}
74
82
}
75
83
}
76
84
77
- func peripheral( _ peripheral: CBPeripheral , didDiscoverCharacteristicsFor service: CBService , error: Error ? ) {
85
+ func peripheral(
86
+ _ peripheral: CBPeripheral , didDiscoverCharacteristicsFor service: CBService , error: Error ?
87
+ ) {
78
88
if let error = error {
79
- print ( " Error discovering characteristics: \( error. localizedDescription) " )
89
+ print ( " BLE: Error discovering characteristics: \( error. localizedDescription) " )
80
90
return
81
91
}
82
92
if let characteristics = service. characteristics {
83
93
for c in characteristics {
84
- print ( " Discovered characteristic: \( c. uuid) " )
85
- if c. uuid == CBUUID ( string: " 0001 " ) {
94
+ print ( " BLE: Discovered characteristic: \( c. uuid) " )
95
+ if c. uuid == CBUUID ( string: " 799d485c-d354-4ed0-b577-f8ee79ec275a " ) {
86
96
pWriter = c
87
- let max_len = peripheral. maximumWriteValueLength ( for: CBCharacteristicWriteType . withoutResponse)
88
- print ( " Found writer service with max length \( max_len) - \( c. properties. contains ( . write) ) " )
97
+ let max_len = peripheral. maximumWriteValueLength (
98
+ for: CBCharacteristicWriteType . withoutResponse)
99
+ print (
100
+ " BLE: Found writer service with max length \( max_len) - \( c. properties. contains ( . write) ) "
101
+ )
89
102
}
90
- if c. uuid == CBUUID ( string: " 0002 " ) {
103
+ if c. uuid == CBUUID ( string: " 419572a5-9f53-4eb1-8db7-61bcab928867 " ) {
104
+ peripheral. setNotifyValue ( true , for: c)
91
105
pReader = c
92
106
}
93
- if c. uuid == CBUUID ( string: " 0003 " ) {
94
- print ( " Found product characteristic " )
107
+ if c. uuid == CBUUID ( string: " 9d1c9a77-8b03-4e49-8053-3955cda7da93 " ) {
108
+ print ( " BLE: Found product characteristic" )
95
109
peripheral. setNotifyValue ( true , for: c)
96
110
pProduct = c
97
111
}
98
112
}
99
113
}
100
114
}
101
115
102
- func peripheral( _ peripheral: CBPeripheral , didWriteValueFor characteristic: CBCharacteristic , error: Error ? ) {
116
+ func peripheral(
117
+ _ peripheral: CBPeripheral , didWriteValueFor characteristic: CBCharacteristic , error: Error ?
118
+ ) {
103
119
if let error = error {
104
- print ( " Bluetooth error writing data: \( error) " )
120
+ print ( " BLE: Error writing data: \( error) " )
105
121
return
106
122
}
107
- print ( " Blluetooth write ok" )
123
+ print ( " BLE: write ok" )
108
124
}
109
125
110
- func peripheral( _ peripheral: CBPeripheral , didUpdateValueFor characteristic: CBCharacteristic , error: Error ? ) {
126
+ func peripheral(
127
+ _ peripheral: CBPeripheral , didUpdateValueFor characteristic: CBCharacteristic ,
128
+ error: Error ?
129
+ ) {
111
130
if let error = error {
112
- print ( " Error receiving data: \( error) " )
131
+ print ( " BLE: Error receiving data: \( error) " )
113
132
return
114
133
}
115
134
116
135
if characteristic == pReader, let data = characteristic. value {
117
- print ( " Bluetooth received data: \( data. hexEncodedString ( ) ) " )
136
+ if data. count != 64 {
137
+ print ( " BLE: ERROR, expected 64 bytes " )
138
+ }
139
+ print ( " BLE: received data: \( data. hexEncodedString ( ) ) " )
118
140
readBufferLock. lock ( )
119
141
readBuffer. append ( data)
120
142
readBufferLock. unlock ( )
@@ -123,7 +145,7 @@ class BluetoothManager: NSObject, ObservableObject, CBCentralManagerDelegate, CB
123
145
semaphore. signal ( )
124
146
}
125
147
if characteristic == pProduct, let val = characteristic. value {
126
- print ( " Bluetooth product changed: \( val) " )
148
+ print ( " BLE: product changed: \( val) " )
127
149
// Invoke device manager to scan now, which will make it detect the device being connected
128
150
// (or disconnected, in case the product string indicates that) now instead of waiting for
129
151
// the next scan.
@@ -132,11 +154,13 @@ class BluetoothManager: NSObject, ObservableObject, CBCentralManagerDelegate, CB
132
154
}
133
155
134
156
// This method gets called if the peripheral disconnects
135
- func centralManager( _ central: CBCentralManager , didDisconnectPeripheral peripheral: CBPeripheral , error: Error ? ) {
136
- print ( " Bluetooth disconnected " )
137
- discoveredPeripheral = nil ;
138
- pReader = nil ;
139
- pWriter = nil ;
157
+ func centralManager(
158
+ _ central: CBCentralManager , didDisconnectPeripheral peripheral: CBPeripheral , error: Error ?
159
+ ) {
160
+ print ( " BLE: perhipheral disconnected " )
161
+ discoveredPeripheral = nil
162
+ pReader = nil
163
+ pWriter = nil
140
164
141
165
// TODO: start scanning again.
142
166
}
@@ -150,26 +174,24 @@ class BluetoothManager: NSObject, ObservableObject, CBCentralManagerDelegate, CB
150
174
print ( " discoveredPeripheral is not set " )
151
175
return nil
152
176
}
153
- print ( " Bluetooth wants to read \( length) " )
154
- readBufferLock. lock ( )
155
- readBuffer. removeAll ( ) // Clear buffer before starting
156
- readBufferLock. unlock ( )
177
+ print ( " BLE: wants to read \( length) " )
178
+
179
+ var data = Data ( )
157
180
158
181
// Loop until we've read the required amount of data
159
- while readBuffer. count < length {
160
- // Trigger a read request
161
- peripheral. readValue ( for: pReader)
162
- // Block until the delegate signals
182
+ while data. count < length {
183
+ // Block until BLE reader callback notifies us
163
184
semaphore. wait ( )
185
+ readBufferLock. lock ( )
186
+ data. append ( readBuffer. prefix ( 64 ) )
187
+ readBuffer = readBuffer. advanced ( by: 64 )
188
+ readBufferLock. unlock ( )
164
189
}
165
- print ( " Bluetooth read: need \( length) , got \( readBuffer. count) " )
166
- readBufferLock. lock ( )
167
- let data = readBuffer. prefix ( length)
168
- readBufferLock. unlock ( )
190
+ print ( " BLE: got \( data. count) " )
169
191
170
192
return data
171
193
}
172
-
194
+
173
195
func productStr( ) -> String {
174
196
guard let pProduct = self . pProduct else {
175
197
return " "
@@ -206,7 +228,7 @@ class BluetoothDeviceInfo: NSObject, MobileserverGoDeviceInfoInterfaceProtocol {
206
228
}
207
229
208
230
func open( ) throws -> MobileserverGoReadWriteCloserInterfaceProtocol {
209
- return BluetoothReadWriteCloser ( bluetoothManager: bluetoothManager)
231
+ return BluetoothReadWriteCloser ( bluetoothManager: bluetoothManager)
210
232
}
211
233
212
234
func product( ) -> String {
@@ -250,10 +272,10 @@ class BluetoothReadWriteCloser: NSObject, MobileserverGoReadWriteCloserInterface
250
272
return
251
273
}
252
274
253
- print ( " Bluetooth write data: \( data!. hexEncodedString ( ) ) " )
275
+ print ( " BLE: write data: \( data!. hexEncodedString ( ) ) " )
254
276
255
277
bluetoothManager. discoveredPeripheral!. writeValue ( data!, for: pWriter, type: . withResponse)
256
- n!. pointee = data!. count;
278
+ n!. pointee = data!. count
257
279
}
258
280
}
259
281
0 commit comments