间歇性出现‘不可连接’设备——Linux内核BLE疑似Bug
你的判断完全正确:Linux内核处理SCAN_RSP的全局变量导致BLE设备被错误标记为不可连接
问题根源分析
你定位的内核代码逻辑确实存在缺陷:
- 处理SCAN_RSP时,代码默认将设备标记为
NOT_CONNECTABLE - 随后尝试用
last_adv_flags变量覆盖该标志,但这个变量是全局的,并非按设备地址独立存储 - 在BLE设备密集的环境中,不同设备的ADV_IND和SCAN_RSP报文会交替被内核处理,
last_adv_flags很可能被其他设备的ADV_IND标志覆盖,导致当前设备的SCAN_RSP使用了错误的标志位
抓包证据对应
从你的btmon抓包可以明确看到:
- 目标设备(F4:B8:5E:64:02:55)的ADV_IND报文携带的Flags为
0x06,明确标记为可连接(LE General Discoverable Mode) - 但收到该设备的SCAN_RSP后,MGMT事件中Flags被设为
0x00000004(Not Connectable),这正是因为此时last_adv_flags已经被其他设备的ADV_IND覆盖,没有正确继承目标设备自身的可连接标志
验证与解决方向
- 代码验证:修改内核中
hci_event.c的相关逻辑,将last_adv_flags替换为按设备地址存储的哈希表,确保每个设备的SCAN_RSP只会继承自身的ADV_IND标志 - 临时规避:
- 延长BLE发现流程的持续时间,确保在停止发现前,目标设备的ADV_IND已经被正确处理并保留缓存
- 在代码中监听
interfacesRemoved回调时,触发一次短时间的重新发现,确认设备是否真的不可连接,避免误判
- 环境测试:在低BLE设备密度的环境中复现问题,若问题消失则进一步验证你的判断
内容的提问来源于stack exchange,提问作者meerlol
相关产品推荐
相关产品推荐

