我们继续理解bluez设置Adapter属性DBus最基本的应用程序之一是可以同时访问任何客户端(bluez包含一个DBUS服务端),修改后的属性可以通知所有客户端。DBUS该操作可以通过信号完成。
/* * bluez_adapter_set_properties.c - Set the Powered property of Adapter * - The example uses GDBUS to set the Adapter Powered state to "on" and "off" * in sequence. * - It also registers signal handling for the PropertiesChanged event and prints * the current powere state of the Adapter * gcc `pkg-config --cflags glib-2.0 gio-2.0` -Wall -Wextra -o ./bin/bluez_adapter_set_properties ./bluez_adapter_set_properties.c `pkg-config --libs glib-2.0 gio-2.0` */ #include <glib.h> #include <gio/gio.h> GDBusConnection *con; static void bluez_signal_adapter_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; static int exit = 0; 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, "Powered")) { if(!g_strcmp0(key, "Powered")) { 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("Adapter is Powered \"%s\"\n", g_variant_get_boolean(value) ? "on" : "off"); exit ; } } done: if(properties != NULL) g_variant_iter_free(properties); if(value != NULL) g_variant_unref(value); if(exit == 2) g_main_loop_quit((GMainLoop *)userdata); } static int bluez_adapter_set_property(const char *prop, GVariant *value) { GVariant *result; GError *error = NULL; result = g_dbus_connection_call_sync(con, "org.bluez", "/org/bluez/hci0", "org.freedesktop.DBus.Properties", "Set", g_variant_new("(ssv)", "org.bluez.Adapter1", prop, value), NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); if(error != NULL) return 1; g_variant_unref(result); return 0; } int main(void) { GMainLoop *loop; int rc; guint sub; con = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL); if(con == NULL) { g_print("Not able to get connection to system bus\n"); return 1; } loop = g_main_loop_new(NULL, FALSE); sub = g_dbus_connection_signal_subscribe(con, "org.bluez", "org.freedesktop.DBus.Properties", "PropertiesChanged", NULL, "org.bluez.Adapter1", G_DBUS_SIGNAL_FLAGS_NONE, bluez_signal_adapter_changed, loop, NULL); rc = bluez_adapter_set_property("Powered", g_variant_new("b", TRUE)); if(rc) { g_print("Not able to enable the adapter\n"); g_main_loop_quit(loop); } rc = bluez_adapter_set_property("Powered", g_variant_new("b", FALSE)); if(rc) { g_print("Not able to disable the adapter\n"); g_main_loop_quit(loop); } g_main_loop_run(loop); g_dbus_connection_signal_unsubscribe(con, sub); g_object_unref(con); return 0; }
信号描述:
为了在属性变化时获得信号通知,我们需要订阅信号。订阅信号是将回调函数与该信号相关联。当检测到该信号时,调用回调函数。具体相关内容可参考DBUS规范和bluez的API文档。