BLE on Linux with bluetoothctl
In this example we want to connect with a LE device and explore its provided GATT services.
Used LE device (sensor) in this example provides a number of vendor specific GATT services but also the standard GATT services like:
Device Information - 0x180A
Battery Service - 0x180F
Environmental Sensing - 0x181A
First, connect with the discovered LE device by using the bluetoothctl command
sudo bluetoothctl
Than we need to scan for devices
[bluetooth]# scan on
After some time you will get list of devices
[bluetooth]# scan on
[NEW] Device 94:53:30:1D:09:12 KD-55XD8005
[NEW] Device D3:4D:D2:CA:BA:2A sbleTAG
Now when we got MAC address of device we can connect
[bluetooth]# connect D3:4D:D2:CA:BA:2A
Attempting to connect to D3:4D:D2:CA:BA:2A
[CHG] Device D3:4D:D2:CA:BA:2A Connected: yes
Connection successful
[NEW] Primary Service
/org/bluez/hci0/dev_D3_4D_D2_CA_BA_2A/service0001
00001801-0000-1000-8000-00805f9b34fb
Generic Attribute Profile
[NEW] Characteristic
/org/bluez/hci0/dev_D3_4D_D2_CA_BA_2A/service0001/char0002
00002a05-0000-1000-8000-00805f9b34fb
Service Changed
[NEW] Descriptor
/org/bluez/hci0/dev_D3_4D_D2_CA_BA_2A/service0001/char0002/desc0004
00002902-0000-1000-8000-00805f9b34fb
Client Characteristic Configuration
[NEW] Characteristic
/org/bluez/hci0/dev_D3_4D_D2_CA_BA_2A/service0001/char0005
00002b29-0000-1000-8000-00805f9b34fb
Unknown
[NEW] Characteristic
/org/bluez/hci0/dev_D3_4D_D2_CA_BA_2A/service0001/char0007
00002b2a-0000-1000-8000-00805f9b34fb
Unknown
[NEW] Primary Service
/org/bluez/hci0/dev_D3_4D_D2_CA_BA_2A/service0014
0000180a-0000-1000-8000-00805f9b34fb
Device Information
[NEW] Characteristic
/org/bluez/hci0/dev_D3_4D_D2_CA_BA_2A/service0014/char0015
00002a24-0000-1000-8000-00805f9b34fb
Model Number String
[NEW] Characteristic
/org/bluez/hci0/dev_D3_4D_D2_CA_BA_2A/service0014/char0017
00002a29-0000-1000-8000-00805f9b34fb
Manufacturer Name String
[NEW] Characteristic
/org/bluez/hci0/dev_D3_4D_D2_CA_BA_2A/service0014/char0019
00002a25-0000-1000-8000-00805f9b34fb
Serial Number String
[NEW] Characteristic
/org/bluez/hci0/dev_D3_4D_D2_CA_BA_2A/service0014/char001b
00002a26-0000-1000-8000-00805f9b34fb
Firmware Revision String
[NEW] Characteristic
/org/bluez/hci0/dev_D3_4D_D2_CA_BA_2A/service0014/char001d
00002a27-0000-1000-8000-00805f9b34fb
Hardware Revision String
[NEW] Characteristic
/org/bluez/hci0/dev_D3_4D_D2_CA_BA_2A/service0014/char001f
00002a28-0000-1000-8000-00805f9b34fb
Software Revision String
[NEW] Primary Service
/org/bluez/hci0/dev_D3_4D_D2_CA_BA_2A/service0021
0000181a-0000-1000-8000-00805f9b34fb
Environmental Sensing
[NEW] Characteristic
/org/bluez/hci0/dev_D3_4D_D2_CA_BA_2A/service0021/char0022
00002a6e-0000-1000-8000-00805f9b34fb
Temperature
[NEW] Descriptor
/org/bluez/hci0/dev_D3_4D_D2_CA_BA_2A/service0021/char0022/desc0024
00002902-0000-1000-8000-00805f9b34fb
Client Characteristic Configuration
[NEW] Characteristic
/org/bluez/hci0/dev_D3_4D_D2_CA_BA_2A/service0021/char0025
00002a6f-0000-1000-8000-00805f9b34fb
Humidity
[NEW] Descriptor
/org/bluez/hci0/dev_D3_4D_D2_CA_BA_2A/service0021/char0025/desc0027
00002902-0000-1000-8000-00805f9b34fb
Client Characteristic Configuration
[NEW] Characteristic
/org/bluez/hci0/dev_D3_4D_D2_CA_BA_2A/service0021/char0028
00002a6d-0000-1000-8000-00805f9b34fb
Pressure
[NEW] Descriptor
/org/bluez/hci0/dev_D3_4D_D2_CA_BA_2A/service0021/char0028/desc002a
00002902-0000-1000-8000-00805f9b34fb
Client Characteristic Configuration
[CHG] Device D3:4D:D2:CA:BA:2A UUIDs: 00001800-0000-1000-8000-00805f9b34fb
[CHG] Device D3:4D:D2:CA:BA:2A UUIDs: 00001801-0000-1000-8000-00805f9b34fb
[CHG] Device D3:4D:D2:CA:BA:2A UUIDs: 0000180a-0000-1000-8000-00805f9b34fb
[CHG] Device D3:4D:D2:CA:BA:2A UUIDs: 0000180f-0000-1000-8000-00805f9b34fb
[CHG] Device D3:4D:D2:CA:BA:2A UUIDs: 0000181a-0000-1000-8000-00805f9b34fb
After successful connection we will get list of all services and characteristics that we can use for reading data
It's good to get info
once you got connected (simplified version)
[sbleTAG]# info
Device D3:4D:D2:CA:BA:2A (random)
Name: sbleTAG
Alias: sbleTAG
Paired: no
Trusted: no
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: Environmental Sensing (0000181a-0000-1000-8000-00805f9b34fb)
Now we can use one of characteristics to get data but first we need to switch to GATT menu from bluetoothctl
[sbleTAG]# menu gatt
now if you list help
you have some additional commands to work with
[sbleTAG:/service0021/char0025]# help
Menu gatt:
Available commands:
-------------------
list-attributes [dev] List attributes
select-attribute <attribute/UUID> Select attribute
attribute-info [attribute/UUID] Select attribute
read Read attribute value
write <data=xx xx ...> Write attribute value
acquire-write Acquire Write file descriptor
release-write Release Write file descriptor
acquire-notify Acquire Notify file descriptor
release-notify Release Notify file descriptor
notify <on/off> Notify attribute value
register-application [UUID ...] Register profile to connect
unregister-application Unregister profile
register-service <UUID> Register application service.
unregister-service <UUID/object> Unregister application service
register-characteristic <UUID> <Flags=read,write,notify...> Register application characteristic
unregister-characteristic <UUID/object> Unregister application characteristic
register-descriptor <UUID> <Flags=read,write...> Register application descriptor
unregister-descriptor <UUID/object> Unregister application descriptor
back Return to main menu
version Display version
quit Quit program
exit Quit program
help Display help about this program
As we can see on top we have select-attribute
[sbleTAG]# menu[sbleTAG]# select-attribute /org/bluez/hci0/dev_D3_4D_D2_CA_BA_2A/service0021/char0022 gatt
And after we select correct one (in this case Temperature) we will get data
[sbleTAG:/service0021/char0022]# readAttempting to read /org/bluez/hci0/dev_D3_4D_D2_CA_BA_2A/service0021/char0022[CHG] Attribute /org/bluez/hci0/dev_D3_4D_D2_CA_BA_2A/service0021/char0022
Value:
32 02 11 00
32 02 11 00
As you can see we got value in hex
so as this is Little Endian simple reverse 1st 4 bit
32 02
will be 02 32
what is in decimal 562
what is value of our temperature 5.62°C
Same if we do for other characteristic (Humidity)
[sbleTAG:/service0021/char0022]# select-attribute /org/bluez/hci0/dev_D3_4D_D2_CA_BA_2A/service0021/char0025
[sbleTAG:/service0021/char0025]# read
Attempting to read /org/bluez/hci0/dev_D3_4D_D2_CA_BA_2A/service0021/char0025
[CHG] Attribute /org/bluez/hci0/dev_D3_4D_D2_CA_BA_2A/service0021/char0025 Value:
5d 1a 3d 03 ].=.
5d 1a 3d 03
And if we do the same for data here 5d 1a
will reverse 1a 5d
in decimal is 6749
So our humidity will be 67.49%
This is really easy sample but there is lot more you can do. Also is also possible to receive notifications when the value of a characteristic changes.
Hope this was useful for someone :)