Deprecating `handle`
See original GitHub issueIn #883 we realized that Android has an solution for differentiating services/characteristics that isn’t compatible with the current Bleak notion of an attribute handle. The reason we expose the handle
property in Bleak to begin with is to differentiate between two services or characteristics that have the same UUID. To get the value, we are using the attribute handle of the service/characteristic. However, this value is not the same cross-platform - it can be off-by-one between OSes. On macOS, we are using a private ObjC property to get the value (which could disappear some day and break Bleak). On BlueZ we have to do some string scraping to get the value from the D-Bus object path. And as we have just realized, on Android, there isn’t a way to get the value at all.
But Android actually has IMHO a rather elegant solution. Each service/characteristic is identified by two pieces of information, the UUID and an “instance id” that is essentially a 0 based index of the occurrences of that UUID. We could use this idea in Bleak by allowing a tuple of a UUID and instance id as the char_specifier
argument.
This seems much nicer that the existing situation. Currently, I think many users are just hard-coding the handle value, but as mentioned already, this doesn’t work cross-platform since the value varies by OS, and it also breaks if the device has a firmware upgrade that rearranges the GATT attributes. The current way to avoid these pitfalls is to iterate all of the characteristics to find the one you want and then pass the characteristic instance itself as the char_specifier
. But we could avoid the iteration step by allowing the new form of the argument as describe above.
If we deprecate the use of handle
s, then we don’t have to come up with a hack to fix #883 and we can just not implement handles on Android. (And there seems to be a decent amount of support for #759 which is going in the same direction of not using handle
).
Issue Analytics
- State:
- Created a year ago
- Reactions:4
- Comments:6 (3 by maintainers)
Top GitHub Comments
Hmm, good point. I’ve used accessing by handle only to debug issues in my BLE server implementation (where it allowed me to determine that I had accidentally attached the descriptors to my characteristic twice). But that’s hardly a common use case.
Ok, point taken. Allowing people never to have to use integer handles is much more important.
I think that completely hiding handles (if the backend supports them) is the wrong way to go, because really handles are the common low-level addressing mechanism for attributes and therefore for all higher level abstractions (services, characteristics, values, …).
But steering users away from using handles if they don’t have to is a good idea. For example, by not allow a bare integer handle as parameter to all types of calls, but introducing a
BleakGATTAttribute
type that encapsulates the handle, and allowing that in stead.I don’t think it should be a superclass of
BleakGATTCharacteristic
and friends, because then allowing it as parameter to, say,read_gatt_char
would not catch the programmer error of passing aBleakGATTService
in stead of aBleakGATTCharacteristic
.But implementation-wise most of the
read_gatt_*
methods in most backends could be implemented with all the common code in aread_gatt_attribute
after getting theBleakGATTAttribute
from their argument.