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

相关文章

W外链微信推广短连接怎么做?

制作微信推广链接的难点分析 一、内容创作难度 制作微信推广链接时,首先需要创作有吸引力的内容。这不仅要求内容本身有趣、有价值,还要能够激起人们的分享欲望。对于许多企业和个人来说,尤其是那些缺乏创意和写作能力的人来说,这是制作微信推广链接的一大难点。 二、精准定位难度 微信用户群体庞大,不同用户的需求和兴趣各异。因此,制作推广链接时需要精准定位目标受众,以便更有效地吸引他们点击并分享链接

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟 开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚 第一站:海量资源,应有尽有 走进“智听

安卓链接正常显示,ios#符被转义%23导致链接访问404

原因分析: url中含有特殊字符 中文未编码 都有可能导致URL转换失败,所以需要对url编码处理  如下: guard let allowUrl = webUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else {return} 后面发现当url中有#号时,会被误伤转义为%23,导致链接无法访问

Retrieval-based-Voice-Conversion-WebUI模型构建指南

一、模型介绍 Retrieval-based-Voice-Conversion-WebUI(简称 RVC)模型是一个基于 VITS(Variational Inference with adversarial learning for end-to-end Text-to-Speech)的简单易用的语音转换框架。 具有以下特点 简单易用:RVC 模型通过简单易用的网页界面,使得用户无需深入了

Java 创建图形用户界面(GUI)入门指南(Swing库 JFrame 类)概述

概述 基本概念 Java Swing 的架构 Java Swing 是一个为 Java 设计的 GUI 工具包,是 JAVA 基础类的一部分,基于 Java AWT 构建,提供了一系列轻量级、可定制的图形用户界面(GUI)组件。 与 AWT 相比,Swing 提供了许多比 AWT 更好的屏幕显示元素,更加灵活和可定制,具有更好的跨平台性能。 组件和容器 Java Swing 提供了许多

Java ArrayList扩容机制 (源码解读)

结论:初始长度为10,若所需长度小于1.5倍原长度,则按照1.5倍扩容。若不够用则按照所需长度扩容。 一. 明确类内部重要变量含义         1:数组默认长度         2:这是一个共享的空数组实例,用于明确创建长度为0时的ArrayList ,比如通过 new ArrayList<>(0),ArrayList 内部的数组 elementData 会指向这个 EMPTY_EL

如何在Visual Studio中调试.NET源码

今天偶然在看别人代码时,发现在他的代码里使用了Any判断List<T>是否为空。 我一般的做法是先判断是否为null,再判断Count。 看了一下Count的源码如下: 1 [__DynamicallyInvokable]2 public int Count3 {4 [__DynamicallyInvokable]5 get

工厂ERP管理系统实现源码(JAVA)

工厂进销存管理系统是一个集采购管理、仓库管理、生产管理和销售管理于一体的综合解决方案。该系统旨在帮助企业优化流程、提高效率、降低成本,并实时掌握各环节的运营状况。 在采购管理方面,系统能够处理采购订单、供应商管理和采购入库等流程,确保采购过程的透明和高效。仓库管理方面,实现库存的精准管理,包括入库、出库、盘点等操作,确保库存数据的准确性和实时性。 生产管理模块则涵盖了生产计划制定、物料需求计划、

基于UE5和ROS2的激光雷达+深度RGBD相机小车的仿真指南(五):Blender锥桶建模

前言 本系列教程旨在使用UE5配置一个具备激光雷达+深度摄像机的仿真小车,并使用通过跨平台的方式进行ROS2和UE5仿真的通讯,达到小车自主导航的目的。本教程默认有ROS2导航及其gazebo仿真相关方面基础,Nav2相关的学习教程可以参考本人的其他博客Nav2代价地图实现和原理–Nav2源码解读之CostMap2D(上)-CSDN博客往期教程: 第一期:基于UE5和ROS2的激光雷达+深度RG

Java 连接Sql sever 2008

Java 连接Sql sever 2008 /Sql sever 2008 R2 import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; public class TestJDBC