yanshouwang / bluetooth_low_energy

A Flutter plugin for controlling the bluetooth low energy.
https://pub.dev/packages/bluetooth_low_energy
MIT License
48 stars 16 forks source link

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

Open justinfriberg opened 2 days ago

justinfriberg commented 2 days ago

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 commented 1 day ago

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

justinfriberg commented 1 day ago

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 commented 1 day ago

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.