蓝牙技术在现代操作系统中扮演着至关重要的角色,从无线键鼠到音频传输,从物联网设备到车联网应用,无处不在。Linux 内核作为开源操作系统的典范,提供了完整的蓝牙协议栈实现------从底层的硬件驱动到高层的应用接口。本文聚焦于 Linux 蓝牙子系统的核心枢纽:hci_core 模块与 BlueZ 用户态协议栈的交互机制。
目录
[二、HCI 套接字通信机制](#二、HCI 套接字通信机制)
[三、BlueZ HCI 封装层实现](#三、BlueZ HCI 封装层实现)
[四、HCI 指令发送流程](#四、HCI 指令发送流程)
[五、HCI 事件接收与处理](#五、HCI 事件接收与处理)
[六、HCI 事件注册机制](#六、HCI 事件注册机制)
[七、mgmt 管理接口](#七、mgmt 管理接口)
[八、adapter 模块与 HCI 交互](#八、adapter 模块与 HCI 交互)
[九、HCI 协议报文格式](#九、HCI 协议报文格式)
本文深入源码,剖析这套精密的分层架构:如何通过 PF_BLUETOOTH 套接字实现内核与用户态的高效通信?BlueZ 如何封装 HCI 指令发送与事件接收?mgmt 管理接口如何提供适配器的高级控制?将完整拆解从蓝牙适配器初始化、设备发现、建立连接到数据传输的每一步源码流程,揭示 bt_hci 封装层的指令队列与事件回调机制,解读 mgmt 接口的请求-响应模式,并梳理 adapter 模块如何协调与整合所有操作。
无论您是蓝牙驱动开发者、BlueZ 贡献者,还是对无线协议栈感兴趣的工程师,本篇深度解析将打通内核态与用户态的任督二脉,提供实战级的源码剖析与调试方案。
一、蓝牙协议栈分层架构
Linux 蓝牙子系统采用经典的分层架构设计,从下到上依次为:

核心分工:
-
内核 hci_core:负责 HCI 协议报文收发、L2CAP 协议处理、设备注册管理
-
BlueZ 用户态:负责 Profile 实现、D-Bus 对外接口、设备发现/连接/配对逻辑
二、 HCI 套接字通信机制
2.1 HCI 套接字创建
BlueZ 通过 Linux 特有的 PF_BLUETOOTH 地址族与内核 hci_core 通信:
cpp
// src/shared/hci.c
#define BTPROTO_HCI 1
struct sockaddr_hci {
sa_family_t hci_family;
unsigned short hci_dev; // 设备索引 (hci0, hci1...)
unsigned short hci_channel; // 通道类型
};
// 创建 HCI 套接字
static int create_socket(uint16_t index, uint16_t channel)
{
struct sockaddr_hci addr;
int fd;
// 使用 PF_BLUETOOTH + SOCK_RAW + BTPROTO_HCI
fd = socket(PF_BLUETOOTH, SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK,
BTPROTO_HCI);
if (fd < 0)
return -1;
memset(&addr, 0, sizeof(addr));
addr.hci_family = AF_BLUETOOTH;
addr.hci_dev = index; // 绑定到指定蓝牙适配器
addr.hci_channel = channel; // 指定通道类型
if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
close(fd);
return -1;
}
return fd;
}
2.2 HCI 通道类型
Linux 内核定义了三种 HCI 通道:
cpp
// 通道类型定义
#define HCI_CHANNEL_RAW 0 // 原始通道:直接与硬件通信
#define HCI_CHANNEL_USER 1 // 用户通道:替代内核协议栈
#define HCI_CHANNEL_MONITOR 2 // 监控通道:抓包分析
通道对比:
|-----------------------|-------------|----------------------------|
| 通道类型 | 用途 | 特点 |
| HCI_CHANNEL_RAW | 常规 BlueZ 使用 | 内核处理 L2CAP,用户态处理上层协议 |
| HCI_CHANNEL_USER | 完全用户态实现 | 绕过内核,用户态实现包括 L2CAP 在内的所有协议 |
| HCI_CHANNEL_MONITOR | 抓包/调试 | 只读模式,接收所有 HCI 报文 |
2.3 HCI 过滤器 设置
为控制内核向用户态推送哪些事件,需要设置 HCI 过滤器:
cpp
// HCI 过滤器结构
#define SOL_HCI 0
#define HCI_FILTER 2
struct hci_filter {
uint32_t type_mask; // 报文类型掩码
uint32_t event_mask[2]; // 事件掩码(位图)
uint16_t opcode; // 特定指令过滤
};
// 示例:监控模式设置过滤器
struct hci_filter flt;
memset(&flt, 0, sizeof(flt));
// 只接收事件包
flt.type_mask = 1 << BT_H4_EVT_PKT;
// 启用所有事件
flt.event_mask[0] = 0xffffffff;
flt.event_mask[1] = 0xffffffff;
// 设置过滤器
setsockopt(fd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt));
三、BlueZ HCI 封装层实现
3.1 bt_hci 核心数据结构
BlueZ 在 src/shared/hci.c 中实现了 HCI 通信的封装层:
cpp
// src/shared/hci.c
struct bt_hci {
int ref_count; // 引用计数
struct io *io; // IO 抽象层(封装 socket fd)
bool is_stream; // 是否为流式(监控模式)
bool writer_active; // 写入状态标记
uint8_t num_cmds; // 允许的待处理指令数
unsigned int next_cmd_id; // 下一个指令 ID
unsigned int next_evt_id; // 下一个事件 ID
struct queue *cmd_queue; // 待发送指令队列
struct queue *rsp_queue; // 等待响应的指令队列
struct queue *evt_list; // 事件回调列表
};
// 指令结构
struct cmd {
unsigned int id; // 指令 ID
uint16_t opcode; // HCI 操作码
void *data; // 指令参数数据
uint8_t size; // 参数长度
bt_hci_callback_func_t callback; // 响应回调
bt_hci_destroy_func_t destroy; // 销毁回调
void *user_data; // 用户数据
};
// 事件回调结构
struct evt {
unsigned int id; // 事件 ID
uint8_t event; // HCI 事件码
bt_hci_callback_func_t callback; // 事件回调
bt_hci_destroy_func_t destroy; // 销毁回调
void *user_data; // 用户数据
};
3.2 bt_hci 创建流程
BlueZ 提供三种创建 bt_hci 实例的方式:
cpp
// src/shared/hci.c
// 方式一:从现有 fd 创建
struct bt_hci *bt_hci_new(int fd)
{
return create_hci(fd);
}
// 方式二:用户通道模式(完全接管 HCI)
struct bt_hci *bt_hci_new_user_channel(uint16_t index)
{
struct bt_hci *hci;
int fd;
// 创建用户通道套接字
fd = create_socket(index, HCI_CHANNEL_USER);
if (fd < 0)
return NULL;
hci = create_hci(fd);
if (!hci) {
close(fd);
return NULL;
}
hci->is_stream = false;
bt_hci_set_close_on_unref(hci, true);
return hci;
}
// 方式三:原始设备模式(常规 BlueZ 使用)
struct bt_hci *bt_hci_new_raw_device(uint16_t index)
{
struct bt_hci *hci;
struct hci_filter flt;
int fd;
// 创建原始通道套接字
fd = create_socket(index, HCI_CHANNEL_RAW);
if (fd < 0)
return NULL;
// 设置过滤器接收所有事件
memset(&flt, 0, sizeof(flt));
flt.type_mask = 1 << BT_H4_EVT_PKT;
flt.event_mask[0] = 0xffffffff;
flt.event_mask[1] = 0xffffffff;
setsockopt(fd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt));
hci = create_hci(fd);
if (!hci) {
close(fd);
return NULL;
}
hci->is_stream = false;
bt_hci_set_close_on_unref(hci, true);
return hci;
}
3.3 内部初始化
cpp
// 内部创建函数
static struct bt_hci *create_hci(int fd)
{
struct bt_hci *hci;
if (fd < 0)
return NULL;
hci = new0(struct bt_hci, 1);
hci->io = io_new(fd); // 封装 fd 为 io 对象
if (!hci->io) {
free(hci);
return NULL;
}
hci->is_stream = true;
hci->writer_active = false;
hci->num_cmds = 1; // 初始允许 1 条指令
hci->next_cmd_id = 1;
hci->next_evt_id = 1;
// 创建三个队列
hci->cmd_queue = queue_new(); // 待发送队列
hci->rsp_queue = queue_new(); // 等待响应队列
hci->evt_list = queue_new(); // 事件回调列表
// 设置读回调
if (!io_set_read_handler(hci->io, io_read_callback, hci, NULL)) {
queue_destroy(hci->evt_list, NULL);
queue_destroy(hci->rsp_queue, NULL);
queue_destroy(hci->cmd_queue, NULL);
io_destroy(hci->io);
free(hci);
return NULL;
}
return bt_hci_ref(hci);
}
四、HCI 指令发送流程
4.1 指令发送接口
cpp
// src/shared/hci.c
// 发送 HCI 指令
unsigned int bt_hci_send(struct bt_hci *hci, uint16_t opcode,
const void *data, uint8_t size,
bt_hci_callback_func_t callback,
void *user_data, bt_hci_destroy_func_t destroy)
{
struct cmd *cmd;
if (!hci)
return 0;
// 创建指令对象
cmd = new0(struct cmd, 1);
cmd->opcode = opcode;
cmd->size = size;
// 复制指令参数
if (cmd->size > 0) {
cmd->data = malloc(cmd->size);
if (!cmd->data) {
free(cmd);
return 0;
}
memcpy(cmd->data, data, cmd->size);
}
// 分配指令 ID
if (hci->next_cmd_id < 1)
hci->next_cmd_id = 1;
cmd->id = hci->next_cmd_id++;
// 设置回调
cmd->callback = callback;
cmd->destroy = destroy;
cmd->user_data = user_data;
// 入队
if (!queue_push_tail(hci->cmd_queue, cmd)) {
free(cmd->data);
free(cmd);
return 0;
}
// 触发写入
wakeup_writer(hci);
return cmd->id;
}
4.2 指令排队与发送
cpp
// 触发写入
static void wakeup_writer(struct bt_hci *hci)
{
if (hci->writer_active)
return;
if (hci->num_cmds < 1)
return;
if (queue_isempty(hci->cmd_queue))
return;
// 设置写回调
if (!io_set_write_handler(hci->io, io_write_callback, hci, NULL))
return;
hci->writer_active = true;
}
// 写回调:从队列取出指令并发送
static bool io_write_callback(struct io *io, void *user_data)
{
struct bt_hci *hci = user_data;
struct cmd *cmd;
// 从待发送队列取出指令
cmd = queue_pop_head(hci->cmd_queue);
if (cmd) {
// 实际发送指令
send_command(hci, cmd->opcode, cmd->data, cmd->size);
// 移到等待响应队列
queue_push_tail(hci->rsp_queue, cmd);
}
hci->writer_active = false;
return false;
}
4.3 HCI 报文构造
cpp
// 构造并发送 HCI 指令
static void send_command(struct bt_hci *hci, uint16_t opcode,
void *data, uint8_t size)
{
uint8_t type = BT_H4_CMD_PKT; // H4 数据包类型:Command
struct bt_hci_cmd_hdr hdr; // HCI 指令头
struct iovec iov[3]; // 分散/聚集 IO
int iovcnt;
if (hci->num_cmds < 1)
return;
// 填充指令头
hdr.opcode = cpu_to_le16(opcode); // 小端转换
hdr.plen = size; // 参数长度
// 组织 IO 向量
iov[0].iov_base = &type; // 第一部分:包类型字节
iov[0].iov_len = 1;
iov[1].iov_base = &hdr; // 第二部分:指令头
iov[1].iov_len = sizeof(hdr);
if (size > 0) {
iov[2].iov_base = data; // 第三部分:指令参数
iov[2].iov_len = size;
iovcnt = 3;
} else
iovcnt = 2;
// 通过 io 抽象层发送
if (io_send(hci->io, iov, iovcnt) < 0)
return;
hci->num_cmds--; // 递减待处理计数
}
H4 报文格式:

五、HCI 事件接收与处理
5.1 读回调触发
cpp
// src/shared/hci.c
// IO 读回调
static bool io_read_callback(struct io *io, void *user_data)
{
struct bt_hci *hci = user_data;
uint8_t buf[512];
ssize_t len;
int fd;
fd = io_get_fd(hci->io);
if (fd < 0)
return false;
if (hci->is_stream)
return false;
// 从 socket 读取数据
len = read(fd, buf, sizeof(buf));
if (len < 0)
return false;
if (len < 1)
return true;
// 根据包类型分发
switch (buf[0]) {
case BT_H4_EVT_PKT: // 事件包
process_event(hci, buf + 1, len - 1);
break;
}
return true;
}
5.2 事件处理分发
cpp
// 事件处理主函数
static void process_event(struct bt_hci *hci, const void *data, size_t size)
{
const struct bt_hci_evt_hdr *hdr = data;
const struct bt_hci_evt_cmd_complete *cc;
const struct bt_hci_evt_cmd_status *cs;
if (size < sizeof(struct bt_hci_evt_hdr))
return;
data += sizeof(struct bt_hci_evt_hdr);
size -= sizeof(struct bt_hci_evt_hdr);
if (hdr->plen != size)
return;
// 根据事件类型处理
switch (hdr->evt) {
case BT_HCI_EVT_CMD_COMPLETE: // 指令完成事件
if (size < sizeof(*cc))
return;
cc = data;
hci->num_cmds = cc->ncmd; // 更新允许的指令数
// 查找对应指令并回调
process_response(hci, le16_to_cpu(cc->opcode),
data + sizeof(*cc), size - sizeof(*cc));
break;
case BT_HCI_EVT_CMD_STATUS: // 指令状态事件
if (size < sizeof(*cs))
return;
cs = data;
hci->num_cmds = cs->ncmd;
process_response(hci, le16_to_cpu(cs->opcode), &cs->status, 1);
break;
default: // 其他事件
// 遍历事件回调列表
queue_foreach(hci->evt_list, process_notify, (void *) hdr);
break;
}
}
5.3 指令响应匹配
cpp
// 处理指令响应
static void process_response(struct bt_hci *hci, uint16_t opcode,
const void *data, size_t size)
{
struct cmd *cmd;
if (opcode == BT_HCI_CMD_NOP) {
wakeup_writer(hci);
return;
}
// 在等待队列中查找匹配的指令
cmd = queue_remove_if(hci->rsp_queue, match_cmd_opcode,
UINT_TO_PTR(opcode));
if (!cmd)
return;
// 增加引用防止回调中销毁
bt_hci_ref(hci);
// 执行用户回调
if (cmd->callback)
cmd->callback(data, size, cmd->user_data);
cmd_free(cmd);
// 唤醒写入(如果有待发送指令)
wakeup_writer(hci);
bt_hci_unref(hci);
}
六、HCI 事件注册机制
6.1 事件回调注册
cpp
// src/shared/hci.c
// 注册事件回调
unsigned int bt_hci_register(struct bt_hci *hci, uint8_t event,
bt_hci_callback_func_t callback,
void *user_data, bt_hci_destroy_func_t destroy)
{
struct evt *evt;
if (!hci)
return 0;
// 创建事件回调对象
evt = new0(struct evt, 1);
evt->event = event;
// 分配事件 ID
if (hci->next_evt_id < 1)
hci->next_evt_id = 1;
evt->id = hci->next_evt_id++;
// 设置回调
evt->callback = callback;
evt->destroy = destroy;
evt->user_data = user_data;
// 添加到事件列表
if (!queue_push_tail(hci->evt_list, evt)) {
free(evt);
return 0;
}
return evt->id;
}
// 取消事件回调
bool bt_hci_unregister(struct bt_hci *hci, unsigned int id)
{
struct evt *evt;
if (!hci || !id)
return false;
// 从列表中移除
evt = queue_remove_if(hci->evt_list, match_evt_id, UINT_TO_PTR(id));
if (!evt)
return false;
evt_free(evt);
return true;
}
6.2 事件分发实现
cpp
// 事件通知处理
static void process_notify(void *data, void *user_data)
{
struct bt_hci_evt_hdr *hdr = user_data;
struct evt *evt = data;
// 匹配事件码
if (evt->event == hdr->evt)
// 调用用户回调,传入事件数据(跳过事件头)
evt->callback(user_data + sizeof(struct bt_hci_evt_hdr),
hdr->plen, evt->user_data);
}
七、mgmt 管理接口
7.1 mgmt 接口概述
除了直接的 HCI 套接字通信,BlueZ 还通过 mgmt(Management)接口 与内核通信:
cpp
// src/shared/mgmt.h
struct mgmt;
// 创建 mgmt 实例
struct mgmt *mgmt_new(int fd);
struct mgmt *mgmt_new_default(void);
// 发送管理命令
unsigned int mgmt_send(struct mgmt *mgmt, uint16_t opcode, uint16_t index,
uint16_t length, const void *param,
mgmt_request_func_t callback,
void *user_data, mgmt_destroy_func_t destroy);
// 注册事件通知
unsigned int mgmt_register(struct mgmt *mgmt, uint16_t event, uint16_t index,
mgmt_notify_func_t callback,
void *user_data, mgmt_destroy_func_t destroy);
7.2 mgmt 核心数据结构
cpp
// src/shared/mgmt.c
struct mgmt {
int ref_count;
int fd; // socket 文件描述符
bool close_on_unref;
struct io *io; // IO 抽象
bool writer_active;
struct queue *request_queue; // 待发送请求
struct queue *reply_queue; // 等待响应请求
struct queue *pending_list; // 挂起请求
struct queue *notify_list; // 事件通知注册
unsigned int next_request_id;
unsigned int next_notify_id;
// ...
};
// mgmt 请求结构
struct mgmt_request {
struct mgmt *mgmt;
unsigned int id;
uint16_t opcode; // 操作码
uint16_t index; // 适配器索引
void *buf; // 数据缓冲区
uint16_t len; // 数据长度
mgmt_request_func_t callback; // 响应回调
mgmt_destroy_func_t destroy;
void *user_data;
int timeout; // 超时时间
unsigned int timeout_id; // 超时定时器 ID
};
// mgmt 通知结构
struct mgmt_notify {
unsigned int id;
uint16_t event; // 事件码
uint16_t index; // 适配器索引
bool removed;
mgmt_notify_func_t callback; // 通知回调
mgmt_destroy_func_t destroy;
void *user_data;
};
7.3 mgmt 与 HCI 的关系

对比说明:
|--------|--------------|----------------|
| 特性 | mgmt 接口 | bt_hci 接口 |
| 套接字类型 | AF_MGMT | PF_BLUETOOTH |
| 通信协议 | MGMT 协议 | H4/HCI 协议 |
| 抽象层级 | 高层(电源/扫描/连接) | 低层(直接 HCI 指令) |
| 使用场景 | 适配器管理 | 设备通信 |
八、adapter 模块与 HCI 交互
8.1 适配器结构
cpp
// src/adapter.c
struct btd_adapter {
int ref_count;
uint16_t dev_id; // 设备索引
struct mgmt *mgmt; // mgmt 接口实例
bdaddr_t bdaddr; // 蓝牙地址
uint8_t bdaddr_type; // 地址类型
uint32_t dev_class; // 设备类型
char *name; // 设备名
uint32_t supported_settings; // 支持的设置
uint32_t pending_settings; // 待应用设置
uint32_t current_settings; // 当前设置
// ... 其他字段
};
8.2 设置模式变更
cpp
// src/adapter.c
// 设置适配器模式
static bool set_mode(struct btd_adapter *adapter, uint16_t opcode,
uint8_t mode)
{
struct mgmt_mode cp;
uint32_t setting = 0;
memset(&cp, 0, sizeof(cp));
cp.val = mode;
// 根据操作码确定设置类型
switch (opcode) {
case MGMT_OP_SET_POWERED:
setting = MGMT_SETTING_POWERED;
break;
case MGMT_OP_SET_CONNECTABLE:
setting = MGMT_SETTING_CONNECTABLE;
break;
case MGMT_OP_SET_DISCOVERABLE:
setting = MGMT_SETTING_DISCOVERABLE;
break;
case MGMT_OP_SET_BONDABLE:
setting = MGMT_SETTING_BONDABLE;
break;
}
adapter->pending_settings |= setting;
// 通过 mgmt 接口发送命令
if (mgmt_send(adapter->mgmt, opcode, adapter->dev_id,
sizeof(cp), &cp, set_mode_complete, adapter, NULL) > 0)
return true;
return false;
}
8.3 事件回调处理
cpp
// 设置变更回调
static void new_settings_callback(uint16_t index, uint16_t length,
const void *param, void *user_data)
{
struct btd_adapter *adapter = user_data;
uint32_t settings;
if (length < sizeof(settings))
return;
settings = get_le32(param);
if (settings == adapter->current_settings)
return;
// 处理设置变更
settings_changed(adapter, settings);
}
// 设置变更处理
static void settings_changed(struct btd_adapter *adapter, uint32_t settings)
{
uint32_t changed_mask;
changed_mask = adapter->current_settings ^ settings;
adapter->current_settings = settings;
adapter->pending_settings &= ~changed_mask;
// 处理电源状态变更
if (changed_mask & MGMT_SETTING_POWERED) {
if (adapter->current_settings & MGMT_SETTING_POWERED)
adapter_start(adapter);
else
adapter_stop(adapter);
}
// 处理可发现状态变更
if (changed_mask & MGMT_SETTING_DISCOVERABLE)
g_dbus_emit_property_changed(dbus_conn, adapter->path,
ADAPTER_INTERFACE, "Discoverable");
// 处理可配对状态变更
if (changed_mask & MGMT_SETTING_BONDABLE)
g_dbus_emit_property_changed(dbus_conn, adapter->path,
ADAPTER_INTERFACE, "Pairable");
}
九、HCI 协议报文格式
9.1 HCI 指令格式
cpp
// lib/hci.h
// HCI 指令包头
struct {
uint16_t opcode; // 操作码 (OCF + OGF)
uint8_t plen; // 参数长度
} __attribute__((packed));
// 指令操作码编码
#define OGF_LINK_CTL 0x01 // 链路控制
#define OGF_LINK_POLICY 0x02 // 链路策略
#define OGF_HOST_CTL 0x03 // 主机控制
#define OGF_INFO_PARAM 0x04 // 信息参数
#define OGF_STATUS_PARAM 0x05 // 状态参数
#define OGF_LE_CTL 0x08 // LE 控制
#define OGF_VENDOR_CMD 0x3f // 厂商命令
// 示例:创建连接指令
#define OCF_CREATE_CONN 0x0005
typedef struct {
bdaddr_t bdaddr; // 目标地址
uint16_t pkt_type; // 包类型
uint8_t pscan_rep_mode; // 扫描模式
uint8_t pscan_mode; // 扫描模式
uint16_t clock_offset; // 时钟偏移
uint8_t role_switch; // 角色切换
} __attribute__((packed)) create_conn_cp;
9.2 HCI 事件格式
cpp
// lib/hci.h
// 事件头
struct {
uint8_t evt; // 事件码
uint8_t plen; // 事件数据长度
} __attribute__((packed));
// 常用事件码
#define EVT_INQUIRY_COMPLETE 0x01 // 查询完成
#define EVT_INQUIRY_RESULT 0x02 // 查询结果
#define EVT_CONN_COMPLETE 0x03 // 连接完成
#define EVT_CONN_REQUEST 0x04 // 连接请求
#define EVT_DISCONN_COMPLETE 0x05 // 断连完成
#define EVT_AUTH_COMPLETE 0x06 // 认证完成
#define EVT_CMD_COMPLETE 0x0E // 指令完成
#define EVT_CMD_STATUS 0x0F // 指令状态
// 示例:连接完成事件
typedef struct {
uint8_t status; // 状态码
uint16_t handle; // 连接句柄
bdaddr_t bdaddr; // 远程地址
uint8_t link_type; // 链路类型
uint8_t encr_mode; // 加密模式
} __attribute__((packed)) evt_conn_complete;
9.3 H4 包类型
cpp
// H4 数据包类型
#define HCI_COMMAND_PKT 0x01 // 命令包
#define HCI_ACLDATA_PKT 0x02 // ACL 数据包
#define HCI_SCODATA_PKT 0x03 // SCO 数据包
#define HCI_EVENT_PKT 0x04 // 事件包
#define HCI_ISODATA_PKT 0x05 // ISO 数据包
#define HCI_VENDOR_PKT 0xff // 厂商包
十、完整交互流程示例
10.1 初始化蓝牙适配器
cpp
1. BlueZ 启动
└─> main() 初始化
└─> adapter_init() 初始化适配器管理
└─> 枚举 /sys/class/bluetooth 发现设备
└─> mgmt_new() 创建 mgmt 接口
└─> 绑定 AF_MGMT 套接字
2. 适配器上电
└─> set_mode(adapter, MGMT_OP_SET_POWERED, 1)
└─> mgmt_send() 发送管理命令
└─> 通过 mgmt socket 发送到内核
└─> hci_core 处理命令
└─> 驱动上电
└─> 返回命令完成事件
└─> mgmt 回调通知 BlueZ
3. 设置适配器参数
└─> set_name() 设置设备名
└─> set_dev_class() 设置设备类型
└─> set_event_mask() 设置事件掩码
10.2 发现远程设备
cpp
1. 启动扫描
└─> adapter_start_discovery()
└─> mgmt_send(MGMT_OP_START_DISCOVERY, ...)
└─> 内核发送 HCI Inquiry 指令
2. 接收扫描结果
└─> 内核接收 EVT_INQUIRY_RESULT 事件
└─> 通过 mgmt socket 上报
└─> mgmt 通知回调
└─> adapter 处理设备发现
└─> 创建设备对象
3. 停止扫描
└─> mgmt_send(MGMT_OP_STOP_DISCOVERY, ...)
10.3 建立蓝牙连接
cpp
1. 发起连接
└─> device_connect()
└─> mgmt_send(MGMT_OP_LE_CREATE_CONN / MGMT_OP_CREATE_CONN, ...)
└─> 内核发送 HCI Create Connection 指令
2. 接收连接完成
└─> 内核接收 EVT_CONN_COMPLETE 事件
└─> 通过 mgmt socket 上报
└─> BlueZ 接收连接完成通知
└─> 执行 SDP 搜索 / GATT 发现
└─> 完成 Profile 连接
十一、异常处理与容错机制
11.1 超时处理
cpp
// src/shared/mgmt.c
// 请求超时回调
static bool request_timeout(void *data)
{
struct mgmt_request *request = data;
if (!request)
return false;
request->timeout_id = 0;
queue_remove_if(request->mgmt->pending_list, NULL, request);
// 超时回调
if (request->callback)
request->callback(MGMT_STATUS_TIMEOUT, 0, NULL, request->user_data);
destroy_request(request);
return false;
}
// 发送带超时的请求
unsigned int mgmt_send_timeout(struct mgmt *mgmt, uint16_t opcode,
uint16_t index, uint16_t length,
const void *param,
mgmt_request_func_t callback,
void *user_data, mgmt_destroy_func_t destroy,
int timeout)
{
struct mgmt_request *request;
// ... 创建请求 ...
if (timeout)
request->timeout_id = timeout_add_seconds(timeout,
request_timeout, request, NULL);
return request->id;
}
11.2 取消操作
cpp
// src/shared/hci.c
// 取消指定指令
bool bt_hci_cancel(struct bt_hci *hci, unsigned int id)
{
struct cmd *cmd;
if (!hci || !id)
return false;
// 从待发送队列移除
cmd = queue_remove_if(hci->cmd_queue, match_cmd_id, UINT_TO_PTR(id));
if (!cmd) {
// 从等待响应队列移除
cmd = queue_remove_if(hci->rsp_queue, match_cmd_id, UINT_TO_PTR(id));
if (!cmd)
return false;
}
cmd_free(cmd);
wakeup_writer(hci);
return true;
}
// 清空所有指令
bool bt_hci_flush(struct bt_hci *hci)
{
if (!hci)
return false;
// 取消写入
if (hci->writer_active) {
io_set_write_handler(hci->io, NULL, NULL, NULL);
hci->writer_active = false;
}
// 清空两个队列
queue_remove_all(hci->cmd_queue, NULL, NULL, cmd_free);
queue_remove_all(hci->rsp_queue, NULL, NULL, cmd_free);
return true;
}
11.3 内核错误码
cpp
// lib/hci.h
// HCI 错误码
#define HCI_UNKNOWN_COMMAND 0x01 // 未知命令
#define HCI_NO_CONNECTION 0x02 // 无连接
#define HCI_HARDWARE_FAILURE 0x03 // 硬件故障
#define HCI_PAGE_TIMEOUT 0x04 // 页面超时
#define HCI_AUTHENTICATION_FAILURE 0x05 // 认证失败
#define HCI_CONNECTION_TIMEOUT 0x08 // 连接超时
#define HCI_COMMAND_DISALLOWED 0x0c // 命令不允许
#define HCI_REJECTED_SECURITY 0x0e // 安全拒绝
#define HCI_UNSUPPORTED_FEATURE 0x11 // 不支持功能
#define HCI_INVALID_PARAMETERS 0x12 // 无效参数
#define HCI_REMOTE_USER_TERMINATED 0x13 // 远端终止
#define HCI_CONNECTION_TERMINATED 0x16 // 连接终止
十二、调试与抓包
12.1 启用 BlueZ 调试日志
cpp
# 编译时启用调试
./configure --enable-debug
# 运行时设置环境变量
export BLUEZ_DEBUG=all
bluetoothd -n -d
12.2 使用 btmon 抓包
cpp
# 安装 btmon (BlueZ 监控工具)
# btmon 通常随 BlueZ 一起编译
# 启动抓包
btmon
# 保存到文件
btmon -w capture.log
# 过滤特定设备
btmon -f hci0
# 实时查看并保存
btmon -f hci0 -w capture.log &
12.3 使用 hcitool 诊断
cpp
# 查看本地适配器
hcitool dev
# 扫描远程设备
hcitool scan
# LE 扫描
hcitool lescan
# 查看连接状态
hcitool con
# 查询远程设备信息
hcitool info XX:XX:XX:XX:XX:XX
# 读取远程名称
hcitool name XX:XX:XX:XX:XX:XX
12.4 使用 systemd 日志
cpp
# 查看 BlueZ 服务日志
journalctl -u bluetooth -f
# 查看内核蓝牙日志
dmesg | grep -i bluetooth
# 查看 HCI 设备信息
hciconfig hci0
hciconfig hci0 up
hciconfig hci0 down
十三、核心函数索引
13.1 bt_hci 相关函数
|-----------------------------|------------------|-------------------|
| 函数 | 文件 | 功能 |
| bt_hci_new() | src/shared/hci.c | 从 fd 创建 bt_hci 实例 |
| bt_hci_new_user_channel() | src/shared/hci.c | 创建用户通道模式 |
| bt_hci_new_raw_device() | src/shared/hci.c | 创建原始设备模式 |
| bt_hci_send() | src/shared/hci.c | 发送 HCI 指令 |
| bt_hci_cancel() | src/shared/hci.c | 取消指定指令 |
| bt_hci_flush() | src/shared/hci.c | 清空所有指令 |
| bt_hci_register() | src/shared/hci.c | 注册事件回调 |
| bt_hci_unregister() | src/shared/hci.c | 取消事件回调 |
13.2 mgmt 相关函数
|-----------------------|-------------------|--------------|
| 函数 | 文件 | 功能 |
| mgmt_new() | src/shared/mgmt.c | 创建 mgmt 实例 |
| mgmt_new_default() | src/shared/mgmt.c | 创建默认 mgmt 实例 |
| mgmt_send() | src/shared/mgmt.c | 发送管理命令 |
| mgmt_send_timeout() | src/shared/mgmt.c | 发送带超时的命令 |
| mgmt_register() | src/shared/mgmt.c | 注册事件通知 |
| mgmt_cancel() | src/shared/mgmt.c | 取消指定请求 |
13.3 adapter 相关函数
|-----------------------------|---------------|----------|
| 函数 | 文件 | 功能 |
| adapter_init() | src/adapter.c | 初始化适配器管理 |
| btd_adapter_get_default() | src/adapter.c | 获取默认适配器 |
| btd_adapter_get_index() | src/adapter.c | 获取适配器索引 |
| btd_adapter_set_class() | src/adapter.c | 设置设备类型 |
| adapter_set_name() | src/adapter.c | 设置设备名 |
十四、总结
Linux 蓝牙子系统通过精心设计的分层架构,实现了内核与用户态的清晰分离:
内核 hci_core 模块:处理 HCI 协议报文收发、L2CAP 协议、设备驱动管理
HCI 套接字机制:通过 PF_BLUETOOTH 地址族提供标准化通信接口
bt_hci 封装层:BlueZ 对 HCI 套接字的高级封装,提供指令队列、事件回调机制
mgmt 管理接口:提供适配器管理的高层抽象
adapter 模块:协调与整合所有 HCI 相关操作
理解这套交互机制,对于蓝牙外设适配、协议栈开发、问题调试都具有重要意义。