开发者手机与华为AI音响断开蓝牙连接不完全的案例分析
1 关键字
取消配对,连接状态,SDP(服务发现协议),HFP(HandsFree Profile),HSP(HeadSet Profile)
2 问题描述
设备:开发者手机 ; 华为蓝牙AI音响;
OH版本:4.0.10. 311 ;
问题现象:蓝牙音响先与开发者手机配对,在已配对列表里点击华为音响栏最右边的小齿轮,在弹出的界面点击取消配对。然后在可用列表里等待开发者手机再次搜索到华为AI音响,结果是在搜索到的可用设备列表里该栏下方显示"正在配对..."字样。
3 问题原因
蓝牙音响与开发者手机配对后,开发者手机会向蓝牙音响发起连接,连接过程中SDP服务首先发起查找HFP(HandsFree)服务,查找完HFP的SDP服务后,根据系统配置是否需要继续查找HSP(HeadSet)服务,若配置了HSP服务,则继续查找HSP的SDP服务,如果找到HSP服务,则上报状态,在查找HSP服务结束后,这个函数直接return出去了,没有处理没有找到HSP但是找到HFP的情况。如果HSP和HFP都没找到则没有做任何处理,正确流程应该是上报没找到服务的结果,然后触发断开HFP的连接流程。
出现这个问题主要是由于该蓝牙音响即不支持HFP也不支持HSP,导致两次SDP服务都查找失败,然而并没有上报这个结果,而底层是根据这个上报结果的事件触发HFP连接断开。由于没有上报查找失败的结果,底层没有断开HFP状态,取消配对后,再次搜索到的设备因为HFP状态为连接状态,hap层就会显示"正在配对..."的字样。
4 解决方案
在HSP的sdp回调函数里将上报查找结果的函数移到最后,不管是否成功找到服务,都将结果上报给底层。由于默认的状态是失败,原代码是只有查找成功的情况下才会上报状态。
5 定位过程
1. 复现测试机与蓝牙音响配对后,再取消配对,在可用设备列表里仍显示正在配对的问题,下载snoop日志,并用蓝牙耳机做同样的操作,也下载snoop日志,比较两者的日志,分析取消配对后的协议流程。
2. 在hilog日志里面定位到取消配对的时间点,找到调用napi的js取消配对接口,从该日志出发,每一条日志的输出都找到对应的代码里位置,并记录下整个取消配对的流程。分析取消配对的流程代码。包括取消配对的配对状态改变上报的处理。
3. 通过分析hilog日志,发现断开连接后setting的日志里有关于hsp的profileState值为1,连接状态没有断开,对比snoop日志发现,测试机向蓝牙音响发起了hfp和hsp的SDP服务发现请求,但蓝牙音响回复的SDP响应包里对hsp不支持。于是修改hfp和hsp的配置使不发起相应的SDP请求,重新编译版本并刷机测试验证,发现问题没有出现,基本确定这个问题是和HFP和HSP服务相关。
4. 查看取消配对后的hilog日志,发现napi层发起了查询A2DP,HFP, HID的状态的接口,根据日志和代码跟踪这3种状态查询的流程。异常日志里查询到的HFP的ConnectionState为1,而正常的日志里查询到的3个状态均为0,在代码里搜索关于HFP状态变化的地方,查找该状态不为0的原因。
5.从hilog日志层面分析问题,发现取消配对后,hfp_ag收到OnDisconnectCompleted事件后,删除该设备后就没有其他动作,比较正常情况下的hilog日志发现,hfp_ag收到断连事件并删除设备后,接下来会调用DataConnectionCallback函数,在该回调里最终调用了OnConnectionStateChanged,修改了hfp的连接状态。
6.跟踪代码里HFP的连接过程,在开始查找HFP的SDP服务后,若配置了HSP服务,则继续查找HSP的SDP服务,如果找到HSP服务,则上报状态,如果HSP和HFP都没找到则没有做任何处理,正确流程应该是上报没找到服务的结果,然后触发断开HFP的连接流程。修改了没找到HSP和HFP后,上报一个查找失败的结果,编译代码并生成版本,烧录到开发机测试并验证问题,验证结果ok,没有出现该问题。
而在SdpHspHsCallback函数里面只针对修改了hfProfileState_值的时候才上报sdp的发现结果,疏露了没有修改hfProfileState_的情况,当既没发现hfp也没发现hsp的情况下,就不会修改hfProfileState_的值,这种情况下没有上报sdp查找失败的结果,而上层调用函数直接return了,导致最终底层不知道HFP层已经断开的事实。
6 知识分享
- 需要熟悉蓝牙协议相关知识,包括SDP, HFP, HSP等。
- 参考链接 蓝牙协议栈学习笔记_att_find_information_req-CSDN博客
更多推荐
所有评论(0)