BLE 广播包数据格式解析说明 ...... 矜辰所致
前言
报文格式 是 蓝牙学习必备理论基础,本文来讲一讲蓝牙广播报文格式 以及 在 沁恒微蓝牙芯片代码中如何设置广播报文 。
我是矜辰所致,全网同名,尽量用心写好每一系列文章,不浮夸,不将就,认真对待学知识的我们,矜辰所致,金石为开!
一、 广播包格式
BLE 广播报文(Advertising Packet)在空中的完整格式分 4 段,总共 47 字节(BLE 4.x/5.x 都一样),用户能改的只有中间 31 字节 Payload(下图浅绿色部分),其余由链路层自动拼好。
1.1 格式解析
我们先上一张整体的广播包示意图(后面会详细分析):

我们再给加上解释说明:

看完整体的格式包,我们再重点关注一下我们应用时候可以修改的 Payload 部分, 这部分由若干「AD Structure」拼接而成,「AD Structure」是有一定格式的,我们在代码中定义广播包的时候就是要按照这种格式填写我们想要的广播数据。
「AD Structure」 格式如下:
Len(1 B) + Type(1 B) + Data(n B)
整包总长度 ≤ 31 B,不足补 0 ,如下图:

对于每个 「AD Structure」,我们重点要知道的是类型,AD Type(包括 0x01 ~ 0xFF 的全部定义)由 Bluetooth SIG(蓝牙技术联盟)统一分配和维护,大家需要用什么可以网上查询,这里放出部分常用 AD Type(保持更新):
| AD Type | Value (Hex) | 描述 |
|---|---|---|
| Flags | 0x01 | 广播出自己蓝牙某些特性 |
| Incomplete List of 16-bit Service UUIDs | 0x02 | 只放部分 16-bit UUID,不完全 |
| Complete List of 16-bit Service UUIDs | 0x03 | 完全的16-bit UUID |
| Incomplete List of 32-bit Service UUIDs | 0x04 | 部分 32-bit UUID |
| Complete List of 32-bit Service UUIDs | 0x05 | 完全的32-bit UUID |
| Incomplete List of 128-bit Service UUIDs | 0x06 | 部分 128-bit |
| Complete List of 128-bit Service UUIDs | 0x07 | 完全 128-bit |
| Shortened Local Name | 0x08 | 设备简称 |
| Complete Local Name | 0x09 | 设备全名 |
| TX Power Level | 0x0A | 广播出自己的射频发射功率 |
| Simple Pairing Option OOB Tags | 0x0D ~ 0x0F | 广播出安全管理带外标签(本文忽略) |
| Security Manager TK Value | 0x10 | 广播出带外方式配对绑定时的 TK(本文忽略) |
| Security Manager OOB Flags | 0x11 | 广播出带外特性标志(本文忽略) |
| Slave Connection Interval Range | 0x12 | 广播出自己已希望的连接参数范围 |
| ServiceData | 0x16 | 服务数据 |
| Appearance | 0x19 | 外观类型(鼠标/键盘/游戏柄等 HID 设备必放) |
| Advertising Interval | 0x1A | 广播出当前广播间隔(单位 0.625 ms) |
| PB-ADV | 0x22 | Mesh 配网阶段专用广播承载 |
| Manufacturer Specific Data | 0xFF | 广播出厂商信息(用户可以放自定义数据) |
根据上面表格,我们如果想设置短的 16bit UUID:
0x03 0x02 (UUID低8位) (UUID高8位)
0x03 0x02 0xE1 0xFF
如果想设置完整的名字:
(名字长度加+1) 0x09 (名字,自己取,自己算长度)
0x07 0x09 'S' 'i' 'm' 'p' 'l' 'e'
至此,广播包格式详细大家已经完全清楚了。
1.2 蓝牙广播 和 扫描响应
为什么讲蓝牙广播要提到扫描响应?
扫描响应的报文格式和蓝牙广播一摸一样。
我们先来说一下什么是扫描响应,广播是我们从机主动发出的报文,扫描响应是从机在收到主机扫描请求后 回复的响应报文(前提是它支持回复扫描响应),如下图:

扫描响应有什么作用?
我们知道蓝牙广播包只有 31 个字节可以用户自定义,如果我们广播数据放不下,想放更多的数据,我们可以写在 扫描响应里面,在手机扫描过程中,会一并作为广播包加入解析(下面会有示例说明)。
二、 代码示例
我们完成了理论说明,我们来看看在实际工程中广播包的体现,本次测试说明使用的是沁恒微蓝牙芯片 CH585 ,示例为官方的从机示例 Peripheral 。
2.1 示例效果
我们只要关注的点就是在工程中peripheral.c 文件里面,有两个数组就是广播包的定义其中 scanRspData[] 对应扫描响应,advertData[] 对应广播包,我们烧录好程序观察一下现象:

通过图片大家应该可以很直观的理解,然后配合上文说明的 「AD Structure」 格式解析,应该都能明白怎么回事。
大家完全可以根据我们上文的说明,设置成自己想要的广播数据。
2.2 设置广播类型
这里需要额外说明的是,上面说到过不是所有的广播包都支持扫描响应,在 CH58x 的 EVT 是使用:
GAPRole_SetParameter(GAPROLE_ADV_EVENT_TYPE, 1, &advEventType);
来设置广播类型的,但是示例中的从机初始化环节并没有设置GAPROLE_ADV_EVENT_TYPE 这个类型的操作,那是因为默认就是GAP_ADTYPE_ADV_IND类型:

我们可以继续查看一下,官方有哪些类型的定义:

上个表格就一目了然了:
| 宏定义(CH585 SDK) | 实际值 | 广播类型 | 支持连接? | 支持扫描响应? | 典型用途 |
|---|---|---|---|---|---|
GAP_ADTYPE_ADV_IND | 0x00 | 通用广播(可连接 / 非定向) | ✅ | ✅ | 最常见,外设等人来连 |
GAP_ADTYPE_ADV_HDC_DIRECT_IND | 0x01 | 高占空比定向广播(可连接 / 定向) | ✅ | ❌ | 快速重连,不响应扫描 |
GAP_ADTYPE_ADV_SCAN_IND | 0x02 | 可扫描广播(不可连接 / 非定向) | ❌ | ✅ | 只广播数据,允许扫描但不连 |
GAP_ADTYPE_ADV_NONCONN_IND | 0x03 | 不可连接广播(不可连接 / 非定向) | ❌ | ❌ | 纯 beacon,不连也不扫 |
GAP_ADTYPE_ADV_LDC_DIRECT_IND | 0x04 | 低占空比定向广播(可连接 / 定向) | ✅ | ❌ | 功耗更低定向包,同样不响应扫描 |
说明:沁恒微代码把「高占空比」和「低占空比」拆成两条宏,其实都属于同一个 PDU 类型 ADV_DIRECT_IND 。
所以我们想设置广播类型,只要在初始化的时候,加上这两句代码:
uint8_t advEventType = GAP_ADTYPE_ADV_IND;
GAPRole_SetParameter(GAPROLE_ADV_EVENT_TYPE, 1, &advEventType);
2.3 中文广播包
设置中文广播包,首先要知道中文的编码,蓝牙名称采用的编码格式位 UTF-8 格式的,一个汉字 UTF-8 编码格式占用 3 个字节。 我们实际生产编码的时候一般都需要使用工具。
我们测试的时候可以通过这个在线工具生成,网址如下:
https://www.jyshare.com/front-end/695/

然后我们把这个编码按照格式写入广播包定义数组里面,效果如下:

三、 BLE分析仪抓包
广播报文不复杂,我们这里也是简单上一下蓝牙分析仪抓包的效果:


通过 Adv PDU Type 我们就可以看出空中包的类型,简单解释一下:
SCAN_REQ
- 主设备的扫描请求,主设备发送SCAN_REQ请求从机响应,用于获取从设备信息(包括设备名字,或者服务UUID,及其它如厂家特定格式的信息等)
SCAN_RSP
- 从设备的响应,作为广播包的补充,从设备可以给主设备更多的广播数据,依赖此包补充数据,比如说,有些设备在广播包里面没有设备名字,这个时候就可以把设备名字放在这个包里面发给主设备。
ADV_NONCONN_IND
- 不可连接广播包
- 用于设备广播自身信息(如名称、服务类型等),
数据格式:包含广播地址(AdvA)和广播数据(AdvData),其中AdvData由多个AD结构组成,每个AD结构包含长度、类型和数据字段。
典型设备:iBeacon等需要周期广播但无需连接的设备。
ADC_IND
- 通用广播包,可被任何设备接收并响应。
数据格式:与 ADV_NONCONN_IND 类似,但类型标识符不同(报文类型低4位为0000,此处的类型就是在第一张图中粉色部分 Header 中的 4 Bit TYPE 类型)。
AD_EXT_IND
- 这个本不是我们本文讨论的范围,但是上图抓包工具有了,就补充说明一下,AD_EXT_IND 是 BLE5 扩展广播的“索引包”,BLE5 Extended Advertising(辅助广播)的“头包”,只在 primary advertising PHY 上发送,用来告诉扫描者“后面还有一份更长的 payload 在 auxiliary packet 上”。
BLE5 要发 >31 B 的广播或想用 2 M / coded PHY 时,链路层会先把 Header 做成 AD_EXT_IND,发到 37/38/39 信道上(1 M PHY)。
3.1 广播报文类型
上面既然说到了 Adv PDU Type ,那就补充说明一下,这部分的表示是在协议种的这个部分:

上个表格:
| PDU Type | 名称 | 简述 |
|---|---|---|
| 0b0000 (0) | ADV_IND | 可连接、可扫描、非定向 |
| 0b0001 (1) | ADV_DIRECT_IND | 可连接、定向、不扫描 |
| 0b0010 (2) | ADV_NONCONN_IND | 不可连接、不扫描 |
| 0b0011 (3) | SCAN_REQ | 扫描请求 |
| 0b0100 (4) | SCAN_RSP | 扫描响应 |
| 0b0101 (5) | CONNECT_IND | 连接请求 |
| 0b0110 (6) | ADV_SCAN_IND | 可扫描、不可连接 |
| 0b0111 (7) | ADV_EXT_IND | 扩展广播头包(指向 AUX 包 |
| 0b1000 (8) | AUX_ADV_IND | 扩展广播真正负载 |
抓包工具怎么看:

结语
本文我们说明了一下蓝牙广播包的报文格式,以及使用沁恒微蓝牙芯片如何设置广播包,通过本文学习,相信大家能够应对所有广播数据修改的问题 。
在蓝牙设备连接上以后,连接过程数据交互也会有自己的协议包,这个在后期有机会也会写一篇文中给大家分析。
好了,本文就到这里。谢谢大家!
-
蓝牙芯片
+关注
关注
17文章
474浏览量
48101 -
广播
+关注
关注
1文章
333浏览量
24272 -
BLE
+关注
关注
13文章
822浏览量
66658
发布评论请先 登录
荣小菜补钙记第43期:报文合成与解析之字的合成与分解
CAN报文解析需要知道DBC的哪些信息排序方式
tcp报文格式详解
怎样抓取低功耗蓝牙BLE4.2空中数据包的详细资料分析
一种基于粗糙集聚类的报文格式推断方法
Path延时测量相关报文格式介绍
BLE 蓝牙空中报文格式与解析(广播包)
评论