BLE藍牙坑爹集錦 二

pair不上藍牙設(shè)備

  • 我有遇到一個情況,如果出現(xiàn)pair Julia 連續(xù)的多次的失敗(一般情況就一次,下次就會pair成功),就會一直pair 失敗下去,這個pair失敗是安卓底層Api返回的狀態(tài)---------> 殺死App也不能重新pair成功情臭,只有重新啟動平板省撑。你們有遇到這種情況么 ?
  • 我好像可以復現(xiàn)這個問題了俯在,當多次 pair失敗的時候竟秫,可以不開關(guān)機,然后把平板的藍牙重啟一下跷乐,然后在重新去掃描和pair肥败,就可以了成功了--- Lap Chow 如果你們又遇到這種情況,請記得給我說下步驟哈愕提,剛才和 Popo Liang 討論馒稍,她沒有遇到過,就我在測試過程中遇到了

我開始以為是Gatt開多了浅侨,然后導致內(nèi)存中的Gatt少了纽谒,所以我要去關(guān)閉它,但是好像問題不是這個樣子的如输,我看的是鼓黔,Gatt在掃描的同時,然后去pair 不见,那么肯定會 pair failed-----

我們有個服務(wù)请祖,當藍牙斷開連接的時候,會主動的去連接它脖祈,然后導致開了很多的 gatt的句柄在哪里,一個gatt在不斷的生成刷晋,但是沒有銷毀掉 盖高!兩個時間的重疊 ---在返回的藍牙掃描的結(jié)果的同時,還去pair藍牙的設(shè)備眼虱,導致這個設(shè)備就被打入冷宮喻奥,永遠都pair 不上了

todo 思路有點亂 媽的 !D笮撞蚕!

要復現(xiàn)這個問題 -------- -

new we need also disable APCF!

我們還需要禁用APCF!

09:12:27.923 8909-8909/com.tgi.device.cp80 D/BluetoothAdapter: isLeEnabled(): ON
2020-06-04 09:12:27.927 8909-8909/com.tgi.device.cp80 I/Stan: com.tgi.lib.ble.client.states.BluetoothMachine.setState(); 62 - Lines:
     BluetoothMachine  setState StandByState
2020-06-04 09:12:27.935 11301-11331/? D/BtGatt.ScanManager: we need also disable APCF!



2020-06-04 09:00:25.231 11301-11331/? D/BtGatt.ScanManager: we need also disable APCF!
2020-06-04 09:12:27.935 11301-11331/? D/BtGatt.ScanManager: we need also disable APCF!
2020-06-04 09:13:56.715 11301-11331/? D/BtGatt.ScanManager: we need also disable APCF!

pair 失敗的 會出下面的日志

image.png

又出現(xiàn)一個日志


image.png
 bta_gattc_cache_load: can't open GATT cache file /data/misc/bluetooth/gatt_cache_5f00811ec6f5 for reading, error: No such file or directory

image.png

bt_bta_gattc: bta_gattc_explore_srvc no more services found

2020-06-04 11:52:45.886 11301-11341/? W/bt_btif: bta_gattc_conn_cback() - cif=3 connected=0 conn_id=3 reason=0x0013
2020-06-04 11:52:45.886 11301-11341/? W/bt_btif: bta_gattc_conn_cback() - cif=4 connected=0 conn_id=4 reason=0x0013
2020-06-04 11:52:45.886 11301-11341/? W/bt_btif: bta_gattc_conn_cback() - cif=5 connected=0 conn_id=5 reason=0x0013
2020-06-04 11:52:45.886 11301-11341/? W/bt_btif: bta_gattc_conn_cback() - cif=6 connected=0 conn_id=6 reason=0x0013
2020-06-04 11:52:45.886 11301-11341/? W/bt_btif: bta_gattc_conn_cback() - cif=7 connected=0 conn_id=7 reason=0x0013
2020-06-04 11:52:45.886 11301-11341/? I/bt_btm_sec: btm_sec_disconnected clearing pending flag handle:513 reason:19
2020-06-04 11:52:45.886 11301-11341/? E/bt_stack: [ERROR:bta_gattc_utils.cc(509)] bta_gattc_mark_bg_conn unable to find the bg connection mask for: 84:0d:8e:cc:9c:86
2020-06-04 11:52:45.967 11301-11324/? W/bt_btif: btif_av_move_idle: ACL Disconnected state 0 bd_addr=84:0d:8e:cc:9c:86 peer_bda=00:00:00:00:00:00
image.png

https://github.com/espressif/esp-idf/issues/250

ESP32是一系列低成本过牙,低功耗的單片機微控制器甥厦,集成了Wi-Fi和雙模藍牙。 ESP32系列采用Tensilica Xtensa LX6微處理器寇钉,包括雙核心和單核變體刀疙,內(nèi)置天線開關(guān),RF變換器扫倡,功率放大器谦秧,低噪聲接收放大器,濾波器和電源管理模塊。

ESP32 由總部位于上海的中國公司樂鑫信息科技創(chuàng)建和開發(fā)疚鲤,由臺積電采用40納米技術(shù)制造[2]锥累。它是ESP8266微控制器的后繼產(chǎn)品。

image.png

基本概念和問題

1集歇、藍牙設(shè)計范式桶略?

當手機通過掃描低功耗藍牙設(shè)備并連接上后,手機與藍牙設(shè)備構(gòu)成了客戶端-服務(wù)端架構(gòu)鬼悠。手機通過連接藍牙設(shè)備删性,可以讀取藍牙設(shè)備上的信息。手機就是客戶端焕窝,藍牙設(shè)備是服務(wù)端蹬挺。

手機做為客戶端可以連接多個藍牙設(shè)備,所以手機又可以叫中心設(shè)備(Central)它掂,藍牙設(shè)備叫外圍設(shè)備(Peripheral)巴帮。

還有另外一個稱謂:手機叫主設(shè)備(Master),藍牙設(shè)備叫從設(shè)備(Slave)虐秋。

Android4.3 開始支持低功耗藍牙榕茧,此版本只支持單模式:同時只能工作在中心設(shè)備模式或者外圍設(shè)備模式

Android5.0 開始支持主從一體。換句話說客给,手機可以掃描并進行連接用押,連接著藍牙設(shè)備的同時,又可以作為廣播者靶剑,發(fā)送藍牙廣播蜻拨,等待別的支持藍牙掃描的設(shè)備連接自己。

2桩引、從設(shè)備連接數(shù)量的問題缎讼?

理論層面

從經(jīng)典藍牙時代開始,藍牙有個星型拓撲的概念坑匠,一個主設(shè)備(Central)外圍有七個從設(shè)備(Peripheral)血崭,藍牙核心文檔規(guī)定了:同一時間只允許七個從設(shè)備進行連接。

系統(tǒng)層面

Android系統(tǒng)藍牙協(xié)議棧源碼中也使用了這個數(shù)值厘灼,Android手機的藍牙芯片都是雙模藍牙芯片夹纫,即同時支持經(jīng)典藍牙和低功耗藍牙,分析過協(xié)議棧源碼手幢,建立連接的過程經(jīng)典藍牙和低功耗藍牙是公用的代碼捷凄,所以手機作為主設(shè)備(Central)時,從設(shè)備(Peripheral)同時連接的最大值就是7臺設(shè)備围来。

實際情況

開發(fā)Android客戶端以來跺涤,遇到的實際情況就是匈睁,部分手機(偏低端一些機型,比如采用聯(lián)發(fā)科的解決方案桶错,手機的GPS航唆、藍牙、Wi-Fi等都是共模的院刁,都集成在一個芯片上)不能達到7臺設(shè)備糯钙。

3、ATT是什么退腥?

ATT是屬性協(xié)議(Attribute Protocol)任岸,定義了客戶端與服務(wù)器如何相互發(fā)送符合標準的消息。

4狡刘、GATT是什么享潜?

GATT是通用屬性規(guī)范(Generic Attribute Profile),定義了如何發(fā)現(xiàn)與使用服務(wù)嗅蔬、特性與描述符的標準方法剑按。

GATT的規(guī)程基本分為:

發(fā)現(xiàn)規(guī)程:發(fā)現(xiàn)服務(wù)(Service)、發(fā)現(xiàn)特征(Characteristic)等

客戶端發(fā)起規(guī)程:讀取特征(readCharacteristic)澜术、寫入特征(writeCharacteristic)等

服務(wù)端發(fā)起規(guī)程:比如通知(Notification)和指示(Indicate)

5艺蝴、低功耗藍牙頻段和信道問題

藍牙工作在2.45G ISM頻段,波段范圍是:2400-2483.5 MHz

信道:低功耗藍牙使用用40個RF信道鸟废,這些RF信道中心頻率為:f=2402+k*2 MHz, k=0, ... ,39

因為調(diào)試指數(shù)放寬猜敢,低功耗藍牙的信道與經(jīng)典藍牙有所不同。每個信道的功率譜更寬盒延,因此锣枝,為了避免鄰近信道干擾,低功耗藍牙的信道寬度為2MHz兰英,而不是經(jīng)典藍牙的1MHz

低功耗藍牙使用的2.45GHz頻段已經(jīng)非常擁擠,僅僅考慮標準的技術(shù)就包括:經(jīng)典藍牙供鸠、低功耗藍牙畦贸、IEEE 802.11、IEEE802.11b楞捂、IEEE802.11g薄坏、IEEE802.11n以及IEEE 802.15.4。另外寨闹,許多私有的無線電同樣使用這個頻段胶坠,包括X10視頻中繼器、無線報警繁堡、鍵盤和鼠標等沈善。許多其他設(shè)備也會在該頻段發(fā)射噪聲乡数,例如街燈和微波爐。

對于2.45G這個頻段有個很尷尬的特性:怕水闻牡。

舉個例子:微波爐的工作原理就是向帶有水分的物體發(fā)射2.45GHz的微波净赴,利用了水分子能夠很好的吸收2.45GHz電磁波,將電磁波能量轉(zhuǎn)換成為自身的熱量罩润。也正式這個特性玖翅,在很長一段時間里,2.4GHz信道不被人所重視割以,下雨金度、霧氣甚至是潮濕的墻壁都能吸收無線電波,使傳輸距離大大衰減严沥。估計這也是全球都對此頻段不屑而免費開放的理由之一吧猜极。當人站在兩塊藍牙設(shè)備中間,并且距離其中一塊模塊1米左右時祝峻,能夠檢測信號衰減了將近10dB左右魔吐!因為人體的70%左右是水分。

image

有人也許好奇為啥廣播信道這么設(shè)計莱找,請看下圖:

image

是為了盡量避開沖突頻段酬姆,增加通信的魯棒性。

6奥溺、關(guān)于autoConnect參數(shù)為true的意義辞色?

在藍牙核心文檔Vol3: Core System Package[Host volume]->Part C: Generic Access Profile的Connection Modes and Procedures章節(jié)中有涉及到自動連接建立規(guī)程(Auto Connection Establishment Procedure)的定義。

自動連接建立規(guī)程用來向多個設(shè)備同時發(fā)起連接浮定。一個中央設(shè)備的主機與多個外圍設(shè)備綁定相满,只要它們開始廣播,便立刻與其建立連接桦卒。跟多細節(jié)請參考藍牙核心文檔和協(xié)議棧源碼立美。

一些API使用問題

Android 4.3

此版本是首個支持BLE的Android版本,穩(wěn)定性一般方灾,現(xiàn)在的系統(tǒng)分布情況建蹄,基本可以把最低支持版本提高的Android4.4了

Android 5.0

Samsung手機出現(xiàn)BluetoothAdapter.startLeScan()方法使用不當導致的Crash

正常調(diào)用過程startLeScan() -> stopLeScan() -> startLeScan() -> stopLeScan(),不會出現(xiàn)Crash

異常調(diào)用startLeScan() -> startLeScan()會出現(xiàn)Crash

Android 6.0

在Android 6.0版本裕偿,需要APP獲取位置權(quán)限才可以使用藍牙API洞慎,部分機型在未授權(quán)時,調(diào)用藍牙API會引起Crash

Android 6.0.1

Android6.0.1有個連接問題嘿棘,是系統(tǒng)bug劲腿,影響連接問題。

Android 7.0

30s內(nèi)連續(xù)掃描次數(shù)不允許大于5次鸟妙,否則會引起無法掃描到設(shè)備的問題焦人,需要重啟才可以恢復正常挥吵。

并發(fā)執(zhí)行BluetoothGatt.readRemoterssi()會引發(fā)DeadObjectException,三星手機出現(xiàn)概率較高垃瞧。

**Android 8.1 **

掃描方法BluetoothAdapter.startLeScan(UUID[] serviceUuids, BluetoothAdapter.LeScanCallback callback);

部分手機如果沒有指定serviceuuids值蔫劣,手機鎖屏后,掃描回調(diào)會失敗个从,無法掃描到設(shè)備脉幢。Google親兒子Pixel系列必現(xiàn)。

待更新......

另外一些普遍問題

BluetoothDevice.getName() 獲取名字是有些不可靠的嗦锐,因為有些情況下獲取Name是空嫌松,慎用此方法獲取的值來作為掃描過濾條件。

BLE設(shè)備的建立和斷開連接的操作奕污,最好都放在主線程中:例如BluetoothDevice.connectGatt()萎羔,BluetoothGatt.connect(),BluetoothGatt.disconnect()碳默,BluetoothGatt.discoverServices()等

BLE 應(yīng)用異常耗電問題贾陷,在連接 BLE 設(shè)備的過程中,系統(tǒng)會持有這個 WakeLock嘱根,直到連接上或者主動斷開連接才會釋放髓废。如果BLE設(shè)備不在范圍內(nèi)构捡,這個超時時間大約為30s袱巨,而這時你可能又要嘗試重新連接怪瓶,這個WakeLock又被重新持有味滞,這樣系統(tǒng)就永遠不能休眠了。

Android BLE藍牙的各種問題烦感,只要做到如下幾點喜德,大部分問題會得到解決:

原則一:startLeScan()和stopLeScan()一定要確保成對出現(xiàn)逛绵、順序調(diào)用欧引。

否則會導致協(xié)議棧中mClientIf達到上限频伤,掃描registerClient失敗,再也不能掃描到設(shè)備芝此,此時onScanFailed會發(fā)生errorCode=2剂买。

原則二:BluetoothDevice.connectGatt()、BluetoothGatt.disconnect()和BluetoothGatt.close()一定要順序調(diào)用癌蓖。一些情況下可以直接越過disconnect()方法直接調(diào)用close()。

close()非常重要婚肆,對于一個執(zhí)行過連接方法的設(shè)備租副,不管是否連接成功,最后都要調(diào)用close()较性,讓系統(tǒng)底層回收掉資源用僧,否則會有各種問題讓你崩潰结胀。

對于連接成功的藍牙設(shè)備,想斷開時责循,可以先調(diào)用BluetoothGatt.disconnect()糟港,等待onConnectionStateChange響應(yīng)斷開后,再執(zhí)行close()院仿。

如果是執(zhí)行連接方法時出現(xiàn)了無法恢復的錯誤秸抚,比如133、8歹垫、19剥汤、22、62等排惨,可以直接調(diào)用close()吭敢。

原則三:讀/寫特征和描述、設(shè)置通知和指示等操作暮芭,要確保上一個執(zhí)行完成了鹿驼,再執(zhí)行下一個調(diào)用。

Android源碼中使用了mDeviceBusy全局變量辕宏,同時調(diào)用兩個API畜晰,會導致后調(diào)用的直接失敗。

附錄:API常見錯誤碼

GATT_ERROR 0x85 //133任何不懼名字的錯誤都出現(xiàn)這個錯誤碼匾效,出現(xiàn)了就認慫吧舷蟀,重新連接吧。

GATT_CONN_TIMEOUT 0x08 //8 連接超時面哼,大多數(shù)情況是設(shè)備離開可連接范圍野宜,然后手機端連接超時斷開返回此錯誤碼。

GATT_CONN_TERMINATE_PEER_USER 0x13 //19 連接被對端設(shè)備終止魔策,直白點就是手機去連接外圍設(shè)備匈子,外圍設(shè)備任性不讓連接執(zhí)行了斷開。

GATT_CONN_TERMINATE_LOCAL_HOST 0x16 //22 連接被本地主機終止闯袒,可以解釋為手機連接外圍設(shè)備虎敦,但是連接過程中出現(xiàn)一些比如鑒權(quán)等問題,無法繼續(xù)保持連接政敢,主動執(zhí)行了斷開操作其徙。

GATT_CONN_FAIL_ESTABLISH 03E //62 連接建立失敗。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末喷户,一起剝皮案震驚了整個濱河市唾那,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌褪尝,老刑警劉巖闹获,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件期犬,死亡現(xiàn)場離奇詭異,居然都是意外死亡避诽,警方通過查閱死者的電腦和手機龟虎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來沙庐,“玉大人鲤妥,你說我怎么就攤上這事」旃Γ” “怎么了旭斥?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長古涧。 經(jīng)常有香客問我垂券,道長,這世上最難降的妖魔是什么羡滑? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任菇爪,我火速辦了婚禮,結(jié)果婚禮上柒昏,老公的妹妹穿的比我還像新娘凳宙。我一直安慰自己,他們只是感情好职祷,可當我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布氏涩。 她就那樣靜靜地躺著,像睡著了一般有梆。 火紅的嫁衣襯著肌膚如雪是尖。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天泥耀,我揣著相機與錄音饺汹,去河邊找鬼。 笑死痰催,一個胖子當著我的面吹牛兜辞,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播夸溶,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼逸吵,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了缝裁?” 一聲冷哼從身側(cè)響起扫皱,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后啸罢,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡胎食,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年扰才,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片厕怜。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡衩匣,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出粥航,到底是詐尸還是另有隱情琅捏,我是刑警寧澤,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布递雀,位于F島的核電站柄延,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏缀程。R本人自食惡果不足惜搜吧,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望杨凑。 院中可真熱鬧滤奈,春花似錦、人聲如沸撩满。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽伺帘。三九已至昭躺,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間曼追,已是汗流浹背窍仰。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留礼殊,地道東北人驹吮。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像晶伦,于是被迫代替她去往敵國和親碟狞。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內(nèi)容