How to find handles corresponding to different UUIDs of BLE devices

6.8k Views Asked by At

Using gattool, I am able to find the UUIDs correspoing to the handles of my smartwatch as follows:

Device: MAC address
Name: MS1020
Alias: MS1020
Paired: yes
Trusted: yes
Blocked: no
Connected: no
LegacyPairing: no
UUID: Generic Access Profile    (00001800-0000-1000-8000-00805f9b34fb)
UUID: Unknown                   (0000cc00-0000-1000-8000-00805f9b34fb)
UUID: Tencent Holdings Limited  (0000fee7-0000-1000-8000-00805f9b34fb)
UUID: Vendor specific           (00010203-0405-0607-0809-0a0b0c0d1912)
ManufacturerData Key: 0x0211
ManufacturerData Value:
[LE]> characteristics
handle: 0x0002, char properties: 0x12, char value handle: 0x0003, uuid: 2b120008-0600-072a-0100-050200042a00
handle: 0x0004, char properties: 0x02, char value handle: 0x0005, uuid: 0708090a-0b0c-0d2b-1200-080600072a01
handle: 0x0007, char properties: 0x06, char value handle: 0x0008, uuid: 00010203-0405-0607-0809-0a0b0c0d2b12
handle: 0x000b, char properties: 0x08, char value handle: 0x000c, uuid: 0000fec7-0000-1000-8000-00805f9b34fb
handle: 0x000d, char properties: 0x20, char value handle: 0x000e, uuid: 0000fec8-0000-1000-8000-00805f9b34fb
handle: 0x0010, char properties: 0x02, char value handle: 0x0011, uuid: 0000fec9-0000-1000-8000-00805f9b34fb
handle: 0x0012, char properties: 0x32, char value handle: 0x0013, uuid: 0000fea1-0000-1000-8000-00805f9b34fb
handle: 0x0015, char properties: 0x2a, char value handle: 0x0016, uuid: 0000fea2-0000-1000-8000-00805f9b34fb
handle: 0x0019, char properties: 0x0a, char value handle: 0x001a, uuid: 0000cc02-0000-1000-8000-00805f9b34fb
handle: 0x001b, char properties: 0x12, char value handle: 0x001c, uuid: 0000cc03-0000-1000-8000-00805f9b34fb
handle: 0x001e, char properties: 0x12, char value handle: 0x001f, uuid: 0000cc04-0000-1000-8000-00805f9b34fb
handle: 0x0021, char properties: 0x1a, char value handle: 0x0022, uuid: 0000cc05-0000-1000-8000-00805f9b34fb
handle: 0x0024, char properties: 0x08, char value handle: 0x0025, uuid: 0000cc06-0000-1000-8000-00805f9b34fb

[LE]> primary
attr handle: 0x0001, end grp handle: 0x0005 uuid: 00001800-0000-1000-8000-00805f9b34fb
attr handle: 0x0006, end grp handle: 0x0009 uuid: 00010203-0405-0607-0809-0a0b0c0d1912
attr handle: 0x000a, end grp handle: 0x0017 uuid: 0000fee7-0000-1000-8000-00805f9b34fb
attr handle: 0x0018, end grp handle: 0x0025 uuid: 0000cc00-0000-1000-8000-00805f9b34fb

[LE]> char-desc
handle: 0x0001, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x0002, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0003, uuid: 00002a00-0000-1000-8000-00805f9b34fb
handle: 0x0004, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0005, uuid: 00002a01-0000-1000-8000-00805f9b34fb
handle: 0x0006, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x0007, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0008, uuid: 00010203-0405-0607-0809-0a0b0c0d2b12
handle: 0x0009, uuid: 00002901-0000-1000-8000-00805f9b34fb
handle: 0x000a, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x000b, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x000c, uuid: 0000fec7-0000-1000-8000-00805f9b34fb
handle: 0x000d, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x000e, uuid: 0000fec8-0000-1000-8000-00805f9b34fb
handle: 0x000f, uuid: 00002902-0000-1000-8000-00805f9b34fb
handle: 0x0010, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0011, uuid: 0000fec9-0000-1000-8000-00805f9b34fb
handle: 0x0012, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0013, uuid: 0000fea1-0000-1000-8000-00805f9b34fb
handle: 0x0014, uuid: 00002902-0000-1000-8000-00805f9b34fb
handle: 0x0015, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0016, uuid: 0000fea2-0000-1000-8000-00805f9b34fb
handle: 0x0017, uuid: 00002902-0000-1000-8000-00805f9b34fb
handle: 0x0018, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x0019, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x001a, uuid: 0000cc02-0000-1000-8000-00805f9b34fb
handle: 0x001b, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x001c, uuid: 0000cc03-0000-1000-8000-00805f9b34fb
handle: 0x001d, uuid: 00002902-0000-1000-8000-00805f9b34fb
handle: 0x001e, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x001f, uuid: 0000cc04-0000-1000-8000-00805f9b34fb
handle: 0x0020, uuid: 00002902-0000-1000-8000-00805f9b34fb
handle: 0x0021, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0022, uuid: 0000cc05-0000-1000-8000-00805f9b34fb
handle: 0x0023, uuid: 00002902-0000-1000-8000-00805f9b34fb
handle: 0x0024, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0025, uuid: 0000cc06-0000-1000-8000-00805f9b34fb

I am confused, however, how to figure out which handle is for which BLE feature. For instance, the page at https://www.bluetooth.com/specifications/gatt/characteristics/ shows that the Battery level specification feature is at 0x2A19. However, I can not figure out where or how to get the UUID corresponding to 0x2A19 in the char-desc output above. How do I get this?

Edit: Thanks for the very helpful descriptions in the answers (both are very good). I have added the characteristics information above. I also have some additional information which may or may not be useful.

By trial and error, I am able to establish that the blood pressure measurement (obtained from when I press the button on the watchband) Is obtained from the third and fourth entries (in hexadecimal format) of the notification handle (see output):

Notification handle = 0x001f value: f3 14 73 4d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

However, when nothing is done, that is, no button is pressed, I get:

[LE]> char-read-hnd 0x001f
Characteristic value/descriptor: 07 00 04 4e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 

The same notification handle gives the heart rate (when that button is pressed) in the 11th entry:

Notification handle = 0x001f value: 20 00 00 00 00 00 00 00 00 00 63 00 00 00 00 00 00 00 00 00 

In all cases, however, the first entry has also changed (and they appear to be unique to the operation and inaction).

I wonder if I can access the information, and also how to trigger the BP measurement, for example. Thanks again!

Please let me know in the comments if my question is not clear or if more information is needed. I am happy to provide additional information as needed. Thanks for your time in reading and making suggesitons/pointers.

2

There are 2 best solutions below

2
On BEST ANSWER

Battery Level characteristic is not "at 0x2A19", but it is UUID 00002A19-0000-1000-8000-00805f9b34fb. It seems there is no such characteristic on your device. Note Battery Service is allowed to be declared as Secondary Service, then it may not be discovered by "primary" command.

Update after edit:

Unfortunately, this device uses non-standard characteristic (handle 0x1e, type 0000cc04-0000-1000-8000-00805f9b34fb) inside a non-standard service (handle 0x18, type 0000cc00-0000-1000-8000-00805f9b34fb) for passing data. If there is a way to trigger measurements you want, it belongs to reverse-engineering.

TL;DR

Bluetooth Specification wanted to allow vendor-specific GATT features to coexist with standard features, without the need for a global directory. For this, everything in GATT is designated through IDs that are 128 bits UUIDs in a way anyone can generate without really caring about collisions.

  • Everything is typed by an UUID, See 3.G.2.5.1:

    The Attribute Type is a UUID that describes the Attribute Value.

  • Every Service has a type as well, See 3.G.3.1:

    A service declaration is an Attribute with the Attribute Type set to the UUID for «Primary Service» or «Secondary Service». [...] A client may ignore any service definition with an unknown service UUID. An unknown service UUID is a UUID for an unsupported service.

  • And evey characteristic has a type as well, See 3.G.3.3.1:

    A characteristic declaration is an Attribute with the Attribute Type set to the UUID for «Characteristic» and Attribute Value set to the Characteristic Properties, Characteristic Value Attribute Handle and Characteristic UUID.

UUID allocation is simple, and we have a perfect illustration with the dump from your device above:

  • Have standard-defined uses, stick to the standard UUIDs,

  • Bluetooth SIG offers its members to get a Bluetooth-based UUID for optimized usage, so 0000fee7-0000-1000-8000-00805f9b34fb is compliant and vendor-specific (Allocated by SIG to Tencent Holdings Limited on 24/04/2014).

  • Generate a random UUID from scratch and use it for custom purposes. 00010203-0405-0607-0809-0a0b0c0d1912 looks compliant, but does not look random at all. Someone else may get to the same value by chance.

OTOH, I cannot find any Bluetooth spec defining 0000cc00-0000-1000-8000-00805f9b34fb, it looks non-compliant.

Bluetooth spec took care of itself and optimized the UUID process for its own spec usage in two ways:

  • To make them easy to look for, all Bluetooth-defined IDs have a common base that is nnnnnnnn-0000-1000-8000-00805f9b34fb, where nnnnnnnn is 32-bit value where collisions are not acceptable, thus must be strictly controlled when allocated. See 3.B.2.5.1:

    To reduce the burden of storing and transferring 128-bit UUID values, a range of UUID values has been pre-allocated for assignment to often-used, registered purposes.

    When you look at the GATT Service/GATT Characteristics page, you are actually looking at a list of bluetooth-based UUIDs, i.e. you should append -0000-1000-8000-00805f9b34fb when you look for them in the output of gatttool.

  • As an optimization, GATT protocol allows to encode Bluettoth-based UUIDs as shorter variants that are the "16-bit" and "32-bit" variants, i.e. not repeating -0000-1000-8000-00805f9b34fb. For an example of such thing, see table 3.4 in 3.G.3.3.1.

0
On

The output of primary is telling you which services your device supports, e.g.: the first segment of uuid: 00001800-0000-1000-8000-00805f9b34fb is 00001800 which is the Generic Access service (org.bluetooth.service.generic_access, 0x1800).

The output of primary does not list the Battery Service (org.bluetooth.service.battery_service, 0x180F):

[LE]> primary
attr handle: 0x0001, end grp handle: 0x0005 uuid: 00001800-0000-1000-8000-00805f9b34fb
attr handle: 0x0006, end grp handle: 0x0009 uuid: 00010203-0405-0607-0809-0a0b0c0d1912
attr handle: 0x000a, end grp handle: 0x0017 uuid: 0000fee7-0000-1000-8000-00805f9b34fb
attr handle: 0x0018, end grp handle: 0x0025 uuid: 0000cc00-0000-1000-8000-00805f9b34fb

Due to the absence of the Battery Service you will not find any Battery Service-related characteristics, such as Battery Level, Battery Level State, Batter Power State, etc..

References: