安卓源码避坑指南11—手机侧连接HFP总是失败

2023-10-24 17:59

本文主要是介绍安卓源码避坑指南11—手机侧连接HFP总是失败,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

手机侧连接HFP总是失败

在这里插入图片描述

安卓版本:Android-9(P版本)

问题现象:手机侧主动连接设备蓝牙总是出现通话不可用

蓝牙连接出现通话协议不可用,说明此次连接中 HFP 连接失败,从而导致通话不可用,HFP相关的连接流程可查看往期文章,此处直接进入正题。

首先查看设备端的HCI,明显看到手机主动连接RFCOMM请求DLC参数协商时,设备侧总是拒绝回复DM,并断开此次的L2CAP链路。
在这里插入图片描述

从logcat上能更加清晰知晓设备侧回复DM的具体原因:没找到与之匹配的服务端口 tPORT

01-01 00:44:20.182  1068  1684 D bt_rfcomm: RFCOMM_BufDataInd: Handle multiplexer event 0, p_mcb=0x76aa7ff100
01-01 00:44:20.182  1068  1684 I bt_rfcomm: rfc_mx_sm_state_wait_sabme - evt:0
01-01 00:44:20.182  1068  1684 I bt_rfcomm: rfc_timer_stop
01-01 00:44:20.182  1068  1684 I bt_rfcomm: PORT_StartInd
01-01 00:44:20.182  1068  1684 D bt_rfcomm: PORT_StartInd, RFCOMM_StartRsp RFCOMM_SUCCESS: p_mcb:0x76aa7ff100
01-01 00:44:20.182  1068  1684 I bt_rfcomm: rfc_mx_sm_state_wait_sabme - evt:7
01-01 00:44:20.182  1068  1684 I bt_rfcomm: PORT_StartCnf result:0
01-01 00:44:20.182  1068  1684 I bt_rfcomm: rfc_timer_start - timeout:2 seconds
01-01 00:44:20.193  1068  1684 D bt_rfcomm: RFCOMM_BufDataInd: Handle multiplexer event 4, p_mcb=0x76aa7ff100
01-01 00:44:20.193  1068  1684 D bt_rfcomm: rfc_process_mx_message: type=128, p_mcb=0x76aa7ff100
01-01 00:44:20.193  1068  1684 I bt_stack: [INFO:port_utils.cc(322)] port_find_mcb_dlci_port: Cannot find allocated RFCOMM app port for DLCI 4 on 90:94:97:30:50:21, p_mcb=0x76aa7ff100
01-01 00:44:20.193  1068  1684 I bt_rfcomm: PORT_ParNegInd dlci:4 mtu:256
01-01 00:44:20.193  1068  1684 E bt_stack: [ERROR:port_rfc.cc(285)] PORT_ParNegInd: Disconnect RFCOMM, port not found, dlci=4, p_mcb=0x76aa7ff100, bd_addr=90:94:97:30:50:21
01-01 00:44:20.193  1068  1684 I bt_rfcomm: rfc_timer_start - timeout:2 seconds

查看代码,确定该服务端口是由HF侧通过 bta_hf_client_start_server() 创建并等待AG侧发起连接时使用的。

并且该服务端口的创建在协议栈代码中只有两处调用到:

  1. bta_hf_client_api_enable()协议栈初始化成功后
  2. bta_hf_client_mgmt_cback()前一个AG侧发起的连接成功后

既然协议栈已经考虑到AG侧主动来连接HFP的场景,且做好了相关服务端口的初始化工作,那么本问题中出现端口无法匹配到的情况,又是怎么回事呢? 难道端口没有被创建出来?

带着这样的疑问继续分析logcat,发现在首次无法匹配到服务端口前有一处异常:HFP连接已达最大连接数时,如果再有HFP的连接请求从AG侧过来,HF侧会直接断开新的连接

01-01 00:36:58.991  1068  1684 D bt_rfcomm: PORT_DlcEstablishInd p_mcb:0x76aa7ff5e0, dlci:4 mtu:1685i, p_port:0x76aa7ff048
01-01 00:36:58.991  1068  1684 I bt_rfcomm: rfc_timer_stop
01-01 00:36:58.991  1068  1684 W bt_btif : bta_hf_client_find_cb_by_rfc_handle: no cb yet 30 alloc 1 conn_handle 29
01-01 00:36:58.991  1068  1684 E bt_btif : bta_hf_client_find_cb_by_rfc_handle: no cb found for rfc handle 30
01-01 00:36:58.992  1068  1684 I bt_rfcomm: PORT_CheckConnection() handle:30
01-01 00:36:58.992  1068  1684 W bt_btif : bta_hf_client_find_cb_by_bda: bdaddr mismatch for handle 0 alloc 1
01-01 00:36:58.992  1068  1684 E bt_btif : bta_hf_client_find_cb_by_bda: block not found
01-01 00:36:58.992  1068  1684 W bt_btif : bta_hf_client_allocate_handle: control block already used index 0
01-01 00:36:58.992  1068  1684 E bt_btif : bta_hf_client_allocate_handle: all control blocks in use!
01-01 00:36:58.992  1068  1684 E bt_btif : bta_hf_client_find_cb_by_handle: handle out of range (1, 1) 65535
01-01 00:36:58.992  1068  1684 E bt_btif : bta_hf_client_mgmt_cback: error allocating a new handle 65535
01-01 00:36:58.992  1068  1684 I bt_rfcomm: RFCOMM_RemoveServer() handle:30
01-01 00:36:58.992  1068  1684 I bt_rfcomm: rfc_port_timer_start - timeout:3 seconds
01-01 00:36:58.992  1068  1684 E bt_btif : bta_hf_client_find_cb_by_handle: handle out of range (1, 1) 0
01-01 00:36:58.992  1068  1684 E bt_btif : bta_hf_client_sm_execute: cb not found for handle 0
01-01 00:36:59.000  1068  1684 D bt_rfcomm: RFCOMM_BufDataInd: Handle multiplexer event 4, p_mcb=0x76aa7ff5e0
01-01 00:36:59.000  1068  1684 D bt_rfcomm: rfc_process_mx_message: type=224, p_mcb=0x76aa7ff5e0
01-01 00:36:59.000  1068  1684 I bt_rfcomm: PORT_ControlInd
01-01 00:36:59.000  1068  1684 I bt_rfcomm: PORT_ControlInd DTR_DSR : 1, RTS_CTS : 1, RI : 0, DCD : 1
01-01 00:36:59.001  1068  1684 W bt_rfcomm: rfc_port_sm_disc_wait_ua, RFC_EVENT_DM|RFC_EVENT_UA[1], index=30
01-01 00:36:59.001  1068  1684 I bt_rfcomm: rfc_port_timer_stop
01-01 00:36:59.001  1068  1684 I bt_rfcomm: rfc_mx_sm_state_connected - evt:8
01-01 00:36:59.001  1068  1684 I bt_rfcomm: rfc_timer_start - timeout:3 seconds
01-01 00:36:59.001  1068  1684 W bt_rfcomm: port_rfc_closed: RFCOMM connection closed, index=30, state=2 reason=Closed[19], UUID=111E, bd_addr=fc:d4:36:22:22:29, is_server=1
01-01 00:36:59.001  1068  1684 D bt_rfcomm: port_release_port p_port: 0x76aa7ff048 state: 0 keep_handle: 0
01-01 00:36:59.001  1068  1684 I bt_rfcomm: rfc_timer_start - timeout:2 seconds
01-01 00:36:59.001  1068  1684 I bt_rfcomm: rfc_port_timer_stop
01-01 00:36:59.001  1068  1684 D bt_rfcomm: port_release_port Clean-up handle: 30

因此在 bta_hf_client_mgmt_cback() 回调函数中因为连接数已达最大值而导致HFP连接失败,首先会 RFCOMM_RemoveServer() 清除掉此次连接所使用的服务端口,但是没有启动创建新服务端口等待其他连接请求。

解决方案:
在bta_hf_client_mgmt_cback()回调中不管连接成功还是失败都重新创建新的服务端口,保证后续AG侧的HFP连接请求都能正常回复。感兴趣的小伙伴欢迎私信留言一起讨论,共同学习,一起进步!

更多互联互通技术,欢迎关注微信公众号:Connectivity
在这里插入图片描述

这篇关于安卓源码避坑指南11—手机侧连接HFP总是失败的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/276852

相关文章

PostgreSQ数据库实现在Windows上异地自动备份指南的详细教程

《PostgreSQ数据库实现在Windows上异地自动备份指南的详细教程》这篇文章主要为大家详细介绍了如何在Windows系统上实现PostgreSQL数据库的异地自动备份,文中的示例代码讲解详细,... 目录前期准备实现步骤步骤一:创建备份脚本步骤二:配置免密登录(可选但推荐)步骤三:设置任务计划程序步

Python在二进制文件中进行数据搜索的实战指南

《Python在二进制文件中进行数据搜索的实战指南》在二进制文件中搜索特定数据是编程中常见的任务,尤其在日志分析、程序调试和二进制数据处理中尤为重要,下面我们就来看看如何使用Python实现这一功能吧... 目录简介1. 二进制文件搜索概述2. python二进制模式文件读取(rb)2.1 二进制模式与文本

SpringBoot整合 Quartz实现定时推送实战指南

《SpringBoot整合Quartz实现定时推送实战指南》文章介绍了SpringBoot中使用Quartz动态定时任务和任务持久化实现多条不确定结束时间并提前N分钟推送的方案,本文结合实例代码给大... 目录前言一、Quartz 是什么?1、核心定位:解决什么问题?2、Quartz 核心组件二、使用步骤1

在C#中分离饼图的某个区域的操作指南

《在C#中分离饼图的某个区域的操作指南》在处理Excel饼图时,我们可能需要将饼图的各个部分分离出来,以使它们更加醒目,Spire.XLS提供了Series.DataFormat.Percent属性,... 目录引言如何设置饼图各分片之间分离宽度的代码示例:从整个饼图中分离单个分片的代码示例:引言在处理

Python列表的创建与删除的操作指南

《Python列表的创建与删除的操作指南》列表(list)是Python中最常用、最灵活的内置数据结构之一,它支持动态扩容、混合类型、嵌套结构,几乎无处不在,但你真的会创建和删除列表吗,本文给大家介绍... 目录一、前言二、列表的创建方式1. 字面量语法(最常用)2. 使用list()构造器3. 列表推导式

Prometheus+cpolar如何在手机上也能监控服务器状态?

《Prometheus+cpolar如何在手机上也能监控服务器状态?》本文强调了通过Cpolar这一内网穿透工具,轻松突破Prometheus仅限于局域网访问的限制,实现外网随时随地访问监控数据,教你... 目录前言1.安装prometheus2.安装cpolar实现随时随地开发3.配置公网地址4.保留固定

Python数据验证神器Pydantic库的使用和实践中的避坑指南

《Python数据验证神器Pydantic库的使用和实践中的避坑指南》Pydantic是一个用于数据验证和设置的库,可以显著简化API接口开发,文章通过一个实际案例,展示了Pydantic如何在生产环... 目录1️⃣ 崩溃时刻:当你的API接口又双叒崩了!2️⃣ 神兵天降:3行代码解决验证难题3️⃣ 深度

Python+FFmpeg实现视频自动化处理的完整指南

《Python+FFmpeg实现视频自动化处理的完整指南》本文总结了一套在Python中使用subprocess.run调用FFmpeg进行视频自动化处理的解决方案,涵盖了跨平台硬件加速、中间素材处理... 目录一、 跨平台硬件加速:统一接口设计1. 核心映射逻辑2. python 实现代码二、 中间素材处

JavaWeb项目创建、部署、连接数据库保姆级教程(tomcat)

《JavaWeb项目创建、部署、连接数据库保姆级教程(tomcat)》:本文主要介绍如何在IntelliJIDEA2020.1中创建和部署一个JavaWeb项目,包括创建项目、配置Tomcat服务... 目录简介:一、创建项目二、tomcat部署1、将tomcat解压在一个自己找得到路径2、在idea中添加

SpringBoot项目整合Netty启动失败的常见错误总结

《SpringBoot项目整合Netty启动失败的常见错误总结》本文总结了SpringBoot集成Netty时常见的8类问题及解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参... 目录一、端口冲突问题1. Tomcat与Netty端口冲突二、主线程被阻塞问题1. Netty启动阻