Advertising Data — 是BLE设备在广播包中发送的结构化数据,用于标识自身及其服务。Bluetooth Core Specification 5.4(2023)定义了AD Structure格式:每个元素包含长度(1字节)、类型(1字节)和值(最多29字节)。该规范总共描述了30多种AD类型——从Flags和Local Name到Service UUID和Manufacturer Specific Data。正确打包advertising data对于设备与iOS、Android及其他平台的兼容性至关重要,同时也决定了广播的检测速度和能效。
要点
Advertising Data — 是BLE设备在广播包中发送的结构化字段集合,用于标识和描述其能力。Central通过扫描信道读取这些数据并做出决定:连接到设备、忽略它或通过Scan Response请求更多信息。
数据按照TLV(Type-Length-Value)原则组织:每个AD元素由三个字段组成。Length(1字节)——Value + Type的长度(即元素总长度减去Length的1字节)。Type(1字节)——来自Bluetooth Assigned Numbers的数据类型标识符。Value(N字节)——取决于类型的内容。
标准广播包最多可包含31字节的AD数据。如果不够,则使用Scan Response(额外31字节)或Extended Advertising(BLE 5.0,最多251字节)。广播包的前几个字节保留给PDU标头和设备地址——AD有效载荷从偏移位置开始。
每个AD元素在广播包中以Length(1字节)字段开始。Length的值表示Length之后的字节数——即Type + Value。例如,Length=3的元素意味着Length之后有1字节Type和2字节Value。当所有元素的长度之和达到广播数据的大小时,数据包结束。
| 字段 | 大小 | 描述 |
|---|---|---|
| Length | 1字节 | Type + Value的长度(不包括Length) |
| Type(AD Type) | 1字节 | 根据Bluetooth SIG的数据类型标识符 |
| Value | 0–29字节 | 特定类型的数据 |
Central解析器从标头后的第一个字节开始读取AD元素序列。如果Length=0,则忽略该元素,解析器移至下一个字节。重复的AD类型——一个数据包中多个具有相同Type的元素——是允许的,但Central可能根据协议栈的实现只处理第一个或最后一个。
重要规则:数据包中所有Length(+1)的总和不得超过广播数据的大小(广播PDU为31字节)。如果数据放不下,需要确定优先级——哪些AD类型对初始检测至关重要,哪些可以转移到Scan Response。
Flags(AD Type 0x01) — 每个BLE设备广播包中的强制元素。占用3字节:Length(0x02)、Type(0x01)、Value(1字节位标志)。标志定义设备的检测模式和能力。Core Specification建议在每个广播包中包含Flags。
主要标志:LE Limited Discoverable Mode(位0)——设备在有限时间内可被检测到,LE General Discoverable Mode(位1)——设备持续可被检测到,BR/EDR Not Supported(位2)——设备仅支持LE,Simultaneous LE and BR/EDR(位3)——支持两种模式。对于纯BLE设备,强制组合为:LE General Discoverable + BR/EDR Not Supported。
错误的Flags值是设备在iOS或Android中无法被检测到的常见原因之一。例如,如果BR/EDR Not Supported标志未设置,iOS可能尝试通过经典蓝牙而非BLE进行连接。请检查Flags值,使用蓝牙分析仪(nRF Connect、Wireshark)调试广播包时。
Local Name(AD Type 0x08或0x09) — BLE设备的显示名称。类型0x08(Shortened Local Name)——缩短名称,当完整名称无法放入广播包时使用。类型0x09(Complete Local Name)——设备的完整名称。名称的最大长度为248字节,但在标准广播包中最多只有28字节可用。
如果设备名称超过广播包中的可用空间,建议:将缩短名称放入广播PDU(类型0x08),将完整名称放入Scan Response(类型0x09)。iOS在扫描时显示来自广播包的名称,完整名称在连接或Scan Response后可用。
选择设备名称时需考虑:过长的名称会占用本可用于Service UUID或其他重要数据的空间。建议名称长度为8–16个字符。避免非标准字符和空格——某些BLE协议栈可能无法正确处理它们。
Service UUID(AD Type 0x02–0x07) — 最重要的AD类型之一,使Central能够在无需连接设备的情况下确定设备提供哪些服务。Bluetooth SIG根据大小定义了多种UUID传输格式:0x02(Incomplete 16-bit)、0x03(Complete 16-bit)、0x04(Incomplete 32-bit)、0x05(Complete 32-bit)、0x06(Incomplete 128-bit)、0x07(Complete 128-bit)。
16位UUID(2字节)——标准Bluetooth SIG服务,例如0x180F(Battery Service)、0x180A(Device Information)。128位UUID(16字节)——开发者定义的自定义服务。16位UUID在AD中仅占用4字节(Length + Type + 2字节UUID),而128位占用18字节。如果需要在单个数据包中传输多个自定义UUID,它们可能无法放入31字节。
如果并非传输设备的所有UUID,而仅传输对过滤最重要的UUID,建议使用Incomplete(0x02/0x04/0x06)类型。完整UUID列表通过Scan Response或连接后的GATT Discovery传输。这为广播包中的其他AD类型节省了空间。
Manufacturer Specific Data(AD Type 0xFF) — 最灵活的AD类型,旨在传输制造商的自定义数据。Value的前2个字节是Company Identifier Code,由Bluetooth SIG分配(例如Apple为0x004C,Samsung为0x0075)。其余字节是以制造商定义的格式表示的任意数据。
Apple将Manufacturer Data用于iBeacon:Company ID(0x004C)、Beacon类型(0x0215)、UUID(16字节)、Major(2字节)、Minor(2字节)、TX Power(1字节)。Google使用类似的格式用于Eddystone。IoT设备制造商通常将传感器读数或设备状态放入Manufacturer Data。
// 在Central上解析Manufacturer Specific Data
function parseManufacturerData(data) {
const view = new DataView(data.buffer);
// 公司标识码(前2字节)
const companyId = view.getUint16(0, true);
// 检查Apple iBeacon
if (companyId === 0x004C) {
return parseIBeacon(view);
}
return null;
}
使用Manufacturer Data时,务必遵守大小限制:整个广播包31字节减去强制AD类型。对于Apple iBeacon,整个数据包占用30字节,仅留给Flags(3字节)空间。对于Eddystone——最多31字节。紧凑的自定义格式可以在4–8字节中包含温度、湿度或气压。
正确打包advertising data — 是在31字节的有限空间中放置最大有用信息的艺术。策略取决于设备的用途:信标需要标识符,IoT传感器需要读数,健身追踪器需要名称和服务UUID。一般原则:Central需要做出决定的速度越快,广播PDU中的数据越关键。
推荐策略:广播PDU(前31字节)——Flags(3字节)+ 一个16位Service UUID(4字节)+ 缩短名称(最多12个字符=14字节)+ Manufacturer Data(最多10字节)。Scan Response(后31字节)——完整名称(剩余部分)+ 额外的Service UUID + TX Power Level(3字节)。这种分配使Central能够根据UUID快速过滤设备。
| 优先级 | AD类型 | 大小 | 放置位置 |
|---|---|---|---|
| 1(强制) | Flags(0x01) | 3字节 | 广播PDU |
| 2(过滤) | Service UUID(0x02–0x03) | 4+字节 | 广播PDU |
| 3(标识) | Local Name(0x08–0x09) | 2+字节 | 广播PDU(缩短) |
| 4(附加) | TX Power Level(0x0A) | 3字节 | Scan Response |
| 5(自定义) | Manufacturer Data(0xFF) | 4+字节 | 广播PDU / Scan Response |
| 6(完整数据) | 其他UUID | 按大小 | Scan Response |
调试advertising data是BLE设备开发的必经阶段。使用nRF Connect(Nordic Semiconductor)或带蓝牙分析仪的Wireshark查看数据包的原始数据。检查所有AD类型是否具有正确的Length、长度之和是否不超过31字节以及Flags是否针对您的使用场景正确设置。
常见问题
蓝牙控制器协议栈会拒绝超过限制的数据或不发送数据包。在组装广播包时检查AD元素的总长度。如果数据放不下——将部分数据移至Scan Response或使用限制为251字节的Extended Advertising(BLE 5.0)。
可以,通过Manufacturer Specific Data(0xFF)。将读数打包在4–8字节中:例如温度(2字节定点格式)、湿度(2字节)、电池电压(2字节)。这种方法使Central能够在无需连接的情况下读取数据,从而节省能源。
对于自定义服务,使用128位UUID(AD Type 0x06–0x07)。如果UUID无法放入广播PDU(一个UUID占用16字节),将其移至Scan Response或使用缩短的Incomplete(0x06)格式仅指示前一个或两个UUID。
Complete — 数据包中列出了设备的所有服务UUID。Incomplete — 仅部分UUID(通常是最重要的)。Central不能将Incomplete视为完整列表,但会将其用于快速过滤。完整列表在GATT Discovery后可用。
常见原因——Flags(0x01)不正确。确保BR/EDR Not Supported位已设置。第二个原因——广播包中缺少Service UUID(iOS按UUID过滤)。第三个——设备广播频率太低(iOS期望间隔不超过1000毫秒)。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。