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
	Generic Attribute Profile
[NEW] Characteristic
	Service Changed
[NEW] Descriptor
	Client Characteristic Configuration
[NEW] Characteristic
[NEW] Characteristic
[NEW] Primary Service
	Device Information
[NEW] Characteristic
	Model Number String
[NEW] Characteristic
	Manufacturer Name String
[NEW] Characteristic
	Serial Number String
[NEW] Characteristic
	Firmware Revision String
[NEW] Characteristic
	Hardware Revision String
[NEW] Characteristic
	Software Revision String
[NEW] Primary Service
	Environmental Sensing
[NEW] Characteristic
[NEW] Descriptor
	Client Characteristic Configuration
[NEW] Characteristic
[NEW] Descriptor
	Client Characteristic Configuration
[NEW] Characteristic
[NEW] Descriptor
	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 
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 :)