本文介绍了Linux上的蓝牙LE超时过多?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编写了一个应用程序,该应用程序在Linux上以非阻塞模式使用Bluetooth LE L2CAP连接来读取/写入ATT数据包(使用socket(PF_BLUETOOTH, SOCK_SEQPACKET|SOCK_CLOEXEC, BTPROTO_L2CAP)).通常,当设备关闭或超出范围时,read()给出errno = ETIMEDOUT.

I have written an application that uses Bluetooth LE L2CAP connections in nonblocking mode on Linux to read/write ATT packets (using socket(PF_BLUETOOTH, SOCK_SEQPACKET|SOCK_CLOEXEC, BTPROTO_L2CAP)). Normally, when the device turns off or goes out of range, read() gives errno=ETIMEDOUT.

但是,当Bluetooth LE设备似乎仍在工作时,read()给予errno = ETIMEDOUT的频率比应有的多.超时的原因是什么?超时可以配置吗?

However, read() is giving errno=ETIMEDOUT more often than it should, when the Bluetooth LE device still appears to be working. What is the cause of the timeout? Is the timeout configurable?

我的Linux配置是3.13.0-24-generic;蓝牙核心版本2.17.

My Linux configuration is 3.13.0-24-generic; Bluetooth Core ver 2.17.

推荐答案

已建立的LE L2CAP套接字上的ETIMEDOUT错误实际上来自蓝牙适配器,它连续丢失了多个数据包.多少取决于连接参数.主机启动与从机的连接后,主机会每隔 Connection Interval (7.5ms–4s)对从机执行ping操作,并且从机将在听到ping响应后作出响应.如果在监控超时(100ms–32s)之后,任何一台设备都无法听到另一台设备的声音,它将关闭连接.第三个参数,从属延迟(0-499),允许从属设备通过不响应某些ping来节省电池电量.另请参见什么是连接参数?

The ETIMEDOUT errors on an established LE L2CAP socket actually come from the Bluetooth adapter after several consecutive missed packets. How many depends on the Connection Parameters. Once a master initiates a connection with a slave, the master pings the slave every Connection Interval (7.5ms–4s), and the slave will respond if it heard the ping. If either device fails to hear back from the other device after Supervision Timeout (100ms–32s), it will close the connection. A third parameter, the Slave Latency (0-499), allows the slave to save battery power by not responding to some pings. See also What are connection parameters?

操作系统在启动连接时设置默认的连接参数.从设备可能会建议一组更合适的连接参数,以平衡电池寿命,延迟和对障碍物/干扰的恢复能力,并且操作系统有机会批准这些参数(请参见 Apple的蓝牙设计指南,以了解Apple操作系统将接受的连接参数范围).但是,如果从属服务器不建议使用一组新参数,则该设置将受操作系统默认值的影响,默认值在一个操作系统与另一个操作系统之间差异很大!

The OS sets the default connection parameters when initiating a connection. The slave may recommend a more appropriate set of connection parameters to balance battery life, latency, and resilience to obstructions/interference, and the OS gets a chance to approve these parameters (see Apple’s Bluetooth Design Guidelines for the range of connection parameters that Apple’s OSs will accept). But if the slave does not suggest a new set of parameters, then it is at the mercy of the operating system’s defaults, which vary wildly from one OS to another!

在Wireshark中查看hcidump btsnoop文件时,似乎我的特定设备(蓝牙笔)从不建议不同的间隔和超时.因此,其可靠性将取决于操作系统的默认设置.

In looking at the hcidump btsnoop files in Wireshark, it appears that my particular device (a bluetooth pen) never suggests a different interval and timeout. Therefore, its reliability will depend on the OS defaults.

这是实验确定的默认间隔和超时时间.

Here are experimentally determined default intervals and timeouts.

带有内部蓝牙适配器的Linux 3.13(当前在hci_core.c ):
操作系统允许的间隔:50–70ms
蓝牙适配器选择的连接间隔:67.5ms
监督超时:420ms( 6 在断开连接之前丢失数据包)

Linux 3.13 with internal bluetooth adapter (currently defined in hci_core.c):
Intervals allowed by OS: 50–70ms
Connection Interval chosen by bluetooth adapter: 67.5ms
Supervision timeout: 420ms (6 missing packets before disconnect)

装有iOS 7的iPhone 4S:
操作系统允许的间隔:未知
蓝牙适配器选择的连接间隔:30ms
从属延迟:0个数据包
监督超时:720ms( 23 断开连接前丢失数据包)

iPhone 4S with iOS 7:
Intervals allowed by OS: unknown
Connection Interval chosen by bluetooth adapter: 30ms
Slave latency: 0 packets
Supervision timeout: 720ms (23 missing packets before disconnect)

Nexus 4上的Android 5.0.1 Lollipop
操作系统允许的间隔:30–50ms
蓝牙适配器选择的连接间隔:48.75ms
从属延迟:0个数据包
监督超时:2000ms( 41 在断开连接之前丢失数据包)

Android 5.0.1 Lollipop on Nexus 4
Intervals allowed by OS: 30–50ms
Connection Interval chosen by bluetooth adapter: 48.75ms
Slave latency: 0 packets
Supervision timeout: 2000ms (41 missing packets before disconnect)

带有外部适配器的OSX 10.10.1(Apple蓝牙软件版本:4.3.1f2 15015):
操作系统允许的间隔:未知
蓝牙适配器选择的连接间隔:15ms
从属延迟:0个数据包
监督超时:2000ms( 133 在断开连接之前丢失数据包)

OSX 10.10.1 (Apple Bluetooth Software Version: 4.3.1f2 15015) with external adapter:
Intervals allowed by OS: unknown
Connection Interval chosen by bluetooth adapter: 15ms
Slave latency: 0 packets
Supervision timeout: 2000ms (133 missing packets before disconnect)

这说明了为什么我与Livescribe笔的连接在Linux上似乎不太可靠.内核的默认设置是仅丢失6个数据包后即断开连接,并且笔从未推荐使用更好的参数.

This explains why my connections to my Livescribe pen appeared less reliable on Linux. The kernel default is to drop the connection after only 6 missing packets, and the pen never recommended better parameters.

在Linux 3.17及更高版本上,可以通过写入/sys/kernel/debug/bluetooth/hci0/supervision_timeout来调整监视超时.

On Linux 3.17 and above, the supervision timeout can be tweaked by writing to /sys/kernel/debug/bluetooth/hci0/supervision_timeout.

测试方法:使用hcidump(在Android的Developer Options中)获得Linux上的跟踪,并在Wireshark中针对HCI LE Create Connection命令进行了分析.使用TI CC2540和TI的数据包嗅探器软件获得了OSX和iPhone的踪迹.

Testing methodology: the traces on Linux were obtained using hcidump (in Developer Options in Android) and were analyzed in Wireshark for HCI LE Create Connection commands. The traces for OSX and iPhone were obtained using the TI CC2540 with TI’s packet sniffer software.

这篇关于Linux上的蓝牙LE超时过多?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-26 13:01