3、Linux内核蓝牙子系统架构:BlueZ架构、内核蓝牙核心层(Bluetooth Core)、HCI设备层、L2CAP层、RFCOMM层源码目录结构

本章深入剖析Linux内核蓝牙子系统的分层架构,从用户空间的BlueZ协议栈到内核空间的各协议层源码目录结构。理解这一架构是调试RFCOMM协议数据传输的基础,也是定位数据流瓶颈和协议错误的关键。

3.1 BlueZ整体架构概览

BlueZ是Linux官方蓝牙协议栈,采用用户空间-内核空间双层架构。用户空间负责高层协议(如GATT、A2DP)和配置管理,内核空间负责低层协议(HCI、L2CAP、RFCOMM)和硬件交互。

架构要点: BlueZ将实时性要求高的协议处理放在内核,将策略性、复杂逻辑放在用户空间,兼顾性能与灵活性。
BlueZ 整体架构分层图 用户空间 (User Space) bluetoothd (蓝牙守护进程) | obexd | gatttool | hcitool | bluetoothctl BlueZ 库 (libbluetooth) | D-Bus API | SDP 服务发现 高层协议: GATT, A2DP, HFP, AVRCP, PAN 内核空间 (Kernel Space) 蓝牙核心层 (Bluetooth Core) — net/bluetooth/ HCI 设备层 (HCI Device) — net/bluetooth/hci_core.c, hci_sock.c L2CAP 层 (L2CAP) — net/bluetooth/l2cap_core.c, l2cap_sock.c RFCOMM 层 (RFCOMM) — net/bluetooth/rfcomm/ 蓝牙硬件 (UART/USB/SDIO 蓝牙适配器)

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.cHCI设备核心管理,控制器初始化与事件处理
net/bluetooth/hci_conn.cHCI连接管理,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层架构

HCI 设备层内部结构 L2CAP / RFCOMM 上层协议 HCI 核心层 (hci_core.c) hci_dev 结构体管理 | 命令/事件/数据队列 HCI Socket (hci_sock.c) HCI 传输层 (hci_uart.c / hci_usb.c) 蓝牙硬件 (UART/USB 控制器)

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.cL2CAP协议核心逻辑:信道状态机、数据收发、信令处理
net/bluetooth/l2cap_sock.cL2CAP Socket接口实现,与用户空间交互
net/bluetooth/l2cap.hL2CAP数据结构定义: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.cRFCOMM协议核心:DLCI管理、帧解析、状态机、流控
net/bluetooth/rfcomm/sock.cRFCOMM Socket接口,实现 bind()/listen()/connect()/sendmsg()/recvmsg()
net/bluetooth/rfcomm/tty.cTTY驱动接口,将RFCOMM信道映射为 /dev/rfcomm* 设备节点
net/bluetooth/rfcomm/rfcomm.hRFCOMM数据结构: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为控制信道)
};
RFCOMM 协议栈数据流与源码映射 用户空间应用 (open /dev/rfcomm0) rfcomm/tty.c — TTY驱动层 rfcomm/sock.c — Socket接口层 rfcomm/core.c — 协议核心层 DLCI管理 | 帧解析 | 状态机 | Credit流控 l2cap_core.c — L2CAP层

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. 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数据传输的前提。