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.conf 的 ControllerMode 为 dual 或 le |
| 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 性能优化建议
-
批量读取:MGMT_OP_READ_INFO 一次性获取所有属性,减少往返
-
事件驱动:使用 MGMT_EV_* 事件而非轮询检测状态变化
-
引用计数:合理使用 btd_adapter_ref() / btd_adapter_unref() 避免内存泄漏
-
延迟加载:GATT 数据库和广播管理器仅在需要时创建
-
配置缓存:使用 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 适配器模块设计哲学
-
抽象封装:通过 struct btd_adapter 完整描述控制器状态,上层无需关心 MGMT 协议细节
-
事件驱动:所有状态变化通过 MGMT 事件回调触发,而非轮询
-
防御性编程:全面的错误检查、长度验证、空指针防护
-
引用计数:基于引用计数的内存管理,防止泄漏
-
热插拔支持:完整的 `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 // 设置被屏蔽的密钥