这将是一个复杂的问题,但请耐心等待。在我向linux-bluetooth邮件列表提问之前,我想先在这里询问。
我正在开发一个树莓派设备,它会定期进行BLE发现并尝试连接多个设备。大多数情况下都很顺利,但特别是在BLE密集环境中,偶尔会因为找不到设备而失败。我已经调试了几周,最终发现问题出在这里:
- 连接到DBus以开始发现
- 找到设备,进行
interfacesAdded
回调,一切看起来都很好 - 停止发现
- 直接通过
interfacesRemoved
回调删除一些设备 - 我的代码没有得到它要查找的设备->用户不满意
底层发生的事情是,DBus从其缓存中删除所有被Bluez标记为“不可连接”的设备。也就是说,保留它们没有任何用处,因为你无法连接它们。但是...对于我正在寻找的设备来说,这并不正确,它被错误地标记为“不可连接”。
为了追踪问题,我创建了一个btmon
转储,显示设备在收到SCAN_RSP
后被报告为不可连接
。> HCI Event: LE Meta Event (0x3e) plen 38 #73 [hci0] 34.359921
LE Advertising Report (0x02)
Num reports: 1
Event type: Scan response - SCAN_RSP (0x04)
Address type: Public (0x00)
Address: F4:B8:5E:64:02:55 (Texas Instruments)
Data length: 26
Name (complete): BeeWi SmartLite
Peripheral Conn. Interval: 0x0028 - 0x0050
TX power: 0 dBm
RSSI: -42 dBm (0xd6)
@ MGMT Event: Device Found (0x0012) plen 40 {0x0001} [hci0] 34.360057
LE Address: F4:B8:5E:64:02:55 (Texas Instruments)
RSSI: -42 dBm (0xd6)
Flags: 0x00000004
Not Connectable
Data length: 26
Name (complete): BeeWi SmartLite
Peripheral Conn. Interval: 0x0028 - 0x0050
TX power: 0 dBm
但是在此之前,所有的ADV_IND
PDU都明确表明设备是可连接的,只有在接收到这个SCAN_RSP之后,才会报告为 不可连接
:
> HCI Event: LE Meta Event (0x3e) plen 27 #46 [hci0] 34.152817
LE Advertising Report (0x02)
Num reports: 1
Event type: Connectable undirected - ADV_IND (0x00)
Address type: Public (0x00)
Address: F4:B8:5E:64:02:55 (Texas Instruments)
Data length: 15
Flags: 0x06
LE General Discoverable Mode
BR/EDR Not Supported
Company: Texas Instruments Inc. (13)
Data: 06030108b0e408f7
RSSI: -43 dBm (0xd5)
@ MGMT Event: Device Found (0x0012) plen 31 {0x0001} [hci0] 34.152905
LE Address: 44:6E:FF:00:0D:65 (Resolvable)
RSSI: -74 dBm (0xb6)
Flags: 0x00000000
Data length: 17
Flags: 0x1a
LE General Discoverable Mode
Simultaneous LE and BR/EDR (Controller)
Simultaneous LE and BR/EDR (Host)
TX power: 9 dBm
Company: Apple, Inc. (76)
Type: Unknown (16)
Data: 01188898dc
> HCI Event: LE Meta Event (0x3e) plen 41 #47 [hci0] 34.156958
LE Advertising Report (0x02)
Num reports: 1
Event type: Connectable undirected - ADV_IND (0x00)
Address type: Random (0x01)
Address: FA:BD:8D:12:26:BF (Static)
Data length: 29
Name (short): P mesh
Flags: 0x04
BR/EDR Not Supported
128-bit Service UUIDs (partial): 1 entry
Vendor specific
RSSI: -47 dBm (0xd1)
@ MGMT Event: Device Found (0x0012) plen 29 {0x0001} [hci0] 34.157030
LE Address: F4:B8:5E:64:02:55 (Texas Instruments)
RSSI: -43 dBm (0xd5)
Flags: 0x00000000
Data length: 15
Flags: 0x06
LE General Discoverable Mode
BR/EDR Not Supported
Company: Texas Instruments Inc. (13)
Data: 06030108b0e408f7
所以,我非常怀疑Linux内核代码在处理SCAN_RSP
时是否存在漏洞。请看内核的这一部分:https://github.com/torvalds/linux/blob/48b1320a674e1ff5de2fad8606bee38f724594dc/net/bluetooth/hci_event.c#L6326
默认情况下,它为SCAN_RSP设置了NOT CONNECTABLE标志,并将使用先前的ADV_IND接收到的任何标志覆盖它。但是它似乎没有考虑到,在BLE重负载环境中,之前的ADV_IND可能是完全不同的设备。因此,偶尔会进入第一条路径,其中仅报告带有NOT_CONNECTABLE标志的设备。或者我在这里错过了什么吗?