GATT CharacteristicGATT 中表示一个具体状态值、测量值或控制入口的数据项,由 characteristic declaration、characteristic value 和可选 GATT Descriptor 组成。

核心问题

Service 只说明“这是电池服务”或“这是设备信息服务”,还需要更细的单个数据项来表达“电量是多少”“固件版本是什么”“写入哪个字段能触发动作”。Characteristic 就是这些可访问数据项的单位。

核心机制

Characteristic declaration 是一个 attribute,类型为 0x2803,其 value 包含三部分:

Characteristic Declaration Value =
  properties        # 1 octet bit field
  value_handle      # 2 octets
  characteristic_uuid

示例:

0x0002  type=0x2803  value={properties=read|notify, value_handle=0x0003, uuid=0x2A19}
0x0003  type=0x2A19  value=85
0x0004  type=0x2902  value=0x0000

这里真正的电量值在 0x0003,不是 declaration 本身。properties 告诉客户端可以对 value 执行哪些 GATT 过程,例如 read、write、notify、indicate。value_handle 告诉客户端读写哪个 handle。characteristic_uuid 告诉客户端这个值是什么类型。

工程用途

  • 表示设备状态:电池电量、温度、门锁状态。
  • 表示控制入口:写入配置、命令、阈值或模式。
  • 表示事件流:通过 notification/indication 推送变化。
  • 承载自定义小协议:一个 write characteristic + 一个 notify characteristic 是常见设计。

边界与常见坑

  • 不要读写 declaration handle 当成 value handle:声明 handle 只描述 characteristic,真正数据在 value handle。
  • properties 不是 permissions:properties 声明支持哪些过程,permissions 决定当前连接是否满足安全条件。
  • value 字节结构要另查规范:UUID 只能告诉类型,具体位域、单位、端序和缩放常由 service spec 或厂商协议定义。
  • notify 需要 CCCD:仅 characteristic properties 支持 notify 不够,client 通常还要写 descriptor 订阅。
  • 一个 UUID 可以在多个 service 中出现:解释 characteristic 时要结合所属 service。

相关术语

外部参考