Sunday, February 8 2015

Bluetooth BLE, gatttool and (almost) all those numbers .... explained

It's a short guide to practical side of bluetooth LE using gatttool. How to read characteristics, turn on notifications and where to find more info about all those BLE numbers.

I was strugging for a while to read data from a BLE heart rate strap. It was working flawlessly with android apps, but I needed it to use it with raspberry pi and python. So, I had to dig a bit deeper under the surface of BLE. The results are below.

Prerequisites:

1. A computer with bluetooth v4.0 card or dongle

2. gatttool (part of bluez). Fedora users might have to compile bluez as there is no gatttool in bluez-5.23-1.fc21 bugreport: [1].

3. A BLE (bluetooth Low Energy, Bluetooth Smart) device - I use a Tacx heart rate belt [2]

An example command line session (red - important or info for later use, blue - value from previous steps, green - comment):

$ hciconfig
hci0:    Type: BR/EDR  Bus: USB
^^ hci0: that's our hci device
    BD Address: C4:85:08:06:9F:C7  ACL MTU: 310:10  SCO MTU: 64:8
    UP RUNNING PSCAN
    RX bytes:10243057 acl:34567 sco:0 events:5307 errors:0
    TX bytes:46612 acl:737 sco:0 commands:2685 errors:0

fedora-lan:/home/przemo
$ sudo hciconfig hci0 up
fedora-lan:/home/przemo
$ sudo hcitool -i hci0 lescan
LE Scan ...   <-- LE Scan was not showing anything, so Ctrl-C and hci0 reset
^Cfedora-lan:/home/przemo
$ sudo hciconfig hci0 reset
fedora-lan:/home/przemo
$ sudo hcitool -i hci0 lescan
LE Scan ...
D6:90:A8:08:F0:E4 Tacx HRB 04741
^^ D6:90:A8:08:F0:E4 that's BLE device address
D6:90:A8:08:F0:E4 (unknown)
D6:90:A8:08:F0:E4 Tacx HRB 04741
D6:90:A8:08:F0:E4 (unknown)

^Cfedora-lan:/home/przemo
$ sudo gatttool -i hci0 -b D6:90:A8:08:F0:E4 -t random -I
^^ if you can't connect try to use "-t random"
[D6:90:A8:08:F0:E4][LE]> connect
Attempting to connect to D6:90:A8:08:F0:E4
Connection successful

Reading velue of battery level characteristic
[D6:90:A8:08:F0:E4][LE]> primary
attr handle: 0x0001, end grp handle: 0x0007 uuid: 00001800-0000-1000-8000-00805f9b34fb
attr handle: 0x0008, end grp handle: 0x000b uuid: 00001801-0000-1000-8000-00805f9b34fb
attr handle: 0x000c, end grp handle: 0x0011 uuid: 0000180d-0000-1000-8000-00805f9b34fb
attr handle: 0x0012, end grp handle: 0x0015 uuid: 0000180f-0000-1000-8000-00805f9b34fb
^^^ 180f is "Battery Service", see link [3]
attr handle: 0x0016, end grp handle: 0xffff uuid: 0000180a-0000-1000-8000-00805f9b34fb
[D6:90:A8:08:F0:E4][LE]> characteristics 0x0012 0x0015
handle: 0x0013, char properties: 0x12, char value handle: 0x0014, uuid: 00002a19-0000-1000-8000-00805f9b34fb
^^ 2a19 is Battery Level, links [4] and [5]
char properties 0x12: supports NOTIFICATION 0x10 and READ 0x02 (0x10 | 0x02 = 0x12)

[D6:90:A8:08:F0:E4][LE]> char-read-hnd 0x0014
^^ Reading handle value
Characteristic value/descriptor: 64           
^^ value of battery level is 64, but it's hex, so 0x64 = 100. It's in %, link [4]
Reading heart rate
[D6:90:A8:08:F0:E4][LE]> primary
attr handle: 0x0001, end grp handle: 0x0007 uuid: 00001800-0000-1000-8000-00805f9b34fb
attr handle: 0x0008, end grp handle: 0x000b uuid: 00001801-0000-1000-8000-00805f9b34fb
attr handle: 0x000c, end grp handle: 0x0011 uuid: 0000180d-0000-1000-8000-00805f9b34fb
^^ 180d is "Heart Rate" service, link [3]
attr handle: 0x0012, end grp handle: 0x0015 uuid: 0000180f-0000-1000-8000-00805f9b34fb
attr handle: 0x0016, end grp handle: 0xffff uuid: 0000180a-0000-1000-8000-00805f9b34fb
[D6:90:A8:08:F0:E4][LE]> characteristics 0x000c 0x0011
handle: 0x000d, char properties: 0x10, char value handle: 0x000e, uuid: 00002a37-0000-1000-8000-00805f9b34fb
^^ 2a37 is Heart Rate characteristic, links [5] and [6]
char properties: 0x10: supports NOTIFICATION
handle: 0x0010, char properties: 0x02, char value handle: 0x0011, uuid: 00002a38-0000-1000-8000-00805f9b34fb
^^ 2a38 is Body Sensor Location, links [6] and [7]
char properties: 0x02: supports READ
[D6:90:A8:08:F0:E4][LE]> char-read-hnd 0x0011
^^ Reading Body Sensor Location
Characteristic value/descriptor: 01
^^ 0x01 it's "Chest", see link [7] for more options
We need more info to switch on NOTIFICATION of heart rate
[D6:90:A8:08:F0:E4][LE]> char-desc 0x000d 0x000f
^^ range of handles for heart rate: 0x000d is start of the range obtained with 'characteristics 0x000c 0x0011'
0x0010 is start of next characteristic minus 1: 0x0010 - 0x1 = 0x000f
handle: 0x000d, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x000e, uuid: 00002a37-0000-1000-8000-00805f9b34fb
handle: 0x000f, uuid: 00002902-0000-1000-8000-00805f9b34fb
^^ 2902 it is Client Characteristic Configuration, link [8]
[D6:90:A8:08:F0:E4][LE]> char-write-cmd 0x000f 01
^^ 01 comes from link [8], NOTIFICATIONS enabled
Notification handle = 0x000e value: 00 3e        <-- heart rate, 0x003e is 63 BPM
Notification handle = 0x000e value: 00 3d        <-- heart rate, 0x003d is 62 BPM
Notification handle = 0x000e value: 00 3d        <-- heart rate, 0x003d is 62 BPM
Notification handle = 0x000e value: 00 3c        <-- heart rate, 0x003c is 61 BPM
[D6:90:A8:08:F0:E4][LE]> char-write-cmd 0x000f 00
^^ 00 comes from link [8], NOTIFICATIONS disabled
[D6:90:A8:08:F0:E4][LE]> disconnect              <-- end of connection
[D6:90:A8:08:F0:E4][LE]>
fedora-lan:/home/przemo/android

[1] https://bugzilla.redhat.com/show_bug.cgi?id=1141909

[2] http://www.tacx.com/en/products/sensors/heart-rate-belt

[3] https://developer.bluetooth.org/gatt/services/Pages/ServicesHome.aspx

[4] https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.battery_level.xml

[5] https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicsHome.aspx

[6] https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml

[7] https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.body_sensor_location.xml

[8] https://developer.bluetooth.org/gatt/descriptors/Pages/DescriptorViewer.aspx?u=org.bluetooth.descriptor.gatt.client_characteristic_configuration.xml