蓝牙连接每次弹出确认框问题的排查及解决

一周前客户提交了一个Bug。 具体的问题是这样的, 客户的一台设备坏了, 临时换了一台设备后发现,新换的设备不像老设备那样每次进行蓝牙连接时都提示要确认配对。这个问题确实是不对比不知道,一直以来谁都没注意这个问题, 以为正常的情况就是每次连接时都需要确实配对。实际上安卓系统上蓝牙首次连接会出现确认配对的对话框, 首次连接配对成功后, 以后再次连接时不需要重新配对, 也不会出现确认配对的对话框除非你从蓝牙设置的配对列表中删除该设备。收到问题后,还是按照一般解决Bug的三部曲: 1.复现问题 2. 分析问题 3. 解决问题进行操做。

复现问题

根据以往的经验, 如果能复现问题,基本上就能解决问题。 首先要求用户把那台有问题的设备寄给我们,收到设备后首先试图复现一下问题。 我们这个设备的使用场景是:我们的APP运行在手机或平板上(为方便区分以下都叫用户端), APP通过蓝牙和设备连接, 连接成功后可以接收设备发送的数据。收到这台设备后, 我们先设计了几个测试用例:

  1. 同一台设备, 不同的用户端
    我们在几台不同的手机/平板上运行APP试图通过蓝牙连接设备, 确实每次连接都弹出确认对话框。
  2. 不同的设备,不同的用户端
    在这个用例中, 我们试了几台手机/平板,几台设备。 每部手机都去连接几台测试的设备, 测试结果发现有一台设备在和某些手机连接时弹出对话框,在和一台荣耀平板连接时不弹出对话框。 还有一部小米手机无论连接哪台设备都不弹出对话框。

通过上面的测试用例, 我们发现了一些现象:

  • 我们测试的大部分设备,无论用户端是什么系统(一部小米手机除外),问题都会出现。
  • 有一台小米手机就对任何设备都不出现问题。
  • 有一台设备, 用一台荣耀平板和上面提到的一台小米手机测量不出现问题, 用其它的平板都会出现问题,而这台荣耀平板连接其它的设备都会出现问题。
分析问题

经过上面的测试, 我们确认了大部分设备确实存在问题。用户端安卓系统对问题的处理方式不一样, 比如一部小米手机连接所有设备都不出问题,但具体问题出在哪里了,从这些现象很难判断, 还需要进一步分析出问题时用户端到底哪不同来决定。为此我们需要从代码的层面和通讯协议的层面分析下正常情况和非正常情况的不同。幸运的是正好上面提到的那台荣耀平板, 连接一台设备没问题, 而连接其他的设备都有问题。 那么我们可以比较连接没问题设备时的通讯协议和连接有问题的设备时的协议不同来定位问题。为此我们首先重新写了一个APP,在这个APP中只做蓝牙连接,其他什么也不做。写这个APP的目的就是简化代码减少多余代码有可能引入的Bug。 这样一来就还剩一个问题: “我们怎么Debug蓝牙通讯协议呢?” 百度一下很快就能得到答案。实际上手机都有一个功能,如下图:

图一 打开蓝牙HCI日志

在手机的设置-->开发人员页面下有一个开启蓝牙HCI信息收集日志选项开关,如图中标红处, 打开该开关,就可以收集本机发送和接收的蓝牙HCI包。看起来很简单是不是, 打开这个开关,我们测试连接一下两台设备, 然后就拿到了蓝牙包日志,分析日志,就可以发现问题了。 可是理论很清晰,现实很残酷啊。我们打开了开关, 分别通过蓝牙连接了上面提到的两台设备, 一台有弹出确认框,一台没有。测试完成了,准备获取日志,可是将PAD连接到电脑,到处也找不到btsnoop_hci.log文件。按照bt_stack_log.conf设置的路径也找不到。真是让人着急。 首先想到的是root一下这个PAD, 但是查了一下华为官网,华为现在已经不再提供root解锁码,大致度娘了一下,root这个平板不太容易,比较简单的方法还是看看有没有别的办法获取的蓝牙日志。度娘了一下,感觉方法都不靠谱,果断翻墙去google。说真心话, 碰到一些比较冷僻复杂的技术问题, 百度上还真难找到线索。不服不行,老外的程序员回答问题的质量还是比较高的。

在这个帖子里,有人提到现在大部分手机厂商不再把蓝牙日志放在用户可以访问的文件分区(难怪我们找不到),取而代之的是可以通过bug report获取。按照帖子里的方法,先执行下面的指令:

adb bugreport c:\tmp\

得到一个压缩文件bugreport-JDN2-W09HN-HUAWEIJDN2-W09HN-2021-06-08-15-07-38.zip,展开这个文件到一个目录后会看到一个同名的TXT文件。然后执行:

btsnooz.py bugreport-JDN2-W09HN-HUAWEIJDN2-W09HN-2021-06-08-15-07-38.txt > btsnoop.log

其中btsnooz.py 是一个Python文件,可以点击上面的链接获取。根据Google的说明, 这个script文件用于从bug report中获取蓝牙日志。终于我们得到了蓝牙日志。总算可以再向前前进一步去分析蓝牙日志了。

蓝牙日志的分析软件比较常用的有三个:

  • Wire Shark
  • Ellisys
  • Frontline Comproble Protocol Analysis System

    在网上找了这三个软件的评测版试了一下, 最后觉得还是Frontline比较好用。主要是这个软件有一个时序图的功能,这个功能对于我们这种对蓝牙协议不是很熟的人来说很有用。

    每次需要确认配对的设备蓝牙连接时序图

图二 每次需要确认配对的设备蓝牙连接时序图

不需要确认配对的设备蓝牙连接时序图

图三 不需要确认配对的设备蓝牙连接时序图


对比蓝牙授权请求发出后两台设备交互请求的不同, 我们很容易发现, 双方在交互Key的过程中,出现了问题。需要确认设备配对(图二)双方交互key后, 设备方不认可,随后就发出了设备I/O兼容请求。这应该就是问题的所在, 设备蓝牙模块在处理key时应该有bug。
问题解决

至此,我们确定了问题的原因。 那么下来怎么解决这个问题可并不容易。解决这个问题有两个方案:

  1. 蓝牙固件代码修改----这个问题大概率是蓝牙硬件模块代码的问题(当然安卓系统也有可能有问题,这种概率很小,因为一方面大部分设备都出问题,另一方面,市场上蓝牙设备那么多,如果是安卓系统的问题,这个问题应该早被提出来修改了。),涉及到硬件的固件的修改。这个方案是比较优雅的解决方案,但实施起来也有一定难度, 因为我们的设备都已经卖给了客户, 升级固件实际上是很难实现的。不管怎么说,厂家修复后,以后的产品不会出现问题。
  2. 修改应用程序软件代码-------这个方案的思路是,设置消息优先级,在程序中优先接收蓝牙配对请求,模拟系统蓝牙配对的过程,在过程中不显示对话框。请参考这篇文章。
    但这种方法因为需要BLUETOOTH_PRIVILEGED权限,而这个权限是系统级应用才有的,需要对应用进行系统签名,做成系统应用。这对我们并不适合。当然重写蓝牙通讯栈API或者不用安卓系统蓝牙API用第三方的蓝牙API也能解决这个问题,但不太现实, 所以我们只能放弃软件的解决方案。只能选用第一种方案,虽然不够完美,因为现有的用户没法更改固件。 不过幸亏,这个Bug不影响蓝牙传输功能, 对用户来说就是繁琐些,但也只能如此了。
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值