5、应用实例
一般 BLE(低功耗蓝牙)设备的连接流程可以分为以下几个步骤:
- 启动设备发现:通过
StartDiscovery
方法开始扫描周围的 BLE 设备。 - 监听设备发现信号:监听
InterfacesAdded
信号,以获取发现的设备对象路径。 - 停止设备发现:扫描到目标设备后,通过
StopDiscovery
方法停止扫描。 - 配对设备(可选):如果设备需要配对,可以调用
Pair
方法进行配对。 - 连接到设备:通过
Connect
方法连接到设备。 - 发现服务和特征:连接成功后,发现设备上的服务和特征。
- 操作特征:读取或写入特征,订阅通知等。
#include <gio/gio.h>
#include <stdio.h>// 回调函数,处理设备发现信号
void on_interface_added(GDBusConnection *connection, const gchar *sender_name, const gchar *object_path, const gchar *interface_name, const gchar *signal_name, GVariant *parameters, gpointer user_data) {GVariantIter *interfaces;gchar *object;gchar *interface;GVariant *properties;g_variant_get(parameters, "(oa{sa{sv}})", &object, &interfaces);while (g_variant_iter_next(interfaces, "{sa{sv}}", &interface, &properties)) {if (g_strcmp0(interface, "org.bluez.Device1") == 0) {g_print("Discovered device: %s\n", object);// 创建设备代理对象GError *error = NULL;GDBusProxy *device_proxy = g_dbus_proxy_new_sync(connection,G_DBUS_PROXY_FLAGS_NONE,NULL,"org.bluez", // D-Bus 服务名object, // 设备对象路径"org.bluez.Device1", // 设备接口名NULL,&error);if (error != NULL) {g_printerr("Error creating device proxy: %s\n", error->message);g_error_free(error);return;}// 停止设备发现GDBusProxy *adapter_proxy = (GDBusProxy *) user_data;g_dbus_proxy_call_sync(adapter_proxy,"StopDiscovery",NULL,G_DBUS_CALL_FLAGS_NONE,-1,NULL,&error);if (error != NULL) {g_printerr("Error stopping discovery: %s\n", error->message);g_error_free(error);}// 调用 Pair 方法配对设备(如果需要)g_dbus_proxy_call_sync(device_proxy,"Pair",NULL,G_DBUS_CALL_FLAGS_NONE,-1,NULL,&error);if (error != NULL) {g_printerr("Error pairing with device: %s\n", error->message);g_error_free(error);g_object_unref(device_proxy);return;}g_print("Paired with device: %s\n", object);// 调用 Connect 方法连接到设备g_dbus_proxy_call_sync(device_proxy,"Connect",NULL,G_DBUS_CALL_FLAGS_NONE,-1,NULL,&error);if (error != NULL) {g_printerr("Error connecting to device: %s\n", error->message);g_error_free(error);g_object_unref(device_proxy);return;}g_print("Connected to device: %s\n", object);// 获取设备的服务和特征GVariant *result = g_dbus_connection_call_sync(connection,"org.bluez",object,"org.freedesktop.DBus.ObjectManager","GetManagedObjects",NULL,G_VARIANT_TYPE("(a{oa{sa{sv}}})"),G_DBUS_CALL_FLAGS_NONE,-1,NULL,&error);if (error != NULL) {g_printerr("Error getting services and characteristics: %s\n", error->message);g_error_free(error);g_object_unref(device_proxy);return;}GVariantIter *iter;gchar *service_path;GVariant *interfaces_and_properties;g_variant_get(result, "(a{oa{sa{sv}}})", &iter);while (g_variant_iter_next(iter, "{oa{sa{sv}}}", &service_path, &interfaces_and_properties)) {if (g_str_has_prefix(service_path, object)) {GVariantIter *iface_iter;gchar *interface_name;GVariant *properties;g_variant_get(interfaces_and_properties, "a{sa{sv}}", &iface_iter);while (g_variant_iter_next(iface_iter, "{sa{sv}}", &interface_name, &properties)) {if (g_strcmp0(interface_name, "org.bluez.GattService1") == 0) {g_print("Found service: %s\n", service_path);// 在这里你可以进一步获取特征并进行操作}g_variant_unref(properties);g_free(interface_name);}g_variant_iter_free(iface_iter);}g_variant_unref(interfaces_and_properties);g_free(service_path);}g_variant_iter_free(iter);g_variant_unref(result);g_object_unref(device_proxy);}g_variant_unref(properties);g_free(interface);}g_variant_iter_free(interfaces);g_free(object);
}int main(int argc, char *argv[]) {GError *error = NULL;GDBusProxy *adapter_proxy;GMainLoop *loop;// 创建 D-Bus 代理对象adapter_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, // 使用系统总线,你也可以使用 G_BUS_TYPE_SESSIONG_DBUS_PROXY_FLAGS_NONE,NULL,"org.bluez", // D-Bus 服务名"/org/bluez/hci0", // D-Bus 对象路径"org.bluez.Adapter1", // D-Bus 接口名NULL,&error);if (error != NULL) {g_printerr("Error creating proxy: %s\n", error->message);g_error_free(error);return 1;}// 连接 org.freedesktop.DBus.ObjectManager 接口的 InterfacesAdded 信号g_dbus_connection_signal_subscribe(g_dbus_proxy_get_connection(adapter_proxy),"org.bluez", // 发送者(服务)名称"org.freedesktop.DBus.ObjectManager", // 接口名称"InterfacesAdded", // 信号名称NULL, // 对象路径(NULL 表示所有路径)NULL, // 参数匹配G_DBUS_SIGNAL_FLAGS_NONE,on_interface_added, // 回调函数adapter_proxy, // 用户数据,传递适配器代理NULL // 销毁通知函数);// 调用 StartDiscovery 方法开始设备发现GVariant *result = g_dbus_proxy_call_sync(adapter_proxy,"StartDiscovery", // 调用的方法名称NULL, // 无参数G_DBUS_CALL_FLAGS_NONE,-1, // 超时时间,-1 表示无限等待NULL, // 可取消对象&error);if (error != NULL) {g_printerr("Error calling StartDiscovery: %s\n", error->message);g_error_free(error);g_object_unref(adapter_proxy);return 1;}// 创建并运行主循环loop = g_main_loop_new(NULL, FALSE);g_main_loop_run(loop);// 清理资源g_main_loop_unref(loop);g_object_unref(adapter_proxy);return 0;
}