Skip to content

Instantly share code, notes, and snippets.

@ukBaz
Last active October 15, 2022 14:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ukBaz/d7cd0c4b9e7078c89980a3db2bbad98b to your computer and use it in GitHub Desktop.
Save ukBaz/d7cd0c4b9e7078c89980a3db2bbad98b to your computer and use it in GitHub Desktop.
DBus interaction from the command line

busctl

busctl tree org.bluez
busctl introspect org.bluez /
sudo busctl monitor org.bluez
busctl tree ukBaz.bluezero
busctl introspect ukBaz.bluezero /ukBaz/bluezero
busctl call ukBaz.bluezero /ukBaz/bluezero org.freedesktop.DBus.Properties GetAll s org.bluez.LEAdvertisement1
busctl call ukBaz.bluezero /ukBaz/bluezero org.freedesktop.DBus.Properties Get ss org.bluez.LEAdvertisement1 Type
busctl call ukBaz.bluezero /ukBaz/bluezero/advertisement0001 org.freedesktop.DBus.Properties GetAll s org.bluez.LEAdvertisement1
returned: a{sv} 3 "ServiceUUIDs" as 1 "12341000-1234-1234-1234-123456789abc" "Type" s "peripheral" "IncludeTxPower" b false
busctl call org.bluez /org/bluez/hci0/dev_DE_82_35_E7_43_BE org.bluez.Device1 Connect
busctl call org.bluez /org/bluez/hci0/dev_DE_82_35_E7_43_BE/service0032/char0036 org.bluez.GattCharacteristic1 WriteValue aya{sv} 4 0xa0 0x01 0x03 0x7f 0

gdbus

gdbus introspect --system --dest org.bluez --object-path / --recurse
gdbus call -e -d com.example.SampleService -o /SomeObject -m com.example.SampleInterface.GetTuple
gdbus call -e -d com.example.SampleService -o /SomeObject -m com.example.SampleInterface.HelloWorld "This is a test"

Monitor DBus

dbus-monitor type=signal interface="org.bluez.GattService1"

Execute DBus methods

dbus-send --system --print-reply --dest=org.bluez /org/bluez/hci0 org.freedesktop.DBus.Properties.GetAll string:"org.bluez.Adapter1"

dbus-send --system --print-reply --dest=org.bluez /org/bluez/hci0/dev_F7_17_E4_09_C0_C6/service002f/char0030 org.freedesktop.DBus.Properties.GetAll string:"org.bluez.GattCharacteristic1"

Bluetooth on the Linux commandline

pi@raspberrypi:~ $ bluetoothctl 
Agent registered
[bluetooth]# advertise.uuids feaa
[bluetooth]# advertise.service 0xfeaa 0x10 0x00 0x00 0x62 0x6c 0x75 0x65 0x74 0x6f 0x6f 0x74 0x68 0x00
[bluetooth]# advertise.discoverable on
[bluetooth]# advertise on
[CHG] Controller B8:27:EB:22:57:E0 SupportedInstances: 0x04
[CHG] Controller B8:27:EB:22:57:E0 ActiveInstances: 0x01
Advertising object registered
UUID: (feaa)
UUID: Google(0xfeaa)
  10 00 00 62 6c 75 65 74 6f 6f 74 68 00           ...bluetooth.   
Tx Power: off
Name: off
Appearance: off
Discoverable: on
[bluetooth]# discoverable on
Changing discoverable on succeeded
[CHG] Controller B8:27:EB:22:57:E0 Discoverable: yes
[bluetooth]# 
pi@raspberrypi:~ $ sudo btmgmt add-adv -u feaa -d 1016aafe100001626c7565746f6f746800 -g 1

AltBeacon:

pi@raspberrypi:~ $ sudo btmgmt add-adv --adv-data 1BFF1801BEAC0000000000000000000000000000000000010001C501 ---general-discov 1

Eddystone UID Beacon:

pi@raspberrypi:~ $ sudo btmgmt add-adv -u feaa -d 1516aafe0000112233445566778899AA112233445566 1

iBeacon

sudo btmgmt add-adv -d 1AFF4C000215000102030405060708090A0B0C0D0E0F1234567800 -g 1
@ukBaz
Copy link
Author

ukBaz commented Apr 21, 2017

A number of the tools have been deprecated as captured in this patch:
http://marc.info/?l=linux-bluetooth&m=148353686301008&w=2

An attempt to identify the alternatives:

Deprecated tool Most likely replacement
gatttool D-Bus Gatt API https://git.kernel.org/cgit/bluetooth/bluez.git/tree/doc/gatt-api.txt
hciattach btattach
hciconfig btmgmt (and bluetoothctl?)
hcidump btmon (and btsnoop)
hcitool D-Bus Device API https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/device-api.txt
rfcomm implement with D-Bus Profile1 API https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/profile-api.txt
sdptool missing, functionality seems to be scattered over different D-Bus objects: Profile, Advertising, and the UUIDs arrays in device and adapter.

@ukBaz
Copy link
Author

ukBaz commented Jul 26, 2019

If you are using bluetoothctl to interact with a device, there will be a need to find the characteristic path.
This can be done more easily if you know the UUID.

$ gdbus introspect --system --dest org.bluez --object-path / --recurse | grep -i -B17 <UUID> | grep node

So for example, to find the Button B characteristic of a micro:bit

$ gdbus introspect --system --dest org.bluez --object-path / --recurse | grep -i -B17 DA91 | grep node

Should give an output something like:

        node /org/bluez/hci0/dev_E3_AC_D2_F8_EB_B9/service002b/char002f {

@ukBaz
Copy link
Author

ukBaz commented Dec 22, 2021

The BlueZ D-Bus API for the Linux Bluetooth adapter is probably the easiest to get started with.

The documentation for this API is at:

https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/adapter-api.txt

At the top it says what the D-Bus Service and Interface is. And that the object path can be variable.

Service		org.bluez
Interface	org.bluez.Adapter1

The bluetoothd is communicating on the D-Bus System bus.

D-Bus has a GetManagedObjects method that we can use to report all the things BlueZ knows about so to list all the information about BlueZ use:

$ gdbus call --system --dest org.bluez --object-path / --method org.freedesktop.DBus.ObjectManager.GetManagedObjects

That is a lot of information so let's use grep to find the object path for the adapter:

$ gdbus call --system --dest org.bluez --object-path / --method org.freedesktop.DBus.ObjectManager.GetManagedObjects | grep -Pio "/org/bluez/hci.*Adapter1"

/org/bluez/hci0': {'org.freedesktop.DBus.Introspectable': {}, 'org.bluez.Adapter1

So we can now see that (for me) the D-Bus object path is /org/bluez/hci0. I can introspect this now:

$ gdbus introspect --system --dest org.bluez --object-path /org/bluez/hci0

Now I have the Service, Interface and Object Path I can call methods as documented by BlueZ. For example to find what available filters that can be given to SetDiscoveryFilter:

$ gdbus call --system --dest org.bluez --object-path /org/bluez/hci0 --method org.bluez.Adapter1.GetDiscoveryFilters

(['UUIDs', 'RSSI', 'Pathloss', 'Transport', 'DuplicateData'],)

To get all the properties on the Adapter then we can use the GetAll method (that we can see from the introspection) is on the org.freedesktop.DBus.Properties interface. A call example:

$ gdbus call --system --dest org.bluez --object-path /org/bluez/hci0 --method org.freedesktop.DBus.Properties.GetAll "org.bluez.Adapter1"

To get the value of one property we use Get:

$ gdbus call --system --dest org.bluez --object-path /org/bluez/hci0 --method org.freedesktop.DBus.Properties.Get "org.bluez.Adapter1" "Powered"

To set the value of a property we use Set:

$ gdbus call --system --dest org.bluez --object-path /org/bluez/hci0 --method org.freedesktop.DBus.Properties.Set "org.bluez.Adapter1" "Powered" "<boolean true>"

@ukBaz
Copy link
Author

ukBaz commented Dec 22, 2021

Using bluetoothctl to write multiple bytes to a characteristic:

pi@SensePi:~ $ bluetoothctl 
[bluetooth]# connect E1:4B:6C:22:56:F0
[BBC micro:bit [toveg]]# gatt.select-attribute 6e400003-b5a3-f393-e0a9-e50e24dcca9e
[BBC micro:bit [toveg]:/service0028/char0029]# gatt.write "0x42 0x4C 0x45 0x23"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment