bluez – Locating Object Path for GATT Server in BlueZ

bluetoothbluezlinux

Making a Bluetooth GATT server on a Linux machine is done using BlueZ. The preferred way to use modern (5.50) BlueZ is through the dbus API.

The documentation on this topic states:

GATT local and remote services share the same high-level D-Bus API.
Local refers to GATT based service exported by a BlueZ plugin or an
external application. Remote refers to GATT services exported by the
peer.

I am interpreting this as:

Both local services (Linux machine is the server, other devices connect to it via Bluetooth) and remote services (Linux machine is the client, it connects to other devices via Bluetooth) are represented on dbus

That sets the base assumption for the question.

The bluez source code provides an example-gatt-server. An example you can execute an it will just work and turn your Linux machine in a GATT server.

In that example an arbitrarily named dbus object is referenced. It's name is /org/bluez/example/service

From the documentation I would expect then that once the ./example-gatt-server is run successfully there should be a /org/bluez/example/service somewhere.

That is not the case:

~$ busctl tree org.bluez
└─/org
  └─/org/bluez
    └─/org/bluez/hci0

I am confirming with an external device that the Linux machine is acting as the GATT server, but /org/bluez/example/service isn't listed.

Why isn't /org/bluez/example/service found as an object under org.bluez?

Best Answer

I was also getting puzzled with this and i found that we are not able to see the dbus object as this example does not define a well-known/requested-name for this service on the dbus.

As per busctl documentation for being able to query the service, you would need to have a name associated with it. While this example Gatt server does not have one.

Shows an object tree of one or more services. If SERVICE is specified, show object tree of the specified services only. Otherwise, show all object trees of all services on the bus that acquired at least one well-known name.

Although you can either use sudo dbus-monitor --system for monitoring the object being registered or can request a name from dbus by calling request_name on bus before creating the Application object in gatt server example code. You can check an example service with a requested name here.

bus.request_name(BUS_NAME)
named_bus = dbus.service.BusName(BUS_NAME, bus=bus)

You need to also give permission on system bus for publishing by editing /etc/dbus-1/system.conf and add your service name as follows:

<policy user="root">
  <allow own="com.example.gattServer"/>
</policy>
Related Question