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 :)