协议栈之 BLE 和 经典蓝牙
目录
- 蓝牙技术全面解析: 从协议栈到工程实践
- 1. 蓝牙技术概述
- 1.1 蓝牙技术发展时间线
- 1.2 经典蓝牙 VS BLE
- 1.3 应用场景分析
- 2. 蓝牙协议栈架构
- 2.1 经典蓝牙协议栈
- 2.2 BLE 协议栈
- 2.3 协议栈对比分析
- 3. 物理层与射频技术
- 3.1 2.4GHz ISM频段
- 3.2 解调过程详解
- 4. 链路层与数据包处理
- 4.1 BLE链路层状态机
- 4.2 广播包结构详解
- 4.3 跳频机制
- 4.4 错误检测与纠正
- 5. HCI层详解
- 5.1 HCI架构与作用
- 5.2 HCI传输层
- 5.3 HCI数据包格式
- 5.4 实际HCI数据解析
- 6. GAP与设备发现
- 6.1 GAP角色定义
- 6.2 广播数据结构
- 6.3 Manufacturer Specific Data详解
- 6.4 设备发现流程
- 7. GATT与服务架构
- 7.1 GATT层次结构
- 7.2 ATT协议基础
- 7.3 标准GATT服务
- 7.4 Characteristic Properties详解
- 8. 经典蓝牙协议详解
- 8.1 RFCOMM协议
- 8.2 SDP服务发现协议
- 9. SPP协议详解
- 9.1 SPP架构
- 9.2 SPP工作流程
- 10. HFP协议详解
- 10.1 HFP架构
- 10.2 HFP工作流程
蓝牙技术全面解析: 从协议栈到工程实践
1. 蓝牙技术概述
蓝牙是一种短距离无线通信技术,主要用于设备间数据交换。它起源于1998年,由爱立信等公司推动,现在已成为物联网和智能设备的核心。蓝牙分为经典蓝牙(高带宽)和BLE(低功耗),各自有独特应用。理解发展历史,能帮你们把握技术脉络。
1.1 蓝牙技术发展时间线
timelinetitle 蓝牙技术发展时间线1998 : 蓝牙1.0规范发布2001 : 蓝牙1.1 改进互操作性2003 : 蓝牙1.2 抗干扰增强2004 : 蓝牙2.0+EDR 提升数据率2007 : 蓝牙2.1+EDR 简化配对2009 : 蓝牙3.0+HS 高速传输2010 : 蓝牙4.0 引入BLE2013 : 蓝牙4.1 改进共存2014 : 蓝牙4.2 增强安全2016 : 蓝牙5.0 四倍范围2019 : 蓝牙5.1 方向检测2020 : 蓝牙5.2 LE Audio2021 : 蓝牙5.3 连接增强2023 : 蓝牙5.4 广播增强
1.2 经典蓝牙 VS BLE
两种蓝牙技术的设计理念截然不同: 经典蓝牙注重高带宽替换有线,BLE聚焦低功耗物联网。以下表格对比了关键特性,帮助你们快速区分。
特性 | 设计目标 | 功耗 | 数据率 | 连接时间 | 网络拓扑 | 应用场景 |
---|---|---|---|---|---|---|
经典蓝牙 (BR/EDR) | 替代有线连接, 高带宽应用 | 高 (100mW 级别) | 1-3 Mbps | 秒级 | 点对点, 星形网络 | 音频, 输入设备, 文件传输 |
低功耗蓝牙 (BLE) | 物联网设备, 超低功耗 | 极低 (uW 级别) | 125 Kbps - 2 Mbps | 毫秒级 | 星形, 网状, 广播 | 传感器, 可穿戴, 信标 |
1.3 应用场景分析
经典蓝牙典型应用:
- 音频设备: 耳机、音响、车载系统(想想无线耳机如何传输高品质音乐)
- 输入设备: 键盘、鼠标、游戏手柄
- 数据传输: 文件传输、打印、调试接口
BLE典型应用:
- 可穿戴设备: 智能手表、健身追踪器(低功耗是关键)
- 健康监测: 心率带、血压计、体重秤
- 智能家居: 温湿度传感器、智能锁、照明控制
- 信标应用: 室内定位、广告推送、资产追踪
小贴士: 选择技术时,先问自己:功耗重要吗?如果是,选BLE;需要高速度,选经典。
2. 蓝牙协议栈架构
协议栈是蓝牙的“骨架”,分层设计让复杂系统变简单。从底层物理层到应用层,每层有特定职责。经典蓝牙更复杂,适合多媒体;BLE简化,适合低功耗。
2.1 经典蓝牙协议栈
各层职责:
- Profile Layer: 应用级协议, 定义具体应用的数据格式和交互流程(例如音频Profile)
- RFCOMM: 串口仿真协议, 为上层应用提供虚拟串口接口
- SDP: 服务发现协议, 用于查询和发布设备服务信息
- L2CAP: 逻辑链路控制协议, 提供数据分段、重组和多路复用
- HCI: 主机控制接口, 标准化的硬件抽象层
- Link Manager: 链路管理, 处理连接建立、认证、加密等
- Baseband: 基带处理, 时序控制、跳频、错误纠正
- Radio: 射频层, 2.4GHz 信号的发送和接收
2.2 BLE 协议栈
BLE 协议栈特点:
- 简化架构: 相比经典蓝牙, 层次更少, 复杂度降低(更适合小设备)
- 统一服务模型: 所有应用都基于GATT服务
- 安全集成: SMP 安全管理协议深度集成
- 灵活连接: 支持广播、扫描、连接多种工作模式
2.3 协议栈对比分析
层次 | 经典蓝牙 | BLE | 主要区别 |
---|---|---|---|
应用层 | 多种 Profile | 统一 GATT 服务 | BLE 更简化统一 |
中间层 | RFCOMM/SDP | ATT/SMP | BLE 专门优化 |
传输层 | L2CAP (复杂) | L2CAP (简化) | BLE 简化 |
接口层 | HCI | HCI | 基本相同 |
控制层 | Link Manager | GAP | BLE 状态机简化 |
底层 | Baseband | Link Layer | BLE 时序优化 |
小贴士: 开发时,从HCI层入手,能抽象硬件差异,便于移植。
3. 物理层与射频技术
物理层是蓝牙的“基础”,处理信号传输。小白们,记住2.4GHz频段易干扰,所以设计时需优化抗干扰。
3.1 2.4GHz ISM频段
蓝牙工作在2.4GHz ISM (Industrial, Scientific, Medical) 免许可频段, 具体范围为2400-2485MHz。
频段特性:
- 全球通用: 大部分国家都开放此频段
- 免许可: 无需申请即可使用
- 共享频段: WiFi、微波炉等设备也使用此频段
- 干扰复杂: 需要良好的抗干扰设计
信道分配:
- 经典蓝牙: 79个数据信道, 2MHz间隔
- BLE: 40个信道, 其中37个数据信道, 3个广播信道(37,38,39)
3.2 解调过程详解
解调 (Demodulation) 过程:
- 射频信号接收: 天线接收2.4GHz的GFSK调制信号
- 下变频: 混频器将射频信号转换为中频或基带信号
- ADC采样: 将模拟信号转换为数字信号
- 数字解调: 从频率变化中恢复0/1数字序列
- 帧同步: 识别前导码和接入地址
- 包解析: 解析出ADV_IND包的完整内容
解调时序:
射频信号 → 解调器: GFSK调制信号 → 包解析器: 数字比特流 → 链路层: ADV_IND包
链路层内部: CRC校验 → 地址过滤
小贴士: 实际调试时,用频谱仪看信号强度,避免干扰源。
4. 链路层与数据包处理
链路层管理数据包传输和状态转换。小白们,这层是蓝牙“心脏”,理解状态机能帮你们debug连接问题。
4.1 BLE链路层状态机
BLE设备在链路层有5个主要状态, 状态转换决定了设备的行为模式。
状态详解:
- Standby: 待机状态, 设备空闲, 可以转换到任何其他状态
- Advertising: 广播状态, 设备周期性发送广播包
- Scanning: 扫描状态, 设备监听广播包
- Initiating: 发起连接状态, 向目标设备发送连接请求
- Connection: 连接状态, 两个设备建立了数据链路
4.2 广播包结构详解
小白们,ADV_IND是BLE(低功耗蓝牙)中最常见的广播包类型,用于设备发现和简单数据传输。下面我结合长度限制,简单扩展讲解它的结构、关键字段,以及与内部AD Structure的区别。整个包像一个“数据包裹”:外层有同步和校验,内层有地址和内容。重点是广播数据限于31字节,但有扩展方法。我会说明它们是不是同一个东西、区别在哪,以及涉及的协议栈和流程。
ADV_IND是什么?(缩写、所属和协议栈):
- 缩写: ADV_IND全称Advertising Indication,意思是“可连接的非定向广播指示”。它是广播包的一种类型,允许设备广播信息并可被连接。
- 所属: 专属于BLE(低功耗蓝牙,Bluetooth Low Energy,从蓝牙4.0引入),不属于经典蓝牙(BR/EDR)。经典蓝牙有自己的发现机制,不用ADV_IND。
- 协议栈位置: 位于BLE协议栈的链路层(Link Layer),但涉及物理层(射频传输)和上层如GAP(解析内容)。不是独立“无协议栈”,而是链路层定义的空口包(air interface packet),从物理层发送到上层应用。
ADV_IND包整体结构
ADV_IND包在LE 1M物理层(常见类型)上传输,总长度有限(广播数据最多31字节)。包从射频信号发出,接收端从物理层解调后,在链路层解析。为什么有“奇怪的东西”如前导码?因为这是完整空口包,不仅是“6字节MAC + 31字节数据”的简化版——前导码等确保传输可靠(同步、过滤、校验),否则信号在空中易丢失或干扰。这些字段在协议栈低层处理,用户编程时通常只关注MAC和广播数据。
每个字段简单解释(为什么有这些?与流程对应):
- 前导码 (1字节, LE 1M): 0/1交替序列(如0xAA),物理层用于接收器同步频率/时序(像“信号铃声”)。没有它,包无法被正确捕捉——这是为什么不止“6+31字节”的原因。
- 接入地址 (4字节): 固定值0x8E89BED6,链路层用于确认是蓝牙广播(过滤非蓝牙噪声)。它确保包不被误认。
- PDU Header (2字节): 包的“说明标签”,包括类型和长度(详见表格)。链路层用它知道包类型和数据多长。
- 设备地址 (6字节): 发送设备的MAC地址(公共或随机)。这是用户可见的“发件人”,GAP层用它识别设备。
- 广播数据 (0-31字节): 核心内容,如设备名或UUID。由AD Structures组成。长度由Header指定,这是“31字节限制”的部分。
- CRC (3字节): 24位校验码,链路层基于Header到广播数据计算,确保无错误。没有它,包易损坏。
PDU Header简单详解:
位域 | 长度 | 含义 | 简单说明(与包对应) |
---|---|---|---|
PDU Type | 4 bits | 包类型 | 0000=ADV_IND(确认是广播包,与整体用途对应) |
RFU | 1 bit | 保留 | 固定0(无特殊作用) |
ChSel | 1 bit | 信道选择 | 通常0(与跳频对应,详见4.3) |
TxAdd | 1 bit | 发送地址类型 | 0=公共,1=随机(对应设备地址如何解释) |
RxAdd | 1 bit | 接收地址类型 | 广播中固定0(无特定接收者,与广播性质对应) |
Length | 6 bits | 载荷长度 | 设备地址+广播数据总字节(6+X, X=0-31,与广播数据直接对应) |
RFU | 2 bits | 保留 | 固定00(保持2字节完整) |
与AD Structure的区别和关系(是不是同一个东西?):
- 不是同一个东西:ADV_IND包格式是整个包的“大框架”(物理/链路层,包含前导码等传输必需字段);AD Structure是广播数据内部的“小格式”(LTV: Length + Type + Value, GAP层)。包格式是外层传输容器,AD Structure是内层内容组织。
- 区别:
- 包格式固定(e.g., 总是前导码 + 接入地址 + Header + 6字节地址 + 最多31字节数据 + CRC),关注低层可靠(如同步/校验);AD Structure灵活(多个小块,每个Length表示Type+Value长度,Type如0x09=设备名)。
- 包的Length(Header中)对应整个广播数据总长(0-31);AD Structure的Length对应单个小块(e.g., Length=0x09表示Type+Value=9字节)。
- “奇怪字段”如前导码是物理层必需(同步信号),不属于用户数据;6+31是简化view,但完整包更多以确保空中传输。
- 关系: AD Structure填充广播数据区。广播数据=多个AD Structure累加(总<=31)。解析时,链路层给GAP整个广播数据,GAP循环读每个AD Structure。
长度限制与扩展方法(为什么限31?如何解决?):
- 限制原因: BLE设计为低功耗,31字节限减少传输时间/能耗。规范定义:AdvData最大31字节(蓝牙4.x)。
- 实际可用: 通常28-30字节(留空间给必需AD如Flags)。整个包更长(~47字节,包括Header等)。
版本与限制表格:
蓝牙版本 | 广播数据最大长度 | 扫描响应最大长度 | 备注 |
---|---|---|---|
Bluetooth 4.x | 31字节 | 31字节 | 标准限制,总可达62字节(广播+响应) |
Bluetooth 5.x | 扩展达255字节 | 255字节 | 支持扩展广告包 |
扩展方法:
- 扫描响应: 加31字节(总62),响应SCAN_REQ请求。
- 分段广播: 数据分成多包,周期发送。
- BLE5.x扩展: 用扩展包到255字节。
- 优化: 压缩数据或自定义格式(e.g., 合并UUID)。
涉及的协议栈和处理流程(简单版):
- 协议栈对应: 物理层(前导码/信号调制)→ 链路层(接入地址/Header/CRC/地址/数据)→ GAP层(AD Structure解析)→ 应用层(用数据如显示名)。
- 发送流程: 应用准备AD Structures → GAP组广播数据 → 链路层加Header/地址/CRC → 物理层加前导码/调制广播(37/38/39信道)。
- 接收流程: 物理层同步前导码/解调 → 链路层查接入地址/校验CRC/解析Header(Type=ADV_IND, Length提取数据) → GAP循环AD Structures(读Length-Type-Value) → 应用处理(e.g., Type=0x09 → Value=设备名)。
广播数据示例(LTV,与包对应):
uint8_t adv_data[] = {0x02, 0x01, 0x06, // Flags: Length=2, Type=0x01, Value=0x06
0x07, 0x09, ‘D’, ‘e’, ‘v’, ‘i’, ‘c’, ‘e’}; // Name: Length=7, Type=0x09, Value=“Device”
- 总10字节,与Header Length对应(6+10=16)。
- 不是“同一个东西”——这是AD Structure,填充包的广播数据区。
小贴士: 限31是为低功耗;用nRF工具抓包,看完整结构(不只6+31)。超限?试扫描响应或BLE5。测试时,弱信号易丢前导码,导致包丢失。
4.3 跳频机制
经典蓝牙跳频:
- 79个信道, 每秒1600次跳频
- 伪随机跳频序列, 基于主设备时钟和地址
- 抗干扰能力强, 适合嘈杂环境
BLE信道使用:
4.4 错误检测与纠正
CRC校验:
- CRC-24多项式: x²⁴ + x¹⁰ + x⁹ + x⁶ + x⁴ + x³ + x + 1
- 初始值基于接入地址计算
- 检测能力: 可检测所有1-3位错误, 大部分多位错误
自动重传请求(ARQ):
- 仅在连接模式下使用
- 接收端发送ACK/NACK
- 发送端根据响应决定是否重传
- 广播模式无重传机制, 依靠重复发送
小贴士: 跳频是抗干扰神器,实际项目中监控信道利用率。
5. HCI层详解
HCI是桥梁,连接主机和控制器。小白们,这层标准化接口,让你们不用关心芯片差异。
5.1 HCI架构与作用
HCI的价值:
- 灵活部署: Host和Controller可以分离或集成
- 标准接口: 统一的命令和事件格式
- 硬件抽象: 屏蔽不同蓝牙芯片的差异
- 便于调试: 可以在HCI层监控所有蓝牙活动
5.2 HCI传输层
UART传输(最常用):
传输参数:
- 波特率:115200-3000000 bps
- 数据位:8位
- 停止位:1位
- 奇偶校验:无
- 流控制:RTS/CTS硬件流控
5.3 HCI数据包格式
HCI Command格式:
字段 | 长度 | 描述 |
---|---|---|
Packet Type | 1字节 | 0x01 (Command) |
Opcode | 2字节 | 命令操作码 |
Parameter Length | 1字节 | 参数长度 |
Parameters | 0-255字节 | 命令参数 |
HCI Event格式:
字段 | 长度 | 描述 |
---|---|---|
Packet Type | 1字节 | 0x04 (Event) |
Event Code | 1字节 | 事件类型 |
Parameter Length | 1字节 | 参数长度 |
Parameters | 0-255字节 | 事件参数 |
5.4 实际HCI数据解析
HCI_LE_Set_Advertising_Data命令:
- Opcode: 0x2008
- OGF: 0x08 (LE Controller Commands)
- OCF: 0x008 (LE Set Advertising Data)
- Total Length: 32
- Advertising_Data_Length: 29
AD数据解析:
HCI_LE_Set_Advertising_Enable命令:
- Opcode: 0x200a
- Advertising_Enable: Enabled (0x01)
HCI_LE_Advertising_Report事件:
- Event: HCI_LE_Meta_Event (0x3E)
- Subevent: HCI_LE_Advertising_Report (0x02)
- Event_Type: Non Connectable Undirected
- Address: 0x0b-cf-bc-27-22-36 (Random)
- RSSI: -60 dBm
小贴士: 用Wireshark抓HCI日志,快速定位问题。
6. GAP与设备发现
GAP定义设备行为和角色。小白们,这层处理发现和连接,广播是BLE低功耗关键。
6.1 GAP角色定义
角色组合应用:
- 信标设备: Broadcaster only
- 扫描设备: Observer only
- 传感器: Broadcaster + Peripheral
- 手机: Observer + Central
- 网关: Central + Peripheral
6.2 广播数据结构
Advertisement Data (AD) 格式:
[Length] [AD Type] [AD Data]
1字节 | 1字节 | N字节
常用AD Type:
AD Type | 名称 | 用途 |
---|---|---|
0x01 | Flags | 设备发现模式和能力 |
0x02 | 不完整16位UUID列表 | 部分服务UUID |
0x03 | 完整16位UUID列表 | 所有服务UUID |
0x08 | 短设备名称 | 缩短的设备名 |
0x09 | 完整设备名称 | 完整设备名 |
0xFF | 厂商特定数据 | 厂商自定义格式 |
6.3 Manufacturer Specific Data详解
什么是Manufacturer Specific Data?
Manufacturer Specific Data(厂商特定数据)是BLE广播包中的一个标准字段,允许设备厂商在标准蓝牙框架内传输自定义数据。
基本概念:
- ADType=0xFF,标识这是厂商数据
- 前2字节是CompanyID,标识数据格式的定义者
- 后续字节是厂商自定义的数据格式
- 任何厂商都可以定义自己的数据格式
用途分析:
- 设备识别: 通过特定的数据格式识别自家设备
- 状态传输: 传输设备状态信息(电量、温度等)
- 控制指令: 在广播中嵌入控制命令
- 兼容扩展: 在标准框架内实现自定义功能
实际应用示例:
6.4 设备发现流程
完整的设备发现时序:
小贴士: 广播间隔影响功耗和响应速度,调优时从100ms开始测试。
7. GATT与服务架构
GATT是BLE数据模型的核心,一切应用基于服务和特征。小白们,想象成数据库:服务是表,特征是字段。
7.1 GATT层次结构
层次说明:
- Profile: 完整的应用场景定义
- Service: 功能相关的特征集合
- Characteristic: 具体的数据项
- Descriptor: 特征的元数据描述
属性结构:
字段 | 长度 | 描述 |
---|---|---|
Handle | 2字节 | 属性句柄(地址) |
Type | 2/16字节 | 属性类型(UUID) |
Value | 变长 | 属性值 |
Permissions | - | 访问权限 |
7.2 ATT协议基础
ATT (Attribute Protocol) 是GATT的底层协议, 定义了属性的基本操作。
7.3 标准GATT服务
设备信息服务(Device Information Service):
- Service UUID: 0x180A
- Manufacturer Name String (0x2A29): Properties: Read
- Model Number String (0x2A24): Properties: Read
- Serial Number String (0x2A25): Properties: Read
- Hardware Revision String (0x2A27): Properties: Read
- Firmware Revision String (0x2A26): Properties: Read
电池服务(Battery Service):
- Service UUID: 0x180F
- Battery Level (0x2A19): Properties: Read, Notify
- Client Characteristic Configuration (0x2902)
心率服务(Heart Rate Service):
- Service UUID: 0x180D
- Heart Rate Measurement (0x2A37): Properties: Notify
- Body Sensor Location (0x2A38): Properties: Read
- Heart Rate Control Point (0x2A39): Properties: Write
- Client Characteristic Configuration (0x2902)
7.4 Characteristic Properties详解
Property | 值 | 描述 | 用途 |
---|---|---|---|
Broadcast | 0x01 | 可广播 | 在广播包中包含值 |
Read | 0x02 | 可读取 | 客户端读取值 |
Write Without Response | 0x04 | 写入无响应 | 快速写入,不等待确认 |
Write | 0x08 | 写入 | 写入并等待响应 |
Notify | 0x10 | 通知 | 服务器主动发送,无需确认 |
Indicate | 0x20 | 指示 | 服务器主动发送,需要确认 |
Authenticated Signed Writes | 0x40 | 认证签名写入 | 带数字签名的写入 |
Extended Properties | 0x80 | 扩展属性 | 在描述符中定义额外属性 |
小贴士: Notify适合实时数据如心率,节省功耗。
8. 经典蓝牙协议详解
经典蓝牙协议更丰富,适合音频等。小白们,这部分复杂,但理解后能扩展应用。
8.1 RFCOMM协议
RFCOMM(Radio Frequency Communication)在蓝牙上模拟RS-232串口,为应用提供简单的流式接口。
RFCOMM帧格式:
字段 | 长度 | 描述 |
---|---|---|
Address | 1字节 | DLCI + C/R + EA |
Control | 1字节 | 帧类型 |
Length | 1-2字节 | 数据长度 |
Information | 变长 | 用户数据 |
FCS | 1字节 | 帧校验序列 |
8.2 SDP服务发现协议
SDP(Service Discovery Protocol)允许设备发布和发现可用服务。
9. SPP协议详解
SPP (Serial Port Profile) 是经典蓝牙中模拟串口传输的协议,常用于数据交换。小白们,这是个基础Profile,理解它能帮你们实现可靠的点对点通信。
9.1 SPP架构
SPP关键特性:
- 基于RFCOMM,提供虚拟串口
- 支持流式数据传输
- 常用于调试和文件传输
9.2 SPP工作流程
SPP参数表格:
参数 | 描述 | 典型值 |
---|---|---|
波特率 | 数据传输速度 | 9600-115200 bps |
数据位 | 每个字节位数 | 5-8 |
停止位 | 帧结束标志 | 1-2 |
奇偶校验 | 错误检测 | 无/奇/偶 |
小贴士: SPP适合简单数据链路,结合HCI日志调试传输问题。
10. HFP协议详解
HFP (Hands-Free Profile) 是经典蓝牙中用于免提通话的协议,支持音频和控制命令。小白们,这在车载和耳机中很常见,学好能处理实时语音应用。
10.1 HFP架构
HFP关键特性:
- 基于RFCOMM传输AT命令
- SCO链路处理音频
- 支持呼叫控制和音量调节
10.2 HFP工作流程
HFP命令表格:
命令 | 描述 | 示例响应 |
---|---|---|
AT+BRSF | 支持功能查询 | +BRSF: |
AT+CIND | 指示器查询 | +CIND: (call),… |
AT+BCC | 建立连接 | +BCS: |
小贴士: HFP结合A2DP能实现完整音频系统,测试时模拟呼叫场景验证稳定性。