Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

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.

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">
    <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);
                thank you a ton! However this code assumes that we have 'found' bt device in a prior, doesn't it?
– rsht
                Oct 11, 2016 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, 2016 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, 2016 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, 2016 at 12:01
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.