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_SESSION
G_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;
}