chipweinberger / flutter_blue_plus

Flutter plugin for connecting and communicationg with Bluetooth Low Energy devices, on Android, iOS, macOS
Other
788 stars 477 forks source link

[Feature]: Support multiple characteristics with same uuid (HID Service) #795

Open chipweinberger opened 9 months ago

chipweinberger commented 9 months ago

FlutterBluePlus Version

1.31.14

Flutter Version

3.18.1

What is your feature request?

Relevant Issue: https://github.com/boskokg/flutter_blue_plus/issues/789

FlutterBluePlus does not yet support multiple characteristics with the same uuid in the same service, which is needed for the 0x1812 HID Service.

We need to add a new class member to BluetoothCharacteristic: final int characteristicIndex

For most characteristics, index will be 0. But If there are multiple characteristics with the same uuid, index represents first, second, third, etc. Android & iOS always keep characteristics in the same order, so we can use an index to find the right one.


in the BLE 0x1812 service is it possible to have multiple 0x2a4d characteristics?

Yes, in the Bluetooth Low Energy (BLE) specification, the Human Interface Device (HID) service, identified by the UUID 0x1812, can indeed have multiple instances of the Report characteristic, which is identified by the UUID 0x2A4D. This design allows a single HID service to support multiple reports, such as keyboard input, mouse input, and other control or data reports, each of which can be defined by its own instance of the Report characteristic.

This capability is crucial for devices that serve multiple functions or support complex interactions, allowing them to report different types of data to a host device under a single HID service. Each 0x2A4D characteristic instance can be configured with different properties (like Read, Write, Notify) and permissions, and it can be associated with different Report Reference descriptors that define the type and ID of the report, enabling the host to distinguish between them.

Logs

No Logs
vishal788 commented 9 months ago

All data is coming properly but after some time have some error and freez application.

i need some help for this error given below :-

D/FBP-Android: [FBP] onCharacteristicChanged: D/FBP-Android: [FBP] chr: ffe1

MrCsabaToth commented 8 months ago

Same UUID? That sounds wild, almost defeats the "unique" part of UUID. I didn't know that such a scenario is even possible and valid: I thought that the service UUID + characteristic UUID is unique tuple.

matt-meades commented 4 months ago

Would be great to see this resolved! I'm facing this issue with my current implementation, and in response to @MrCsabaToth, as per the Bluetooth spec Vol 3, Part G, Section 3.3.1:

"A service may have multiple characteristic definitions with the same Characteristic UUID"

I'm currently implementing something similar to this wifi scanner service, which populates the scan results as characteristics.

As a workaround for now I'm going to give each of the scan results the same Characteristic UUID up to the first 120 bits to identify them, then increment the last 8 bits giving me 256 possible options.

chipweinberger commented 4 months ago

@matt-meades

feel free to open a PR, and test it

nebkat commented 4 months ago

See previous discussions/PR from flutter_blue:

https://github.com/pauldemarco/flutter_blue/pull/215

LINK BROKEN https://github.com/pauldemarco/flutter_blue/issues/213

Same UUID? That sounds wild, almost defeats the "unique" part of UUID. I didn't know that such a scenario is even possible and valid: I thought that the service UUID + characteristic UUID is unique tuple.

The UUID is a unique identifier for what the characteristic represents - not the characteristic instance itself. The true unique identifier of an instance is its attribute handle, a 2-byte identifier. The GATT client obtains the table of attribute handles upon connection and then only has to include the 2-byte identifier in operations, rather than a 16 byte UUID.

chipweinberger commented 3 weeks ago

copying this here for future reference.


instead of characteristicIndex, I think we should add an index to Guid.

class Guid {
  final List<int> bytes;
  final int index = 0;

string representation:

 String get str128 {
        if (index != 0) {
           // 0000-0000-1000-8000-00805f9b34fb:$index
        } else {
           // 0000-0000-1000-8000-00805f9b34fb
        }

uuid accessors

  String get uuid128 => //  0000-1234-1000-8000-00805f9b34fb:
  String get uuid => // 1234 (shortest possible represention)

normally it will be set to 0.

and only in cases where there are dupicate services, or duplicate characteristics in a service, will it have a value.

I think we should try to make it work with an index, first, as opposed to an opaque handle. If we can get that to wokr on android and iOS, that seems best to me.