android HFPclient的相关分析

12 篇文章 0 订阅

在高通平台和三星平台上调过这个功能,基于安卓6.0,该功能是将手机上的蓝牙功能用成和蓝牙耳机一样的功能。蓝牙电话和蓝牙音乐它们之间的差异较大,蓝牙电话要求实时性比较高,其和A2DP使用的物理通路并不一致,蓝牙电话走pcm物理通路,而蓝牙音乐走uart通路。

关键词

Hfpclient   BT SCO   ATA command

在调试该功能时,最好能先测试一下,如下信号指标是否符合要求,以免带来卡顿和断连等不可靠因素。

此外,还要测试频偏,其晶振以及外围的电容等器件也会影响,一般在正负10之内,否则也可能会导致卡顿或断连等现象。

开启HFP client支持

首先将hfp client角色功能打开。

packages/apps/Bluetooth/res/values/config.xml

    <bool name="profile_supported_hs_hfp">false</bool>
    <bool name="profile_supported_hfpclient">true</bool>
首先将hfp client角色功能打开。
修改后以支持电话功能,但是手机连接后会断开,并有如下错误信息:

01-12 17:51:58.850  3319  3572 E bt_rfcomm: PORT_DataInd, p_port:0xe2ece48c, p_data_co_callback is null
01-12 17:51:58.850  3319  3572 E bt_btif : HFPClient: Failed to create SLC due to AT error, disconnecting (2)
截屏如下:

出错信息提示是

01-12 17:51:58.850  3319  3572 E bt_rfcomm: PORT_DataInd, p_port:0xe2ece48c, p_data_co_callback is null
01-12 17:51:58.850  3319  3572 E bt_btif : HFPClient: Failed to create SLC due to AT error, disconnecting (2)

这是提示AT命令错误,蓝牙电话使用AT命令子集。这是因为不支持codec negotiate特点,修改如下:
system/bt/bta/hf_client/bta_hf_client_at.c
 static void bta_hf_client_handle_brsf(UINT32 value)
 {
     APPL_TRACE_DEBUG("%s 0x%x", __FUNCTION__, value);
-    bta_hf_client_cb.scb.peer_features = value;
+    bta_hf_client_cb.scb.peer_features = value & ~0x200;

 }
到这里应该有蓝牙提示音出现了。也就是蓝牙的呼叫事件能够正常响应了,但是呼叫响应是通过UART走的是AT command协议,提示音是hfp client自带的。
codec negotiate是为了支持宽带语音信号,支持16KHz的语音信号,在支持这一feature时,hfpclient和设备之间会进行协商,以期望使用wbs方式数据。

HeadsetClientStateMachine.java

如果想更改蓝牙提示音,修改如下文件;

@@ -126,7 +126,7 @@ final class HeadsetClientStateMachine extends StateMachine {
     private int mIndicatorCallHeld;
     private boolean mVgsFromStack = false;
     private boolean mVgmFromStack = false;
-    private Uri alert = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
+    private Uri alert = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
有+++号的是调试信息,Enter AudioOn是进入蓝牙电话的语音了,可以看到语音的采样率是8KHz。
 

 

 

蓝牙语音的物理通路

正如开篇提到的,语音数据不走UART,而是走PCM或者IIS,这一信息在:
hardware/broadcom/libbt/src/hardware.c
当然高通平台未使用博通的芯片时,不会有这个问题,而且目录和代码的差异性也非常大,基本上高通将底层细节都屏蔽了,走高通adsp通路时,开发者甚至都不需要关系语音走的底层物理通路。

<code class="language-plain">#define HCI_VSC_WRITE_PCM_DATA_FORMAT_PARAM     0xFC1E
#define HCI_VSC_WRITE_I2SPCM_INTERFACE_PARAM    0xFC6D
#define HCI_VSC_ENABLE_WBS                      0xFC7E</code>

这是三星平台使用博通芯片定义的数据格式,这在使用btsnoop工具抓数据时,可以看到这类的命令。btsnoop抓到的数据可以使用comprobe工具进行解析查看。

            #define HCI_VSC_WRITE_SCO_PCM_INT_PARAM         0xFC1C
 
                /* do we need this VSC for I2S??? */
                UINT16_TO_STREAM(p, HCI_VSC_WRITE_SCO_PCM_INT_PARAM);
                *p++ = SCO_PCM_PARAM_SIZE;
                memcpy(p, &bt_sco_param, SCO_PCM_PARAM_SIZE);
                ALOGI("SCO PCM configure {0x%x, 0x%x, 0x%x, 0x%x, 0x%x}",
                        bt_sco_param[0], bt_sco_param[1], bt_sco_param[2], bt_sco_param[3],
                        bt_sco_param[4]);
                if ((ret = bt_vendor_cbacks->xmit_cb(HCI_VSC_WRITE_SCO_PCM_INT_PARAM, p_buf,
                        hw_sco_i2spcm_cfg_cback)) == FALSE)
                {
                    bt_vendor_cbacks->dealloc(p_buf);
                }
                else
                    return;

如果是基于手机方案的,基本以上设置基本就可以了。手机方案的图如下(略去了基带)
但是如果BT的PCM没有和codec直接连接,而是像UART一样和AP直接相连接,这样就要涉及到驱动的改动了。

首先ap侧需要编写驱动程序以将codec实现的功能由ap完成,并且,codec和headset设备的连接也变成了ap和headset设备的连接,这样就存在对audiopolicy的部分了,毕竟最基本的是audio engin对audio device的选择,由于是通话场景,需要使用low latency buffer,或之类似的,AOSP中就有这一类。gao 高通的ADSP也有从硬件到软件的架构支持。

内核的修改涉及的是alsa驱动的编写,主要包括设备树,pcm驱动,machine驱动以及bt虚拟出来的codec驱动,因为bt的硬件配置等在安卓6.0时放在了蓝牙协议栈中,所以这里使用虚拟codec实现是一个好的解决方案。

1)hardware/broadcom/libbt/include/vnd_avl8890.txt 

SCO_I2SPCM_IF_ROLE = 1 

SCO_PCM_IF_CLOCK_MODE = 1 

SCO_PCM_IF_SYNC_MODE = 1 

1改成0   --》0是slave,1是master

 

2)上面txt里的flag最终影响bt_vendor_brcm.h,需要检查里面的bt设置跟AP侧PCM设置是否一样

如:

 /* PCM_DATA_FMT_SHIFT_MODE 0 : MSB first 1 : LSB first */ 

#ifndef PCM_DATA_FMT_SHIFT_MODE 

#define PCM_DATA_FMT_SHIFT_MODE 0 
#endif</code>

 

 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值