目录
可收获
一、广播的基本概念
1.1 向哪里发送广播数据包?
1.2 发送广播数据包的周期取多久?
1.3 广播数据包里包含哪些信息?
PDU 头
PDU 有效负载
二、扫描的基本概念
2.1 到什么地方去扫描?
2.2 多久扫描一次?一次扫描多久?
2.3 扫描的过程中需要做什么?
三、Wireshark抓ble数据包
3.1 概览数据包:时间、来源等等
3.2 验证一次广播在37-39三个信道广播数据
3.3 实抓广播数据包 // 注:BLE设备只广播情况下抓取的数据
可收获
1.BLE 广播的基本概念
-向哪里发送广播数据包?
-发送广播数据包的周期?
-广播数据包里包含哪些信息?物理层数据包:前导码、访问地址、PDU、CRC
-详解广播PDU
2.BLE 扫描的基本概念
-到什么地方去扫描?
-多久扫描一次?一次扫描多久?
-扫描的过程中需要做什么?
3.*补充:wireshark抓ble数据包,为调试连接问题打下基础
-分析链路层 (Link Layer)数据:从“接入地址”开始,到“CRC”结束的原始数据以及分析
-实际看到广播事件确实在 37、38、39 三个信道依次发送相同包
-掌握链路层协议的核心字段PDU Type、Length等
广播 (Advertising) 与扫描 (Scanning) 是 BLE 设备在进入连接前在设备发现 (Device Discovery) 阶段的工作状态。下面,我们先了解与广播有关的基本概念。
一、广播的基本概念
广播是设备通过蓝牙天线,向外发送广播数据包的过程。由于广播者在广播时并不知道环境中是否存在接收方,也不知道接收方会在什么时候启动,所以需要周期性地发送广播数据包,直到有设备响应。在上述过程中,对于广播者来说存在以下几个问题,让我们一起来思考一下
1.1 向哪里发送广播数据包?
蓝牙核心规范规定为 2.4 GHz频段。此频段是一个全球可用的免费无线电频段,这也意味着 2.4 GHz频段非常拥挤,可能会与其他无线通信协议发生数据冲突。
蓝牙技术联盟为了解决数据冲突的问题,在 BLE 上也应用了自适应跳频技术 (Adaptive Frequency Hopping, AFH) ,该技术可以判断 RF 信道的拥挤程度,通过跳频避开拥挤的 RF 信道,以提高通信质量。
在BLE 4.2 标准中, RF 信道分为两种类型,如下
| 类型 | 数量 | 编号 | 作用 |
| 广播信道 (Advertising Channel) | 3 | 37-39 | 用于发送广播数据包和扫描响应数据包 |
| 数据信道 (Data Channel) | 37 | 0-36 | 用于发送数据通道数据包 |
广播者在广播时,会在 37-39 这三个广播信道中进行广播数据包的发送。在三个广播信道的广播数据包均发送完毕后,可以认为一次广播结束,广播者会在下一次广播时刻到来时重复上述过程。
BLE 4.2 标准中,广播数据包允许搭载最多 31 字节广播数据;称为 “Legacy ADV”
BLE 5.0 标准中,支持最多 255 字节广播数据; 称为 “Extended ADV”
1.2 发送广播数据包的周期取多久?
蓝牙标准中给出了一个明确的参数定义,即广播间隔 (Advertising Interval)。广播间隔可取的范围为 20 ms 到 10.24 s ,取值步长为 0.625 ms。 // P1341,步长 后续在代码中解释
广播间隔的取值决定了广播者的可发现性 (Discoverability) 以及设备功耗。当广播间隔取得太长时,广播数据包被接收方接收到的概率就会变得很低,此时广播者的可发现性就会变差。 同时,广播间隔也不宜取得太短,因此频繁发送广播数据需要消耗更多的电量。所以,广播者需要在可发现性和能耗之间进行取舍,根据应用场景的需求选择最合适的广播间隔。
如果在同一空间中存在两个广播间隔相同的广播者,那么有概率出现重复性的撞包 (Packet Collision) 现象,即两个广播者总是在同一时刻向同一信道发送广播数据。由于广播是一个只发不收的过程,广播者无法得知是否发生了广播撞包。为了降低上述问题的发生概率,广播者应在每一次广播事件后添加 0-10 ms 的随机时延。
1.3 广播数据包里包含哪些信息?
在 Bluetooth LE 4.2 标准给出了广播数据包的格式定义,如下图所示: 物理层数据包:前导码、访问地址、PDU、CRC (重点是PDU,Protocol Data Unit)
看起来非常复杂,让我们来逐层分解。广播数据包的最外层包含四个部分,分别是:
| 序号 | 名称 | 字节数 | 功能 |
| 1 | 预置码 (Preamble) | 1 | 特殊的比特序列,用于设备时钟同步 // 物理层同步头,不属于链路层帧的逻辑部分。无需太关注 |
| 2 | 访问地址 (Access Address) | 4 | 标记广播数据包的地址 // 区分广播包和数据包,广播通道(37、38、39):固定值 0x8E89BED6(小端格式发送)。当设备扫描广播通道时,只有收到这个地址的包,才会继续解析后面的 PDU |
| 3 | 协议数据单元 (Protocol Data Unit, PDU) | 2-39 | 有效数据的存放区域 |
| 4 | 循环冗余校验和 | 3 | 用于循环冗余校验 |
在蓝牙低功耗(BLE)的链路层(Link Layer)中,PDU 指的是“协议数据单元”,简单理解:整个广播数据包就像一封信,PDU 就是信纸(实际内容),而前导码、访问地址和 CRC 是信封(辅助传送)
所以我们重点了解PDU,不要带偏了哦!
PDU 为有效数据存放的区域,其结构如下:
| 序号 | 名称 | 字节数 |
| 1 | 头 (Header) | 2 |
| 2 | 有效负载 (Payload) | 0-37 |
PDU 头
PDU 头中含有较多信息,可以分为以下六个部分
| 序号 | 名称 | 比特位数 | 备注 |
| 1 | PDU 类型 (PDU Type) | 4 | 下面详解 |
| 2 | 保留位 (Reserved for Future Use, RFU) | 1 | |
| 3 | 通道选择位 (Channel Selection Bit, ChSel) | 1 | 标记广播者是否支持 LE Channel Selection Algorithm #2 通道选择算法 |
| 4 | 发送地址类型 (Tx Address, TxAdd) | 1 | 0/1 分别表示公共地址(即 IEEE 分配的全球唯一地址)/随机地址(用于保护隐私) |
| 5 | 接收地址类型 (Rx Address, RxAdd) | 1 | 0/1 分别表示公共地址/随机地址,对于非定向广播,此位无意义,通常置 0。 |
| 6 | 有效负载长度 (Payload Length) | 8 |
PDU 类型位反映了设备的广播行为。在蓝牙标准中,共有以下三对广播行为
可连接 (Connectable)与不可连接 (Non-connectable)
是否接受其他设备的连接请求
可扫描 (Scannable)与不可扫描 (Non-scannable)
是否接受其他设备的扫描请求
不定向 (Undirected)与定向 (Directed)
是否发送广播数据至指定设备
上述广播行为可以组合成以下四种常见的广播类型,对应四种不同的 PDU 类型(ADV_IND 对应 Advertising Indication)
| 可连接? | 可扫描? | 不定向? | PDU 类型 | 作用 |
| 是 | 是 | 是 | ADV_IND | 最常见的广播类型,可连接的非定向广播。设备可以被任何扫描者连接。 |
| 是 | 否 | 否 | ADV_DIRECT_IND | 可连接的定向广播。只允许一个指定的设备连接。 |
| 否 | 否 | 是 | ADV_NONCONN_IND | 不可连接的非定向广播。仅广播数据,不接受连接。可作为信标设备, |
| 否 | 是 | 是 | ADV_SCAN_IND | 一般用于广播数据包长度不足的情况,此时可以通过扫描响应向外发送额外的数据可扫描的非定向广播。允许扫描器请求更多数据。作为信标设备, |
PDU 有效负载
PDU 有效负载也分为两部分
| 序号 | 名称 | 字节数 | 备注 |
| 1 | 广播地址 (Advertisement Address, AdvA) | 6 | 广播设备的 48 位蓝牙地址 |
| 2 | 广播数据 (Advertisement Data, AdvData) | 0-31 | 由若干广播数据结构 (Advertisement Data Structure) 组成 |
先看广播地址,即蓝牙地址,可以分为
| 类型 | 说明 |
| 公共地址 (Public Address) | 全球范围内独一无二的固定设备地址,厂商必须为此到 IEEE 组织注册并缴纳一定费用 |
| 随机地址 (Random Address) | 随机生成的地址 |
随机地址又根据用途分为两类 // 这部分简单了解一下就好了,很少用
| 类型 | 说明 |
| 随机静态地址 (Random Static Address) | 可以随固件固化于设备,也可以在设备启动时随机生成,但在设备运行过程中不得变更;常作为公共地址的平替 |
| 随机私有地址 (Random Private Address) | 可在设备运行过程中周期性变更,避免被其他设备追踪 |
若使用随机私有地址的设备要与其他受信任的设备通信,则应使用身份解析秘钥 (Identity Resolving Key, IRK) 生成随机地址,此时其他持有相同 IRK 的设备可以解析并得到设备的真实地址。此时,随机私有地址又可以分为两类
| 类型 | 说明 |
| 可解析随机私有地址 (Resolvable Random Private Address) | 可通过 IRK 解析得到设备真实地址 |
| 不可解析随机私有地址 (Non-resolvable Random Private Address) | 完全随机的地址,仅用于防止设备被追踪,非常少用 |
经过一层一层的解析,终于到我们真正的广播数据了!
一个广播数据结构的格式定义如下:
| 序号 | 名称 | 字节数 | 备注 |
| 1 | 数据长度 (AD Length) | 1 | |
| 2 | 数据类型 (AD Type) | n | 大部分数据类型占用 1 字节 |
| 3 | 数据 (AD Data) | (AD Length - n) |
下节将在代码中写广播数据,并用NRF connect 抓取广播包数据。
二、扫描的基本概念
我们一起思考一下下面三个问题
2.1 到什么地方去扫描?
对于 Bluetooth LE 4.2 设备: 对于广播来说,广播者只会在广播信道,即编号为 37-39 的三个信道发送广播数据; 所以相应的,扫描者只需在广播信道接收广播数据包即可。// 主动扫描时,也是在这些广播信道上发送SCAN_REQ并接收SCAN_RS。(下文会解释主动/被动扫描)
2.2 多久扫描一次?一次扫描多久?
第二个问题分别指向扫描窗口 (Scan Window) 和 扫描间隔 (Scan Interval) 概念。
扫描窗口:扫描者在同一个 RF 信道持续接收蓝牙数据包的持续时间,例如扫描窗口参数设定为 50 ms 时,扫描者在每个 RF 信道都会不间断地扫描 50 ms。
扫描间隔:相邻两个扫描窗口开始时刻之间的时间间隔,所以扫描间隔必然大于等于扫描窗口。
下图在时间轴上展示了扫描者的广播数据包接收过程,其中扫描者的扫描间隔为 100 ms ,扫描窗口为 50 ms ;广播者的广播间隔为 50 ms ,广播数据包的发送时长仅起到示意作用。可以看到,第一个扫描窗口对应 37 信道,此时扫描者恰好接收到了广播者第一次在 37 信道发送的广播数据包,以此类推。
广播与扫描时序示意图
2.3 扫描的过程中需要做什么?
从目前的介绍来看,似乎广播过程中广播者只发不收,扫描过程中扫描者只收不发。事实上,扫描行为分为以下两种
被动扫描 (Passive Scanning)
扫描者只接收广播数据包
主动扫描 (Active Scanning)
扫描者在接收广播数据包以后,还向可扫描广播者发送扫描请求 (Scan Request)
可扫描广播者在接收到扫描请求之后,会广播扫描响应 (Scan Response) 数据包,以向感兴趣的扫描者发送更多的广播信息。扫描响应数据包的结构与广播数据包完全一致,区别在于 PDU 头中的 PDU 类型不同。
在广播者处于可扫描广播模式、扫描者处于主动扫描模式的场景下,广播者和扫描者的数据发送时序变得更加复杂。对于扫描者来说,在扫描窗口结束后会短暂进入 TX 模式,向外发送扫描请求,随后马上进入 RX 模式以接收可能的扫描响应;对于广播者来说,每一次广播结束后都会短暂进入 RX 模式以接收可能的扫描请求,并在接收到扫描请求后进入 TX 模式,发送扫描响应。
扫描请求的接收与扫描响应的发送
三、Wireshark抓ble数据包
3.1 概览数据包:时间、来源等等
3.2 验证一次广播在37-39三个信道广播数据
第一次:
第二次:
第三次:
3.3 实抓广播数据包 // 注:BLE设备只广播情况下抓取的数据
1字节 前导码 物理层同步头,不属于链路层帧的逻辑部分。无需太关注
4字节 地址
34字节 PDU负载
3字节 CRC
PUD负载数据: