2014-07-24 64 views
1

我已經編寫了一個應用程序,它在Linux上以非阻塞模式使用藍牙LE L2CAP連接來讀取/寫入ATT數據包(使用socket(PF_BLUETOOTH, SOCK_SEQPACKET|SOCK_CLOEXEC, BTPROTO_L2CAP))。通常,當設備關閉或超出範圍時,read()給出errno = ETIMEDOUT。在Linux上過度的藍牙LE超時?

但是,當藍牙LE設備仍然工作時,read()更經常地給出errno = ETIMEDOUT。超時的原因是什麼?超時是否可配置?

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

回答

3

建立的LE L2CAP套接字上的ETIMEDOUT錯誤實際上來自藍牙適配器,連續丟失數據包之後。多少取決於連接參數。一旦主設備發起與從設備的連接,主設備每連接間隔(7.5ms-4s)對從設備進行ping操作,如果從設備接收到ping請求,它將響應。如果其中一個設備在監督超時(100ms-32s)之後無法聽到其他設備的迴音,它將關閉連接。第三個參數從站延遲(0-499)允許從站通過不響應某些ping來節省電池電量。另請參見What are connection parameters?

操作系統在啓動連接時設置默認連接參數。從設備可能會推薦一組更合適的連接參數來平衡電池使用時間,延遲以及對障礙/干擾的恢復能力,並且操作系統有機會批准這些參數(有關蘋果操作系統可接受的連接參數範圍,請參閱Apple’s Bluetooth Design Guidelines) 。但是,如果從設備沒有提供一組新的參數,那麼它就受操作系統默認設置的限制,從一個操作系統到另一個操作系統,這些默認設置會有很大差異!

在查看Wireshark中的hcidump btsnoop文件時,似乎我的特定設備(藍牙筆)從不建議不同的間隔和超時。因此,其可靠性將取決於操作系統的默認設置。

這裏是實驗確定的默認間隔和超時。

Linux的3.13與內部藍牙適配器(currently defined in hci_core.c):
間隔由操作系統允許:50-70ms通過藍牙適配器選擇
連接間隔:67.5ms
監督超時:420ms(丟失斷開之前的數據包)

與iOS 7 iPhone 4S:通過藍牙適配器選擇未知
連接間隔:30毫秒
區間由操作系統允許從屬等待時間:0分組
監督超時:720ms(丟失斷開之前的數據包)

的Android 5.0.1棒棒糖上的Nexus 4
區間由操作系統允許:30-50ms的通過藍牙選擇
連接間隔適配器:48。75ms
從延遲:0包
監督超時:2000毫秒(失蹤斷開之前的數據包)

OSX 10.10.1(蘋果藍牙軟件版本:4.3.1f2 15015)與外部適配器:
允許時間間隔由OS:未知
連接間隔通過藍牙適配器選自:15ms的
從屬等待時間:0分組
監督超時:2000毫秒(丟失斷開之前的數據包)

這解釋了爲什麼我的Livescribe筆的連接在Linux上看起來不太可靠。內核默認是在丟失6個丟包後丟棄連接,並且筆從不建議更好的參數。

在Linux 3.17及以上版本中,可以通過寫入/ sys/kernel/debug/bluetooth/hci0/supervision_timeout來調整監視超時。

測試方法:使用hcidump(在Android的Developer Options中)獲取Linux上的痕跡,並在Wireshark中分析HCI LE創建連接命令。使用帶有TI數據包嗅探器軟件的TI CC2540獲得OSX和iPhone的蹤跡。