BLE Pairing the Raspberry Pi 3 Model B With Hexiwear
This hands-on, low-level tutorial explains working with and pairing a Raspberry Pi, and Hexiwear using BLE transceivers.
Join the DZone community and get the full member experience.
Join For FreeThe Hexiwear (see "Hexiwear: Teardown of the Hackable ‘Do-Anything’ Device") is a small and portable sensor node with a built-in BLE (Bluetooth Low Energy) transceiver. In a research project, we try to use multiple Hexiwear in a classroom environment and to collect sensor data on a Raspberry Pi. The Raspberry Pi 3 Model B, running Linux, has an onboard BLE transceiver, too, so why not bind them (wirelessly) together?
Raspberry Pi 3 connected with Hexiwear over BLE
As always, things seemed to be rather simple at the start, and the feeling was that, "Someone else must already have done this." And, as with many other times, such an assumption turns out to be wrong. Well, that part was not really considered to be part of the research project, but now, pairing a Hexiwear with a Raspberry Pi had become a research project in a research project.
In this article, I describe my journey and the steps I explored to pair the Hexiwear and a Raspberry Pi 3 Model B together. This requires downloading BlueZ (a Bluetooth stack) for Linx and building and installing the BlueZ software on the Raspberry. I describe the needed settings on the Hexiwear and how to use the command line tools on the Raspberry to pair and explore the Hexiwear, including the necessary steps for authentication. The tutorial shows this using the ‘bluetoothctl’ tool and finally using the ‘gatttool’. With this, I was able to read sensor values or trigger notifications to be sent from the Hexiwear to the Raspberry Pi.
What does not work at this time is using the Alert/Notification service (e.g. to write the current date/time to the Hexiwear).
Versions Used
I’m using the following versions on the Hexiwear:
- KW40 Firmware version 1.0.0
- MK64 FW version 1.0.2
- Hardware version 1.0.0
Hexiwear KW40 Firmware Version
And here's the Raspberry Pi 3 Model B V1.2 with onboard BLE transceiver and running Raspbian GNU/Linux 8 (jessie) version 8.
Raspberry Pi 3 Model B v1.2
As the Bluetooth stack (BlueZ), I used V5.43.
See this link for more details about the steps needed. I have listed the short steps.
Get a link to the latest version of BlueZ from http://www.bluez.org/download/ and download it:
wget http://www.kernel.org/pub/linux/bluetooth/bluez-5.43.tar.xz
Then unpack it with:
tar xvf bluez-5.43.tar.xz
Change the directory:
cd bluez-5.43/
Then copy the needed packages:
sudo apt-get updatesudo apt-get install -y libusb-dev libdbus-1-dev libglib2.0-dev libudev-dev libical-dev libreadline-dev
Then build BlueZ with the standard configuration:
./configure
This should create a configuration with no errors. If there are errors, something probably went wrong with the above dependencies and library installation.
Start the compilation with the standard make:
make
This takes about 20 minutes to build. Then, install it with:
sudo make install
Starting/Stop/Enable/Disable Service
As the system service on the disk has changed with our build, reload the service with:
sudo systemctl daemon-reload
Use the following to start or stop the service:
sudo systemctl start bluetoothsudo systemctl stop bluetooth
The following is used to get the status of the service:
systemctl status bluetooth
To automatically turn on the service at the system startup, use:
sudo systemctl enable bluetooth
This can be disabled again with:
sudo systemctl disable bluetooth
To enable the BLE features, the ‘experimental’ mode needs to be turned on in the service configuration. For this, edit the file with:
sudo nano /lib/systemd/system/bluetooth.service
Add ‘--experimental’ to the following line:
ExecStart=/usr/local/libexec/bluetooth/bluetoothd --experimental
As we changed the service settings, use the following to restart it
sudo systemctl daemon-reloadsudo systemctl restart bluetooth
Preparing the Hexiwear for Pairing
Turn on Bluetooth on the Hexiwear. This is under Menu > Settings Bluetooth. The Bluetooth icons turn blue to show that Bluetooth is turned ON:
Hexiwear Bluetooth turned on
Before trying to connect to the Hexiwear, make sure you are not already connected. I lost hours because the Hexiwear was still connected to my mobile phone. On the Hexiwear, make sure that on the main menu the Bluetooth icon is white (NOT blue!):
Hexiwear with no Bluetooth connection
‘bluetoothctl’ is a command line utility to manage, scan, and connect to Bluetooth devices. Start the tool with
bluetoothctl
First, power off the Bluetooth host controller on the Raspberry with the ‘power off’ command:
[bluetooth]# power off
Changing power off succeeded
[CHG] Controller B8:27:EB:20:B7:23 Powered: no
[CHG] Controller B8:27:EB:20:B7:23 Discovering: no
Then power it on again with ‘power on’:
[bluetooth]# power on
Changing power on succeeded
[CHG] Controller B8:27:EB:20:B7:23 Powered: yes
Then turn on the agent (which is used to ask for the pairing pin code) with the ‘agent on’ command, followed by ‘default-agent’ to enable the default pin agent:
[bluetooth]# agent on
Agent registered
[bluetooth]# default-agent
Default agent request successful
Then start scanning for devices using the ‘scan on’ command:
[bluetooth]# scan on
Discovery started
[CHG] Controller B8:27:EB:20:B7:23 Discovering: yes
[CHG] Device 00:32:40:08:00:12 RSSI: -62
[CHG] Device 7A:E1:8C:61:25:E4 RSSI: -44
After a while, it should show the Hexiwear, e.g.
New Hexiwear detected
[NEW] Device 00:34:40:0A:00:4E HEXIWEAR
If the Hexiwear does not show up, try resetting the Hexiwear with Bluetooth enabled.
Stop the scanning with:
scan off
And with...
info 00:34:40:0A:00:4E
...I get information about the device:
[bluetooth]# info 00:34:40:0A:00:4E
Device 00:34:40:0A:00:4E
Name: HEXIWEAR
Alias: HEXIWEAR
Paired: no
Trusted: no
Blocked: no
Connected: no
LegacyPairing: no
With the ‘pair’ command, I make a pairing with the device:
pair 00:34:40:0A:00:4E
The Hexiwear should now show a pairing pin code like this:
Note: According to a community article, I should be asked to enter a pin (displayed on the Hexiwear). However, with the BlueZ 5.43 I have not been asked for a pin initially. I can pair/bind without a pin, but then I only can read values that do not need authentication, so pairing is pretty much useless. If you don’t get asked for a pairing/bonding pin, repeat the steps above, including a) disconnecting from a connected Hexiwear (disconnect command), removing a Hexiwear (remove command) and make sure you quit and restart the bluetootctl program.
Bonding/Pairing Code on Hexiwear
The agent will ask for that key:
[agent] Enter passkey (number in 0-999999): 900112
[CHG] Device 00:32:40:08:00:12 Paired: yes
Pairing successful
Pairing with Hexiwear
Success! I have paired the Raspberry Pi and the Hexiwear over BLE! Below is the full sequence again:
Successful Hexiwear pairing
With the ‘info’ command, it shows that it is now paired, trusted, and connected:
[HEXIWEAR]# info 00:32:40:08:00:12
Device 00:32:40:08:00:12
Name: HEXIWEAR
Alias: HEXIWEAR
Appearance: 0x0380
Paired: yes
Trusted: yes
Blocked: no
Connected: yes
LegacyPairing: no
UUID: Generic Access Profile (00001800-0000-1000-8000-00805f9b34fb)
UUID: Generic Attribute Profile (00001801-0000-1000-8000-00805f9b34fb)
UUID: Device Information (0000180a-0000-1000-8000-00805f9b34fb)
UUID: Battery Service (0000180f-0000-1000-8000-00805f9b34fb)
UUID: Unknown (00002000-0000-1000-8000-00805f9b34fb)
UUID: Unknown (00002010-0000-1000-8000-00805f9b34fb)
UUID: Unknown (00002020-0000-1000-8000-00805f9b34fb)
UUID: Unknown (00002030-0000-1000-8000-00805f9b34fb)
UUID: Unknown (00002040-0000-1000-8000-00805f9b34fb)
UUID: Vendor specific (01ff5550-ba5e-f4ee-5ca1-eb1e5e4b1ce0)
Go back in the menu on the Hexiwear, and you should see the Bluetooth icon in blue:
Paired Bluetooth devices
The 'devices' command should now list the Hexiwear:
[bluetooth]# devices
Device 00:34:40:0A:00:4E HEXIWEAR
Services, Descriptors, and Characteristics
With the first pairing, it will report a lot of information about the device services, characteristics, and descriptors. I need the service, descriptor, and characteristics information to read/write values on the BLE device:
[NEW] Primary Service
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service0004
00001801-0000-1000-8000-00805f9b34fb
Generic Attribute Profile
[NEW] Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service0004/char0005
00002a05-0000-1000-8000-00805f9b34fb
Service Changed
[NEW] Descriptor
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service0004/char0005/desc0007
00002902-0000-1000-8000-00805f9b34fb
Client Characteristic Configuration
[NEW] Primary Service
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service0013
01ff5550-ba5e-f4ee-5ca1-eb1e5e4b1ce0
Vendor specific
[NEW] Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service0013/char0014
01ff5551-ba5e-f4ee-5ca1-eb1e5e4b1ce0
Vendor specific
[NEW] Descriptor
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service0013/char0014/desc0016
00002902-0000-1000-8000-00805f9b34fb
Client Characteristic Configuration
[NEW] Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service0013/char0017
01ff5552-ba5e-f4ee-5ca1-eb1e5e4b1ce0
Vendor specific
[NEW] Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service0013/char0019
01ff5553-ba5e-f4ee-5ca1-eb1e5e4b1ce0
Vendor specific
[NEW] Primary Service
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service001c
0000180a-0000-1000-8000-00805f9b34fb
Device Information
[NEW] Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service001c/char001d
00002a29-0000-1000-8000-00805f9b34fb
Manufacturer Name String
[NEW] Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service001c/char001f
00002a26-0000-1000-8000-00805f9b34fb
Firmware Revision String
[NEW] Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service001c/char0021
00002a25-0000-1000-8000-00805f9b34fb
Serial Number String
[NEW] Primary Service
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service0026
0000180f-0000-1000-8000-00805f9b34fb
Battery Service
[NEW] Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service0026/char0027
00002a19-0000-1000-8000-00805f9b34fb
Battery Level
[NEW] Descriptor
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service0026/char0027/desc0029
00002904-0000-1000-8000-00805f9b34fb
Characteristic Format
[NEW] Descriptor
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service0026/char0027/desc002a
00002902-0000-1000-8000-00805f9b34fb
Client Characteristic Configuration
[NEW] Primary Service
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service002e
00002000-0000-1000-8000-00805f9b34fb
Unknown
[NEW] Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service002e/char002f
00002001-0000-1000-8000-00805f9b34fb
Unknown
[NEW] Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service002e/char0033
00002002-0000-1000-8000-00805f9b34fb
Unknown
[NEW] Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service002e/char0037
00002003-0000-1000-8000-00805f9b34fb
Unknown
[NEW] Primary Service
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service003d
00002010-0000-1000-8000-00805f9b34fb
Unknown
[NEW] Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service003d/char003e
00002011-0000-1000-8000-00805f9b34fb
Unknown
[NEW] Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service003d/char0042
00002012-0000-1000-8000-00805f9b34fb
Unknown
[NEW] Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service003d/char0046
00002013-0000-1000-8000-00805f9b34fb
Unknown
[NEW] Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service003d/char004a
00002014-0000-1000-8000-00805f9b34fb
Unknown
[NEW] Primary Service
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service0050
00002020-0000-1000-8000-00805f9b34fb
Unknown
[NEW] Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service0050/char0051
00002021-0000-1000-8000-00805f9b34fb
Unknown
[NEW] Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service0050/char0055
00002022-0000-1000-8000-00805f9b34fb
Unknown
[NEW] Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service0050/char0059
00002023-0000-1000-8000-00805f9b34fb
Unknown
[NEW] Primary Service
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service005f
00002030-0000-1000-8000-00805f9b34fb
Unknown
[NEW] Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service005f/char0060
00002031-0000-1000-8000-00805f9b34fb
Unknown
[NEW] Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service005f/char0064
00002032-0000-1000-8000-00805f9b34fb
Unknown
[NEW] Descriptor
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service005f/char0064/desc0067
00002902-0000-1000-8000-00805f9b34fb
Client Characteristic Configuration
[NEW] Primary Service
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service006b
00002040-0000-1000-8000-00805f9b34fb
Unknown
[NEW] Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service006b/char006c
00002041-0000-1000-8000-00805f9b34fb
Unknown
[NEW] Descriptor
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service006b/char006c/desc006f
00002902-0000-1000-8000-00805f9b34fb
Client Characteristic Configuration
[CHG] Device 00:34:40:0A:00:4E UUIDs: 00001800-0000-1000-8000-00805f9b34fb
[CHG] Device 00:34:40:0A:00:4E UUIDs: 00001801-0000-1000-8000-00805f9b34fb
[CHG] Device 00:34:40:0A:00:4E UUIDs: 0000180a-0000-1000-8000-00805f9b34fb
[CHG] Device 00:34:40:0A:00:4E UUIDs: 0000180f-0000-1000-8000-00805f9b34fb
[CHG] Device 00:34:40:0A:00:4E UUIDs: 00002000-0000-1000-8000-00805f9b34fb
[CHG] Device 00:34:40:0A:00:4E UUIDs: 00002010-0000-1000-8000-00805f9b34fb
[CHG] Device 00:34:40:0A:00:4E UUIDs: 00002020-0000-1000-8000-00805f9b34fb
[CHG] Device 00:34:40:0A:00:4E UUIDs: 00002030-0000-1000-8000-00805f9b34fb
[CHG] Device 00:34:40:0A:00:4E UUIDs: 00002040-0000-1000-8000-00805f9b34fb
[CHG] Device 00:34:40:0A:00:4E UUIDs: 01ff5550-ba5e-f4ee-5ca1-eb1e5e4b1ce0
[CHG] Device 00:34:40:0A:00:4E ServicesResolved: yes
[CHG] Device 00:34:40:0A:00:4E Appearance: 0x0380
[HEXIWEAR]#
With the device paired, I can inspect the device with...
info 00:34:40:0A:00:4E
...which gives me a list of UUID’s:
Device 00:34:40:0A:00:4E
Name: HEXIWEAR
Alias: HEXIWEAR
Appearance: 0x0380
Paired: no
Trusted: yes
Blocked: no
Connected: yes
LegacyPairing: no
UUID: Generic Access Profile (00001800-0000-1000-8000-00805f9b34fb)
UUID: Generic Attribute Profile (00001801-0000-1000-8000-00805f9b34fb)
UUID: Device Information (0000180a-0000-1000-8000-00805f9b34fb)
UUID: Battery Service (0000180f-0000-1000-8000-00805f9b34fb)
UUID: Unknown (00002000-0000-1000-8000-00805f9b34fb)
UUID: Unknown (00002010-0000-1000-8000-00805f9b34fb)
UUID: Unknown (00002020-0000-1000-8000-00805f9b34fb)
UUID: Unknown (00002030-0000-1000-8000-00805f9b34fb)
UUID: Unknown (00002040-0000-1000-8000-00805f9b34fb)
UUID: Vendor specific (01ff5550-ba5e-f4ee-5ca1-eb1e5e4b1ce0)
And with...
list-attributes 00:34:40:0A:00:4E
...I can get again the list of services, characteristics, and descriptors from above:
Primary Service
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service0004
00001801-0000-1000-8000-00805f9b34fb
Generic Attribute Profile
Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service0004/char0005
00002a05-0000-1000-8000-00805f9b34fb
Service Changed
Descriptor
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service0004/char0005/desc0007
00002902-0000-1000-8000-00805f9b34fb
Client Characteristic Configuration
Primary Service
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service0013
01ff5550-ba5e-f4ee-5ca1-eb1e5e4b1ce0
Vendor specific
Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service0013/char0014
01ff5551-ba5e-f4ee-5ca1-eb1e5e4b1ce0
Vendor specific
Descriptor
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service0013/char0014/desc0016
00002902-0000-1000-8000-00805f9b34fb
Client Characteristic Configuration
Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service0013/char0017
01ff5552-ba5e-f4ee-5ca1-eb1e5e4b1ce0
Vendor specific
Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service0013/char0019
01ff5553-ba5e-f4ee-5ca1-eb1e5e4b1ce0
Vendor specific
Primary Service
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service001c
0000180a-0000-1000-8000-00805f9b34fb
Device Information
Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service001c/char001d
00002a29-0000-1000-8000-00805f9b34fb
Manufacturer Name String
Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service001c/char001f
00002a26-0000-1000-8000-00805f9b34fb
Firmware Revision String
Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service001c/char0021
00002a25-0000-1000-8000-00805f9b34fb
Serial Number String
Primary Service
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service0026
0000180f-0000-1000-8000-00805f9b34fb
Battery Service
Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service0026/char0027
00002a19-0000-1000-8000-00805f9b34fb
Battery Level
Descriptor
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service0026/char0027/desc0029
00002904-0000-1000-8000-00805f9b34fb
Characteristic Format
Descriptor
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service0026/char0027/desc002a
00002902-0000-1000-8000-00805f9b34fb
Client Characteristic Configuration
Primary Service
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service002e
00002000-0000-1000-8000-00805f9b34fb
Unknown
Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service002e/char002f
00002001-0000-1000-8000-00805f9b34fb
Unknown
Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service002e/char0033
00002002-0000-1000-8000-00805f9b34fb
Unknown
Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service002e/char0037
00002003-0000-1000-8000-00805f9b34fb
Unknown
Primary Service
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service003d
00002010-0000-1000-8000-00805f9b34fb
Unknown
Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service003d/char003e
00002011-0000-1000-8000-00805f9b34fb
Unknown
Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service003d/char0042
00002012-0000-1000-8000-00805f9b34fb
Unknown
Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service003d/char0046
00002013-0000-1000-8000-00805f9b34fb
Unknown
Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service003d/char004a
00002014-0000-1000-8000-00805f9b34fb
Unknown
Primary Service
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service0050
00002020-0000-1000-8000-00805f9b34fb
Unknown
Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service0050/char0051
00002021-0000-1000-8000-00805f9b34fb
Unknown
Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service0050/char0055
00002022-0000-1000-8000-00805f9b34fb
Unknown
Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service0050/char0059
00002023-0000-1000-8000-00805f9b34fb
Unknown
Primary Service
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service005f
00002030-0000-1000-8000-00805f9b34fb
Unknown
Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service005f/char0060
00002031-0000-1000-8000-00805f9b34fb
Unknown
Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service005f/char0064
00002032-0000-1000-8000-00805f9b34fb
Unknown
Descriptor
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service005f/char0064/desc0067
00002902-0000-1000-8000-00805f9b34fb
Client Characteristic Configuration
Primary Service
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service006b
00002040-0000-1000-8000-00805f9b34fb
Unknown
Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service006b/char006c
00002041-0000-1000-8000-00805f9b34fb
Unknown
Descriptor
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service006b/char006c/desc006f
00002902-0000-1000-8000-00805f9b34fb
Client Characteristic Configuration
Now I’m going to use that information to read and write values on the device.
The battery service is documented as:
Hexiwear battery service
It has been listed as:
Primary Service
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service0026
0000180f-0000-1000-8000-00805f9b34fb
Battery Service
The characteristic is reported as:
Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service0026/char0027
00002a19-0000-1000-8000-00805f9b34fb
Battery Level
I can select the attribute with:
select-attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service0026/char0027
Use the <tab> key to autocomplete the values.
And then use the following command:
read
Reading attribute value
It reports 0x64 (decimal 100), so my battery level is at 100%.
Another example is to read the DIS (Device Information Service). It is documented as:
Device Information Service
The characteristic for the Manufacturer Name String is listed as:
Characteristic
/org/bluez/hci0/dev_00_34_40_0A_00_4E/service001c/char001d
00002a29-0000-1000-8000-00805f9b34fb
Manufacturer Name String
I select the attribute:
select-attribute /org/bluez/hci0/dev_00_34_40_0A_00_4E/service001c/char001d
And with this command...
atribute-info
...I get the information with the values:
[HEXIWEAR:/service001c/char001d]# attribute-info
Characteristic - Manufacturer Name String
UUID: 00002a29-0000-1000-8000-00805f9b34fb
Service: /org/bluez/hci0/dev_00_32_40_08_00_12/service001c
Value: 0x4d
Value: 0x69
Value: 0x6b
Value: 0x72
Value: 0x6f
Value: 0x65
Value: 0x6c
Value: 0x65
Value: 0x6b
Value: 0x74
Value: 0x72
Value: 0x6f
Value: 0x6e
Value: 0x69
Value: 0x6b
Value: 0x61
Flags: read
Or I can read it with the ‘read’ command:
[HEXIWEAR:/service001c/char001d]# read
Attempting to read /org/bluez/hci0/dev_00_32_40_08_00_12/service001c/char001d
[CHG] Attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service001c/char001d Value: 0x4d
[CHG] Attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service001c/char001d Value: 0x69
[CHG] Attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service001c/char001d Value: 0x6b
[CHG] Attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service001c/char001d Value: 0x72
[CHG] Attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service001c/char001d Value: 0x6f
[CHG] Attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service001c/char001d Value: 0x65
[CHG] Attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service001c/char001d Value: 0x6c
[CHG] Attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service001c/char001d Value: 0x65
[CHG] Attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service001c/char001d Value: 0x6b
[CHG] Attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service001c/char001d Value: 0x74
[CHG] Attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service001c/char001d Value: 0x72
[CHG] Attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service001c/char001d Value: 0x6f
[CHG] Attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service001c/char001d Value: 0x6e
[CHG] Attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service001c/char001d Value: 0x69
[CHG] Attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service001c/char001d Value: 0x6b
[CHG] Attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service001c/char001d Value: 0x61
4d 69 6b 72 6f 65 6c 65 6b 74 72 6f 6e 69 6b 61 Mikroelektronika
Reading Values With Encryption and Authentication
The above setup works even without authentication/encryption (what we enabled with the bonding pin). Now let’s look at the motion service, which has now a different security mode:
Motion Service in Hexiwear
They are listed as:
[NEW] Primary Service
/org/bluez/hci0/dev_00_32_40_08_00_12/service002e
00002000-0000-1000-8000-00805f9b34fb
Unknown
[NEW] Characteristic
/org/bluez/hci0/dev_00_32_40_08_00_12/service002e/char002f
00002001-0000-1000-8000-00805f9b34fb
Unknown
[NEW] Characteristic
/org/bluez/hci0/dev_00_32_40_08_00_12/service002e/char0033
00002002-0000-1000-8000-00805f9b34fb
Unknown
[NEW] Characteristic
/org/bluez/hci0/dev_00_32_40_08_00_12/service002e/char0037
00002003-0000-1000-8000-00805f9b34fb
Unknown
Select the attribute for the accelerometer:
select-attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service002e/char002f
And when I read it:
[HEXIWEAR:/service002e/char002f]# read
Attempting to read /org/bluez/hci0/dev_00_32_40_08_00_12/service002e/char002f
[CHG] Attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service002e/char002f Value: 0x03
[CHG] Attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service002e/char002f Value: 0x00
[CHG] Attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service002e/char002f Value: 0xff
[CHG] Attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service002e/char002f Value: 0xff
[CHG] Attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service002e/char002f Value: 0xa1
[CHG] Attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service002e/char002f Value: 0xff
03 00 ff ff a1 ff ......
If you read all zeros, make sure you have the ‘Sensor Tag’ application running on the Hexiwear.
At the time of this article, there is only the Alert/Command service, which allows writing to the Hexiwear:
Hexiwear Alert command service
It is listed as:
[NEW] Primary Service
/org/bluez/hci0/dev_00_32_40_08_00_12/service005f
00002030-0000-1000-8000-00805f9b34fb
Unknown
[NEW] Characteristic
/org/bluez/hci0/dev_00_32_40_08_00_12/service005f/char0060
00002031-0000-1000-8000-00805f9b34fb
Unknown
[NEW] Characteristic
/org/bluez/hci0/dev_00_32_40_08_00_12/service005f/char0064
00002032-0000-1000-8000-00805f9b34fb
Unknown
Read gives:
[HEXIWEAR:# read
Attempting to read /org/bluez/hci0/dev_00_32_40_08_00_12/service005f/char0060
[CHG] Attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service005f/char0060 Value: 0x00
[CHG] Attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service005f/char0060 Value: 0x00
[CHG] Attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service005f/char0060 Value: 0x00
[CHG] Attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service005f/char0060 Value: 0x00
[CHG] Attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service005f/char0060 Value: 0x00
[CHG] Attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service005f/char0060 Value: 0x00
[CHG] Attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service005f/char0060 Value: 0x00
[CHG] Attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service005f/char0060 Value: 0x00
[CHG] Attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service005f/char0060 Value: 0x00
[CHG] Attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service005f/char0060 Value: 0x00
[CHG] Attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service005f/char0060 Value: 0x00
[CHG] Attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service005f/char0060 Value: 0x00
[CHG] Attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service005f/char0060 Value: 0x00
[CHG] Attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service005f/char0060 Value: 0x00
[CHG] Attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service005f/char0060 Value: 0x00
[CHG] Attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service005f/char0060 Value: 0x00
[CHG] Attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service005f/char0060 Value: 0x00
[CHG] Attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service005f/char0060 Value: 0x00
[CHG] Attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service005f/char0060 Value: 0x00
[CHG] Attribute /org/bluez/hci0/dev_00_32_40_08_00_12/service005f/char0060 Value: 0x00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 ....
[HEXIWEAR:/service005f/char0060]#
Next, I tried to write the date/time:
write 0x3 0x4 0x10 0x20 0x30 0x40
I tried to write the notifications with:
write 0x1 0x2 0x1
Or even writing all 20 bytes:
write 0x1 0x2 0x1 0x0 0x0 0x0 0x0
But all attempts failed:
Attempting to write /org/bluez/hci0/dev_00_32_40_08_00_12/service005f/char0060
Failed to write: org.bluez.Error.InProgress
So I’m not sure what I’m doing wrong. At this point, I’m not able to write to that service.
Disconnecting
Disconnect the device with:
disconnect 00:32:40:08:00:12
And then leave bluetoothctl with:
quit
The gatttool is another powerful tool, like bluetoothctl. With the gatttool, I can inspect the attributes.
Before using the gatttool, make sure you have used the ‘disconnect’ command in the bluetoothctl, followed by ‘quit’ to exit the program, otherwise, the gatttool will not work!
Run the gatttool in interactive mode:
sudo gatttool -I
And then connect to the Hexiwear with the address from above:
connect 00:32:40:08:00:12
Connecting with gatttool
Alternatively, I can launch it directly with:
sudo gatttool -b 00:32:40:08:00:12 -t random -I
In case of problems connecting to the device, stop and restart the Bluetooth service:
sudo systemctl stop bluetooth
sudo systemctl start bluetooth
With the ‘primary’ command, I list the primary services:
[00:32:40:08:00:12][LE]> primary
attr handle: 0x0004, end grp handle: 0x0007 uuid: 00001801-0000-1000-8000-00805f9b34fb
attr handle: 0x0009, end grp handle: 0x0011 uuid: 00001800-0000-1000-8000-00805f9b34fb
attr handle: 0x0013, end grp handle: 0x001a uuid: 01ff5550-ba5e-f4ee-5ca1-eb1e5e4b1ce0
attr handle: 0x001c, end grp handle: 0x0022 uuid: 0000180a-0000-1000-8000-00805f9b34fb
attr handle: 0x0026, end grp handle: 0x002a uuid: 0000180f-0000-1000-8000-00805f9b34fb
attr handle: 0x002e, end grp handle: 0x0038 uuid: 00002000-0000-1000-8000-00805f9b34fb
attr handle: 0x003d, end grp handle: 0x004b uuid: 00002010-0000-1000-8000-00805f9b34fb
attr handle: 0x0050, end grp handle: 0x005a uuid: 00002020-0000-1000-8000-00805f9b34fb
attr handle: 0x005f, end grp handle: 0x0067 uuid: 00002030-0000-1000-8000-00805f9b34fb
attr handle: 0x006b, end grp handle: 0x006f uuid: 00002040-0000-1000-8000-00805f9b34fb
According to the Hexiwear BLE documentation, there is a custom motion service with UUID 0x2000:
Hexiwear Custom motion service
According to the information from the ‘primary’ command above, attribute handle is 0x002e with a group handle of 0x0038:
attr handle: 0x002e, end grp handle: 0x0038 uuid: 00002000-0000-1000-8000-00805f9b34fb
Both the attribute handle and the group handle can now be used with a characteristic discovery command:
char-desc 0x002e 0x0038
Which gives:
handle: 0x002e, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x002f, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0030, uuid: 00002001-0000-1000-8000-00805f9b34fb
handle: 0x0033, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0034, uuid: 00002002-0000-1000-8000-00805f9b34fb
handle: 0x0037, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0038, uuid: 00002003-0000-1000-8000-00805f9b34fb
From the documentation above, there is
- 0x2001: Accelerometer
- 0x2002: Gyro
- 0x2003: Magnetometer
With this, I can read the accelerometer three 16bit values with:
char-read-uuid 0x2001
That gives:
[00:32:40:08:00:12][LE]> char-read-uuid 0x2001
handle: 0x0030 value: 04 00 ff ff a2 ff
If it returns all zeros, check that the Hexiwear has the sensors enabled. Turn on the ‘Sensor Tag’ application.
The values are in ‘centi-g’, therefore:
- X (0x0004): 0.04 g
- Y (0xffff): -0.01 g
- Z (0xffa2): -0.94 g
Alert Service
The information about the alert service is the following:
Hexiwear Alert Command Service
According to the ‘primary’ command, I have:
attr handle: 0x005f, end grp handle: 0x0067 uuid: 00002030-0000-1000-8000-00805f9b34fb
So I check the attributes with:
char-desc 0x005f 0x0067
Which gives:
[00:32:40:08:00:12][LE]> char-desc 0x005f 0x0067
handle: 0x005f, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x0060, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0061, uuid: 00002031-0000-1000-8000-00805f9b34fb
handle: 0x0064, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0065, uuid: 00002032-0000-1000-8000-00805f9b34fb
handle: 0x0067, uuid: 00002902-0000-1000-8000-00805f9b34fb
The handle is 0x0061. I read it with:
char-read-hnd 0x0061
Which gives:
[00:32:40:08:00:12][LE]> char-read-hnd 0x0061
Characteristic value/descriptor: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Next, I tried to write a dummy date/time (0x01020304) to the handle with:
[00:32:40:08:00:12][LE]> char-write-cmd 0x0061 030401020304
[00:32:40:08:00:12][LE]> char-write-req 0x0061 030401020304
I have not found clear documentation about the difference between char-write-cmd and char-write-req. To me, the char-write-req is expecting a response, while char-write-cmd gives no output indicating success or failure.
But both trials did nothing! I'm not sure what is wrong or what I should do.
After a while, all I get is:
Error: Characteristic Write Request failed: A timeout occured
I tried writing the exact 20 bytes, too:
char-write-cmd 0x61 0304010203040000000000000000000000000000
But that failed as well. I even tried to send the bytes in reverse order.
So here I’m really stuck: I can read, but I cannot write the time information.
So far, I was not able to use the WireShark sniffer with encrypted traffic. Thanks to a tip from a colleague, I should be able to get this worked out.
On the Hexiwear, there is an application mode service:
Hexiwear application mode service
This allows me to read in which mode the application is running, plus get notifications if something has changed.
With the primary command, I get a list of services handles of their IDs. The one with 0x2040 is listed last:
[00:32:40:08:00:12][LE]> primary
attr handle: 0x0004, end grp handle: 0x0007 uuid: 00001801-0000-1000-8000-00805f9b34fb
attr handle: 0x0009, end grp handle: 0x0011 uuid: 00001800-0000-1000-8000-00805f9b34fb
attr handle: 0x0013, end grp handle: 0x001a uuid: 01ff5550-ba5e-f4ee-5ca1-eb1e5e4b1ce0
attr handle: 0x001c, end grp handle: 0x0022 uuid: 0000180a-0000-1000-8000-00805f9b34fb
attr handle: 0x0026, end grp handle: 0x002a uuid: 0000180f-0000-1000-8000-00805f9b34fb
attr handle: 0x002e, end grp handle: 0x0038 uuid: 00002000-0000-1000-8000-00805f9b34fb
attr handle: 0x003d, end grp handle: 0x004b uuid: 00002010-0000-1000-8000-00805f9b34fb
attr handle: 0x0050, end grp handle: 0x005a uuid: 00002020-0000-1000-8000-00805f9b34fb
attr handle: 0x005f, end grp handle: 0x0067 uuid: 00002030-0000-1000-8000-00805f9b34fb
attr handle: 0x006b, end grp handle: 0x006f uuid: 00002040-0000-1000-8000-00805f9b34fb
With char-desc I list and limit the handles for that service. The UUID for the ‘App Mode’ characteristics is 0x2041:
[00:32:40:08:00:12][LE]> char-desc 0x6b 0x6f
handle: 0x006b, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x006c, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x006d, uuid: 00002041-0000-1000-8000-00805f9b34fb
handle: 0x006f, uuid: 00002902-0000-1000-8000-00805f9b34fb
I can read that value with the char-read-uuid or char-read-hnd command:
[00:32:40:08:00:12][LE]> char-read-uuid 0x2041
handle: 0x006d value: 00
[00:32:40:08:00:12][LE]> char-read-hnd 0x6d
Characteristic value/descriptor: 00
This means the Hexiwear is in ‘Idle’ mode. When I start the ‘Pedometer’ application on the Hexiwear, I get:
[00:32:40:08:00:12][LE]> char-read-hnd 0x6d
Characteristic value/descriptor: 06
How do you get notifications abouot mode changes? Besides 0x2041, there are other UUIDs:
- 0x2800: handle: 0x006b, uuid: 00002800-0000-1000-8000-00805f9b34fb
- 0x2803: handle: 0x006c, uuid: 00002803-0000-1000-8000-00805f9b34fb
- 0x2902:handle: 0x006f, uuid: 00002902-0000-1000-8000-00805f9b34fb
These are standard BLE UUIDs (with links to the GATT XML description):
- 0x2800: GATT Primary Service
- 0x2803: GATT Characteristics Declaration
- 0x2902: GATT Client Characteristics Configuration
Checking the 0x2800 (handle 0x6b) reveals the GATT Primary Service:
[00:32:40:08:00:12][LE]> char-read-hnd 0x6b
Characteristic value/descriptor: 40 20
So the primary service is the UUID 0x2040 (note the conversion from big endian to little endian). The 0x2040 is the Hexiwear ‘Application Mode’ service.
Next reading the UUID 0x2803 (handle 0x6c) which provides the GATT Characteristics Declaration:
[00:32:40:08:00:12][LE]> char-read-hnd 0x6c
Characteristic value/descriptor: 12 6d 00 41 20
The first byte (0x12, 0b00010010) contains information about the characteristics. Bit 1 set tells me that I can read the value, and Bit 4 set tells me that I can get notifications:
GATT Characteristics Declaration
The next is a 16-bit value (0x006D), which points to the characteristics value. So the handle 0x6D contains the value. This is what we used above to read the value:
handle: 0x006d, uuid: 00002041-0000-1000-8000-00805f9b34fb
The UUID 0x2902 (handle 0x6f) is the GATT Client Characteristics Configuration which allows me to configure the characteristics. Reading it gives:
[00:32:40:08:00:12][LE]> char-read-hnd 0x6f
Characteristic value/descriptor: 00 00
GATT 0x2902 value fields
To turn on notifications, I have to write a 0x0001 to the handle:
[00:32:40:08:00:12][LE]> char-write-req 0x6f 0001
Characteristic value was written successfully
Seems OK, but now read back the value again:
[00:32:40:08:00:12][LE]> char-read-hnd 0x6f
Characteristic value/descriptor: 00 00
So the value was not written? Ah, right, Little-Endian vs. Big Endian! Swapping the bytes does it correctly:
[00:32:40:08:00:12][LE]> char-write-req 0x6f 0100
Characteristic value was written successfully
[00:32:40:08:00:12][LE]> char-read-hnd 0x6f
Characteristic value/descriptor: 01 00
Now I get notifications when the application mode changes:
[00:32:40:08:00:12][LE]> char-read-hnd 0x6f
Characteristic value/descriptor: 01 00
Notification handle = 0x006d value: 00
Notification handle = 0x006d value: 06
Notification handle = 0x006d value: 00
Notification handle = 0x006d value: 02
Notification handle = 0x006d value: 02
Notification handle = 0x006d value: 00
Notification handle = 0x006d value: 02
Notification handle = 0x006d value: 02
Interestingly, I get two notification with value 02 when I enter the Sensor Tag Hexiwear mode.
To disable notifications, I write back 0x0000 to the characteristics:
[00:32:40:08:00:12][LE]> char-write-req 0x6f 0000
Characteristic value was written successfully
[00:32:40:08:00:12][LE]> char-read-hnd 0x6f
Characteristic value/descriptor: 00 00
With this, I’m able to read values and turn on notifications. Still, writing the date/time is something which is missing
Exit the gatttool with:
quit
Summary
The Hexiwear is a cool BLE-enabled device. Unfortunately, the BLE documentation for it is very thin, and while searching the community and forums, I have found many good hints. Still, I also found others asking the same questions I did, unanswered. While I can successfully authenticate and read attributes and turn on and get notifications, I’m not yet able to write to the Hexiwear, e.g. writing the current date/time to update the Hexiwear RTC. As I’ve been struggling with this for more than two weeks, I made a point and to publish what I know and can do. So I think I have to dig more over the coming days and weeks on that topic. On the plus side, I have learned a lot about BLE and GATT.
Happy Hexiwearing!
Links
- Installing BlueZ on a Raspberry Pi.
- Bluefruit LE Python Library.
- Tutorial about bluetoothctl (German).
- Freescale community post.
- Hexiwear BLE specification.
- Connecting to BLE with Python.
- PiGATT.
- Python Scripting.
- Reverse Engineering a Bluetooth LW Light Bulb.
- Gatttool example usage.
- Getting Started with Bluetooth Low Energy.
- Bluetooth: ATT and GATT.
Published at DZone with permission of Erich Styger, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Trending
-
Web Development Checklist
-
Seven Steps To Deploy Kedro Pipelines on Amazon EMR
-
Design Patterns for Microservices: Ambassador, Anti-Corruption Layer, and Backends for Frontends
-
Auto-Scaling Kinesis Data Streams Applications on Kubernetes
Comments