Linux BlueZ 5.65 BLE GATT服务加密后指示功能失效问题
在Linux环境使用BlueZ 5.65搭建BLE GATT服务,基于官方gatt-service.c编写自定义工具并与BlueZ源码一同编译,通过BlueZ的DBus/gdbus接口与bluetoothd进程通信。已配置两个特性:
- 支持读取/指示的特性,配置加密认证属性:
"encrypt-authenticated-read", "encrypt-authenticated-indicate" - 支持写入的特性,配置加密认证属性:
"encrypt-authenticated-write"
对应的代码片段:
static const char *tx_characteristic_properties[] = { "encrypt-authenticated-read", "encrypt-authenticated-indicate", NULL }; static const char *rx_characteristic_properties[] = { "encrypt-authenticated-write", NULL };
已通过bluetoothctl完成手动配对,配对后可正常读写特性,但激活加密后指示功能失效。手机激活指示时,btmon返回如下错误日志:
> ACL Data RX: Handle 68 flags 0x02 dlen 9 #25387 [hci0] 75486.664071 ATT: Write Request (0x12) len 4 Handle: 0x009b Type: Client Characteristic Configuration (0x2902) Data: 0200 Indication (0x02) < ACL Data TX: Handle 68 flags 0x00 dlen 9 #25388 [hci0] 75486.664606 ATT: Error Response (0x01) len 4 Write Request (0x12) Handle: 0x009b Error: Write Not Permitted (0x03) > HCI Event: Number of Completed Packets (0x13) plen 5 #25389 [hci0] 75486.784052 Num handles: 1 Handle: 68 Address: 66:65:18:91:30:D5 (Resolvable) Identity type: Public (0x00) Identity: A8:79:8D:EB:B9:8B (OUI A8-79-8D) Count: 1
经排查,gatt-database::parse_chrc_flags为CCC(Client Characteristic Configuration)设置了BT_ATT_PERM_WRITE_AUTHEN权限,但gatt-server::check_permissions检查时要求必须设置BT_ATT_PERM_WRITE位,导致写入CCC失败。手动添加BT_ATT_PERM_WRITE和BT_ATT_PERM_READ权限后指示功能恢复正常,疑惑为何仅设置BT_ATT_PERM_WRITE_AUTHEN无法通过权限检查?
BlueZ的GATT权限检查逻辑中,认证/加密权限(如BT_ATT_PERM_WRITE_AUTHEN)是基础权限(BT_ATT_PERM_WRITE)的附加条件,而非替代。
具体细节:
- 在
gatt-server.c的check_permissions函数中,权限验证会先检查操作对应的基础权限位是否存在(比如写操作必须要有BT_ATT_PERM_WRITE),再校验附加的认证/加密权限是否满足。 - 仅配置
encrypt-authenticated-indicate时,parse_chrc_flags只会给CCC属性设置BT_ATT_PERM_WRITE_AUTHEN,但未设置基础的BT_ATT_PERM_WRITE位,直接触发权限检查失败,返回"Write Not Permitted"错误。
对于CCC属性(用于控制通知/指示),BlueZ要求必须同时具备基础读写权限,再叠加认证/加密权限。正确的做法是:
- 对于支持指示的特性,除了配置
encrypt-authenticated-read和encrypt-authenticated-indicate,还需要显式添加基础的read和write属性,让parse_chrc_flags同时设置BT_ATT_PERM_READ、BT_ATT_PERM_WRITE以及对应的认证权限位。
总结:BlueZ的权限模型是基础权限 + 增强权限的组合,单独设置增强权限无法通过基础操作的权限校验,必须同时配置对应的基础权限。
内容的提问来源于stack exchange,提问作者Kim

