Bluetooth LE 主动扫描导致其他机器出现连接问题

Bluetooth LE active scanning causes connection problems on other machine

我遇到一个问题,一台机器上的 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 命令参数)是由于脚本的粗糙,并且仅因连接失败而发生。

值得注意的是,它看起来像是建立了连接,然后它说无法(无法建立连接)。这让我有点困惑。

我已经在不同的机器上试过了。 (台式电脑和树莓派)

关于创建连接与建立连接的混淆,请参阅低能量规范(核心 4.2)的第 6 卷 B 部分第 4.5 节。所以在第二种情况下,远程设备似乎没有发送任何 CONNECT_REQ PDU 之后的数据通道数据包。在第二种情况下,如果在未建立的 link 上尝试断开连接,控制器将抱怨无效句柄(因为不存在有效连接)。要进一步调试,您可以在 hcidump 中启用计时,这将确认主机在监督超时后收到建立失败事件。

”Link层在发起者发送一个 CONNECT_REQ 给广告商的 PDU 或广告商收到 CONNECT_REQ 来自发起者的 PDU。 进入Connection State后,连接被认为是 创建。此时不认为连接已建立。一个连接只有在一个数据通道包被认为是建立了 已从对等设备收到。创建的连接和建立的连接之间的唯一区别是使用的 Link 层连接监督超时值

"If the Link Layer connection supervision timer reaches 6 * connInterval before the connection is established (see Section 4.5), the connection shall be considered lost. This enables fast termination of connections that fail to establish"

周边有广告。这意味着它会定期在某个广告频道上发送广告 (ADV_IND) 数据包。为了响应这个数据包,中央可以 (Core_v4.2, 6.B.4.4.2.3):

  1. 什么都不做,
  2. 发送一个扫描请求(SCAN_REQ)包(图4.3),外设应响应一个扫描响应(SCAN_RSP),
  3. 发送一个连接请求(CONN_REQ)数据包(图4.5)。

在这里,你有两个中央试图同时到达同一个外设。一个是主动扫描(上面的#2),另一个是启动(上面的#3)。不幸的是,两者都必须同时发送它们的数据包,接收器会被阻塞,并且扫描请求和连接请求数据包都会丢失。

没有连接请求的确认。发起者必须假设广告商收到并接受了连接请求,推测性地创建连接,然后可能会超时。这就是 bare_metal 指出的快速终止特性存在的原因。如果外设不接受连接请求,中央不应该永远等待。

转储中的 LE 连接完成 事件只是告诉连接请求数据包已发送,它并没有告诉它实际上已被目标接收、处理或接受。