GAP与广播机制:角色、模式与数据格式
GAP(Generic Access Profile)是BLE协议栈的“门面”。说白了,它决定了你的设备怎么被发现、怎么跟别人建立连接。我刚开始做BLE项目时,总觉得GAP就是个配置参数,后来踩了不少坑才明白——GAP角色选错了,广播数据配不对,设备可能根本连不上。
GAP角色与模式
BLE设备在GAP层有四种角色,每种角色对应不同的行为模式。我习惯把它们分成两组:
| 角色 | 典型设备 | 核心行为 |
|---|---|---|
| Broadcaster(广播者) | 信标、温度传感器 | 只发广播,不接收连接 |
| Observer(观察者) | 扫描仪、网关 | 只收广播,不发起连接 |
| Peripheral(外设) | 手环、心率带 | 发广播,等待连接 |
| Central(中心) | 手机、平板 | 扫描广播,发起连接 |
这里有个容易混淆的点:Broadcaster和Peripheral都会发广播,但前者不响应连接请求,后者会。我在项目中遇到过客户把信标设成Peripheral角色,结果手机一直弹配对框——其实人家只想收个UUID而已。
广播类型:三种核心模式
BLE广播分三种类型,每种类型决定了扫描者能做什么。嗯,这里直接看表:
| 广播类型 | 可连接 | 可扫描 | 典型场景 |
|---|---|---|---|
| 可连接广播 | 是 | 是 | 外设等待中心连接 |
| 不可连接广播 | 否 | 否 | 信标、广播数据 |
| 可扫描广播 | 否 | 是 | 需要扫描响应的场景 |
你可能会问:可扫描广播有什么用?它允许扫描者发送扫描请求,广播者回复扫描响应数据。这样可以在不建立连接的情况下,多传一些数据。我曾经用这个模式做室内定位——广播包放主要UUID,扫描响应放附加的RSSI校准值,省了一次连接开销。
广播数据格式:AD Structure
广播数据不是随便塞的。BLE协议规定,广播数据由若干个AD Structure组成,每个AD Structure的结构如下:
Length (1 byte) | AD Type (1 byte) | AD Data (Length-1 bytes)
举个例子,假设你要广播一个16位Service UUID 0x180D(心率服务):
0x03 0x03 0x0D 0x18
| | |____|
| | └─ UUID (小端序)
| └─ AD Type = 0x03 (完整16位UUID列表)
└─ Length = 3 (包含Type和Data)
常见的AD Type我列一下:
- 0x01 — Flags(广播标志,必填)
- 0x02/0x03 — 16位Service UUID(不完整/完整)
- 0x06/0x07 — 128位Service UUID
- 0x08/0x09 — 本地名称(缩短/完整)
- 0xFF — 厂商自定义数据
广播间隔与占空比
广播间隔决定了设备多久发一次广播包。间隔越短,被发现越快,但功耗越高。间隔越长,省电,但扫描者可能要等更久才能发现你。
广播间隔的范围是20ms到10.24s,步进0.625ms。实际项目中,我常用的几个值:
| 场景 | 推荐间隔 | 占空比 | 说明 |
|---|---|---|---|
| 快速发现(配对) | 20~50ms | 高 | 用户等待时用,功耗大 |
| 常规广播 | 100~500ms | 中 | 日常连接场景 |
| 低功耗广播 | 1~5s | 低 | 电池供电设备 |
| 信标 | 100ms~1s | 中低 | 根据定位精度调整 |
占空比 = 广播包发送时间 / 广播间隔。举个例子,一个广播包大约376μs(37字节@1Mbps),间隔100ms时占空比约0.376%。间隔20ms时占空比约1.88%——功耗差了5倍。
GAP与广播机制知识体系
下面这张图把GAP角色、广播类型、数据格式和间隔的关系串起来了:
这张图从顶层GAP角色开始,往下分广播类型,再到底层数据格式和间隔参数。你想想看,选角色决定了广播类型,广播类型决定了数据怎么封装,而间隔和占空比直接影响功耗和发现速度——环环相扣。