3、Linux内核蓝牙子系统架构:BlueZ架构、内核蓝牙核心层(Bluetooth Core)、HCI设备层、L2CAP层、RFCOMM层源码目录结构
本章深入剖析Linux内核蓝牙子系统的分层架构,从用户空间的BlueZ协议栈到内核空间的各协议层源码目录结构。理解这一架构是调试RFCOMM协议数据传输的基础,也是定位数据流瓶颈和协议错误的关键。
3.1 BlueZ整体架构概览
BlueZ是Linux官方蓝牙协议栈,采用用户空间-内核空间双层架构。用户空间负责高层协议(如GATT、A2DP)和配置管理,内核空间负责低层协议(HCI、L2CAP、RFCOMM)和硬件交互。
架构要点: BlueZ将实时性要求高的协议处理放在内核,将策略性、复杂逻辑放在用户空间,兼顾性能与灵活性。
3.2 内核蓝牙核心层(Bluetooth Core)
蓝牙核心层位于 net/bluetooth/ 目录,是整个内核蓝牙子系统的中枢神经。它负责设备管理、连接管理、Socket抽象以及各协议层之间的数据调度。
3.2.1 核心层职责
- 设备管理: 蓝牙适配器的注册、注销、电源管理。
- 连接管理: 建立/断开ACL(异步无连接)和SCO(同步面向连接)链路。
- Socket抽象: 提供统一的
struct sock接口,供上层协议使用。 - 数据调度: 在HCI、L2CAP、RFCOMM之间路由数据包。
3.2.2 核心层关键文件
| 文件路径 | 核心功能 |
|---|---|
net/bluetooth/af_bluetooth.c | 蓝牙协议族(PF_BLUETOOTH)Socket创建与绑定 |
net/bluetooth/hci_core.c | HCI设备核心管理,控制器初始化与事件处理 |
net/bluetooth/hci_conn.c | HCI连接管理,ACL/SCO链路建立与拆除 |
net/bluetooth/mgmt.c | 管理接口(Management Interface),用户空间控制命令 |
net/bluetooth/smp.c | 安全管理协议(Security Manager Protocol) |
调试提示: 当蓝牙适配器无法被系统识别时,优先检查
hci_core.c 中的 hci_register_dev() 调用是否成功,以及 dmesg 中是否有“hci_core”相关的错误日志。
3.3 HCI设备层
HCI(Host Controller Interface)设备层是主机与蓝牙控制器之间的桥梁。它定义了命令、事件、数据三种数据包的传输格式,并负责与底层传输层(UART、USB、SDIO)交互。
3.3.1 HCI层架构
3.3.2 HCI关键数据结构
// 核心结构体:hci_dev (位于 net/bluetooth/hci_core.h)
struct hci_dev {
char name[8]; // 设备名,如 hci0
struct list_head list; // 全局设备链表
unsigned long flags; // 设备状态标志 (HCI_UP, HCI_RUNNING)
struct hci_conn_hash conn_hash; // 连接哈希表
struct sk_buff_head rx_q; // 接收数据队列
struct sk_buff_head tx_q; // 发送数据队列
struct hci_dev_stats stat; // 统计信息 (包计数、错误计数)
int (*open)(struct hci_dev *hdev); // 打开硬件接口
int (*close)(struct hci_dev *hdev); // 关闭硬件接口
int (*send)(struct hci_dev *hdev, struct sk_buff *skb); // 发送数据帧
};
常见调试场景: 如果
hcitool dev 显示设备但无法扫描,检查 hci_dev->flags 是否包含 HCI_UP 标志。若未设置,说明设备未成功初始化,需排查传输层驱动。
3.4 L2CAP层
L2CAP(Logical Link Control and Adaptation Protocol)位于HCI之上,为上层协议提供逻辑信道复用、分段重组、服务质量(QoS)等功能。RFCOMM、BNEP、ATT等协议都运行在L2CAP之上。
3.4.1 L2CAP核心功能
- 信道复用: 通过CID(Channel Identifier)区分多个上层协议会话。
- 分段与重组: 将大于MTU的L2CAP SDU分割为多个HCI ACL数据包发送,接收端重组。
- 流控与重传: 支持ERTM(增强重传模式)和SAR(分段与重组)机制。
- 连接建立: 通过L2CAP_CONN_REQ/RSP信令建立逻辑信道。
3.4.2 L2CAP源码目录结构
| 文件 | 职责 |
|---|---|
net/bluetooth/l2cap_core.c | L2CAP协议核心逻辑:信道状态机、数据收发、信令处理 |
net/bluetooth/l2cap_sock.c | L2CAP Socket接口实现,与用户空间交互 |
net/bluetooth/l2cap.h | L2CAP数据结构定义:struct l2cap_chan、struct l2cap_conn |
3.4.3 L2CAP信道状态机
// L2CAP 信道状态 (l2cap.h)
#define BT_OPEN 0 // 信道已创建,等待连接
#define BT_BOUND 1 // 已绑定PSM
#define BT_LISTEN 2 // 监听状态
#define BT_CONNECT 3 // 连接进行中
#define BT_CONFIG 4 // 配置进行中
#define BT_CONNECTED 5 // 已连接,可传输数据
#define BT_DISCONN 6 // 断开进行中
调试技巧: 使用
btmon 或 hcidump 抓取L2CAP信令包。若RFCOMM连接失败,先检查L2CAP信道是否成功建立(状态机是否到达 BT_CONNECTED)。
3.5 RFCOMM层
RFCOMM(Radio Frequency Communication)模拟RS-232串口,在L2CAP之上提供串行端口仿真。它是蓝牙SPP(Serial Port Profile)的核心协议,也是本课程调试的重点。
3.5.1 RFCOMM协议特点
- 多路复用: 通过DLCI(Data Link Connection Identifier)在一个L2CAP信道上支持最多30个虚拟串口。
- 帧类型: 支持UIH(无信息头帧)、UI(无编号信息帧)、SABM/DISC(链路控制帧)。
- 流控: 支持基于Credit的流控机制,防止接收端缓冲区溢出。
3.5.2 RFCOMM源码目录结构
RFCOMM代码集中在 net/bluetooth/rfcomm/ 子目录下:
| 文件 | 核心功能 |
|---|---|
net/bluetooth/rfcomm/core.c | RFCOMM协议核心:DLCI管理、帧解析、状态机、流控 |
net/bluetooth/rfcomm/sock.c | RFCOMM Socket接口,实现 bind()/listen()/connect()/sendmsg()/recvmsg() |
net/bluetooth/rfcomm/tty.c | TTY驱动接口,将RFCOMM信道映射为 /dev/rfcomm* 设备节点 |
net/bluetooth/rfcomm/rfcomm.h | RFCOMM数据结构:struct rfcomm_dlc、struct rfcomm_session |
3.5.3 RFCOMM核心数据结构
// RFCOMM 数据链路连接 (rfcomm.h)
struct rfcomm_dlc {
struct sock *sk; // 关联的Socket
struct rfcomm_session *session; // 所属会话
u8 dlci; // 数据链路连接标识符 (0~63)
u8 state; // 连接状态 (BT_OPEN, BT_CONNECTED等)
u8 ms; // 调制信号状态 (RTS/CTS/DTR/DSR)
u8 out; // 发送Credit数
u8 in; // 接收Credit数
spinlock_t lock;
struct sk_buff_head tx_queue; // 发送队列
struct timer_list timer; // 重传/超时定时器
};
// RFCOMM 会话 (rfcomm.h)
struct rfcomm_session {
struct list_head list; // 全局会话链表
struct hci_conn *hcon; // 底层HCI连接
struct l2cap_chan *l2cap_chan; // 关联的L2CAP信道
u8 initiator; // 是否为会话发起方
u8 state; // 会话状态
struct rfcomm_dlc *dlcs[32]; // 最多32个DLCI (0~31为控制信道)
};
3.6 各层源码目录结构汇总
以下表格汇总了内核蓝牙子系统各层在Linux源码树中的位置,方便快速定位:
| 层次 | 源码路径 | 核心文件 |
|---|---|---|
| 蓝牙核心层 | net/bluetooth/ | af_bluetooth.c, hci_core.c, mgmt.c, smp.c |
| HCI设备层 | net/bluetooth/ | hci_core.c, hci_sock.c, hci_conn.c, hci_event.c |
| HCI传输层 | drivers/bluetooth/ | hci_uart.c, hci_usb.c, btusb.c, hci_bcm.c |
| L2CAP层 | net/bluetooth/ | l2cap_core.c, l2cap_sock.c, l2cap.h |
| RFCOMM层 | net/bluetooth/rfcomm/ | core.c, sock.c, tty.c, rfcomm.h |
| BNEP层 | net/bluetooth/bnep/ | bnep_core.c, bnep_sock.c |
| HIDP层 | net/bluetooth/hidp/ | hidp_core.c, hidp_sock.c |
调试路径速查: 当RFCOMM数据传输异常时,按以下顺序排查源码:
1.
2.
3.
4.
1.
rfcomm/core.c — 检查DLCI状态机和Credit流控2.
rfcomm/tty.c — 检查TTY缓冲区是否溢出3.
l2cap_core.c — 检查L2CAP信道是否正常建立4.
hci_core.c — 检查HCI连接和ACL数据包收发
3.7 本章小结
- BlueZ采用用户空间-内核空间双层架构,内核负责实时协议处理。
- 蓝牙核心层(
net/bluetooth/)提供设备管理、连接管理和Socket抽象。 - HCI设备层是主机与蓝牙控制器的桥梁,通过命令/事件/数据包交互。
- L2CAP层提供信道复用、分段重组和QoS,是RFCOMM的基础。
- RFCOMM层模拟串口,通过DLCI实现多路复用,其源码集中在
net/bluetooth/rfcomm/。 - 掌握各层源码目录结构,是高效调试RFCOMM数据传输的前提。