通过 Bluez DBus API 的设备连接/断开通知

Posted

技术标签:

【中文标题】通过 Bluez DBus API 的设备连接/断开通知【英文标题】:Device connect/disconnect notification via Bluez DBus API 【发布时间】:2019-05-08 21:39:02 【问题描述】:

如何在通过 bluez dbus API 创建或销毁连接时接收信号或通知?

在 /org/bluez/hci0 下的所有设备中轮询 Connected() 有效,但恕我直言,这不是一种有效的方式。

【问题讨论】:

【参考方案1】:

您需要在org.bluez.Device1 接口上监听PropertiesChanged 信号。我没有直接的设备接口示例,但模板如下,

static void bluez_signal_device_changed(GDBusConnection *conn,
                    const gchar *sender,
                    const gchar *path,
                    const gchar *interface,
                    const gchar *signal,
                    GVariant *params,
                    void *userdata)

    (void)conn;
    (void)sender;
    (void)path;
    (void)interface;
    (void)userdata;

    GVariantIter *properties = NULL;
    GVariantIter *unknown = NULL;
    const char *iface;
    const char *key;
    GVariant *value = NULL;
    const gchar *signature = g_variant_get_type_string(params);

    if(strcmp(signature, "(sasvas)") != 0) 
        g_print("Invalid signature for %s: %s != %s", signal, signature, "(sasvas)");
        goto done;
    

    g_variant_get(params, "(&sasvas)", &iface, &properties, &unknown);
    while(g_variant_iter_next(properties, "&sv", &key, &value)) 
        if(!g_strcmp0(key, "Connected")) 
            if(!g_variant_is_of_type(value, G_VARIANT_TYPE_BOOLEAN)) 
                g_print("Invalid argument type for %s: %s != %s", key,
                        g_variant_get_type_string(value), "b");
                goto done;
            
            g_print("Device is \"%s\"\n", g_variant_get_boolean(value) ? "Connected" : "Disconnected");
        
    
done:
    if(properties != NULL)
        g_variant_iter_free(properties);
    if(value != NULL)
        g_variant_unref(value);



GDBusConnection *con = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
prop_changed = g_dbus_connection_signal_subscribe(con,
                    "org.bluez",
                    "org.freedesktop.DBus.Properties",
                    "PropertiesChanged",
                    NULL,
                    "org.bluez.Device1",
                    G_DBUS_SIGNAL_FLAGS_NONE,
                    bluez_signal_device_changed,
                    NULL,
                    NULL);

使用上面的示例代码,只要 Device` 接口中的属性发生变化,就会调用信号处理函数 bluez_signal_device_changed

您可以在https://gist.github.com/parthitce 中找到更多示例,在https://www.linumiz.com/ 中找到说明

【讨论】:

谢谢。我在/org/bluez 上收听了PropertiesChanged 信号。当手机连接到我的设备时,我收到了两个信号。其中之一包括UUIDsServiceResolved(正确)。另一个包括NameAlias。断开连接后,我又收到了两个信号。一个包括UUIDs,其中一个UUID 丢失但另外两个保留,另一个包括ServiceResovled(假)和Connected(假)。所以,Connected 不会成对改变。 Donno 为什么 bluez 开发人员采用了这样的设计。现在我尝试依赖ServiceResolved。希望它有效。 @matianfu Connected 表示此处提到的设备的连接状态git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/…。因此,在服务解决后连接设备时,此状态会发生变化。当您断开连接时,它会切换回来。

以上是关于通过 Bluez DBus API 的设备连接/断开通知的主要内容,如果未能解决你的问题,请参考以下文章

BlueZ DBUS API - GATT 接口对 BLE 设备不可用

BlueZ 5.4 DBus API ConnectProfile GATT 服务 UUID

使用 DBus 和 Bluez 将数据写入蓝牙设备

Linux BlueZ dbus 通信

如何使用 Bluez Profile1 DBus API 注册连接回调

dbus 上 C 上的 Bluez 编程