Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
198 views
in Technique[技术] by (71.8m points)

swift - IOS : Getting Bluetooth state after reconnection : weird issue

)

I'm currently developing an app that is synced to a BT device. This BT device has 2 states (let's say ON and OFF though it is still powered on, like a bulb).

When I connect to the peripheral, I get 2 characteristics : a write and a read characteristic. In order to retrieve the current state, I have to send a write frame that basically ask the peripheral to give me its current state. As a response, I get a frame that contains the current peripheral state.

If I connect to the peripheral, ask the state (ON for instance), I receive ON. I turn the peripheral OFF, I receive OFF. Now I kill my app and launch it again. The app will reconnect to the peripheral, ask the current state. The response is OFF. So far so good.... I can keep on changing the peripheral state, I always retrieve the last state of the peripheral when I relaunch the app. Now for the weird part : I do exactly the same operations, but before launching my app, I switch again the peripheral state (in the above example, it would now be ON). I launch the app, send a write frame to the peripheral, and the response is ... OFF.

One could argue that it is a peripheral issue, but fellow colleagues on Android do not have this bug, so I guess it's on my side.

Just for the record, here are my BT implementation, which is pretty straightforward.

extension BluetoothManager: CBPeripheralDelegate {
? ? func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
? ? ? ? log("didDiscoverServices (peripheral)")
? ? ? ? if let services = peripheral.services {
? ? ? ? ? ? for service in services {
? ? ? ? ? ? ? ? peripheral.discoverCharacteristics(nil, for: service)
? ? ? ? ? ? }
? ? ? ? }
? ? }
?? ?
? ? func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
? ? ? ? log("didDiscoverCharacteristicsFor (service)")
? ? ? ? if let characteristics = service.characteristics {
? ? ? ? ? ? for characteristic in characteristics {
? ? ? ? ? ? ? ? if let chara = ATACharacteristics.from(characteristic) {
? ? ? ? ? ? ? ? ? ? switch chara {
? ? ? ? ? ? ? ? ? ? case .write:
? ? ? ? ? ? ? ? ? ? ? ? log("write? ATACharacteristics(characteristic)")
? ? ? ? ? ? ? ? ? ? ? ? peripheral.setNotifyValue(true, for: characteristic)
? ? ? ? ? ? ? ? ? ? ? ? self.characteristics.append(chara)
? ? ? ? ? ? ? ? ? ? ? ? readStateFromBox(characteristic)
?? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ? case .read:
? ? ? ? ? ? ? ? ? ? ? ? log("read? ATACharacteristics(characteristic)")
? ? ? ? ? ? ? ? ? ? ? ? self.characteristics.append(chara)
?? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ? case .nus: ()
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? }
?? ?
? ? func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: CBCharacteristic, error: Error?) {
? ? ? ? log("didUpdateNotificationStateFor (characteristic)")
? ? }

? ? func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
? ? ? ? log("didUpdateValueFor (characteristic)")
? ? ? ? if let data = characteristic.value,
?? ? ? ? ? let validator = try? ATAFrameDecoder().decode(data) as? LuminousStatusFrameValidator {
? ? ? ? ? ? log(" ? data (data as NSData)")
? ? ? ? ? ? updateState(from: validator)
? ? ? ? }
? ? }

? ? func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) {
? ? ? ? log("didWriteValueFor (characteristic)")
? ? ? ? if let data = characteristic.value,
?? ? ? ? ? let validator = try? ATAFrameDecoder().decode(data) as? LuminousStatusFrameValidator? {
? ? ? ? ? ? log(" ? data (data as NSData)")
? ? ? ? ? ? updateState(from: validator)
? ? ? ? }
? ? }
?? ?
? ? private func updateState(from validator: LuminousStatusFrameValidator) {
? ? ? ? log("updateState (validator.state)")
? ? ? ? acknowledge(for: validator.frameType)

? ? ? ? guard let ataBox = ataBox,
? ? ? ? ? ? ? Defaults[.recopyBoxState] == true else { return }
? ? ? ? ataBox.updateState(validator)
? ? ? ? boxDelegate?.stateDidChanged(ataBox.state)
? ? }

? ? private func log(_ message: String) {
? ? ? ? guard verbose == true else { return }
? ? ? ? print("?? (message)")
? ? }
}

Here are although the logs for both scenarios. When receiving the didWrite frame, if I get a "00" after "02a00461" it means ON, if I get a "fe", it means OFF

First the good one :

?? centralManagerDidUpdateState poweredOn
?? didDiscoverServices <CBPeripheral: 0x281508000, identifier = A274CD79-938C-CAEF-2CE7-D20CB5B6961F, name = ATA-000008, state = connected>
?? didDiscoverCharacteristicsFor <CBService: 0x2831a5280, isPrimary = YES, UUID = 6E400001-B5A3-F393-E0A9-E50E24DCCA9E>
?? read  ATACharacteristics<CBCharacteristic: 0x280006100, UUID = 6E400002-B5A3-F393-E0A9-E50E24DCCA9E, properties = 0xC, value = (null), notifying = NO>
?? write  ATACharacteristics<CBCharacteristic: 0x2800044e0, UUID = 6E400003-B5A3-F393-E0A9-E50E24DCCA9E, properties = 0x10, value = {length = 13, bytes = 0x02a00461fe0000000000122903}, notifying = NO>
?? readStateFromBox {length = 9, bytes = 0x02a50000000001a603} for <CBCharacteristic: 0x2800044e0, UUID = 6E400003-B5A3-F393-E0A9-E50E24DCCA9E, properties = 0x10, value = {length = 13, bytes = 0x02a00461fe0000000000122903}, notifying = NO>
?? didUpdateNotificationStateFor <CBCharacteristic: 0x2800044e0, UUID = 6E400003-B5A3-F393-E0A9-E50E24DCCA9E, properties = 0x10, value = {length = 13, bytes = 0x02a00461fe0000000000122903}, notifying = YES>
?? didWriteValueFor <CBCharacteristic: 0x2800044e0, UUID = 6E400003-B5A3-F393-E0A9-E50E24DCCA9E, properties = 0x10, value = {length = 13, bytes = 0x02a00461fe0000000000122903}, notifying = YES>
??    data {length = 13, bytes = 0x02a00461fe0000000000122903}
?? updateState occupied
?? acknowledge {length = 9, bytes = 0x0206a000000003a703} for Optional(<CBCharacteristic: 0x2800044e0, UUID = 6E400003-B5A3-F393-E0A9-E50E24DCCA9E, properties = 0x10, value = {length = 13, bytes = 0x02a00461fe0000000000122903}, notifying = YES>)

and then the bug


?? centralManagerDidUpdateState poweredOn
?? didDiscoverServices <CBPeripheral: 0x2839885a0, identifier = A274CD79-938C-CAEF-2CE7-D20CB5B6961F, name = ATA-000008, state = connected>
?? didDiscoverCharacteristicsFor <CBService: 0x281dd5100, isPrimary = YES, UUID = 6E400001-B5A3-F393-E0A9-E50E24DCCA9E>
?? read  ATACharacteristics<CBCharacteristic: 0x282c88300, UUID = 6E400002-B5A3-F393-E0A9-E50E24DCCA9E, properties = 0xC, value = (null), notifying = NO>
?? write  ATACharacteristics<CBCharacteristic: 0x282c881e0, UUID = 6E400003-B5A3-F393-E0A9-E50E24DCCA9E, properties = 0x10, value = {length = 13, bytes = 0x02a0046100000000000013d603}, notifying = NO>
?? readStateFromBox {length = 9, bytes = 0x02a50000000001a603} for <CBCharacteristic: 0x282c881e0, UUID = 6E400003-B5A3-F393-E0A9-E50E24DCCA9E, properties = 0x10, value = {length = 13, bytes = 0x02a0046100000000000013d603}, notifying = NO>
?? didUpdateNotificationStateFor <CBCharacteristic: 0x282c881e0, UUID = 6E400003-B5A3-F393-E0A9-E50E24DCCA9E, properties = 0x10, value = {length = 13, bytes = 0x02a0046100000000000013d603}, notifying = YES>
?? didWriteValueFor <CBCharacteristic: 0x282c881e0, UUID = 6E400003-B5A3-F393-E0A9-E50E24DCCA9E, properties = 0x10, value = {length = 13, bytes = 0x02a0046100000000000013d603}, notifying = YES>
??    data {length = 13, bytes = 0x02a0046100000000000013d603}
?? updateState free
?? acknowledge {length = 9, bytes = 0x0206a000000003a703} for Optional(<CBCharacteristic: 0x282c881e0, UUID = 6E400003-B5A3-F393-E0A9-E50E24DCCA9E, properties = 0x10, value = {length = 13, bytes = 0x02a0046100000000000013d603}, notifying = YES>)

Is there some kind of cache on BT exchanges ? I don't know why it reacts like that.

Thanks for your help.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
等待大神答复

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...