低功耗蓝牙ble开发(三)——基于bluez5接口的ble应用示例

5、应用实例

一般 BLE(低功耗蓝牙)设备的连接流程可以分为以下几个步骤:

  1. 启动设备发现:通过 StartDiscovery 方法开始扫描周围的 BLE 设备。
  2. 监听设备发现信号:监听 InterfacesAdded 信号,以获取发现的设备对象路径。
  3. 停止设备发现:扫描到目标设备后,通过 StopDiscovery 方法停止扫描。
  4. 配对设备(可选):如果设备需要配对,可以调用 Pair 方法进行配对。
  5. 连接到设备:通过 Connect 方法连接到设备。
  6. 发现服务和特征:连接成功后,发现设备上的服务和特征。
  7. 操作特征:读取或写入特征,订阅通知等。
#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;
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值