Skip to content
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

Android characteristicNotified only notifies on last chunk of characteristic notification stream? #100

Open
justinfriberg opened this issue Sep 18, 2024 · 6 comments
Labels

Comments

@justinfriberg
Copy link

justinfriberg commented Sep 18, 2024

We're observing a BLE GNSS device notification characteristic that returns a chunk of data every second. This data is generally larger than the MTU (over 514 bytes). On iOS, we get notified each time an MTU chunk is reached. On Android, we only get partial amount, which appears to be the size of whatever is in the last chunk (decoding the bytes bears this out). Not seeing any configuration outside of the requestMTU call to fix this.

Code:

        if (Platform.isAndroid) {
          await centralManager.requestMTU(device.peripheral, mtu: 517).catchError((_) => 0);
        }

        final characteristicStreamSubscription = centralManager.characteristicNotified.listen((eventArgs) {
          print(eventArgs.value.lengthInBytes);
        }

Android:

D/BluetoothGatt(29008): cancelOpen() - device: XX:XX:XX:XX:4E:32
D/BluetoothGatt(29008): onClientConnectionState() - status=0 clientIf=13 device=E0:5A:1B:C6:4E:32
D/BluetoothAdapter(29008): isLeEnabled(): ON
D/BluetoothLeScanner(29008): onScannerRegistered() - status=0 scannerId=2 mScannerId=0
D/BluetoothGatt(29008): close()
D/BluetoothGatt(29008): unregisterApp() - mClientIf=13
D/BluetoothAdapter(29008): isLeEnabled(): ON
D/BluetoothGatt(29008): connect() - device: XX:XX:XX:XX:4E:32, auto: false
D/BluetoothGatt(29008): registerApp()
D/BluetoothGatt(29008): registerApp() - UUID=3bb6a248-cd34-4724-87fa-efe055304eae
D/BluetoothGatt(29008): onClientRegistered() - status=0 clientIf=13
D/BluetoothGatt(29008): onClientConnectionState() - status=0 clientIf=13 device=E0:5A:1B:C6:4E:32
D/BluetoothGatt(29008): configureMTU() - device: XX:XX:XX:XX:4E:32 mtu: 517
D/BluetoothGatt(29008): onConfigureMTU() - Device=E0:5A:1B:C6:4E:32 mtu=517 status=0
D/BluetoothGatt(29008): discoverServices() - device: XX:XX:XX:XX:4E:32
D/BluetoothGatt(29008): onSearchComplete() = Device=E0:5A:1B:C6:4E:32 Status=0
D/BluetoothGatt(29008): setCharacteristicNotification() - uuid: 00002a05-0000-1000-8000-00805f9b34fb enable: true
D/BluetoothGatt(29008): setCharacteristicNotification() - uuid: 6e400003-b5a3-f393-e0a9-e50e24dcca9e enable: true
491
493
489
...

iOS:

514
443
514
514
443
514
514
@yanshouwang
Copy link
Owner

Change the MTU to 512 and test again to see if this issue is resolved.

@justinfriberg
Copy link
Author

justinfriberg commented Sep 19, 2024

Same behavior with MTU at 512.

I just noticed that even though the request was 512, the response indicated it's still at 517:

D/BluetoothGatt(13764): configureMTU() - device: XX:XX:XX:XX:4E:32 mtu: 512
D/BluetoothGatt(13764): onConfigureMTU() - Device=E0:5A:1B:C6:4E:32 mtu=517 status=0

@yanshouwang
Copy link
Owner

I just noticed that even though the request was 512, the response indicated it's still at 517:


D/BluetoothGatt(13764): configureMTU() - device: XX:XX:XX:XX:4E:32 mtu: 512

D/BluetoothGatt(13764): onConfigureMTU() - Device=E0:5A:1B:C6:4E:32 mtu=517 status=0

I think you should check if there are issues on the peripheral side. You can use other debug tools like nrf connect to check this.

@justinfriberg
Copy link
Author

Will try to get the nrf connect tool running, but wasn't immediately able to get it to load.

It's odd that it works properly on iOS - is your suggestion of checking the peripheral side a MTU failure request? This size issue seems to be due to Android: https://developer.android.com/about/versions/14/behavior-changes-all#mtu-set-to-517.

@yanshouwang
Copy link
Owner

yanshouwang commented Sep 24, 2024

Will try to get the nrf connect tool running, but wasn't immediately able to get it to load.

It's odd that it works properly on iOS - is your suggestion of checking the peripheral side a MTU failure request? This size issue seems to be due to Android: https://developer.android.com/about/versions/14/behavior-changes-all#mtu-set-to-517.

Yes, as the doc said, this issue maybe caused by the peripheral doesn't negotiate the MTU correctly.

Note: This change doesn't have an impact unless the peripheral device isn't handling the MTU negotiation properly and accepting any MTU size even if it doesn't support it. In such cases, it could cause issues when your app sends large amounts of data from Android 14 devices.

Copy link

This issue is stale because it has been open for 30 days with no activity.

@github-actions github-actions bot added the stale label Oct 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants