Introduction: Reading Values From a BLE Device Using CSR1010 and Dragonboard 410c

This tutorial shows how to read values from BLE device CSR1010 using Dragonboard 410c with Linaro

In this example, CSR1010 is emulating a heart rate sensor.

Step 1: Scan BLE Device

In this step, check if your BT client is ready for scan BLE devices.

<p>root@linaro-alip:/home/linaro# sudo hcitool lescan</p><p>LE Scan ...<br>18:EE:69:00:CE:00 (unknown)
18:EE:69:00:CE:00 (unknown)
EE:52:5B:04:00:02 CSR HR Sensor</p>

Step 2: Connecting Device

We will use gatttool to connect our device

-b: Device MAC address

-t: LE address type. Can be public or random, need check device spec. In this case is public.

-I: gatttool interactive mode. It will open a prompt to send cmds to the device

root@linaro-alip:/home/linaro# sudo gatttool -b EE:52:5B:04:00:02 -t public -I

Once the prompt is open, we can send connect cmd to the device.

[EE:52:5B:04:00:02][LE]> connect
Attempting to connect to EE:52:5B:04:00:02
Connection successful
[EE:52:5B:04:00:02][LE]>

Step 3: Retrieving Device Characteristics

Once the device is connected, we can read all the available services by sending the cmd "primary"

Based on the service UUID, we can discover the service type in GATT specification

https://www.bluetooth.com/specifications/gatt/services

Step 4: Reading Device Name

Let's explore the characteristics read on Generic Access Profile (uuid=1800). First we need to get the service handle values, described on first picture, in this case, starts from 5 until 11. Now we can retrieve all handles in this interval by using the cmd char-desc

[EE:52:5B:04:00:02][LE]> char-desc 05 11
handle: 0x0005, uuid: 00002800-0000-1000-8000-00805f9b34fb handle: 0x0006, uuid: 00002803-0000-1000-8000-00805f9b34fb handle: 0x0007, uuid: 00002a00-0000-1000-8000-00805f9b34fb handle: 0x0008, uuid: 00002803-0000-1000-8000-00805f9b34fb handle: 0x0009, uuid: 00002a01-0000-1000-8000-00805f9b34fb handle: 0x000a, uuid: 00002803-0000-1000-8000-00805f9b34fb handle: 0x000b, uuid: 00002a04-0000-1000-8000-00805f9b34fb handle: 0x000c, uuid: 00002800-0000-1000-8000-00805f9b34fb handle: 0x000d, uuid: 00002803-0000-1000-8000-00805f9b34fb handle: 0x000e, uuid: 00002a37-0000-1000-8000-00805f9b34fb handle: 0x000f, uuid: 00002902-0000-1000-8000-00805f9b34fb handle: 0x0010, uuid: 00002803-0000-1000-8000-00805f9b34fb handle: 0x0011, uuid: 00002a38-0000-1000-8000-00805f9b34fb

According the Generic Access Profile specification, the UUID 2A00 refers to Device Name.

Considering that the 2a00 is the handle 0x0007 in our device, let's read the value

[EE:52:5B:04:00:02][LE]> char-read-hnd 7
Characteristic value/descriptor: 43 53 52 20 48 52 20 53 65 6e 73 6f 72

Converting hex to ASCII, the device name is : ''CSR HR Sensor"

Step 5: Reading the BPM

[EE:52:5B:04:00:02][LE]> primary
attr handle: 0x0001, end grp handle: 0x0004 uuid: 00001801-0000-1000-8000-00805f9b34fb attr handle: 0x0005, end grp handle: 0x000b uuid: 00001800-0000-1000-8000-00805f9b34fb attr handle: 0x000c, end grp handle: 0x0013 uuid: 0000180d-0000-1000-8000-00805f9b34fb attr handle: 0x0014, end grp handle: 0x0017 uuid: 0000180f-0000-1000-8000-00805f9b34fb attr handle: 0x0018, end grp handle: 0x0021 uuid: 00001016-d102-11e1-9b23-00025b00a5a5 attr handle: 0x0022, end grp handle: 0xffff uuid: 0000180a-0000-1000-8000-00805f9b34fb

The Heart Rate service UUID is 0x180d, so handle interval is from 0x000c until 0x0013

[EE:52:5B:04:00:02][LE]> char-desc 0x00c 0x0013
handle: 0x000c, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x000d, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x000e, uuid: 00002a37-0000-1000-8000-00805f9b34fb
handle: 0x000f, uuid: 00002902-0000-1000-8000-00805f9b34fb
handle: 0x0010, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0011, uuid: 00002a38-0000-1000-8000-00805f9b34fb
handle: 0x0012, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0013, uuid: 00002a39-0000-1000-8000-00805f9b34fb

Reading all the Characteristic Declarations (UUID 0x2803).

[EE:52:5B:04:00:02][LE]> char-read-hnd 0x000d
Characteristic value/descriptor: 10 0e 00 37 2a
[EE:52:5B:04:00:02][LE]> char-read-hnd 0x0010
Characteristic value/descriptor: 02 11 00 38 2a
[EE:52:5B:04:00:02][LE]> char-read-hnd 0x0012
Characteristic value/descriptor: 08 13 00 39 2a

Notice that:

- handle 0x000d is the CCCD for service 2a37 (Heart Rate Measurement) with bit 10 (support NOTIFY)

- handle 0x0010 is the CCCD for service 2a38 (Body Sensor Location) with bit 02 (support READ)

- handle 0x0012 is the CCCD for service 2a39 (Heart Rate Control Point) with bit 08 (support WRITE)

Now we know that Heart Rate Measurement works only with notification. It means that first we have to register for value changes in its CCCD (UUID 0x2902), which in this case is handle 0xf

[EE:52:5B:04:00:02][LE]> char-write-req 0x00f 0100
Notification handle = 0x000e value: 16 65 f3 01
Characteristic value was written successfully
Notification handle = 0x000e value: 16 6d fa 01
Notification handle = 0x000e value: 16 6d fa 01
Notification handle = 0x000e value: 16 6c f9 01
Notification handle = 0x000e value: 16 6a f7 01
Notification handle = 0x000e value: 16 69 f6 01

According to the profile specification, the second hex number is the BPM information.

BPM:

6d = 109

6d = 109

6c = 108

6a = 106

69 = 105

Step 6: Reading the Body Sensor Location

Body Sensor Location is the UUID 0x2A38. According to its descriptor, this characteristic supports basic reading, so we can read its value directly.

[EE:52:5B:04:00:02][LE]> char-read-hnd 0x11
Characteristic value/descriptor: 03

According SIG specification, 03 means "Finger"