3

Background: I'm working on OOB Pairing (via USB) between iOS device and embedded Linux board. Currently, on Linux side, I'm receiving bluetooth linkkey (needed for future connections) and mac address.
ps: if you are familiar with the subject - please, look at this question as well.

My current implementation, uses mac address as device's name (for details - see link to the question above), which is being resolved after second bluetoothd service restart.


Question: is there a way to get bluetooth name of the device having it's mac only with a help of BlueZ? I will use this in the C code with an access to BlueZ's DBus interface.

rsht
  • 1,522
  • 12
  • 27

1 Answers1

1

AFAIK, there is no straight forward DBus API or method to find the name from MAC address. But this can done using the method "GetManagedObjects" in "org.freedesktop.DBus.Properties" interface of the device.

Below is the pseudo code which will should work if proper error handling and variables are added. DBus XML is added at the top of the source just for reference.

#if 0
dbus-send --system --dest=org.bluez --type=method_call --print-reply  /org/bluez/hci0/dev_44_D8_84_02_A3_17 org.freedesktop.DBus.Introspectable.Introspect
method return sender=:1.1 -> dest=:1.7 reply_serial=2
   string "<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
    <interface name="org.freedesktop.DBus.Introspectable">
        <method name="Introspect">
            <arg name="xml" type="s" direction="out"/>
        </method>
    </interface>
    <interface name="org.bluez.Device1">
        <method name="Disconnect"></method>
        <method name="Connect"></method>
        <method name="ConnectProfile">
            <arg name="UUID" type="s" direction="in"/>
        </method>
        <method name="DisconnectProfile">
            <arg name="UUID" type="s" direction="in"/>
        </method>
        <method name="Pair"></method>
        <method name="CancelPairing"></method>

        <property name="Address" type="s" access="read"></property>
        <property name="Name" type="s" access="read"></property>
        <property name="Alias" type="s" access="readwrite"></property>
        <property name="Class" type="u" access="read"></property>
        <property name="Appearance" type="q" access="read"></property>
        <property name="Icon" type="s" access="read"></property>
        <property name="Paired" type="b" access="read"></property>
        <property name="Trusted" type="b" access="readwrite"></property>
        <property name="Blocked" type="b" access="readwrite"></property>
        <property name="LegacyPairing" type="b" access="read"></property>
        <property name="RSSI" type="n" access="read"></property>
        <property name="Connected" type="b" access="read"></property>
        <property name="UUIDs" type="as" access="read"></property>
        <property name="Modalias" type="s" access="read"></property>
        <property name="Adapter" type="o" access="read"></property>
    </interface>
    <interface name="org.freedesktop.DBus.Properties">
        <method name="Get">
            <arg name="interface" type="s" direction="in"/>
            <arg name="name" type="s" direction="in"/>
            <arg name="value" type="v" direction="out"/>
        </method>
        <method name="Set">
            <arg name="interface" type="s" direction="in"/>
            <arg name="name" type="s" direction="in"/>
            <arg name="value" type="v" direction="in"/>
        </method>
        <method name="GetAll">
            <arg name="interface" type="s" direction="in"/>
            <arg name="properties" type="a{sv}" direction="out"/>
        </method>
        <signal name="PropertiesChanged">
            <arg name="interface" type="s"/>
            <arg name="changed_properties" type="a{sv}"/>
            <arg name="invalidated_properties" type="as"/>
        </signal>
    </interface>
<node name="player0"/></node>"
#endif
#define BT_BLUEZ_NAME "org.bluez"
#define BT_MANAGER_PATH "/"
#define BT_ADAPTER_INTERFACE    "org.bluez.Adapter1"
#define BT_DEVICE_IFACE     "org.bluez.Device1"
#define BT_MANAGER_INTERFACE "org.freedesktop.DBus.ObjectManager"
#define BT_PROPERTIES_INTERFACE "org.freedesktop.DBus.Properties"

int main(void)
{
    char *known_address = "2C:F0:A2:26:D7:F5"; /*This is your address to search */

        conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
        proxy =  g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, NULL, BT_BLUEZ_NAME, BT_MANAGER_PATH, BT_MANAGER_INTERFACE, NULL, &err);
        result = g_dbus_proxy_call_sync(proxy, "GetManagedObjects", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);

    g_variant_get(result, "(a{oa{sa{sv}}})", &iter);

        char *device_path = NULL;
        char device_address[18] = { 0 };
        /* Parse the signature:  oa{sa{sv}}} */
        while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &device_path, NULL)) {
        {
            char address[BT_ADDRESS_STRING_SIZE] = { 0 };
            char *dev_addr;

            dev_addr = strstr(device_path, "dev_");
            if (dev_addr != NULL) {
                char *pos = NULL;
                dev_addr += 4;
                g_strlcpy(address, dev_addr, sizeof(address));

                while ((pos = strchr(address, '_')) != NULL) {
                    *pos = ':';
                }

                g_strlcpy(device_address, address, BT_ADDRESS_STRING_SIZE);
            }

        }

        if (g_strcmp0(known_address, device_address) == 0) {
            /* Find the name of the device */
            device_property_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, NULL, BT_BLUEZ_NAME, &device_path, BT_PROPERTIES_INTERFACE, NULL, NULL);
            result = g_dbus_proxy_call_sync(proxy, "Get", g_variant_new("(ss)", BT_DEVICE_IFACE, "Alias"), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);

            const char *local = NULL;
            g_variant_get(result, "(v)", &temp);
            local = g_variant_get_string(temp, NULL);
            printf("Your desired name : %s\n", local);
        }
        }
}
Parthiban
  • 2,130
  • 2
  • 14
  • 27
  • thank you a ton! However this code assumes that we have 'found' bt device in a prior, doesn't it? – rsht Oct 11 '16 at 11:40
  • @rsht Yes, from your question I understand that you have the device MAC address already available. If not, you may be interested in some adapter API's like "StartDiscovery". – Parthiban Oct 11 '16 at 11:44
  • Yes, I do have it. But I have it from OOB pairing process via iOS special protocol (iAP2 via USB), not via BlueZ's scanning. The point of OOB pairing is to pair two devices without regular bluetooth scan/pair procedures. Anyhow, thanks for your efforts and kindly let me know if you will have some other ideas. – rsht Oct 11 '16 at 11:48
  • @rsht AFAIK iOS provides one vendor specific profile with UUID 00000000-deca-fade-deca-deafdecacafe, which can be used to follow iAP2. But this one is also based on BlueZ scan and pairing procedure. But not sure about the Accessory Specifications. AFAIK iAP2 follows some ConnectionUpdates commands to achieve the same. – Parthiban Oct 11 '16 at 12:01