Search code examples
bluetoothbluetooth-lowenergyandroid-bluetoothdbusbluez

Bluez: Scanning and listing BLE profiles of devices before connection?


I'm quite new to bluetooth development, but currently working on building my understanding by developing some basic python scripts. I'm using Bluez 5.58, python 3.9 and dbus.

So far, I am able to scan and connect to devices as well as monitor properties after connection, I've used https://www.bluetooth.com/blog/the-bluetooth-for-linux-developers-study-guide/ as a guide for much of the project.

Right now, I am trying to find a way to list BLE profiles of discovered devices before deciding what device to connect to in cmdline, such as:

Nameofdevice1: [[BLEprofiles], bdaddr1]

Nameofdevice2: [[BLEprofiles], bdaddr2]

I am quite new to BLE profiles but as I understand them they are "standard collections of services for specific use cases", describing the roles, requirements and structure of the attribute tables. There doesn't seem to be any intuitive way to list profiles and check for compatibility before connection as I've found, using bluez and dbus. SDPtool seemed useful for this purpose, but not supported with Bluez 5+.

My first thought would be to use the standard SIG UUIDs (https://www.bluetooth.com/specifications/assigned-numbers/) to match, but this also seems to require connection with bluez and dbus. It seems quite backwards to have to connect to a device before being able to judge if it suits the use case. For example, if I want to connect my phone to a speaker to play audio but don't know the name of the speaker, I would want to see what devices support A2DP or similar audio profiles.

Can listing BLE profiles in dbus/bluez be done without connecting? If it requires connection, what is the best way to implement the listing?

Thanks for any help!


Solution

  • When a new device is discovered by BlueZ it sends the InterfacesAdded signal. Below is an example of the data included for a device that has a custom service with the UUID f0cd1400-95da-4f4b-9ac8-aa55d312af0c

    BlueZ has the functionality to filter devices that it will find during discovery. One of those filters is by the advertised service UUID. This is done with setDiscoveryFilter method.

    This allows that BlueZ either only reports devices which are advertising services of a required UUID or you can look at the service UUIDs on all devices and pick a device from that.

    You

    ‣ Type=signal  Endian=l  Flags=1  Version=1 Cookie=668
      Sender=:1.12  Path=/  Interface=org.freedesktop.DBus.ObjectManager  Member=InterfacesAdded
      UniqueName=:1.12
      MESSAGE "oa{sa{sv}}" {
              OBJECT_PATH "/org/bluez/hci0/dev_C7_18_1E_21_F4_87";
              ARRAY "{sa{sv}}" {
                      DICT_ENTRY "sa{sv}" {
                              STRING "org.freedesktop.DBus.Introspectable";
                              ARRAY "{sv}" {
                              };
                      };
                      DICT_ENTRY "sa{sv}" {
                              STRING "org.bluez.Device1";
                              ARRAY "{sv}" {
                                      DICT_ENTRY "sv" {
                                              STRING "Address";
                                              VARIANT "s" {
                                                      STRING "C7:18:1E:21:F4:87";
                                              };
                                      };
                                      DICT_ENTRY "sv" {
                                              STRING "AddressType";
                                              VARIANT "s" {
                                                      STRING "random";
                                              };
                                      };
                                      DICT_ENTRY "sv" {
                                              STRING "Name";
                                              VARIANT "s" {
                                                      STRING "Aranet4 0578A";
                                              };
                                      };
                                      DICT_ENTRY "sv" {
                                              STRING "Alias";
                                              VARIANT "s" {
                                                      STRING "Aranet4 0578A";
                                              };
                                      };
                                      DICT_ENTRY "sv" {
                                              STRING "Paired";
                                              VARIANT "b" {
                                                      BOOLEAN false;
                                              };
                                      };
                                      DICT_ENTRY "sv" {
                                              STRING "Trusted";
                                              VARIANT "b" {
                                                      BOOLEAN false;
                                              };
                                      };
                                      DICT_ENTRY "sv" {
                                              STRING "Blocked";
                                              VARIANT "b" {
                                                      BOOLEAN false;
                                              };
                                      };
                                      DICT_ENTRY "sv" {
                                              STRING "LegacyPairing";
                                              VARIANT "b" {
                                                      BOOLEAN false;
                                              };
                                      };
                                      DICT_ENTRY "sv" {
                                              STRING "RSSI";
                                              VARIANT "n" {
                                                      INT16 -71;
                                              };
                                      };
                                      DICT_ENTRY "sv" {
                                              STRING "Connected";
                                              VARIANT "b" {
                                                      BOOLEAN false;
                                              };
                                      };
                                      DICT_ENTRY "sv" {
                                              STRING "UUIDs";
                                              VARIANT "as" {
                                                      ARRAY "s" {
                                                              STRING "f0cd1400-95da-4f4b-9ac8-aa55d312af0c";
                                                      };
                                              };
                                      };
                                      DICT_ENTRY "sv" {
                                              STRING "Adapter";
                                              VARIANT "o" {
                                                      OBJECT_PATH "/org/bluez/hci0";
                                              };
                                      };
                                      DICT_ENTRY "sv" {
                                              STRING "ManufacturerData";
                                              VARIANT "a{qv}" {
                                                      ARRAY "{qv}" {
                                                              DICT_ENTRY "qv" {
                                                                      UINT16 1794;
                                                                      VARIANT "ay" {
                                                                              ARRAY "y" {
                                                                                      BYTE 33;
                                                                                      BYTE 4;
                                                                                      BYTE 4;
                                                                                      BYTE 0;
                                                                                      BYTE 0;
                                                                                      BYTE 9;
                                                                                      BYTE 15;
                                                                              };
                                                                      };
                                                              };
                                                      };
                                              };
                                      };
                                      DICT_ENTRY "sv" {
                                              STRING "ServicesResolved";
                                              VARIANT "b" {
                                                      BOOLEAN false;
                                              };
                                      };
                              };
                      };
                      DICT_ENTRY "sa{sv}" {
                              STRING "org.freedesktop.DBus.Properties";
                              ARRAY "{sv}" {
                              };
                      };
              };
      };