I need to connect my android phone to the Linux PC via bluetooth. Phone needs to be able to create connection through the PC MAC and the UUID of the service (or UUID only) fully authomatically. And phone should be the connection initiator.
I've used this example: An Introduction to Bluetooth Programming and ran into problems, which are most likely occurs because my sample is deprecated. I was advised to use new DBus library, but I can not really understand how to connect program on my phone (which should be written in Java/Kotlin/Flutter) to the DBus architecture.
I've found this example: DBus tutorial using the low-level API and this line confuses me the most: With DBUS, before applications can communicate each other, they must be connected to the same BUS.
Does this mean that if I use DBus on my server (Linux, C++), I have to use DBus on my phone also?
If so, what else can I use to acomplish my task?
Before diving in to coding it might be useful to experiment with interacting with the BlueZ bluetoothd
through the D-Bus API. This can be done with various command line tools. I'm going to assume that you will be using the gdbus library for your C code so that seems like a good choice to experiment on the command line.
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>"
The following looks like a useful introduction to doing some of this in C: