我遇到一个问题,一台机器上的BLE主动扫描会导致另一台机器的连接问题。如果有人能解释原因,并就如何修复提出任何建议,我会很惊讶。
我已经将我的代码的粗略版本分解为简单的脚本。
在机器1上:
sudo stdbuf -oL hcidump -X |tee hci.log &
sudo hcitool lewlclr
sudo hcitool lewladd 68:C9:0B:xx:xx:01
sudo hcitool lewladd 68:C9:0B:xx:xx:02
sudo hcitool lewladd 68:C9:0B:xx:xx:03
sudo hcitool lewladd 68:C9:0B:xx:xx:04
sudo hcitool lewladd 68:C9:0B:xx:xx:05
sudo hcitool lewladd 68:C9:0B:xx:xx:06
while true; do sudo hcitool lecc --whitelist; if [ $? == 1 ] ; then sleep 20; else sleep 1; sudo hcitool ledc 64 ; fi; done
以上将运行没有问题
然而,在另一台机器上运行以下程序后,我遇到了连接问题。
sudo hcitool lescan --duplicates
从hci日志来看,一个正常的判断看起来像:
< HCI Command: LE Create Connection (0x08|0x000d) plen 25
bdaddr 00:00:00:00:00:00 type 0
interval 4 window 4 initiator_filter 1
own_bdaddr_type 0 min_interval 15 max_interval 15
latency 0 supervision_to 3200 min_ce 1 max_ce 1
> HCI Event: Command Status (0x0f) plen 4
LE Create Connection (0x08|0x000d) status 0x00 ncmd 1
> HCI Event: LE Meta Event (0x3e) plen 19
LE Connection Complete
status 0x00 handle 64, role master
bdaddr 68:C9:0B:xx:xx:xx (Public)
< HCI Command: Disconnect (0x01|0x0006) plen 3
handle 64 reason 0x13
Reason: Remote User Terminated Connection
> HCI Event: Command Status (0x0f) plen 4
Disconnect (0x01|0x0006) status 0x00 ncmd 1
> HCI Event: Disconn Complete (0x05) plen 4
status 0x00 handle 64 reason 0x16
Reason: Connection Terminated by Local Host
并且不良连接如下:
< HCI Command: LE Create Connection (0x08|0x000d) plen 25
bdaddr 00:00:00:00:00:00 type 0
interval 4 window 4 initiator_filter 1
own_bdaddr_type 0 min_interval 15 max_interval 15
latency 0 supervision_to 3200 min_ce 1 max_ce 1
> HCI Event: Command Status (0x0f) plen 4
LE Create Connection (0x08|0x000d) status 0x00 ncmd 1
> HCI Event: LE Meta Event (0x3e) plen 19
LE Connection Complete
status 0x00 handle 64, role master
bdaddr 68:C9:0B:xx:xx:xx (Public)
> HCI Event: Disconn Complete (0x05) plen 4
status 0x00 handle 64 reason 0x3e
Reason: Connection Failed to be Established
< HCI Command: Disconnect (0x01|0x0006) plen 3
handle 64 reason 0x13
Reason: Remote User Terminated Connection
> HCI Event: Command Status (0x0f) plen 4
Disconnect (0x01|0x0006) status 0x12 ncmd 1
Error: Invalid HCI Command Parameters
注意:最后两个条目(无效的HCI命令参数)是由于脚本的粗糙,并且只因连接失败而出现。
值得注意的是,它看起来像是建立了连接,然后它说不能(连接无法建立)。这似乎让我有点困惑。
我在不同的机器上试过这个。(台式电脑和RPi3)
外围设备正在做广告。这意味着它周期性地在某个广告信道上发送平均(ADV_ID)分组。作为对此数据包的响应,中心可以(Core_v4.2,6.B.4.4.2.3):
- 什么都不做
- 发送扫描请求(scan_REQ)包(图4.3),外围设备应使用扫描响应(scan_RSP)进行响应
- 发送一个连接请求(CONN_REQ)数据包(图4.5)
在这里,有两个中枢试图同时到达同一个外围。一个是主动扫描(上面的#2),另一个是启动(上面的#3)。不幸的是,两者必须同时发送数据包,接收器会被阻塞,扫描请求和连接请求数据包都会丢失。
没有对连接请求的确认。发起方必须假设广告商收到并接受了连接请求,推测性地创建连接,然后可能超时。这就是bare_metal指出的快速终止功能存在的原因。在外围设备不接受连接请求的情况下,中心不应该永远等待。
LE连接完成事件在您的转储中只是告诉一个连接请求数据包已经发送,而不是告诉它实际上已经被目标接收、处理或接受。
关于创建的连接与建立的连接的混淆,请参阅低能耗规范(核心4.2)第6卷B部分第4.5节。因此,在第二个实例中,远程设备似乎没有发送任何REQ PDU之后的数据信道分组。在第二种情况下,如果在未建立的链路上尝试断开连接,则控制器将抱怨无效句柄(因为不存在有效连接)。要进一步调试,您可以在hcidump中启用Timing,它将确认主机在Supervisory Timeout之后接收到建立失败事件。
"当启动器发送到广告商或广告商的CONNECT_REQ PDU接收到来自启动器的CONNECT_REQ PDU。进入连接状态后,该连接被视为创建。此时不认为已建立连接。连接只被认为是在数据信道数据包中建立的已从对等设备接收到。创建的连接和建立的连接之间的唯一区别是使用的链路层连接监控超时值"
"如果链路层连接监控计时器在建立连接之前达到6*connInterval(请参阅第4.5节),则该连接将被视为丢失。这可以快速终止未能建立"