-
Notifications
You must be signed in to change notification settings - Fork 335
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
subscribeToCharacteristic fails when Client Characteristic Config descriptor is not present #188
Comments
Following |
@LironKomfort thank you for the clear description of the issue this really helped triaging the issue. We are using for android the reactive ble library from Polidea and their implementation. The boolean you mentioned The library we are using however does support a compatibility mode where it does something similar what you do in the native implementation, link. We can consider supporting the compatibility mode that is used in Polidea however I see this as a workaround and the issue is with the peripheral itself. I am a bit cautious with implementing android specific workarounds in our external Flutter API because we support both platforms and a compatibility mode is not something that is familiar to iOS devs. @werediver what are your thoughts? |
@remonh87 @werediver Hi guys I'm working @LironKomfort on this project, just wanted to give my 2cents I think a workaround would be good because I see a number of peripheral devices not having compatibility mode supported, and updating the device might not be so easy as it is hardware, therefore, making the package limited in use case. Having the workaround provides better options and more use cases. If that makes sense |
I think adding following is less intrusive and quite simple to realise Stream<List<int>> subscribeToCharacteristic(
QualifiedCharacteristic characteristic,
{bool androidCompatibilityMode}
) Also it takes away my concerns about confusing iOS devs |
@remonh87 that looks really good. |
@remonh87 If this "compatibility mode" is practically useful and is easy to implement, we can make some people happier by implementing it. If that compatibility mode should be controlled on per-call basis (so that one subscription can be established using the compatibility mode and another the normal way), extra optional parameter to If the compatibility mode is expected to be used for all subscriptions, when enabled, I'd suggest to introduce some kind of But an even better solution would be to automatically detect whether the compatibility mode is required. Is this possible? |
Actually, after skimming through dariuszseweryn/RxAndroidBle#202 it seems the compatibility mode is controlled on per-connection basis. This may be tricky to implement in our library. |
@werediver see my answers:
It is per call basis according to the docs: * @param setupMode Configures how the notification is set up. For available modes see {@link NotificationSetupMode}.
I found that Android exposes the descriptor of a characteristic. I can check if there is no notify descriptor and then go for compatibility mode. This would be a super simple and less intrusive fix but on Android ble is always very unpredictable so not sure about the side effects.
It may look like at first but it is established per notification itself so shouldn't be all too tricky. |
@remonh87 I'd strongly consider the automatic check approach first. We can release the automatic check and if it doesn't satisfy users, we can reconsider. |
@remonh87 @werediver Custom descriptors are not supported? |
This is a question about iOS and Android BLE stacks, not about this library [as I understand the situation]. A peripheral should comply to the standards to work without such workarounds. |
@LironKomfort I did create a test branch with the automatic detection. Can you check if this works for you: |
@remonh87 Do you think the automatic detection has a noticeable performance impact (requires time [like 50+ ms] to do the check)? |
@werediver we already have discovered the services so the only thing I do is checking the descriptors for this char is empty. I wouldn't expect it to be very costly. |
@remonh87
I edited the if statement you added in the Kotlin code to check for empty OR different from the reserved CCC descriptor. |
@werediver |
@LironKomfort @AlmogRnD is it possible to not set a custom descriptor on your BLE device? If yes then I propose to create a separate issue regarding the custom descriptors. |
@remonh87 |
I'm working on the example project of the library (https://github.com/PhilipsHue/flutter_reactive_ble/tree/master/example),
I added a few buttons to test the API - readCharacteristic, writeCharacteristicWithResponse and subscribeToCharacteristic.
Subscribing to notifications doesn't work as expected (read/write works well).
Flow:
scanForDevices
connectToDevice/connectToAdvertisingDevice (tried both)
subscribeToCharacteristic (after status is connected)
Flow's code (serviceId ,readCharacteristicId & writeCharacteristicId are defined in the BLE server):
Debug output:
I/flutter ( 4075): REACTIVE_BLE: Start subscribing to notifications for QualifiedCharacteristic(characteristicId: 010d815c-031c-4de8-ac10-1ffebcf874fa, serviceId: 06391ebb-4050-42b6-ab55-8282a15fa094, deviceId: 5F:99:E1:54:4A:89)
D/BluetoothGatt( 4075): discoverServices() - device: 5F:99:E1:54:4A:89
D/BluetoothGatt( 4075): onSearchComplete() = Device=5F:99:E1:54:4A:89 Status=0
D/BluetoothGatt( 4075): setCharacteristicNotification() - uuid: 010d815c-031c-4de8-ac10-1ffebcf874fa enable: false
I/flutter ( 4075): REACTIVE_BLE: Received CharacteristicValue(characteristic: QualifiedCharacteristic(characteristicId: 010d815c-031c-4de8-ac10-1ffebcf874fa, serviceId: 06391ebb-4050-42b6-ab55-8282a15fa094, deviceId: 5F:99:E1:54:4A:89), result: CharacteristicValue)
I/flutter ( 4075): Subscribe error Exception: GenericFailure(code: CharacteristicValueUpdateError.unknown, message: "Cannot find client characteristic config descriptor (code 2) with characteristic UUID 010d815c-031c-4de8-ac10-1ffebcf874fa")
Please explain:
Why is the 'enabled' boolean (setCharacteristicNotification) false? how can I set it to true?
What is the reason for the "Subscribe error Exception"? Am I supposed to configure a descriptor? if so, how?
Additional info
My Android based BLE server, creation code:
My Android based BLE client (notifications works as expected), code:
Flutter ble client:
https://github.com/LironKomfort/reactive_ble_test
BLE android client/server projects:
https://github.com/LironKomfort/android_ble_server_client
Client tested on Android version 9 (Xiaomi mi6 + Pixel 4A)
Server tested on Android version 7.1
The text was updated successfully, but these errors were encountered: