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

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

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

【问题讨论】:

    标签: dbus bluez


    【解决方案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, "(sa{sv}as)") != 0) {
            g_print("Invalid signature for %s: %s != %s", signal, signature, "(sa{sv}as)");
            goto done;
        }
    
        g_variant_get(params, "(&sa{sv}as)", &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/…。因此,在服务解决后连接设备时,此状态会发生变化。当您断开连接时,它会切换回来。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-25
    • 2012-11-14
    • 1970-01-01
    • 2015-10-01
    • 1970-01-01
    • 2023-03-22
    • 2016-01-24
    相关资源
    最近更新 更多