【BlueZ 】Adapter 模块:蓝牙适配器(主设备)的初始化与核心逻辑

BlueZ adapter模块是整个蓝牙守护进程 bluetoothd 的中枢神经。它管理系统中所有蓝牙控制器(HCI 设备)的生命周期,从硬件识别、初始化配置到运行时状态维护,贯穿蓝牙通信的每一个环节。


目录

一、核心数据结构深度解析

二、适配器初始化全流程

[三、双模(BR/EDR + LE)的核心区别](#三、双模(BR/EDR + LE)的核心区别)

[四、D-Bus 接口方法与属性](#四、D-Bus 接口方法与属性)

五、广播扫描与发现机制

六、连接管理核心逻辑

七、配置与资源释放

八、异常处理与容错机制

九、驱动机制与扩展点

十、实战调试与常见问题

十一、核心函数调用链路图

十二、总结与开发规范


技术栈全景:

|-----------|----------------------------|------------------------------|
| 层次 | 组件 | 职责 |
| 总线接口 | D-Bus | 向上层应用暴露 org.bluez.Adapter1接口 |
| 管理接口 | MGMT (Management Protocol) | 与内核蓝牙协议栈通信的核心协议 |
| 控制器抽象 | struct btd_adapter | 描述单个蓝牙控制器的完整状态 |
| 设备管理 | struct btd_device | 描述连接到适配器的远端设备 |


一、核心数据结构深度解析

1.1struct btd_adapter: 适配器 的灵魂

这是 BlueZ 中最核心的数据结构,完整定义在 adapter.c#L235-L319

cpp 复制代码
struct btd_adapter {
    int ref_count;                        // 引用计数

    uint16_t dev_id;                     // 设备索引 (hci0 = 0, hci1 = 1...)
    struct mgmt *mgmt;                   // 管理接口句柄

    bdaddr_t bdaddr;                     // 控制器蓝牙地址
    uint8_t bdaddr_type;                 // 地址类型 (BDADDR_BREDR / BDADDR_LE_PUBLIC / BDADDR_LE_RANDOM)
    uint32_t dev_class;                  // 设备类别 (CoD)
    char *name;                          // 设备名(完整)
    char *short_name;                    // 设备名(短名)
    uint32_t supported_settings;         // 内核支持的设置位掩码
    uint32_t pending_settings;           // 待处理的设置位掩码
    uint32_t current_settings;           // 当前生效的设置位掩码

    char *path;                          // D-Bus 对象路径 "/org/bluez/hci%d"
    uint16_t manufacturer;               // 厂商 ID
    uint8_t major_class;                 // 配置的主类别
    uint8_t minor_class;                 // 配置的次类别
    char *system_name;                   // 系统名
    char *modalias;                      // 设备 ID (modalias)

    // 发现相关
    bool discovering;                    // 是否正在发现
    bool filtered_discovery;             // 是否为过滤发现
    uint8_t discovery_type;              // 当前发现类型
    GSList *discovery_list;              // 发现客户端列表
    struct discovery_client *client;    // 当前活跃的发现客户端

    // 安全认证
    GQueue *auths;                       // 待处理的认证请求队列
    GSList *pin_callbacks;               // PIN 码回调列表
    GSList *msd_callbacks;               // MSD 回调列表

    // 设备管理
    GSList *connections;                 // 已连接设备列表
    GSList *devices;                     // 已知设备列表
    GSList *connect_list;                // 待连接设备列表

    // GATT 与广播
    struct btd_gatt_database *database;  // GATT 数据库
    struct btd_adv_manager *adv_manager; // 广播管理器

    // 驱动与 Profile
    GSList *drivers;                     // 已加载的驱动列表
    GSList *profiles;                    // 已注册的 Profile 列表

    bool is_default;                     // 是否为默认适配器
    struct queue *exps;                  // 实验性功能列表
};

1.2 关键字段分类

硬件标识类

cpp 复制代码
uint16_t dev_id;           // HCI 索引:0x0000 ~ 0xFFFF
bdaddr_t bdaddr;           // 蓝牙地址格式:XX:XX:XX:XX:XX:XX
uint8_t bdaddr_type;       // 地址类型:
                           //   BDADDR_BREDR     (0x00) - BR/EDR 地址
                           //   BDADDR_LE_PUBLIC (0x01) - LE 公共地址
                           //   BDADDR_LE_RANDOM (0x02) - LE 随机地址
uint32_t dev_class;        // 设备类别:3 字节,主类别+次类别+服务类别
uint16_t manufacturer;    // 厂商 ID,如 0x004C (Apple), 0x001A (Google)

状态配置类

cpp 复制代码
uint32_t supported_settings;   // 内核支持的设置:如 MGMT_SETTING_LE, MGMT_SETTING_BREDR
uint32_t current_settings;     // 当前生效设置
uint32_t pending_settings;     // 待确认的设置(异步操作中)

运行时状态类

cpp 复制代码
bool discovering;              // 发现状态
bool powering_down;            // 关机中
GSList *connections;           // 连接中的设备
GSList *devices;               // 所有已知设备

1.3 struct mgmt:管理协议抽象

定义在 mgmt.h#L18

cpp 复制代码
struct mgmt;  // 不透明结构体,封装与内核管理接口的通信细节

创建方式

cpp 复制代码
struct mgmt *mgmt_new_default(void);   // 连接默认管理接口(/dev/BTMGT 或 HCI 套接字)

核心能力

  • 发送管理命令:mgmt_send()

  • 注册事件通知:mgmt_register()

  • 请求-响应模型:异步回调机制

二、 适配器 初始化全流程

2.1 初始化总览图

2.2 adapter_init():入口函数

源码位于 adapter.c

cpp 复制代码
int adapter_init(void)
{
    // 1. 获取 D-Bus 连接
    dbus_conn = btd_get_dbus_connection();

    // 2. 创建管理接口连接
    mgmt_primary = mgmt_new_default();
    if (!mgmt_primary) {
        error("Failed to access management interface");
        return -EIO;
    }

    // 3. 读取管理接口版本
    if (mgmt_send(mgmt_primary, MGMT_OP_READ_VERSION,
                MGMT_INDEX_NONE, 0, NULL,
                read_version_complete, NULL, NULL) > 0)
        return 0;  // 异步执行,返回 0 表示成功提交

    return -EIO;
}

2.3 read_version_complete():版本握手

源码位于 adapter.c

cpp 复制代码
static void read_version_complete(uint8_t status, uint16_t length,
                    const void *param, void *user_data)
{
    const struct mgmt_rp_read_version *rp = param;

    // 解析版本号
    mgmt_version = rp->version;       // 主版本号
    mgmt_revision = btohs(rp->revision);  // 修订版本号

    // 版本检查:要求 1.0+
    if (mgmt_version < 1) {
        error("Version 1.0 or later of management interface required");
        abort();
    }

    // 继续读取支持的命令列表
    mgmt_send(mgmt_primary, MGMT_OP_READ_COMMANDS,
                MGMT_INDEX_NONE, 0, NULL,
                read_commands_complete, NULL, NULL);

    // 注册热插拔事件监听
    mgmt_register(mgmt_primary, MGMT_EV_INDEX_ADDED, MGMT_INDEX_NONE,
                        index_added, NULL, NULL);
    mgmt_register(mgmt_primary, MGMT_EV_INDEX_REMOVED, MGMT_INDEX_NONE,
                        index_removed, NULL, NULL);

    // 获取当前已有的控制器列表
    mgmt_send(mgmt_primary, MGMT_OP_READ_INDEX_LIST,
                MGMT_INDEX_NONE, 0, NULL,
                read_index_list_complete, NULL, NULL);
}

2.4 index_added():热插拔检测

源码位于 adapter.c

cpp 复制代码
static void index_added(uint16_t index, uint16_t length, const void *param,
                            void *user_data)
{
    struct btd_adapter *adapter;

    // 1. 检查是否已存在(防重复)
    adapter = btd_adapter_lookup(index);
    if (adapter) {
        btd_warn(adapter->dev_id,
            "Ignoring index added for an already existing adapter");
        return;
    }

    // 2. 检查最大适配器数量限制
    if (btd_opts.max_adapters &&
            btd_opts.max_adapters == g_slist_length(adapters))
        return;

    // 3. 创建适配器对象
    adapter = btd_adapter_new(index);
    if (!adapter) {
        btd_error(index, "Unable to create new adapter for index %u", index);
        return;
    }

    // 4. 先加入列表(防止并发问题)
    adapter_list = g_list_append(adapter_list, adapter);

    // 5. 读取控制器详细信息
    mgmt_send(mgmt_primary, MGMT_OP_READ_INFO, index, 0, NULL,
                read_info_complete, adapter, NULL);
}

2.5 btd_adapter_new():对象创建

源码位于 adapter.c):

cpp 复制代码
static struct btd_adapter *btd_adapter_new(uint16_t index)
{
    struct btd_adapter *adapter;

    // 1. 分配内存
    adapter = g_try_new0(struct btd_adapter, 1);
    if (!adapter)
        return NULL;

    // 2. 设置索引和 mgmt 引用
    adapter->dev_id = index;
    adapter->mgmt = mgmt_ref(mgmt_primary);

    // 3. 应用系统级默认配置
    adapter->system_name = g_strdup(btd_opts.name);
    adapter->major_class = (btd_opts.class & 0x001f00) >> 8;
    adapter->minor_class = (btd_opts.class & 0x0000fc) >> 2;
    adapter->discoverable_timeout = btd_opts.discovto;
    adapter->pairable_timeout = btd_opts.pairto;

    // 4. 创建队列
    adapter->auths = g_queue_new();
    adapter->exps = queue_new();

    return btd_adapter_ref(adapter);
}

2.6 read_info_complete():信息填充与配置

源码位于 adapter.c

cpp 复制代码
static void read_info_complete(uint8_t status, uint16_t length,
                    const void *param, void *user_data)
{
    struct btd_adapter *adapter = user_data;
    const struct mgmt_rp_read_info *rp = param;

    // 1. 填充硬件信息
    adapter->dev_class = rp->dev_class[0] | (rp->dev_class[1] << 8) |
                        (rp->dev_class[2] << 16);
    adapter->name = g_strdup((const char *) rp->name);
    adapter->short_name = g_strdup((const char *) rp->short_name);
    adapter->manufacturer = btohs(rp->manufacturer);
    adapter->supported_settings = btohl(rp->supported_settings);
    adapter->current_settings = btohl(rp->current_settings);

    // 2. 处理蓝牙地址
    if (bacmp(&rp->bdaddr, BDADDR_ANY) == 0) {
        // 无地址时设置静态地址
        set_static_addr(adapter);
    } else {
        bacpy(&adapter->bdaddr, &rp->bdaddr);
        // 根据支持特性判断地址类型
        if (!(adapter->supported_settings & MGMT_SETTING_LE))
            adapter->bdaddr_type = BDADDR_BREDR;      // 纯 BR/EDR
        else
            adapter->bdaddr_type = BDADDR_LE_PUBLIC;  // 双模或纯 LE
    }

    // 3. 根据系统配置设置双模模式
    switch (btd_opts.mode) {
    case BT_MODE_DUAL:       // 双模:同时启用 BR/EDR 和 LE
        set_mode(adapter, MGMT_OP_SET_SSP, 0x01);
        set_mode(adapter, MGMT_OP_SET_LE, 0x01);
        set_mode(adapter, MGMT_OP_SET_BREDR, 0x01);
        break;
    case BT_MODE_BREDR:      // 仅 BR/EDR 模式
        set_mode(adapter, MGMT_OP_SET_BREDR, 0x01);
        set_mode(adapter, MGMT_OP_SET_LE, 0x00);
        break;
    case BT_MODE_LE:         // 仅 LE 模式
        set_mode(adapter, MGMT_OP_SET_LE, 0x01);
        set_mode(adapter, MGMT_OP_SET_BREDR, 0x00);
        break;
    }

    // 4. D-Bus 接口注册
    err = adapter_register(adapter);

    // 5. 注册所有 MGMT 事件回调
    mgmt_register(adapter->mgmt, MGMT_EV_NEW_SETTINGS, ...);
    mgmt_register(adapter->mgmt, MGMT_EV_CLASS_OF_DEV_CHANGED, ...);
    mgmt_register(adapter->mgmt, MGMT_EV_LOCAL_NAME_CHANGED, ...);
    mgmt_register(adapter->mgmt, MGMT_EV_DISCOVERING, ...);
    mgmt_register(adapter->mgmt, MGMT_EV_DEVICE_FOUND, ...);
    mgmt_register(adapter->mgmt, MGMT_EV_DEVICE_DISCONNECTED, ...);
    mgmt_register(adapter->mgmt, MGMT_EV_DEVICE_CONNECTED, ...);
    // ... 更多事件

    // 6. 设置设备类别和名称
    set_dev_class(adapter);
    set_name(adapter, btd_adapter_get_name(adapter));

    // 7. 加载配置与设备
    load_config(adapter);
    load_drivers(adapter);
    load_devices(adapter);

    // 8. 适配器就绪
    if (btd_adapter_get_powered(adapter))
        adapter_start(adapter);
}

2.7 adapter_register():D-Bus 接口注册

源码位于 adapter.c

cpp 复制代码
static int adapter_register(struct btd_adapter *adapter)
{
    // 1. 构造 D-Bus 对象路径
    adapter->path = g_strdup_printf("/org/bluez/hci%d", adapter->dev_id);

    // 2. 注册 org.bluez.Adapter1 接口
    g_dbus_register_interface(dbus_conn,
                    adapter->path,              // "/org/bluez/hci0"
                    ADAPTER_INTERFACE,           // "org.bluez.Adapter1"
                    adapter_methods,             // 方法表
                    NULL,                        // 信号表(无自定义信号)
                    adapter_properties,          // 属性表
                    adapter,                     // user_data
                    adapter_free);               // destroy 回调

    // 3. 标记为默认适配器(第一个注册的)
    if (adapters == NULL)
        adapter->is_default = true;
    adapters = g_slist_append(adapters, adapter);

    // 4. 获取 Agent 并设置 IO 能力
    agent = agent_get(NULL);
    if (agent) {
        uint8_t io_cap = agent_get_io_capability(agent);
        adapter_set_io_capability(adapter, io_cap);
    }

    // 5. 创建 GATT 数据库(仅 LE 或双模模式)
    if (adapter->supported_settings & MGMT_SETTING_LE) {
        adapter->database = btd_gatt_database_new(adapter);
        adapter->adv_manager = btd_adv_manager_new(adapter, adapter->mgmt);
    }

    // 6. 加载配置、驱动、设备
    load_config(adapter);
    load_drivers(adapter);
    load_devices(adapter);

    adapter->initialized = TRUE;
}

三、双模(BR/EDR + LE)的核心区别

3.1 地址类型差异

cpp 复制代码
// read_info_complete() 中的地址类型判断
if (!(adapter->supported_settings & MGMT_SETTING_LE))
    adapter->bdaddr_type = BDADDR_BREDR;      // 仅支持 BR/EDR
else
    adapter->bdaddr_type = BDADDR_LE_PUBLIC;  // 支持 LE(公共地址)

3.2 设置位掩码

cpp 复制代码
// 关键设置位定义(来自 mgmt.h)
#define MGMT_SETTING_POWERED        (1 << 0)
#define MGMT_SETTING_CONNECTABLE   (1 << 1)
#define MGMT_SETTING_DISCOVERABLE  (1 << 2)
#define MGMT_SETTING_BONDABLE      (1 << 3)
#define MGMT_SETTING_LE            (1 << 4)  // LE 支持
#define MGMT_SETTING_BREDR         (1 << 5)  // BR/EDR 支持
#define MGMT_SETTING_SSP           (1 << 6)  // 安全简易配对

3.3 模式设置流程

cpp 复制代码
// BT_MODE_DUAL:双模模式
set_mode(adapter, MGMT_OP_SET_LE, 0x01);     // 开启 LE
set_mode(adapter, MGMT_OP_SET_BREDR, 0x01); // 开启 BR/EDR
set_mode(adapter, MGMT_OP_SET_SSP, 0x01);   // 开启 SSP

// BT_MODE_BREDR:仅经典蓝牙
set_mode(adapter, MGMT_OP_SET_BREDR, 0x01); // 开启 BR/EDR
set_mode(adapter, MGMT_OP_SET_LE, 0x00);    // 关闭 LE

// BT_MODE_LE:仅低功耗蓝牙
set_mode(adapter, MGMT_OP_SET_LE, 0x01);    // 开启 LE
set_mode(adapter, MGMT_OP_SET_BREDR, 0x00); // 关闭 BR/EDR

3.4 GATT 数据库条件创建

cpp 复制代码
// adapter_register() 中的条件判断
if (!(adapter->supported_settings & MGMT_SETTING_LE) ||
                btd_opts.mode == BT_MODE_BREDR)
    goto load;  // 跳过 GATT 数据库创建

// 只有 LE 或双模模式才创建 GATT 数据库
adapter->database = btd_gatt_database_new(adapter);
adapter->adv_manager = btd_adv_manager_new(adapter, adapter->mgmt);

四、D-Bus 接口方法与属性

4.1 org.bluez.Adapter1 方法表

定义在 adapter.c

cpp 复制代码
static const GDBusMethodTable adapter_methods[] = {
    // 开始发现(异步)
    { GDBUS_ASYNC_METHOD("StartDiscovery", NULL, NULL, start_discovery) },

    // 设置发现过滤器
    { GDBUS_METHOD("SetDiscoveryFilter",
            GDBUS_ARGS({ "properties", "a{sv}" }), NULL,
            set_discovery_filter) },

    // 停止发现(异步)
    { GDBUS_ASYNC_METHOD("StopDiscovery", NULL, NULL, stop_discovery) },

    // 移除设备
    { GDBUS_ASYNC_METHOD("RemoveDevice",
        GDBUS_ARGS({ "device", "o" }), NULL, remove_device) },

    // 获取支持的发现过滤器
    { GDBUS_METHOD("GetDiscoveryFilters", NULL,
            GDBUS_ARGS({ "filters", "as" }), get_discovery_filters) },

    // 连接设备(实验性)
    { GDBUS_EXPERIMENTAL_ASYNC_METHOD("ConnectDevice",
            GDBUS_ARGS({ "properties", "a{sv}" }), NULL,
            connect_device) },

    { }  // 终止标志
};

4.2 org.bluez.Adapter1属性表

定义在 adapter.c

cpp 复制代码
static const GDBusPropertyTable adapter_properties[] = {
    { "Address", "s", property_get_address },           // 只读:蓝牙地址
    { "AddressType", "s", property_get_address_type },  // 只读:地址类型
    { "Name", "s", property_get_name },                 // 只读:设备名
    { "Alias", "s", property_get_alias, property_set_alias },  // 读写:别名
    { "Class", "u", property_get_class },               // 只读:设备类别
    { "Powered", "b", property_get_powered, property_set_powered },  // 读写:电源状态
    { "Discoverable", "b", property_get_discoverable,
                    property_set_discoverable },        // 读写:可发现
    { "DiscoverableTimeout", "u", property_get_discoverable_timeout,
                    property_set_discoverable_timeout },  // 读写:发现超时
    { "Pairable", "b", property_get_pairable, property_set_pairable },  // 读写:可配对
    { "PairableTimeout", "u", property_get_pairable_timeout,
                    property_set_pairable_timeout },    // 读写:配对超时
    { "Discovering", "b", property_get_discovering },  // 只读:发现中
    { "UUIDs", "as", property_get_uuids },              // 只读:支持的 UUID
    { "Modalias", "s", property_get_modalias, NULL,
                    property_exists_modalias },        // 条件存在
    { "Roles", "as", property_get_roles },              // 只读:角色列表
    { "ExperimentalFeatures", "as", property_get_experimental },  // 只读:实验特性
    { }  // 终止标志
};

4.3 属性变更通知

settings_changed() 中自动触发属性变更信号:

cpp 复制代码
static void settings_changed(struct btd_adapter *adapter, uint32_t settings)
{
    uint32_t changed_mask = adapter->current_settings ^ settings;
    adapter->current_settings = settings;

    if (changed_mask & MGMT_SETTING_POWERED) {
        // Powered 属性变更
        g_dbus_emit_property_changed(dbus_conn, adapter->path,
                    ADAPTER_INTERFACE, "Powered");

        if (adapter->current_settings & MGMT_SETTING_POWERED)
            adapter_start(adapter);   // 开启
        else
            adapter_stop(adapter);    // 关闭
    }

    if (changed_mask & MGMT_SETTING_DISCOVERABLE) {
        // Discoverable 属性变更
        g_dbus_emit_property_changed(dbus_conn, adapter->path,
                    ADAPTER_INTERFACE, "Discoverable");
        store_adapter_info(adapter);  // 持久化配置
    }

    if (changed_mask & MGMT_SETTING_BONDABLE) {
        // Pairable 属性变更
        g_dbus_emit_property_changed(dbus_conn, adapter->path,
                    ADAPTER_INTERFACE, "Pairable");
        trigger_pairable_timeout(adapter);  // 启动配对超时
    }
}

五、广播扫描与发现机制

5.1 发现类型

cpp 复制代码
#define SCAN_TYPE_BREDR  (1 << BDADDR_BREDR)                              // BR/EDR 扫描
#define SCAN_TYPE_LE     ((1 << BDADDR_LE_PUBLIC) | (1 << BDADDR_LE_RANDOM))  // LE 扫描
#define SCAN_TYPE_DUAL   (SCAN_TYPE_BREDR | SCAN_TYPE_LE)                 // 双模扫描

5.2 发现客户端管理

cpp 复制代码
struct discovery_client {
    struct btd_adapter *adapter;
    DBusMessage *msg;              // 原始 D-Bus 消息(用于回复)
    char *owner;                   // 客户端 D-Bus 名称
    guint watch;                   // 客户端断开监听
    struct discovery_filter *discovery_filter;  // 发现过滤器
};

struct discovery_filter {
    uint8_t type;                  // 过滤器类型
    char *pattern;                 // 名称匹配模式
    uint16_t pathloss;             // 路径损耗阈值
    int16_t rssi;                  // RSSI 阈值
    GSList *uuids;                 // UUID 列表
    bool duplicate;                // 是否上报重复设备
    bool discoverable;             // 仅上报可发现设备
};

5.3 启动发现流程

cpp 复制代码
// start_discovery() 核心逻辑
static void start_discovery(struct btd_adapter *adapter, ...)
{
    // 1. 创建发现客户端
    struct discovery_client *client = g_new0(struct discovery_client, 1);
    client->adapter = adapter;
    client->owner = g_strdup(owner);
    client->msg = dbus_message_ref(msg);

    // 2. 注册客户端断开监视
    client->watch = g_dbus_add_disconnect_watch(dbus_conn, owner,
                    client_disconnected, client, NULL);

    // 3. 加入发现客户端列表
    adapter->discovery_list = g_slist_append(adapter->discovery_list, client);

    // 4. 如果当前没有进行中的发现,则启动扫描
    if (!adapter->client)
        start_discovery_session(adapter, type);
}

5.4 发现会话管理

cpp 复制代码
static void start_discovery_session(struct btd_adapter *adapter, uint8_t type)
{
    // 根据类型选择扫描策略
    if (type & SCAN_TYPE_BREDR)
        mgmt_send(adapter->mgmt, MGMT_OP_START_DISCOVERY, ...);

    if (type & SCAN_TYPE_LE) {
        struct mgmt_cp_start_service_discovery cp;
        // 配置 LE 扫描参数
        cp.max_rssi = -127;
        mgmt_send(adapter->mgmt, MGMT_OP_START_SERVICE_DISCOVERY, ...);
    }

    // 更新状态
    adapter->discovering = true;
    g_dbus_emit_property_changed(dbus_conn, adapter->path,
                ADAPTER_INTERFACE, "Discovering");
}

六、连接管理核心逻辑

6.1 连接状态机

6.2 连接事件处理

cpp 复制代码
// MGMT_EV_DEVICE_CONNECTED 回调
static void connected_callback(uint16_t index, uint16_t length,
                    const void *param, void *user_data)
{
    const struct mgmt_ev_device_connected *ev = param;
    struct btd_adapter *adapter = user_data;
    struct btd_device *device;

    // 1. 查找或创建设备对象
    device = btd_adapter_get_device(adapter, &ev->addr.bdaddr, ev->addr.type);

    // 2. 更新设备状态
    btd_device_set_connected(device, TRUE);

    // 3. 加入连接列表
    adapter->connections = g_slist_append(adapter->connections, device);

    // 4. 触发驱动回调
    device_connected_drivers(adapter, device);

    // 5. 发射 D-Bus 属性变更
    g_dbus_emit_property_changed(dbus_conn, device->path,
                DEVICE_INTERFACE, "Connected");
}

// MGMT_EV_DEVICE_DISCONNECTED 回调
static void disconnected_callback(uint16_t index, uint16_t length,
                    const void *param, void *user_data)
{
    const struct mgmt_ev_device_disconnected *ev = param;
    struct btd_adapter *adapter = user_data;

    // 1. 从连接列表移除
    adapter->connections = g_slist_remove(adapter->connections, device);

    // 2. 更新设备状态
    btd_device_set_connected(device, FALSE);

    // 3. 通知断开回调
    btd_disconnect_cb(device, reason);

    // 4. 发射 D-Bus 属性变更
    g_dbus_emit_property_changed(dbus_conn, device->path,
                DEVICE_INTERFACE, "Connected");
}

6.3 连接参数管理

cpp 复制代码
// 连接参数结构
struct conn_param {
    bdaddr_t bdaddr;
    uint8_t  bdaddr_type;
    uint16_t min_interval;      // 最小连接间隔(1.25ms 单位)
    uint16_t max_interval;      // 最大连接间隔
    uint16_t latency;           // 从机延迟
    uint16_t timeout;           // 监督超时(10ms 单位)
};

// MGMT_EV_NEW_CONN_PARAM 回调
static void new_conn_param(uint16_t index, uint16_t length,
                    const void *param, void *user_data)
{
    const struct mgmt_ev_new_conn_param *ev = param;
    struct btd_device *device;

    device = btd_adapter_get_device(adapter, &ev->addr.bdaddr, ev->addr.type);

    // 更新连接参数缓存
    device->conn_param.min_interval = ev->min_interval;
    device->conn_param.max_interval = ev->max_interval;
    device->conn_param.latency = ev->latency;
    device->conn_param.timeout = ev->timeout;
}

七、配置与资源释放

7.1 配置加载流程

cpp 复制代码
static void load_config(struct btd_adapter *adapter)
{
    GKeyFile *key_file;
    char filename[PATH_MAX];

    // 1. 构造配置文件路径
    snprintf(filename, PATH_MAX, STORAGEDIR "/%s/settings",
                    btd_adapter_get_storage_dir(adapter));

    // 2. 读取配置
    key_file = g_key_file_new();
    if (g_key_file_load_from_file(key_file, filename, 0, NULL)) {
        // 读取别名
        adapter->stored_alias = g_key_file_get_string(key_file,
                    "General", "Alias", NULL);

        // 读取可发现超时
        if (g_key_file_has_key(key_file, "General",
                    "DiscoverableTimeout", NULL))
            adapter->discoverable_timeout = g_key_file_get_integer(key_file,
                        "General", "DiscoverableTimeout", NULL);

        // 读取可配对超时
        if (g_key_file_has_key(key_file, "General",
                    "PairableTimeout", NULL))
            adapter->pairable_timeout = g_key_file_get_integer(key_file,
                        "General", "PairableTimeout", NULL);
    }

    g_key_file_free(key_file);
}

7.2 适配器资源释放

cpp 复制代码
static void adapter_free(gpointer user_data)
{
    struct btd_adapter *adapter = user_data;

    // 1. 清理发现列表
    remove_discovery_list(adapter);

    // 2. 移除定时器
    if (adapter->pairable_timeout_id > 0)
        timeout_remove(adapter->pairable_timeout_id);
    if (adapter->passive_scan_timeout > 0)
        timeout_remove(adapter->passive_scan_timeout);

    // 3. 清理认证队列
    g_queue_foreach(adapter->auths, free_service_auth, NULL);
    g_queue_free(adapter->auths);

    // 4. 卸载驱动与 Profile
    g_slist_foreach(adapter->drivers, remove_driver, adapter);
    g_slist_free(adapter->drivers);
    g_slist_foreach(adapter->profiles, remove_profile, adapter);
    g_slist_free(adapter->profiles);

    // 5. 销毁 GATT 数据库
    if (adapter->database)
        btd_gatt_database_destroy(adapter->database);

    // 6. 销毁广播管理器
    if (adapter->adv_manager)
        btd_adv_manager_destroy(adapter->adv_manager);

    // 7. 释放字符串
    g_free(adapter->name);
    g_free(adapter->short_name);
    g_free(adapter->system_name);
    g_free(adapter->path);
    g_free(adapter->modalias);

    // 8. 释放队列
    queue_free(adapter->exps);

    // 9. 释放 mgmt 引用
    mgmt_unref(adapter->mgmt);

    g_free(adapter);
}

7.3 适配器移除流程

cpp 复制代码
static int adapter_unregister(struct btd_adapter *adapter)
{
    // 1. 从活跃列表移除
    adapters = g_slist_remove(adapters, adapter);

    // 2. 处理默认适配器切换
    if (adapter->is_default && adapters != NULL) {
        struct btd_adapter *new_default;
        new_default = adapter_find_by_id(hci_get_route(NULL));
        if (new_default == NULL)
            new_default = adapters->data;
        new_default->is_default = true;
    }

    // 3. 清理资源
    adapter_list = g_list_remove(adapter_list, adapter);
    adapter_remove(adapter);
    btd_adapter_unref(adapter);
}

八、异常处理与容错机制

8.1 初始化失败回滚

cpp 复制代码
// read_info_complete() 中的失败处理
static void read_info_complete(uint8_t status, uint16_t length, ...)
{
    // ...

    err = adapter_register(adapter);
    if (err < 0) {
        btd_error(adapter->dev_id, "Unable to register new adapter");
        goto failed;
    }

    // ...

    return;

failed:
    // 关键:从列表中移除,防止脏数据
    adapter_list = g_list_remove(adapter_list, adapter);
    btd_adapter_unref(adapter);
}

8.2 事件处理防御性编程

cpp 复制代码
// 所有 MGMT 事件回调的基本防御模式
static void some_event_callback(uint16_t index, uint16_t length,
                    const void *param, void *user_data)
{
    struct btd_adapter *adapter = user_data;

    // 1. 长度检查
    if (length < sizeof(struct expected_struct)) {
        btd_error(adapter->dev_id,
            "Wrong size of parameters: expected >= %zu, got %u",
            sizeof(struct expected_struct), length);
        return;
    }

    // 2. 空指针检查
    if (param == NULL) {
        btd_error(adapter->dev_id, "NULL parameter");
        return;
    }

    // 3. 正常处理
    // ...
}

8.3 热插拔冲突处理

cpp 复制代码
static void index_added(uint16_t index, uint16_t length, ...)
{
    struct btd_adapter *adapter;

    // 防重复添加
    adapter = btd_adapter_lookup(index);
    if (adapter) {
        btd_warn(adapter->dev_id,
            "Ignoring index added for an already existing adapter");
        return;
    }

    // 最大数量限制
    if (btd_opts.max_adapters &&
            btd_opts.max_adapters == g_slist_length(adapters)) {
        btd_info(index, "Maximum number of adapters reached");
        return;
    }

    // 先加入列表,防止并发
    adapter_list = g_list_append(adapter_list, adapter);

    // 如果后续失败,read_info_complete 中的 failed 标签会回滚
    mgmt_send(mgmt_primary, MGMT_OP_READ_INFO, index, 0, NULL,
                read_info_complete, adapter, NULL);
}

九、驱动机制与扩展点

9.1 适配器驱动结构

cpp 复制代码
struct btd_adapter_driver {
    const char *name;                    // 驱动名

    int (*probe)(struct btd_adapter *adapter);    // 探测:驱动加载时调用
    void (*remove)(struct btd_adapter *adapter);  // 移除:驱动卸载时调用
    void (*resume)(struct btd_adapter *adapter);  // 恢复:控制器恢复时调用

    void (*device_added)(struct btd_adapter *adapter,
                        struct btd_device *device);     // 设备添加
    void (*device_removed)(struct btd_adapter *adapter,
                        struct btd_device *device);     // 设备移除
    void (*device_resolved)(struct btd_adapter *adapter,
                        struct btd_device *device);     // 设备解析完成
};

9.2 驱动注册与加载

cpp 复制代码
// 外部驱动注册
int btd_register_adapter_driver(struct btd_adapter_driver *driver)
{
    // 加入全局驱动列表
    adapter_drivers = g_slist_append(adapter_drivers, driver);

    // 对现有适配器执行 probe
    adapter_foreach(probe_driver, driver);
}

// 适配器初始化时加载驱动
static void load_drivers(struct btd_adapter *adapter)
{
    GSList *l;

    for (l = adapter_drivers; l; l = l->next) {
        struct btd_adapter_driver *driver = l->data;

        // 调用驱动的 probe 函数
        if (driver->probe(adapter) == 0) {
            adapter->drivers = g_slist_append(adapter->drivers, driver);
            DBG("Driver '%s' loaded for hci%d", driver->name, adapter->dev_id);
        }
    }
}

9.3 Profile 注册机制

cpp 复制代码
struct btd_profile {
    const char *name;
    const char *uuid;

    // Profile 行为
    bool (*can_connect)(struct btd_device *device, GList *channel);
    int (*connect)(struct btd_device *device, GList *channel,
                    GDBusPendingCall *call);
    void (*disconnect)(struct btd_device *device, GList *channel);

    // 适配器生命周期
    void (*adapter_probe)(struct btd_adapter *adapter);
    void (*adapter_remove)(struct btd_adapter *adapter);
    void (*adapter_resume)(struct btd_adapter *adapter);
};

十、实战调试与常见问题

10.1 调试命令速查

cpp 复制代码
# 1. 启用 BlueZ 调试日志
bluetoothd -d --nodaemon --debug

# 2. 查看管理接口版本
btmgmt info

# 3. 查看所有 HCI 设备
hciconfig -a

# 4. 扫描蓝牙设备
hcitool lescan         # LE 扫描
hcitool scan           # BR/EDR 扫描

# 5. 使用 mgmt 工具
btmgmt showmgmt        # 显示 mgmt 版本
btmgmt supported       # 显示支持的命令

# 6. 启用内核蓝牙调试
echo 1 > /sys/kernel/debug/bluetooth/hci0/debug

# 7. 使用 dbus-monitor 监控
dbus-monitor --system "type='signal',interface='org.bluez.Adapter1'"

# 8. 使用 gdbus 测试接口
gdbus introspect --system \
    --dest org.bluez \
    --object-path /org/bluez/hci0 \
    --recurse

10.2 常见问题与解决方案

|-------------------------------------------|-------------------------|---------------------------------------------------------|
| 问题 | 原因 | 解决方案 |
| Failed to access management interface | 内核不支持 mgmt 接口或权限不足 | 确认内核版本 3.3+,检查 /dev/BTMGT 或 HCI 套接字权限 |
| No Bluetooth address for index X | 控制器无永久地址 | 使用 btmgmt public-addr 设置公共地址,或使用静态随机地址 |
| Ignoring adapter without BR/EDR support | 配置为 BR/EDR 模式但控制器仅支持 LE | 修改 bluetoothd.confControllerModedualle |
| Adapter interface init failed | D-Bus 注册失败 | 检查 D-Bus 配置,确保 bluetooth.conf 正确 |
| Failed to set mode | 内核拒绝设置请求 | 检查控制器当前状态,确保已 power on |
| Maximum number of adapters reached | 超过 MaxControllers 限制 | 修改配置增加数量或移除不需要的控制器 |

10.3 开发调试技巧

技巧 1:查看适配器实际状态

cpp 复制代码
# 通过 D-Bus 获取属性
gdbus call --system \
    --dest org.bluez \
    --object-path /org/bluez/hci0 \
    --method org.freedesktop.DBus.Properties.GetAll \
    org.bluez.Adapter1

# 或使用 bluez 自带的 btmgmt 工具
btmgmt --index 0 info

技巧 2:追踪适配器生命周期

cpp 复制代码
// 在 adapter_register 添加调试
static int adapter_register(struct btd_adapter *adapter)
{
    DBG("=== Adapter %s registration start ===", adapter->path);
    // ...
    DBG("=== Adapter %s registered successfully ===", adapter->path);
}

// 在 adapter_free 添加调试
static void adapter_free(gpointer user_data)
{
    struct btd_adapter *adapter = user_data;
    DBG("=== Adapter %s freeing ===", adapter->path);
    // ...
    DBG("=== Adapter freed ===");
}

技巧 3:注入模拟故障

cpp 复制代码
// 在关键路径添加断言
static void read_info_complete(uint8_t status, ...)
{
    // ...
    assert(adapter != NULL);
    assert(adapter->mgmt != NULL);
    assert(adapter->path != NULL);
    // ...
}

10.4 性能优化建议

  1. 批量读取:MGMT_OP_READ_INFO 一次性获取所有属性,减少往返

  2. 事件驱动:使用 MGMT_EV_* 事件而非轮询检测状态变化

  3. 引用计数:合理使用 btd_adapter_ref() / btd_adapter_unref() 避免内存泄漏

  4. 延迟加载:GATT 数据库和广播管理器仅在需要时创建

  5. 配置缓存:使用 GKeyFile 缓存配置,避免频繁文件读取

十一、核心函数调用链路图

11.1 初始化链路

cpp 复制代码
main()
  │
  ├──► btd_init()
  │       │
  │       └──► adapter_init()
  │               │
  │               ├──► mgmt_new_default()        // 创建 mgmt 连接
  │               ├──► MGMT_OP_READ_VERSION      // 读取版本
  │               │       │
  │               │       └──► read_version_complete()
  │               │               │
  │               │               ├──► MGMT_OP_READ_COMMANDS
  │               │               ├──► mgmt_register(INDEX_ADDED)
  │               │               ├──► mgmt_register(INDEX_REMOVED)
  │               │               └──► MGMT_OP_READ_INDEX_LIST
  │               │                       │
  │               │                       └──► read_index_list_complete()
  │               │                               │
  │               │                               └──► index_added()  // 对每个索引
  │               │                                       │
  │               │                                       ├──► btd_adapter_new()
  │               │                                       └──► MGMT_OP_READ_INFO
  │               │                                               │
  │               │                                               └──► read_info_complete()
  │               │                                                       │
  │               │                                                       ├──► adapter_register()
  │               │                                                       │       ├──► g_dbus_register_interface()
  │               │                                                       │       ├──► btd_gatt_database_new()
  │               │                                                       │       ├──► btd_adv_manager_new()
  │               │                                                       │       ├──► load_config()
  │               │                                                       │       ├──► load_drivers()
  │               │                                                       │       └──► load_devices()
  │               │                                                       │
  │               │                                                       └──► mgmt_register(所有事件)
  │               │
  │               └──► return

11.2 发现链路

cpp 复制代码
StartDiscovery (D-Bus)
  │
  └──► start_discovery()
          │
          ├──► 创建 discovery_client
          ├──► g_dbus_add_disconnect_watch()
          └──► start_discovery_session()
                  │
                  ├──► MGMT_OP_START_DISCOVERY (BR/EDR)
                  ├──► MGMT_OP_START_SERVICE_DISCOVERY (LE)
                  │
                  └──► [运行中]
                          │
                          ├──► MGMT_EV_DEVICE_FOUND
                          │       └──► device_found_callback()
                          │               └──► g_dbus_emit_signal("DeviceFound")
                          │
                          └──► StopDiscovery
                                  └──► stop_discovery_session()
                                          ├──► MGMT_OP_STOP_DISCOVERY
                                          └──► MGMT_OP_STOP_SERVICE_DISCOVERY

十二、总结与开发规范

12.1 适配器模块设计哲学

  1. 抽象封装:通过 struct btd_adapter 完整描述控制器状态,上层无需关心 MGMT 协议细节

  2. 事件驱动:所有状态变化通过 MGMT 事件回调触发,而非轮询

  3. 防御性编程:全面的错误检查、长度验证、空指针防护

  4. 引用计数:基于引用计数的内存管理,防止泄漏

  5. 热插拔支持:完整的 `index_added` / `index_removed` 处理机制

12.2 开发使用规范

|-----------|------------------------------------------------|
| 规范 | 说明 |
| 路径规范 | D-Bus 对象路径必须为 /org/bluez/hci%d |
| 接口命名 | 使用 org.bluez.Adapter1 标准接口 |
| 配置持久化 | 适配器配置存储在 /var/lib/bluetooth/<addr>/settings |
| 生命周期 | 使用 btd_adapter_ref() / btd_adapter_unref()管理引用 |
| 事件注册 | MGMT 事件回调必须在适配器注册成功后注册 |


附录:MGMT 协议常用操作码

cpp 复制代码
// 适配器管理
MGMT_OP_READ_VERSION            // 读取 mgmt 版本
MGMT_OP_READ_COMMANDS           // 查询支持的命令
MGMT_OP_READ_INDEX_LIST         // 获取控制器列表
MGMT_OP_READ_INFO               // 读取控制器信息

// 设置管理
MGMT_OP_SET_POWERED             // 电源开关
MGMT_OP_SET_CONNECTABLE         // 可连接开关
MGMT_OP_SET_DISCOVERABLE        // 可发现开关
MGMT_OP_SET_BONDABLE            // 可配对开关
MGMT_OP_SET_LE                  // LE 开关
MGMT_OP_SET_BREDR               // BR/EDR 开关

// 发现管理
MGMT_OP_START_DISCOVERY         // 启动 BR/EDR 发现
MGMT_OP_STOP_DISCOVERY          // 停止 BR/EDR 发现
MGMT_OP_START_SERVICE_DISCOVERY // 启动 LE 扫描
MGMT_OP_STOP_SERVICE_DISCOVERY  // 停止 LE 扫描

// 设备管理
MGMT_OP_ADD_DEVICE              // 添加设备到白名单/黑名单
MGMT_OP_REMOVE_DEVICE           // 移除设备
MGMT_OP_DISCONNECT              // 断开连接

// 安全管理
MGMT_OP_SET_SSP                 // SSP 开关
MGMT_OP_SET_SECURE_CONN         // 安全连接开关
MGMT_OP_PIN_CODE_REPLY          // PIN 码回复
MGMT_OP_USER_CONFIRM_REPLY      // 用户确认回复
MGMT_OP_SET_BLOCKED_KEYS        // 设置被屏蔽的密钥
相关推荐
玩转单片机与嵌入式1 小时前
深入浅出TinyML 24:剪枝、聚类、蒸馏和算子替换是否真正适合MCU?
人工智能·stm32·机器学习·tinyml
Dawson Zhu1 小时前
Kafka 在 AI Agent 系统中的应用:任务队列与事件总线的角色辨析及工程实践
人工智能·语言模型·架构·aigc·agi
黎阳之光1 小时前
AI黑光相机|赋能低空全域感知,筑牢低空经济全天候视觉防线
人工智能·物联网·算法·安全·数字孪生
wangchunyu1141 小时前
火山引擎 HiAgent介绍和安装说明
人工智能·火山引擎
流浪0011 小时前
Linux系统篇27——通信(四):System V 消息队列 + 信号量:管道之后,Linux 还藏了哪两样 IPC
linux·运维
手写码匠1 小时前
华为云Flexus+DeepSeek征文|DeepSeek R1 推理优化实战:让复杂任务的回答又快又稳
人工智能·深度学习·算法·aigc
不爱运动的跑者1 小时前
架构可视化不是“画图“:让 AI 产出可追溯架构图的四层工程
人工智能·架构
木卫四科技1 小时前
Agent Supply Chain Security:MCP、Skills 与 AI Agent 软件供应链安全新边界 | 木卫四科技
大数据·人工智能·安全·ai-bom·robot security·机器人安全·具身安全
Q一件事1 小时前
RWEQ计算——EF和SCF因子
人工智能