安卓源码避坑指南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

相关文章

python中各种常见文件的读写操作与类型转换详细指南

《python中各种常见文件的读写操作与类型转换详细指南》这篇文章主要为大家详细介绍了python中各种常见文件(txt,xls,csv,sql,二进制文件)的读写操作与类型转换,感兴趣的小伙伴可以跟... 目录1.文件txt读写标准用法1.1写入文件1.2读取文件2. 二进制文件读取3. 大文件读取3.1

SpringBoot中配置Redis连接池的完整指南

《SpringBoot中配置Redis连接池的完整指南》这篇文章主要为大家详细介绍了SpringBoot中配置Redis连接池的完整指南,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以... 目录一、添加依赖二、配置 Redis 连接池三、测试 Redis 操作四、完整示例代码(一)pom.

Java 正则表达式URL 匹配与源码全解析

《Java正则表达式URL匹配与源码全解析》在Web应用开发中,我们经常需要对URL进行格式验证,今天我们结合Java的Pattern和Matcher类,深入理解正则表达式在实际应用中... 目录1.正则表达式分解:2. 添加域名匹配 (2)3. 添加路径和查询参数匹配 (3) 4. 最终优化版本5.设计思

Linux内核参数配置与验证详细指南

《Linux内核参数配置与验证详细指南》在Linux系统运维和性能优化中,内核参数(sysctl)的配置至关重要,本文主要来聊聊如何配置与验证这些Linux内核参数,希望对大家有一定的帮助... 目录1. 引言2. 内核参数的作用3. 如何设置内核参数3.1 临时设置(重启失效)3.2 永久设置(重启仍生效

Python列表去重的4种核心方法与实战指南详解

《Python列表去重的4种核心方法与实战指南详解》在Python开发中,处理列表数据时经常需要去除重复元素,本文将详细介绍4种最实用的列表去重方法,有需要的小伙伴可以根据自己的需要进行选择... 目录方法1:集合(set)去重法(最快速)方法2:顺序遍历法(保持顺序)方法3:副本删除法(原地修改)方法4:

使用Python实现全能手机虚拟键盘的示例代码

《使用Python实现全能手机虚拟键盘的示例代码》在数字化办公时代,你是否遇到过这样的场景:会议室投影电脑突然键盘失灵、躺在沙发上想远程控制书房电脑、或者需要给长辈远程协助操作?今天我要分享的Pyth... 目录一、项目概述:不止于键盘的远程控制方案1.1 创新价值1.2 技术栈全景二、需求实现步骤一、需求

MySQL中的交叉连接、自然连接和内连接查询详解

《MySQL中的交叉连接、自然连接和内连接查询详解》:本文主要介绍MySQL中的交叉连接、自然连接和内连接查询,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、引入二、交php叉连接(cross join)三、自然连接(naturalandroid join)四

Pyserial设置缓冲区大小失败的问题解决

《Pyserial设置缓冲区大小失败的问题解决》本文主要介绍了Pyserial设置缓冲区大小失败的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录问题描述原因分析解决方案问题描述使用set_buffer_size()设置缓冲区大小后,buf

PyInstaller打包selenium-wire过程中常见问题和解决指南

《PyInstaller打包selenium-wire过程中常见问题和解决指南》常用的打包工具PyInstaller能将Python项目打包成单个可执行文件,但也会因为兼容性问题和路径管理而出现各种运... 目录前言1. 背景2. 可能遇到的问题概述3. PyInstaller 打包步骤及参数配置4. 依赖

python连接本地SQL server详细图文教程

《python连接本地SQLserver详细图文教程》在数据分析领域,经常需要从数据库中获取数据进行分析和处理,下面:本文主要介绍python连接本地SQLserver的相关资料,文中通过代码... 目录一.设置本地账号1.新建用户2.开启双重验证3,开启TCP/IP本地服务二js.python连接实例1.