近两年来,安卓客户经常在bug系统上碰到客户提问,BLE蓝牙遥控器无法回连。对策下起来好说,如下:
diff --git a/internal_include/bt_target.h b/internal_include/bt_target.h
index dd8c74e..18cbcba 100644
--- a/internal_include/bt_target.h
+++ b/internal_include/bt_target.h
@@ -548,8 +548,9 @@/** Enables or disables support for local privacy (ex. address rotation)*/
+#undef BLE_LOCAL_PRIVACY_ENABLED#ifndef BLE_LOCAL_PRIVACY_ENABLED
-#define BLE_LOCAL_PRIVACY_ENABLED TRUE
+#define BLE_LOCAL_PRIVACY_ENABLED FALSE#endif/*
diff --git a/stack/btm/btm_ble_bgconn b/stack/btm/btm_ble_bgconn
index 3607cda..3f459b1 100644
--- a/stack/btm/btm_ble_bgconn
+++ b/stack/btm/btm_ble_bgconn
@@ -364,7 +364,9 @@ static bool btm_ble_start_auto_conn() {btm_ble_enable_resolving_list_for_platform(BTM_BLE_RL_INIT);if (btm_cb.ble_ctr_cb.rl_state != BTM_BLE_RL_IDLE &&controller_get_interface()->supports_ble_privacy()) {
+ #if ( BLE_LOCAL_PRIVACY_ENABLED == TRUE)own_addr_type |= BLE_ADDR_TYPE_ID_BIT;
+ #endifpeer_addr_type |= BLE_ADDR_TYPE_ID_BIT;}
好了,问题解决了。但这是什么原因呢?
前面一个对策意思是不使用privacy mode, 后面一个对策意思是本地Device不生成RPA地址(参考4.10节),具体见HCI规格7.8.12.
BLE_LOCAL_PRIVACY_ENABLED默认TRUE是google写的,应该问题不大。同时,观察市面上安卓手机行为,设置的是TRUE。这些遥控器也没办法回连其他手机。而对比其他蓝牙HID LE设备,例如鼠标,是可以回连的。由此可见,这个对策只是规避对策,不是解决对策, 问题还是出在遥控器身上。
通过空中抓包,发现这台HID设备回连的时候一直发定向广播,定向广播回连理论上更快,这原则上没问题。那为什么默认情况下回连失败呢?
经过调查,是因为TargetA地址(外围设备广播消息,221030说明)给的是公有地址,而蓝牙4.2以上规范,定向回连中,规定如果Host使用了可解析私有地址(RPA)时,Device(中央设备端,221030说明)不响应TargetA公有地址和静态私有地址(两个合起来叫做identity address)。所以回连失败。此种情况下,TargetA只能给RPA地址.
那熟悉协议的同学可能会说,定向回连本来就是要用静态私有地址或者公有地址,因为定向回连只接受白名单地址,白名单只可能是静态地址或者公有地址,并且是由控制器完成自动回连的。那不是和上面冲突了?
好吧,直接说答案吧:
确实,在蓝牙4.1以下(含,下同)时,定向回连就是这样的,只接受白名单地址(外围设备地址AdvA)。大家知道,白名单只能是静态地址或者公有地址(才有意义)。在使用白名单情况+蓝牙4.1之前,控制器是不支持reslove list的。也就是说,控制器并不知道对方IRK,4.1之前这些信息是保存在蓝牙Host协议栈的。所以,广播设备的控制器想填充TargetA 地址,只可能是白名单中的地址,不可能填写PRA地址,因为他根本没记录过这个,也不会自己生成(只能Host才有IRK来生成)。
蓝牙4.2(含,下同)以后,就有了Device Privacy Mode。而大家知道,Privacy Mode是基于RPA地址的。安卓作为一个通用OS系统,肯定默认要打开Device Privacy Mode, 用来达成最强的隐私特性。此种情况下,定向回连也是可以支持的,是因为Device Privacy Mode增加的同时,新增了reslove list功能。reslove list中每一组数据中会含有本地IRK,对端IRK和Identity Address。这样,在Device Privacy Mode情况下,即使广播设备使用RPA地址,也可以使用IRK先核对定向广播中的AdvA地址,找到对应的Identity Address在reslove list的记录,并和白名单地址比对,如果一致,Device就接受AdvA地址,同时查看TargetA地址是否符合图1要求,并决定链连接是否继续。
图1 INITIATING STATE代表中心设备的初始状态. 对于外围设备, 对应状态叫做广播状态(221030新增说明).
这里,我们可以分析下为什么遥控器厂为什么一直使用公有地址,然后让安卓厂一直忙于应付,不断发开头所示的补丁?
(1) 相信大家也猜到了,基本上是因为遥控器厂在蓝牙4.0/4.1时代的遗产,那时候使用公有地址+定向广播真香;
(2) 但是到了蓝牙4.2以后,遥控器厂可能疏忽了Device Privacy Mode的变更,并延续了此前设置。然后客户觉得遥控器啥也没动,只有安卓厂升级SDK了。于是把问题扔给安卓厂,安卓厂关闭安卓端本身的Device Privacy Mode特性,这样privacy mode同蓝牙4.1一致, 问题解决。
(3) 相反,鼠标厂没有这个问题,可能基本上是他们意识到,规格变了,手机适配起来了。
所以,现在对策是联系遥控器厂,说明此情况,请他们改正。
鼠标厂看了几个,即使他们宣称支持4.2,5.0或者5.1,无论他们使用Nordical芯片,还是国产小博通芯片,Feature特性都是不支持Device Privacy Mode的,并且只支持特性中的LE Encryption。其他你能想到的,都没有的(实际上也确实不需要,徒增成本)。
所以,鼠标厂的做法,其实就是面对蓝牙4.2以上系统时,使用上面的(5)所说明; 面对蓝牙4.1芯片时,google只支持公有地址. 使用Identity蓝牙地址+定向或非定向广播都可以。
定向广播时,鼠标厂广播使用的TargetA地址,和CONNECT_IND指示的intiator地址应该是一样的。
Nordical
.html#comment-6910
这里是网友“虎妞”的说明,我没Nordical的SDK,所以不知道是不是真的,大家如果有,发我一份。
Dialog
/directed-advertise
如果以上真的代表两个大厂官方立场,他们想要说的应该只是蓝牙4.0/4.1的情况。N厂说只能用静态随机地址,D厂说只能用公有地址, 都不完整, 实际上应该是Identy address, 而Identy addr包括Public addrss和static random address。可能是他们的实现只支持他们说的那样。
不过, 使用静态随机地址时, 一定要follow N厂的说法. 即使开关机, 你的静态随机地址也不要改变. 不然, 肯定无法回连了.
总的来说, 4.0/4.1定向回连还是只支持白名单蓝牙地址, 只能是公有地址和不会变化的静态随机地址. 如上第二节第1个原因所述。但google的蓝牙协议栈, 也只支持公有地址.
4.2及以上, 定向回连只支持RPA地址, 不支持Identy address.
大家如有不同意见,欢迎拍砖。
本文发布于:2024-02-02 10:28:36,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170684091743199.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |