Characteristic 属性详解:Properties、Permissions、Value 与 CCCD
这一章,我们聊聊 Characteristic 的四个核心属性。
Properties、Permissions、Value、CCCD。这四个东西,说白了就是 GATT 服务的「四根柱子」。你调联调,调来调去,最后出问题,十有八九是这四根柱子没对齐。
我刚开始做 BLE 开发那会儿,就吃过这个亏。写了一个服务,手机端死活写不进去数据。查了两天,最后发现是 Permissions 配错了。嗯,从那以后,我再也不敢小看这几个属性了。
1. Properties —— 告诉对端「我能干什么」
Properties 是一个 8 位的 bitmask。它定义了这个 Characteristic 支持哪些操作。说白了,就是告诉对端:我能读、能写、能通知、还是能指示。
| Bit | 属性 | 含义 |
|---|---|---|
| 0 | Broadcast | 支持广播 |
| 1 | Read | 支持读操作 |
| 2 | Write Without Response | 支持无应答写 |
| 3 | Write | 支持有应答写 |
| 4 | Notify | 支持通知(无确认) |
| 5 | Indicate | 支持指示(有确认) |
| 6 | Authenticated Signed Writes | 支持签名写 |
| 7 | Extended Properties | 扩展属性描述符存在 |
2. Permissions —— 谁可以操作
Permissions 是 GATT 层的访问控制。它决定了:谁可以读?谁可以写?需不需要加密?需不需要配对?
你想想看,Properties 只是「声明」,Permissions 才是「执行」。你 Properties 开了 Write,但 Permissions 没配,那写操作照样失败。
Permissions 通常分为三类:
- Access Permissions:读、写、读写
- Authentication Permissions:是否需要配对/绑定
- Authorization Permissions:是否需要应用层授权
3. Value —— 真正的数据
Value 就是 Characteristic 里存的那个值。它可以是任何长度,但协议推荐不超过 20 字节(MTU 默认 23 字节,减去 3 字节头)。
当然,MTU 可以协商。我做过一个项目,MTU 协商到 512 字节,Value 直接塞了 200 字节的传感器数据。但要注意:长包传输,对端不一定支持。
Value 的读写,受 Properties 和 Permissions 双重约束。举个例子:
// 伪代码示例:定义一个 Characteristic
characteristic = {
uuid: "0x2A37", // 心率测量
properties: READ | NOTIFY, // 可读、可通知
permissions: READ, // 只允许读
value: [0x00, 0x00], // 初始值
cccd: null // CCCD 由协议栈自动管理
}
这里有个细节:Value 的初始值,一定要合理。我见过有人把初始值设成 0xFF,结果手机端一读,以为设备出故障了。嗯,这种问题,调试起来很烦人。
4. CCCD —— 通知/指示的开关
CCCD 的全称是 Client Characteristic Configuration Descriptor。它是一个描述符,UUID 固定为 0x2902。
它的作用很简单:客户端(手机)通过写 CCCD,告诉服务端「我要不要收通知/指示」。
CCCD 的值只有两个字节:
| 值 | 含义 |
|---|---|
| 0x0000 | 关闭通知和指示 |
| 0x0001 | 开启通知(Notify) |
| 0x0002 | 开启指示(Indicate) |
| 0x0003 | 同时开启通知和指示(不推荐) |
5. 四者的关系 —— 一张图说清楚
下面这张图,是我自己画的关系图。每次做联调,我都会对着它过一遍。
6. 联调时的检查清单
每次联调前,我都会过一遍这个清单。你可以直接拿去用:
- Properties 配对了没有?—— 特别是 Notify 和 Indicate,别漏了
- Permissions 和 Properties 一致吗?—— 开了 Notify,Permissions 要开 Read
- Value 初始值合理吗?—— 别设成 0xFF 这种奇怪的值
- CCCD 有没有被正确初始化?—— 默认应该是 0x0000
- 手机端有没有写 CCCD?—— 很多问题出在手机端没写 CCCD
7. 总结一下
Properties 是「声明」,Permissions 是「控制」,Value 是「数据」,CCCD 是「开关」。四者缺一不可。
联调时,按这个顺序查:Properties → Permissions → Value → CCCD。别跳步,跳步容易漏。
我见过太多人,一上来就查代码,查了两天发现是 CCCD 没配。嗯,这种问题,其实一张表就能搞定。