本文深入剖析 BlueZ 5.x 的整体架构设计,从用户态到内核态逐层拆解核心组件、源码逻辑与运行机制。通过对比 BlueZ 4.x 与 5.x 的架构差异,揭示 Management Interface 引入的革命性变化。结合源码细节,详细解析适配器管理、设备管理、Profile 框架、插件系统、D-Bus 抽象层、IO 抽象层等核心模块的交互逻辑与数据流转,为蓝牙开发从业者提供系统化的架构认知和源码阅读指南。
目录
[一、BlueZ 5.x 架构演进:从 HCID 到统一蓝牙守护进程](#一、BlueZ 5.x 架构演进:从 HCID 到统一蓝牙守护进程)
[1.1 架构演进历程](#1.1 架构演进历程)
[1.2 架构总览图](#1.2 架构总览图)
[2.1 bluetoothd 主守护进程](#2.1 bluetoothd 主守护进程)
[2.2 Adapter Manager(适配器管理器)](#2.2 Adapter Manager(适配器管理器))
[2.3 Device Manager(设备管理器)](#2.3 Device Manager(设备管理器))
[2.4 Profile Manager(Profile管理器)](#2.4 Profile Manager(Profile管理器))
[2.5 Plugin System(插件系统)](#2.5 Plugin System(插件系统))
[2.6 Advertising Manager(广播管理器)](#2.6 Advertising Manager(广播管理器))
[2.7 Adv Monitor Manager(广播监控管理器)](#2.7 Adv Monitor Manager(广播监控管理器))
[三、D-Bus 抽象层:gdbus 库](#三、D-Bus 抽象层:gdbus 库)
[3.1 设计目标](#3.1 设计目标)
[3.2 核心数据结构](#3.2 核心数据结构)
[3.3 方法调用机制](#3.3 方法调用机制)
[3.4 对象管理器模式](#3.4 对象管理器模式)
[四、IO 抽象层:GLib 到 ELL 的迁移](#四、IO 抽象层:GLib 到 ELL 的迁移)
[4.1 双后端设计](#4.1 双后端设计)
[4.2 IO 抽象接口](#4.2 IO 抽象接口)
[4.3 GLib 后端实现](#4.3 GLib 后端实现)
[五、BTIO 层:蓝牙 Socket 抽象](#五、BTIO 层:蓝牙 Socket 抽象)
[5.1 设计目标](#5.1 设计目标)
[5.2 核心数据结构](#5.2 核心数据结构)
[5.3 核心 API](#5.3 核心 API)
[5.4 Profile 中的应用](#5.4 Profile 中的应用)
[6.1 Management Interface(管理接口)](#6.1 Management Interface(管理接口))
[6.2 mgmt_send() 核心函数源码解析](#6.2 mgmt_send() 核心函数源码解析)
[6.3 HCI 层(主机控制器接口)](#6.3 HCI 层(主机控制器接口))
[6.4 ATT/GATT 层(属性协议)](#6.4 ATT/GATT 层(属性协议))
[6.5 GATT Client(GATT 客户端)](#6.5 GATT Client(GATT 客户端))
[6.6 GATT Database(GATT 数据库服务端)](#6.6 GATT Database(GATT 数据库服务端))
[6.7 GATT 架构关系图](#6.7 GATT 架构关系图)
[七、OBEX 子系统](#七、OBEX 子系统)
[7.1 架构概述](#7.1 架构概述)
[7.2 OBEX 协议层](#7.2 OBEX 协议层)
[7.3 OBEX Profile 插件](#7.3 OBEX Profile 插件)
[8.1 Linux 蓝牙内核子系统](#8.1 Linux 蓝牙内核子系统)
[8.2 用户态与内核态通信机制](#8.2 用户态与内核态通信机制)
[9.1 蓝牙适配器启动流程](#9.1 蓝牙适配器启动流程)
[9.2 BLE 设备发现流程](#9.2 BLE 设备发现流程)
[9.3 GATT 服务发现流程](#9.3 GATT 服务发现流程)
[十、BlueZ 4.x vs 5.x 架构对比](#十、BlueZ 4.x vs 5.x 架构对比)
[10.1 架构差异对比表](#10.1 架构差异对比表)
[10.2 Management Interface 带来的变革](#10.2 Management Interface 带来的变革)
[十一、Profile 层架构详解](#十一、Profile 层架构详解)
[11.1 Profile 实现模式](#11.1 Profile 实现模式)
[11.2 Profile 与 D-Bus 的集成](#11.2 Profile 与 D-Bus 的集成)
[12.1 事件驱动架构](#12.1 事件驱动架构)
[12.2 引用计数管理](#12.2 引用计数管理)
[12.3 队列数据结构](#12.3 队列数据结构)
[12.4 双后端 IO 设计模式](#12.4 双后端 IO 设计模式)
[13.1 架构设计亮点](#13.1 架构设计亮点)
[13.2 源码阅读路线](#13.2 源码阅读路线)
[13.3 工程实践建议](#13.3 工程实践建议)
核心知识点速览
|-------------------|------------------------------|----------------|-----------------------------------------------------|
| 层级 | 核心组件 | 职责定位 | 关键文件 |
| 用户态应用层 | bluetoothctl、btmon、hcitool | 命令行交互与调试工具 | client/main.c、monitor/main.c、tools/hcitool.c |
| D-Bus 抽象层 | gdbus 库 | D-Bus 对象/监视器抽象 | gdbus/gdbus.h、gdbus/object.c |
| 用户态服务层 | bluetoothd 守护进程 | 蓝牙服务核心管理 | src/main.c、src/btd.h |
| IO 抽象层 | io-glib/io-ell | 跨平台 IO 抽象 | src/shared/io-glib.c、src/shared/io-ell.c |
| Profile 层 | A2DP、HFP、GATT、HID 等 | 协议Profile实现 | profiles/audio/、profiles/input/、attrib/ |
| 共享库 层 | HCI、ATT、GATT、mgmt | 协议栈核心逻辑 | src/shared/hci.c、src/shared/mgmt.c、src/shared/att.c |
| 内核接口层 | Management Socket、HCI Socket | 用户态与内核态通信 | lib/mgmt.h、lib/hci.h |
| 内核协议栈层 | HCI、L2CAP、SMP、GATT | 蓝牙协议核心实现 | Linux kernel net/bluetooth/ |
| OBEX 子系统 | obexd | 对象交换协议服务 | obexd/src/main.c、gobex/gobex.h |
一、BlueZ 5.x 架构演进:从 HCID 到统一蓝牙守护进程
1.1 架构演进历程
BlueZ 4.x 架构特点:
多守护进程模式:hcid(HCI管理)、sdpd(SDP服务发现)、hidd(HID设备)等
直接使用 HCI Socket 与内核交互
Profile 模块耦合度高,扩展性差
BlueZ 5.x 架构革新:
统一守护进程:bluetoothd 承担所有蓝牙服务管理职责
引入 Management Interface:取代大量直接 HCI 命令
插件化架构:Profile 和功能模块通过插件动态加载
完整 LE(低功耗)支持:原生支持 BLE 协议栈
GLib 到 ELL 迁移:逐步用 ELL(Embedded Linux Library)替代 GLib
1.2 架构总览图

二、用户态核心组件深度解析
2.1 bluetoothd 主守护进程
bluetoothd 是 BlueZ 5.x 的核心守护进程,负责整个蓝牙协议栈的管理和协调。其启动流程在 src/main.c中定义:
初始化流程( main函数 核心逻辑):
cpp
int main(int argc, char *argv[]) {
init_defaults(); // 1. 初始化默认配置
g_option_context_parse(...); // 2. 解析命令行参数
mainloop_init(); // 3. 初始化事件循环
__btd_log_init(...); // 4. 初始化日志系统
parse_config(main_conf); // 5. 解析配置文件
connect_dbus(); // 6. 连接 D-Bus
adapter_init(); // 7. 初始化适配器管理
btd_device_init(); // 8. 初始化设备管理
btd_agent_init(); // 9. 初始化配对代理
btd_profile_init(); // 10. 初始化Profile框架
start_sdp_server(); // 11. 启动SDP服务器
plugin_init(...); // 12. 加载插件
rfkill_init(); // 13. 初始化射频开关
mainloop_run_with_signal(...); // 14. 进入主事件循环
}
核心配置结构(src/btd.h):
cpp
struct btd_opts {
char *name; // 设备名称
uint32_t class; // 设备类别
gboolean pairable; // 是否可配对
uint32_t pairto; // 配对超时
uint32_t discovto; // 可发现超时
uint32_t tmpto; // 临时设备超时
uint8_t privacy; // 隐私模式
bool device_privacy; // 设备级隐私
bt_mode_t mode; // 工作模式(DUAL/BREDR/LE)
bt_gatt_cache_t gatt_cache; // GATT缓存策略
uint16_t gatt_mtu; // GATT MTU大小
uint8_t gatt_channels; // GATT通道数
struct btd_avdtp_opts avdtp; // AVDTP配置
uint8_t key_size; // 密钥大小
enum jw_repairing_t jw_repairing; // Just Works重配对策略
struct btd_advmon_opts advmon; // 广播监控配置
...
};
2.2 Adapter Manager(适配器管理器)
适配器管理器负责管理系统中的蓝牙控制器,其核心逻辑在 src/adapter.c 中实现。
核心职责:
-
检测和管理蓝牙控制器的接入/移除
-
控制适配器的电源状态(开启/关闭)
-
管理设备发现流程
-
维护适配器级别的配置和状态
关键数据结构(src/adapter.c:235):
cpp
struct btd_adapter {
int ref_count; // 引用计数
uint16_t dev_id; // 设备ID
struct mgmt *mgmt; // Management Interface实例
bdaddr_t bdaddr; // 控制器蓝牙地址
uint8_t bdaddr_type; // 地址类型
uint32_t dev_class; // 控制器设备类别
char *name; // 控制器设备名称
char *short_name; // 控制器短名称
uint32_t supported_settings; // 支持的设置项
uint32_t pending_settings; // 待处理设置项
uint32_t current_settings; // 当前设置项
char *path; // D-Bus对象路径
uint16_t manufacturer; // 制造商ID
uint8_t major_class; // 配置的主类别
uint8_t minor_class; // 配置的子类别
char *system_name; // 配置的系统名称
char *modalias; // 设备别名(USB modalias)
bool stored_discoverable; // 存储的可发现模式
uint32_t discoverable_timeout; // 可发现超时(秒)
uint32_t pairable_timeout; // 可配对超时(秒)
char *current_alias; // 当前适配器名称别名
char *stored_alias; // 存储的适配器名称别名
bool discovering; // 正在发现状态
bool filtered_discovery; // 过滤发现模式
uint8_t discovery_type; // 当前活动发现类型
uint8_t discovery_enable; // 发现使能/禁用
bool discovery_suspended; // 发现已暂停
bool discovery_discoverable; // 发现时可被发现
GSList *discovery_list; // 发现客户端列表
GSList *set_filter_list; // 设置了过滤但未扫描的客户端
struct mgmt_cp_start_service_discovery *current_discovery_filter;
struct discovery_client *client; // 活动发现客户端
GSList *discovery_found; // 已发现设备列表
unsigned int discovery_idle_timeout; // 发现间隔超时
unsigned int passive_scan_timeout; // 被动扫描间隔超时
...
};
适配器发现机制 :通过 Management Interface 监听 MGMT_EV_CONTROLLER_FOUND 事件,当新控制器接入时自动创建适配器对象。
2.3 Device Manager(设备管理器)
设备管理器负责管理已发现的蓝牙设备,核心逻辑在 src/device.c中实现。
核心职责:
-
设备发现与过滤
-
设备配对与绑定
-
连接管理
-
GATT服务发现
-
SDP服务浏览
设备状态机:
cpp
UNKNOWN → DISCOVERING → CONNECTING → CONNECTED
↓ ↓ ↓ ↓
IDLE DISCONNECTED DISCONNECTING IDLE
配对流程核心逻辑:
-
收到配对请求 → 创建
bonding_req结构 -
调用 Agent 获取 PIN/密钥 → 通过 Management Interface 发送配对命令
-
等待配对结果 → 更新设备绑定状态
-
存储绑定信息到本地(storage.c)
2.4 Profile Manager(Profile管理器)
Profile 管理器负责管理各种蓝牙协议 Profile 的注册和生命周期,核心逻辑在 src/profile.c中实现。
Profile 注册机制:
cpp
int btd_profile_register(struct btd_profile *profile) {
// 1. 验证Profile定义
// 2. 注册到Profile列表
// 3. 为已有设备尝试匹配Profile
// 4. 注册D-Bus接口
}
标准 Profile 通道分配(src/profile.c):
|-------------|----------------|----------|
| Profile | 默认RFCOMM通道 | UUID |
| DUN | 1 | 0x1103 |
| SPP | 3 | 0x1101 |
| HSP HS | 6 | 0x1108 |
| HFP HF | 7 | 0x111e |
| OPP | 9 | 0x1105 |
| FTP | 10 | 0x1106 |
| PBAP | 15 | 0x112f |
2.5 Plugin System(插件系统)
插件系统实现了 BlueZ 5.x 的模块化架构,核心逻辑在 [src/plugin 中实现。
插件加载机制:
cpp
struct bluetooth_plugin {
void *handle; // 动态库句柄
gboolean active; // 激活状态
struct bluetooth_plugin_desc *desc; // 插件描述
};
bool add_plugin(void *handle, struct bluetooth_plugin_desc *desc) {
// 1. 检查版本兼容性
// 2. 创建插件对象
// 3. 按优先级排序插入
// 4. 启用调试开关
}
内置插件与动态插件:
-
内置插件:编译时静态链接(通过
src/builtin.h生成) -
动态插件:运行时加载(位于
plugins/目录)
常用插件:
-
policy.c:安全策略管理 -
autopair.c:自动配对功能 -
sixaxis.c:PlayStation控制器支持 -
wiimote.c:Wii遥控器支持
2.6 Advertising Manager(广播管理器)
广播管理器负责管理 BLE 广播功能,核心逻辑在 src/advertising.c中实现。
核心数据结构:
cpp
struct btd_adv_manager {
struct btd_adapter *adapter; // 所属适配器
struct queue *clients; // 广播客户端列表
struct mgmt *mgmt; // Management Interface实例
uint16_t mgmt_index; // 管理索引
uint8_t max_adv_len; // 最大广播长度
uint8_t max_scan_rsp_len; // 最大扫描响应长度
uint8_t max_ads; // 最大广播数
uint32_t supported_flags; // 支持的标志位
uint64_t instance_bitmap; // 实例位图
bool extended_add_cmds; // 扩展添加命令支持
int8_t min_tx_power; // 最小发射功率
int8_t max_tx_power; // 最大发射功率
};
2.7 Adv Monitor Manager(广播监控管理器)
广播监控管理器负责监控 BLE 广播数据,核心逻辑在 src/adv_monitor.c 中实现。
核心功能:
-
广播模式匹配(基于 UUID、名称、地址等)
-
RSSI 采样与阈值检测
-
低功耗广播过滤
三、D-Bus 抽象层:gdbus 库
3.1 设计目标
gdbus 库是 BlueZ 对 D-Bus 的轻量级封装,提供了以下核心抽象:
-
对象管理:统一的 D-Bus 对象注册和生命周期管理
-
方法调用:简化的方法调用和响应处理
-
属性管理:属性的 get/set 接口
-
信号发布:信号的订阅和发布机制
-
安全策略:Polkit 集成的权限检查
3.2 核心数据结构
接口定义结构(gdbus/gdbus.h):
cpp
typedef struct GDBusArgInfo GDBusArgInfo;
typedef struct GDBusMethodTable GDBusMethodTable;
typedef struct GDBusSignalTable GDBusSignalTable;
typedef struct GDBusPropertyTable GDBusPropertyTable;
typedef struct GDBusSecurityTable GDBusSecurityTable;
typedef DBusMessage * (* GDBusMethodFunction) (DBusConnection *connection,
DBusMessage *message, void *user_data);
typedef gboolean (*GDBusPropertyGetter)(const GDBusPropertyTable *property,
DBusMessageIter *iter, void *data);
typedef void (*GDBusPropertySetter)(const GDBusPropertyTable *property,
DBusMessageIter *value, GDBusPendingPropertySet id, void *data);
3.3 方法调用机制
cpp
DBusMessage *g_dbus_create_method_reply(DBusMessage *message,
const char *interface, const char *method, ...);
bool g_dbus_register_interface(DBusConnection *connection,
const char *path, const char *interface,
const GDBusMethodTable *methods,
const GDBusSignalTable *signals,
const GDBusPropertyTable *properties,
void *user_data, GDBusDestroyFunction destroy);
3.4 对象管理器模式
BlueZ 使用 D-Bus Object Manager 模式管理蓝牙对象:
cpp
/org/bluez/hci0 → Adapter 对象
/org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX → Device 对象
/org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX/service0001 → GATT Service 对象
/org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX/service0001/char0002 → GATT Characteristic
四、IO 抽象层:GLib 到 ELL 的迁移
4.1 双后端设计
BlueZ 正在从 GLib 逐步迁移到 ELL(Embedded Linux Library),IO 抽象层是这一迁移的关键部分:
|--------|----------------------|-----------------|----------|
| 后端 | 文件 | 依赖 | 适用场景 |
| GLib | src/shared/io-glib.c | GLib GIOChannel | 传统桌面环境 |
| ELL | src/shared/io-ell.c | ELL io API | 嵌入式环境 |
4.2 IO 抽象接口
统一接口定义(src/shared/io.h):
cpp
struct io;
struct io *io_new(int fd); // 创建IO对象
void io_destroy(struct io *io); // 销毁IO对象
int io_get_fd(struct io *io); // 获取文件描述符
bool io_set_close_on_destroy(struct io *io, bool do_close);
ssize_t io_send(struct io *io, const struct iovec *iov, int iovcnt);
bool io_shutdown(struct io *io);
typedef bool (*io_callback_func_t)(struct io *io, void *user_data);
bool io_set_read_handler(struct io *io, io_callback_func_t callback,
void *user_data, io_destroy_func_t destroy);
bool io_set_write_handler(struct io *io, io_callback_func_t callback,
void *user_data, io_destroy_func_t destroy);
bool io_set_disconnect_handler(struct io *io, io_callback_func_t callback,
void *user_data, io_destroy_func_t destroy);
4.3 GLib 后端实现
核心数据结构(src/shared/io-glib.c):
cpp
struct io_watch {
struct io *io;
guint id;
io_callback_func_t callback;
io_destroy_func_t destroy;
void *user_data;
};
struct io {
int ref_count;
GIOChannel *channel; // GLib IO通道
struct io_watch *read_watch; // 读事件监听
struct io_watch *write_watch; // 写事件监听
struct io_watch *disconnect_watch; // 断开事件监听
};
IO 对象创建:
cpp
struct io *io_new(int fd) {
struct io *io;
io = g_try_new0(struct io, 1);
io->channel = g_io_channel_unix_new(fd);
g_io_channel_set_encoding(io->channel, NULL, NULL);
g_io_channel_set_buffered(io->channel, FALSE);
g_io_channel_set_close_on_unref(io->channel, FALSE);
return io_ref(io);
}
五、BTIO 层:蓝牙 Socket 抽象
5.1 设计目标
btio 层是 BlueZ 对蓝牙 Socket 的高级抽象,基于 GLib 的 GIOChannel 实现,为 Profile 层提供统一的 L2CAP/RFCOMM/SCO 连接管理接口。
核心优势:
-
统一的连接/监听/接受接口
-
异步回调机制,与 mainloop 无缝集成
-
内置安全级别配置
-
支持蓝牙地址类型和模式配置
5.2 核心数据结构
BtIOOption 选项枚举(btio/btio.h):
cpp
typedef enum {
BT_IO_OPT_INVALID = 0,
BT_IO_OPT_SOURCE, // 源地址
BT_IO_OPT_SOURCE_BDADDR, // 源蓝牙地址
BT_IO_OPT_SOURCE_TYPE, // 源地址类型
BT_IO_OPT_DEST, // 目标地址
BT_IO_OPT_DEST_BDADDR, // 目标蓝牙地址
BT_IO_OPT_DEST_TYPE, // 目标地址类型
BT_IO_OPT_DEFER_TIMEOUT, // 延迟超时
BT_IO_OPT_SEC_LEVEL, // 安全级别
BT_IO_OPT_KEY_SIZE, // 密钥大小
BT_IO_OPT_CHANNEL, // RFCOMM通道号
BT_IO_OPT_SOURCE_CHANNEL, // 源通道号
BT_IO_OPT_DEST_CHANNEL, // 目标通道号
BT_IO_OPT_PSM, // L2CAP PSM
BT_IO_OPT_CID, // L2CAP CID
BT_IO_OPT_MTU, // MTU大小
BT_IO_OPT_OMTU, // 输出MTU
BT_IO_OPT_IMTU, // 输入MTU
BT_IO_OPT_CENTRAL, // 中心设备模式
BT_IO_OPT_HANDLE, // 连接句柄
BT_IO_OPT_CLASS, // 设备类别
BT_IO_OPT_MODE, // 连接模式
BT_IO_OPT_FLUSHABLE, // 可刷新模式
BT_IO_OPT_PRIORITY, // 优先级
BT_IO_OPT_VOICE, // 语音编码
BT_IO_OPT_PHY, // PHY类型
} BtIOOption;
连接类型(btio/btio.c):
cpp
typedef enum {
BT_IO_L2CAP, // L2CAP协议
BT_IO_RFCOMM, // RFCOMM协议
BT_IO_SCO, // SCO协议
BT_IO_INVALID,
} BtIOType;
连接选项结构(btio/btio.c):
cpp
struct set_opts {
bdaddr_t src; // 源地址
bdaddr_t dst; // 目标地址
BtIOType type; // 连接类型
uint8_t src_type; // 源地址类型
uint8_t dst_type; // 目标地址类型
int defer; // 延迟超时
int sec_level; // 安全级别
uint8_t channel; // RFCOMM通道
uint16_t psm; // L2CAP PSM
uint16_t cid; // L2CAP CID
uint16_t mtu; // MTU
uint16_t imtu; // 输入MTU
uint16_t omtu; // 输出MTU
int central; // 中心模式
uint8_t mode; // 连接模式
int flushable; // 可刷新标志
uint32_t priority; // 优先级
uint16_t voice; // 语音编码
};
5.3 核心 API
连接建立(btio/btio.h):
cpp
GIOChannel *bt_io_connect(BtIOConnect connect, gpointer user_data,
GDestroyNotify destroy, GError **gerr,
BtIOOption opt1, ...);
服务监听(btio/btio.h):
cpp
GIOChannel *bt_io_listen(BtIOConnect connect, BtIOConfirm confirm,
gpointer user_data, GDestroyNotify destroy,
GError **err, BtIOOption opt1, ...);
接受连接(btio/btio.h):
cpp
gboolean bt_io_accept(GIOChannel *io, BtIOConnect connect,
gpointer user_data, GDestroyNotify destroy, GError **err);
选项设置(btio/btio.h):
cpp
gboolean bt_io_set(GIOChannel *io, GError **err, BtIOOption opt1, ...);
gboolean bt_io_get(GIOChannel *io, GError **err, BtIOOption opt1, ...);
5.4 Profile 中的应用
btio 被几乎所有 Profile 用于建立和管理蓝牙连接:
|-------------|--------------|----------|
| Profile | 使用协议 | 典型用途 |
| A2DP | L2CAP | 音频数据传输 |
| HFP | RFCOMM + SCO | 语音通话 |
| HSP | RFCOMM + SCO | 耳机语音 |
| HID | L2CAP | 人机接口设备 |
| SPP | RFCOMM | 串口协议 |
| GATT | L2CAP | BLE 属性协议 |
典型使用模式:
cpp
// 监听 RFCOMM 通道
GIOChannel *io = bt_io_listen(connect_cb, user_data, destroy_cb, NULL,
BT_IO_OPT_SOURCE_BDADDR, &src_addr,
BT_IO_OPT_CHANNEL, 1,
BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
BT_IO_OPT_INVALID);
// 连接到远程设备
GIOChannel *io = bt_io_connect(connect_cb, user_data, destroy_cb, &err,
BT_IO_OPT_DEST_BDADDR, &dst_addr,
BT_IO_OPT_DEST_TYPE, BDADDR_LE_PUBLIC,
BT_IO_OPT_PSM, 0x1101,
BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_HIGH,
BT_IO_OPT_INVALID);
六、共享库层:协议栈核心逻辑
6.1 Management Interface(管理接口)
Management Interface 是 BlueZ 5.x 引入的核心创新,定义在 src/shared/mgmt.c和 lib/mgmt.h中。
设计理念:
-
将复杂的 HCI 命令封装为高层管理操作
-
提供统一的事件通知机制
-
减少用户态与内核态的直接交互
核心数据结构:
cpp
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; // 下一个请求ID
unsigned int next_notify_id; // 下一个通知ID
bool need_notify_cleanup; // 需要清理通知
bool in_notify; // 正在处理通知
void *buf; // 接收缓冲区
uint16_t len; // 缓冲区数据长度
uint16_t mtu; // MTU大小
mgmt_debug_func_t debug_callback; // 调试回调
mgmt_destroy_func_t debug_destroy; // 调试清理函数
void *debug_data; // 调试数据
};
请求/响应机制:
cpp
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);
关键操作码(lib/mgmt.h):
|---------|--------------------------|---------|
| 操作码 | 名称 | 功能 |
| 0x0001 | MGMT_OP_READ_VERSION | 读取版本信息 |
| 0x0003 | MGMT_OP_READ_INDEX_LIST | 获取控制器列表 |
| 0x0005 | MGMT_OP_SET_POWERED | 设置电源状态 |
| 0x0006 | MGMT_OP_SET_DISCOVERABLE | 设置可发现状态 |
| 0x0007 | MGMT_OP_SET_PAIRABLE | 设置可配对状态 |
| 0x000B | MGMT_OP_CREATE_BOND | 创建绑定 |
| 0x000C | MGMT_OP_REMOVE_BOND | 移除绑定 |
| 0x000D | MGMT_OP_CONNECT | 连接设备 |
| 0x000E | MGMT_OP_DISCONNECT | 断开连接 |
6.2 mgmt_send() 核心函数源码解析
mgmt_send() 是 Management Interface 的核心函数,负责发送管理请求并处理响应。以下是其实际源码分析:
请求发送函数(src/shared/mgmt.c:180):
cpp
static bool send_request(struct mgmt *mgmt, struct mgmt_request *request)
{
struct iovec iov;
ssize_t ret;
iov.iov_base = request->buf; // 构造IO向量
iov.iov_len = request->len;
ret = io_send(mgmt->io, &iov, 1); // 通过IO抽象层发送
if (ret < 0) {
util_debug(mgmt->debug_callback, mgmt->debug_data,
"write failed: %s", strerror(-ret));
if (request->callback)
request->callback(MGMT_STATUS_FAILED, 0, NULL,
request->user_data);
destroy_request(request);
return false;
}
if (request->timeout) // 设置超时定时器(默认10秒)
request->timeout_id = timeout_add_seconds(request->timeout,
request_timeout, request, NULL);
util_debug(mgmt->debug_callback, mgmt->debug_data,
"[0x%04x] command 0x%04x", request->index, request->opcode);
util_hexdump('<', request->buf, ret, mgmt->debug_callback,
mgmt->debug_data);
queue_push_tail(mgmt->pending_list, request); // 加入待处理列表
return true;
}
请求超时处理(src/shared/mgmt.c:160):
cpp
static bool request_timeout(void *data)
{
struct mgmt_request *request = data;
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;
}
请求完成处理(src/shared/mgmt.c:276):
cpp
static void request_complete(struct mgmt *mgmt, uint8_t status,
uint16_t opcode, uint16_t index,
uint16_t length, const void *param)
{
struct opcode_index match = { .opcode = opcode, .index = index };
struct mgmt_request *request;
request = queue_remove_if(mgmt->pending_list,
match_request_opcode_index, &match);
if (!request) {
util_debug(mgmt->debug_callback, mgmt->debug_data,
"Unable to find request for opcode 0x%04x", opcode);
request = queue_remove_if(mgmt->pending_list,
match_request_index, UINT_TO_PTR(index));
}
if (request) {
if (request->callback)
request->callback(status, length, param, request->user_data);
destroy_request(request);
}
wakeup_writer(mgmt);
}
请求优先级机制(src/shared/mgmt.c:217):
cpp
static bool can_write_data(struct io *io, void *user_data)
{
struct mgmt *mgmt = user_data;
struct mgmt_request *request;
bool can_write;
request = queue_pop_head(mgmt->reply_queue); // 响应队列优先
if (!request) {
if (!queue_isempty(mgmt->pending_list)) // 待处理列表不为空则等待
return false;
request = queue_pop_head(mgmt->request_queue); // 否则从请求队列获取
if (!request)
return false;
can_write = false;
} else {
can_write = !queue_isempty(mgmt->reply_queue); // 响应可连续发送
}
if (!send_request(mgmt, request))
return true;
return can_write;
}
设计要点:
-
双队列设计:`reply_queue`(响应队列)优先级高于 `request_queue`(请求队列),确保响应优先处理
-
超时机制:每个请求默认设置10秒超时,超时后自动调用回调返回 `MGMT_STATUS_TIMEOUT`
-
调试支持:内置 `util_hexdump` 函数,可输出请求数据的十六进制 Dump,便于调试
6.3 HCI 层(主机控制器接口)
HCI 层提供对蓝牙控制器的底层访问,定义在 src/shared/hci.c中。
核心数据结构:
cpp
struct bt_hci {
int ref_count; // 引用计数
struct io *io; // IO抽象层
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; // 事件监听列表
};
命令发送机制:
cpp
static void send_command(struct bt_hci *hci, uint16_t opcode,
void *data, uint8_t size)
{
// 1. 构造 HCI 命令包(H4格式)
// H4格式: [Type(1)] [Opcode(2)] [Length(1)] [Data(n)]
uint8_t type = BT_H4_CMD_PKT;
// 2. 加入命令队列
// 3. 触发 IO 写操作
}
6.4 ATT/GATT 层(属性协议)
ATT(Attribute Protocol)和 GATT(Generic Attribute Profile)是 BLE 的核心协议,定义在 src/shared/att.c 和 src/shared/gatt-db.c 中。
ATT 核心操作:
-
Read Request/Response
-
Write Request/Response
-
Read By Type Request
-
Find Information Request
-
Handle Value Notification/Indication
GATT 数据库 API(src/shared/gatt-db.h):
cpp
struct gatt_db *gatt_db_new(void);
struct gatt_db *gatt_db_ref(struct gatt_db *db);
void gatt_db_unref(struct gatt_db *db);
// 添加服务
struct gatt_db_attribute *gatt_db_add_service(struct gatt_db *db,
const bt_uuid_t *uuid, bool primary,
uint16_t num_handles);
// 添加特征
struct gatt_db_attribute *gatt_db_service_add_characteristic(
struct gatt_db_attribute *attrib,
const bt_uuid_t *uuid, uint32_t permissions,
uint8_t properties, gatt_db_read_t read_func,
gatt_db_write_t write_func, void *user_data);
// 添加描述符
struct gatt_db_attribute *gatt_db_service_add_descriptor(
struct gatt_db_attribute *attrib,
const bt_uuid_t *uuid, uint32_t permissions,
gatt_db_read_t read_func, gatt_db_write_t write_func,
void *user_data);
// 添加CCC(Client Characteristic Configuration)
struct gatt_db_attribute *gatt_db_service_add_ccc(
struct gatt_db_attribute *attrib, uint32_t permissions);
GATT 数据库操作回调:
cpp
typedef void (*gatt_db_read_t)(struct gatt_db_attribute *attrib,
unsigned int id, uint16_t offset, uint8_t opcode,
struct bt_att *att, void *user_data);
typedef void (*gatt_db_write_t)(struct gatt_db_attribute *attrib,
unsigned int id, uint16_t offset, const uint8_t *value,
size_t len, uint8_t opcode, struct bt_att *att,
void *user_data);
typedef void (*gatt_db_notify_t)(struct gatt_db_attribute *attrib,
struct gatt_db_attribute *ccc, const uint8_t *value,
size_t len, struct bt_att *att, void *user_data);
6.5 GATT Client(GATT 客户端)
GATT Client 负责与远程 BLE 设备进行 GATT 交互,定义在 src/gatt-client.c) 中。
核心数据结构(src/gatt-client.c:53):
cpp
struct btd_gatt_client {
struct btd_device *device; // 所属设备
uint8_t features; // GATT特性
bool ready; // 客户端就绪状态
char devaddr[18]; // 设备地址字符串
struct gatt_db *db; // GATT数据库
struct bt_gatt_client *gatt; // 底层GATT客户端
struct queue *services; // 服务列表
struct queue *all_notify_clients; // 所有通知客户端
struct queue *ios; // IO连接列表
};
struct service {
struct btd_gatt_client *client; // 所属客户端
bool primary; // 是否为主服务
uint16_t start_handle; // 起始句柄
uint16_t end_handle; // 结束句柄
bt_uuid_t uuid; // 服务UUID
char *path; // D-Bus对象路径
struct queue *chrcs; // 特征列表
struct queue *incl_services; // 包含服务列表
};
struct characteristic {
struct service *service; // 所属服务
struct gatt_db_attribute *attr; // 属性对象
uint16_t handle; // 属性句柄
uint16_t value_handle; // 值句柄
uint8_t props; // 属性特性
...
};
核心职责:
-
GATT 服务发现(Discover Primary Services)
-
GATT 特征发现(Discover Characteristics)
-
GATT 描述符发现(Discover Descriptors)
-
属性读写操作
-
通知/指示管理
-
D-Bus 接口暴露(
org.bluez.GattService1、org.bluez.GattCharacteristic1)
6.6 GATT Database(GATT 数据库服务端)
GATT Database 负责管理本地 GATT 服务和特征,定义在 src/gatt-database.c 中。
核心数据结构(src/gatt-database.c:63):
cpp
struct btd_gatt_database {
struct btd_adapter *adapter; // 所属适配器
struct gatt_db *db; // GATT数据库
unsigned int db_id; // 数据库ID
GIOChannel *le_io; // LE连接IO
GIOChannel *eatt_io; // EATT连接IO
GIOChannel *bredr_io; // BR/EDR连接IO
struct queue *records; // 记录列表
struct queue *device_states; // 设备状态列表
struct queue *ccc_callbacks; // CCC回调列表
struct gatt_db_attribute *svc_chngd; // 服务变更属性
struct gatt_db_attribute *svc_chngd_ccc; // 服务变更CCC
struct gatt_db_attribute *cli_feat; // 客户端特征
struct gatt_db_attribute *db_hash; // 数据库哈希
struct gatt_db_attribute *eatt; // EATT属性
struct queue *apps; // 应用列表
struct queue *profiles; // Profile列表
};
struct gatt_app {
struct btd_gatt_database *database; // 所属数据库
char *owner; // 所有者
char *path; // D-Bus路径
DBusMessage *reg; // 注册消息
GDBusClient *client; // D-Bus客户端
bool failed; // 是否失败
struct queue *profiles; // Profile列表
struct queue *services; // 服务列表
struct queue *proxies; // 代理列表
};
核心职责:
-
管理本地 GATT 服务注册
-
处理远程设备的 GATT 请求
-
支持 EATT(Enhanced ATT)多路复用
-
数据库哈希计算(用于快速比较)
-
服务变更通知(Service Changed)
-
D-Bus 接口暴露(
org.bluez.GattManager1、org.bluez.GattService1)
6.7 GATT 架构关系图

七、OBEX 子系统
7.1 架构概述
OBEX(Object Exchange)是蓝牙对象交换协议,用于文件传输、通讯录同步等功能。BlueZ 的 OBEX 子系统包括:
-
obexd:OBEX 守护进程(obexd/src/main.c)
-
gobex:OBEX 协议库(gobex/gobex.h)
-
plugins:OBEX Profile 插件(FTP、OPP、PBAP、MAP 等)
7.2 OBEX 协议层
gobex 核心数据结构(gobex/gobex.h):
cpp
struct gobex; // OBEX会话
struct gobex_packet; // OBEX数据包
struct gobex_header; // OBEX头部
// OBEX操作码
#define GOBEX_OP_CONNECT 0x80 // 连接请求
#define GOBEX_OP_DISCONNECT 0x81 // 断开请求
#define GOBEX_OP_PUT 0x02 // 推送请求
#define GOBEX_OP_GET 0x03 // 获取请求
#define GOBEX_OP_SETPATH 0x85 // 设置路径
#define GOBEX_OP_SESSION 0x87 // 会话命令
7.3 OBEX Profile 插件
|--------|---------|----------------------|
| 插件 | 功能 | 文件 |
| ftp.c | 文件传输协议 | obexd/plugins/ftp.c |
| opp.c | 对象推送协议 | obexd/plugins/opp.c |
| pbap.c | 电话簿访问协议 | obexd/plugins/pbap.c |
| map.c | 消息访问协议 | obexd/client/map.c |
| mas.c | 消息接入服务 | obexd/plugins/mas.c |
八、内核态协议栈架构
8.1 Linux 蓝牙内核子系统
Linux 内核中的蓝牙子系统位于 net/bluetooth/ 目录,核心组件包括:
|--------------|-------------------------|
| 文件 | 职责 |
| hci_core.c | HCI 核心层,管理控制器和连接 |
| hci_event.c | HCI 事件处理 |
| hci_sock.c | HCI Socket 接口 |
| l2cap_core.c | L2CAP 协议实现 |
| l2cap_sock.c | L2CAP Socket 接口 |
| smp.c | 安全管理协议 |
| gatt.c | GATT 协议实现 |
| mgmt.c | Management Interface 实现 |
8.2 用户态与内核态通信机制
Management Socket:
-
协议类型:
BTPROTO_HCI,通道HCI_CHANNEL_USER -
用途:高层管理操作(电源控制、配对、连接等)
-
优势:封装复杂 HCI 流程,提供原子操作
HCI Raw Socket:
-
协议类型:
BTPROTO_HCI,通道HCI_CHANNEL_RAW -
用途:直接发送/接收 HCI 命令和事件
-
优势:灵活性高,适合调试和特殊需求
L2CAP Socket:
-
协议类型:
BTPROTO_L2CAP -
用途:基于 L2CAP 的数据传输
-
支持:传统 BR/EDR 和 LE 连接
Socket 地址结构:
cpp
struct sockaddr_hci {
sa_family_t hci_family; // AF_BLUETOOTH
unsigned short hci_dev; // 设备索引
unsigned short hci_channel; // 通道号
};
九、核心工作流程解析
9.1 蓝牙适配器启动流程

说明:上述流程中,内核执行的具体 HCI 命令序列(如 HCI_Reset、HCI_Set_Event_Filter、HCI_Set_Event_Mask 等)取决于控制器的当前状态和内核版本。BlueZ 用户态代码通过 Management Interface 向内核发送高层请求,具体的 HCI 命令组装和执行由内核的 `hci_request_power()` 函数完成。
9.2 BLE 设备发现流程

9.3 GATT 服务发现流程

十、BlueZ 4.x vs 5.x 架构对比
10.1 架构差异对比表
|----------------|----------------------|----------------------|
| 对比维度 | BlueZ 4.x | BlueZ 5.x |
| 守护进程 | 多进程(hcid、sdpd、hidd等) | 单进程(bluetoothd) |
| 内核接口 | 直接 HCI 命令 | Management Interface |
| Profile 加载 | 静态编译 | 插件化动态加载 |
| BLE 支持 | 实验性,需补丁 | 原生完整支持 |
| 配置管理 | hcid.conf | main.conf |
| SDP 服务 | 独立 sdpd | 集成到 bluetoothd |
| API 稳定性 | 较差,频繁变更 | 稳定,向后兼容 |
| 调试能力 | 有限 | 丰富(btmon、完整日志) |
| IO 抽象 | GLib 绑定 | GLib/ELL 双后端 |
| OBEX 子系统 | 独立 obexd | 独立 obexd + gobex 库 |
10.2 Management Interface 带来的变革
BlueZ 4.x 的问题:
-
用户态需要处理大量 HCI 命令序列
-
错误处理复杂,容易出错
-
状态同步困难
-
难以支持新的控制器特性
BlueZ 5.x 的解决方案:
-
将复杂操作封装为原子管理命令
-
内核负责状态管理和命令序列执行
-
统一的事件通知机制
-
更好的错误处理和状态反馈
十一、Profile 层架构详解
11.1 Profile 实现模式
BlueZ 5.x 的 Profile 采用统一的实现模式,以音频 Profile 为例:
A2DP 实现(profiles/audio/a2dp.c):
-
a2dp_init():初始化 Profile -
a2dp_register():注册到 Profile Manager -
a2dp_connect():建立 A2DP 连接 -
a2dp_disconnect():断开连接 -
AVCTP/AVDTP 协议处理
GATT 实现(attrib/gatt.c):
-
GATT 客户端:
gatt_connect()、gatt_discover_primary() -
GATT 服务端:
gatt_server_new()、gatt_server_add_service()
11.2 Profile 与 D-Bus 的集成
每个 Profile 在注册时都会创建对应的 D-Bus 接口:
cpp
org.bluez.Media1 → profiles/audio/media.c
org.bluez.MediaPlayer1 → profiles/audio/player.c
org.bluez.A2DPSource1 → profiles/audio/source.c
org.bluez.A2DPSink1 → profiles/audio/sink.c
org.bluez.Input1 → profiles/input/device.c
org.bluez.Battery1 → profiles/battery/bas.c
org.bluez.Network1 → profiles/network/bnep.c
org.bluez.SAPServer1 → profiles/sap/server.c
十二、关键设计模式与工程实践
12.1 事件驱动架构
BlueZ 5.x 采用事件驱动架构,核心是 mainloop(src/shared/mainloop.c):
cpp
void mainloop_init(void); // 初始化事件循环
void mainloop_run(void); // 运行事件循环
void mainloop_quit(void); // 退出事件循环
// IO 事件
unsigned int mainloop_add_fd(int fd, unsigned int events,
mainloop_event_func_t func,
void *user_data, mainloop_destroy_func_t destroy);
// 定时器事件
unsigned int timeout_add(unsigned int msec, timeout_func_t func,
void *user_data, timeout_destroy_func_t destroy);
12.2 引用计数管理
BlueZ 大量使用引用计数管理对象生命周期:
cpp
struct mgmt *mgmt_ref(struct mgmt *mgmt);
void mgmt_unref(struct mgmt *mgmt);
struct bt_hci *bt_hci_ref(struct bt_hci *hci);
void bt_hci_unref(struct bt_hci *hci);
struct gatt_db *gatt_db_ref(struct gatt_db *db);
void gatt_db_unref(struct gatt_db *db);
12.3 队列数据结构
队列是 BlueZ 中最常用的数据结构,定义在 src/shared/queue.c):
cpp
struct queue *queue_new(void);
void queue_destroy(struct queue *queue, queue_destroy_func_t destroy);
bool queue_push_head(struct queue *queue, void *data);
bool queue_push_tail(struct queue *queue, void *data);
void *queue_pop_head(struct queue *queue);
void *queue_pop_tail(struct queue *queue);
void *queue_peek_head(struct queue *queue);
void *queue_peek_tail(struct queue *queue);
bool queue_isempty(struct queue *queue);
unsigned int queue_length(struct queue *queue);
12.4 双后端 IO 设计模式
BlueZ 的 IO 抽象层采用编译时选择的双后端设计:
cpp
configure --enable-ell → 使用 io-ell.c (ELL 后端)
configure --disable-ell → 使用 io-glib.c (GLib 后端)
这种设计允许 BlueZ 在资源受限的嵌入式环境中使用轻量级的 ELL 库,同时保持与传统桌面环境的兼容性。
十三、总结
13.1 架构设计亮点
-
分层清晰:用户态服务层、Profile层、共享库层、内核接口层,职责明确
-
接口统一:Management Interface 简化了用户态与内核态的交互
-
插件化设计:Profile 和功能模块动态加载,提升扩展性
-
事件驱动:基于 mainloop 的异步架构,性能优异
-
完整 BLE 支持:原生支持低功耗蓝牙协议栈
-
双后端 IO:GLib/ELL 双后端设计,适配不同环境
-
D-Bus 集成:统一的对象管理和进程间通信机制
-
独立 OBEX 子系统:完整的对象交换协议支持
13.2 源码阅读路线
cpp
入门阶段:
src/main.c → bluetoothd 启动流程
src/adapter.c → 适配器管理
src/device.c → 设备管理
进阶阶段:
src/shared/mgmt.c → Management Interface核心实现
src/shared/io-glib.c → IO抽象层实现
gdbus/gdbus.h → D-Bus抽象层
src/shared/att.c → ATT协议
高级阶段:
profiles/audio/a2dp.c → 音频Profile实现
attrib/gatt.c → GATT协议
lib/mgmt.h → 内核接口定义
obexd/src/main.c → OBEX子系统
13.3 工程实践建议
-
编译配置:根据需求选择 `configure` 参数,禁用不必要的 Profile
-
调试技巧:使用 `bluetoothd -d` 和 `btmon` 进行调试
-
开发模式:启用 `--enable-experimental` 测试新特性
-
资源优化:对于嵌入式设备,使用 ELL 后端并 `strip` 减小二进制体积
-
版本管理:不同版本部署在独立目录,通过环境变量切换
-
交叉编译:设置 `PKG_CONFIG_LIBDIR` 和 `PKG_CONFIG_SYSROOT_DIR`