micropython / micropython-lib

Core Python libraries ported to MicroPython
Other
2.39k stars 994 forks source link

micropython/aioble: Place multiple UUIDs in single advertisement LTV. #787

Closed xyzzy42 closed 4 months ago

xyzzy42 commented 8 months ago

When multiple UUIDs of the same size are advertised, they should all be listed in a single LTV. Supplement to the Bluetooth Core Specification, Part A, §1.1.1: "A packet or data block shall not contain more than one instance for each Service UUID data size."

When aioble construct the advertisement data, it is creating a new data block for each UUID that contains only that single UUID. Rather than, e.g., a single 16-bit UUID block with a list of multiple UUIDs.

Not only is this against the specification, it wastes two bytes of limited advertisement space per UUID beyond the first for the repeated data block length and type fields.

Fix this by grouping each UUID size together.

dpgeorge commented 4 months ago

Thanks for the contribution. What you've done here looks correct, according to the BT Core Supplement.

A few points:

xyzzy42 commented 4 months ago

I chose the order of increasing size so as to pack the most services possible into the available space. I thought that would be the best result, if there are more services advertised than fit in the available space. If someone is concerned about exactly what services are advertised, then they should probably not try to advertise more than can fit in the packet, in which case the order should not matter.

As I understand it, the aioble central logic is decoding the advertisement data from any other BLE device. The fact that it can't decode BT spec compliant data is a bug that should be triggered already by existing devices, regardless of whether aioble peripherals generate spec compliant advertising data or not.

dpgeorge commented 4 months ago

I chose the order of increasing size so as to pack the most services possible into the available space. I thought that would be the best result, if there are more services advertised than fit in the available space.

Yes, that makes sense.

If someone is concerned about exactly what services are advertised, then they should probably not try to advertise more than can fit in the packet, in which case the order should not matter.

If needed the user can specify the exact byte format of the advertising/response data, so they do have full control over it if needed.

As I understand it, the aioble central logic is decoding the advertisement data from any other BLE device. The fact that it can't decode BT spec compliant data is a bug that should be triggered already by existing devices,

Yes you are correct, fixing the central can be done separately.

dpgeorge commented 4 months ago

See #863 for the corresponding fix on the central side.