已建立的 LE L2CAP 套接字上的 ETIMEDOUT 错误实际上来自蓝牙适配器在几个连续丢失的数据包之后。多少取决于连接参数。一旦 master 发起与 slave 的连接,master 每 Connection Interval (7.5ms–4s) 对 slave 执行一次 ping 操作,slave 如果听到 ping 就会做出响应。如果任一设备在 监督超时 (100ms–32s) 后未能收到另一台设备的回复,它将关闭连接。第三个参数 Slave Latency (0-499) 允许从机通过不响应某些 ping 来节省电池电量。另见What are connection parameters?
操作系统在启动连接时设置默认连接参数。从设备可能会推荐一组更合适的连接参数来平衡电池寿命、延迟和对障碍物/干扰的恢复能力,并且操作系统有机会批准这些参数(请参阅Apple’s Bluetooth Design Guidelines 了解 Apple 操作系统将使用的连接参数范围接受)。但是如果从站不建议一组新的参数,那么它就会受到操作系统默认值的摆布,操作系统的默认值会因操作系统而异!
在查看 Wireshark 中的 hcidump btsnoop 文件时,我的特定设备(蓝牙笔)似乎从未建议不同的间隔和超时。因此,其可靠性将取决于操作系统的默认设置。
这里是通过实验确定的默认间隔和超时。
带有内置蓝牙适配器的 Linux 3.13 (currently defined in hci_core.c):
操作系统允许的时间间隔:50–70ms
蓝牙适配器选择的连接间隔:67.5ms
监督超时:420ms(6在断开前丢失数据包)
装有 iOS 7 的 iPhone 4S:
操作系统允许的时间间隔:未知
蓝牙适配器选择的连接间隔:30ms
从属延迟:0 个数据包
监督超时:720ms(23在断开前丢失数据包)
Nexus 4 上的 Android 5.0.1 Lollipop
操作系统允许的时间间隔:30–50ms
蓝牙适配器选择的连接间隔:48.75ms
从属延迟:0 个数据包
监督超时:2000 毫秒(41 在断开之前丢失数据包)
带有外部适配器的 OSX 10.10.1(Apple 蓝牙软件版本:4.3.1f2 15015):
操作系统允许的时间间隔:未知
蓝牙适配器选择的连接间隔:15ms
从属延迟:0 个数据包
监督超时:2000ms(133在断开之前丢失数据包)
这解释了为什么我与 Livescribe 笔的连接在 Linux 上显得不太可靠。内核默认是只丢了6个包就断开连接,pen从来不推荐更好的参数。
在 Linux 3.17 及更高版本上,可以通过写入 /sys/kernel/debug/bluetooth/hci0/supervision_timeout 来调整监督超时。
测试方法:Linux 上的跟踪是使用 hcidump(在 Android 的开发人员选项中)获得的,并在 Wireshark 中针对 HCI LE Create Connection 命令进行了分析。 OSX 和 iPhone 的跟踪是使用 TI CC2540 和 TI 的数据包嗅探器软件获得的。