BlueZ:通过它获取设备名称的mac地址

时间:2016-10-10 11:52:37

标签: ios c linux bluez bluetooth-oob

背景:我正在iOS设备和嵌入式Linux 板之间进行 OOB配对(通过USB)。目前,在Linux方面,我接收蓝牙linkkey(未来连接需要)和 mac地址
ps:如果您熟悉这个主题 - 请同时查看this question

我当前的实现,使用mac地址作为设备的名称(有关详细信息 - 请参阅上述问题的链接),该服务在第二次bluetoothd服务重新启动后正在解决。


问题:有没有办法只在BlueZ的帮助下获得拥有它的设备的蓝牙名称?我将在C代码中使用它来访问BlueZ的DBus接口。

1 个答案:

答案 0 :(得分:1)

AFAIK,没有直接的DBus API或方法从MAC地址中查找名称。但这可以使用设备的“org.freedesktop.DBus.Properties”界面中的“GetManagedObjects”方法完成。

下面是伪代码,如果添加了适当的错误处理和变量,它将起作用。 DBus XML添加在源代码的顶部,仅供参考。

#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);
        }
        }
}