简体   繁体   English

如何修改Android的蓝牙堆栈以启用A2dp接收器

[英]How To Modify Android's Bluetooth Stack to Enable A2dp Sink

I'm working on an audio recorder app that uses a bluetooth mic to record audio on to an Android device (Nexus 7 - rooted Android 4.4.2). 我正在制作一个录音机应用程序,它使用蓝牙麦克风将音频录制到Android设备上(Nexus 7 - 扎根Android 4.4.2)。 It's currently implemented on HFP and everything is working fine. 它目前在HFP上实施,一切正常。 The bluetooth mic is implemented with Bluegiga's WT32 bluetooth module + a mic input, audio quality via HFP isn't great but it's sufficient for now. 蓝牙麦克风是用Bluegiga的WT32蓝牙模块+麦克风输入实现的,通过HFP的音质不是很好,但现在已足够了。

However, I'm now trying to change the bluetooth profile to A2dp, since there are two mic inputs (L/R) and WT32 supports A2dp (source). 但是,我现在正试图将蓝牙配置文件更改为A2dp,因为有两个麦克风输入(L / R)和WT32支持A2dp(源)。 After much research I found that stock Android doesn't support A2dp (sink), and it's possible to modify Android's bluetooth stack to enable A2dp (sink). 经过大量研究后,我发现Android不支持A2dp(接收器),并且可以修改Android的蓝牙堆栈以启用A2dp(接收器)。

What I don't understand is how does one access and modify the bluetooth stack. 我不明白的是如何访问和修改蓝牙堆栈。 It would be nice if someone with an answer is able to break-down the steps to achieve this. 如果有答案的人能够分解实现这一目标的步骤,那就太好了。

I've tried following the answer to this question: Receive audio via Bluetooth in Android , yet I can't seem to find the appropriate file to modify. 我已经尝试过这个问题的答案: 在Android中通过蓝牙接收音频 ,但我似乎无法找到要修改的相应文件。 Actually, I don't even know if I'm looking into the right folder. 实际上,我甚至不知道我是否正在查找正确的文件夹。 I've looked through the devices file via Android-studio's DDMS-File Explorer. 我通过Android-studio的DDMS-File Explorer查看了设备文件。

ps, I'm still fairly new with Android app development, so I may have misused some of the terminologies and I apologies in-advance for that. ps,我对Android应用程序开发还是比较新的,所以我可能误用了一些术语,并为此提前道歉。

So the above answer isn't totally correct. 所以上面的答案并不完全正确。

The following is how it breaks down: 以下是它如何分解:

HAL, is the hardware abstraction layer that implements the actual Bluetooth state machines in c/cpp code, as such it controls the various state machines for A2dp, HFP, GATT, SPP, AVRCP, etc. services. HAL是硬件抽象层,它以c / cpp代码实现实际的蓝牙状态机,因此它控制A2dp,HFP,GATT,SPP,AVRCP等服务的各种状态机。 Each of these services also reference SMP and ATT files for controlling the actual Bluetooth server or client databases, and there security. 这些服务中的每一个还引用SMP和ATT文件来控制实际的蓝牙服务器或客户端数据库,并且具有安全性。

HCI, is where the actual work gets done. HCI,是实际工作的地方。 the HAL doesn't really do anything, it assembles the complex data messages that get sent along a tty serial (either spi, or UART) to an inter-network connected chip on the PCBA via the methods used in the HCI layer, which can be found in the "BTE" layer in /external/bluetooth/bluedroid/ directory of an android compiling trunk from AOSP 4.2.2 to current. HAL实际上没有任何事情,它通过HCI层中使用的方法组装从tty串行(spi或UART)发送到PCBA上的网络间连接芯片的复杂数据消息,可以在AOSP 4.2.2到当前的Android编译中继的/ external / bluetooth / bluedroid /目录中的“BTE”层中找到。 - currently there are several manufacturers of these chips but they are mostly all Broadcom based ic's packaged in a dual, or triple radio package that contains a wifi, Bluetooth 4.0 Smart, and Bluetooth 4.0 radio. - 目前有几家这些芯片的制造商,但他们大多数都是基于Broadcom的ic,采用双无线或三无线电封装,包含wifi,蓝牙4.0智能和蓝牙4.0无线电。

It is possible to do what you are trying to do, but you would need to include hardware.so, and bluetooth_jni.so into an NDK/JNI package/project that goes with your apps, and registers via the calls from the .cpp files for each of the Bluetooth services found in "Packages/apps/Bluetooth/jni", you would then handle the registration in your NDK library of 'com_android_bluetooth_a2dp.cpp', and 'com_android_bluetooth_avrcp.cpp', as their appropriately typed objects. 可以执行您要执行的操作,但是您需要将hardware.so和bluetooth_jni.so包含在与您的应用程序一起使用的NDK / JNI程序包/项目中,并通过.cpp文件中的调用进行注册对于“Packages / apps / Bluetooth / jni”中的每个蓝牙服务,您将在NDK库中处理“com_android_bluetooth_a2dp.cpp”和“com_android_bluetooth_avrcp.cpp”中的注册,作为其适当类型的对象。

The other issue is, you will need to implement your own custom A2DP stack, as the Android Bluedroid stack only has bit's and piece's of the Sink role implemented in the frameworks while the A2DP role has a full implementation of Source role. 另一个问题是,您需要实现自己的自定义A2DP堆栈,因为Android Bluedroid堆栈仅在框架中实现了Sink角色的位和部分,而A2DP角色具有角色的完整实现。 Additionally, depending what you actually intend to do with your Bluetooth A2DP sink implementation you will need to implement AVRCP as well - as per the Bluetooth SIG (special interest group), there are inter-connectivity requirements between Bluetooth devices that will lead to major issues if you implement sink role, without AVRCP "remote control target device" and "remote control control device", as the sink role ATT commands from Bluetooth over A2DP (or any Bluetooth service/profile) execute certain handshakes during the service discovery process, when the associated gateway ( the connecting device ), executes a capabilities request the A2DP service is expected to implement i/o capabilities for Start Stop commands, and possibly skip/track advance commands. 此外,根据您实际打算如何处理蓝牙A2DP接收器实现,您还需要实施AVRCP - 根据蓝牙SIG(特殊兴趣小组),蓝牙设备之间存在互连要求,这将导致重大问题如果您实现接收器角色,没有AVRCP“远程控制目标设备”和“远程控制控制设备”,则作为接收器角色ATT命令来自蓝牙A2DP(或任何蓝牙服务/配置文件)在服务发现过程中执行某些握手,当相关网关(连接设备)执行功能请求,A2DP服务应该实现Start Stop命令的I / O功能,并可能跳过/跟踪advance命令。

Additional to all of this, when implementing A2DP you will need to choose whether you will be handling PCM streams or AAC streams. 除此之外,在实施A2DP时,您需要选择是否要处理PCM流或AAC流。 If you are handling AAC streams (or DRM protected PCM streams for that matter, which anything like Pandora, spotify, etc. uses), you need to implement the SBC Encoder or Decoder appropriate to you implementation, else all you will have is a bunch of encrypted data. 如果您正在处理AAC流(或DRM保护的PCM流,就像Pandora,spotify等所使用的那样),您需要实现适合您实现的SBC编码器或解码器,否则您将拥有的只是一堆加密数据。 Also, be sure to implement the bitrate at the appropriate speed for your devices AudioManager implementation, some phones use 48,000hZ and some us 44,100hZ, this is important if you want high quality audio as generally most PCM A2DP implementations that are utilizing Surround Sound 7.1+ will require 48,000hZ as well as AAC encoding/decoding. 此外,确保以适当的速度为您的设备实现比特率AudioManager实现,一些手机使用48,000hZ,一些我们使用44,100hZ,如果您想要高质量音频,这一点很重要,因为通常大多数PCM A2DP实施都使用环绕声7.1 +将需要48,000hZ以及AAC编码/解码。

I hope this provides you with some insight. 我希望这能为您提供一些见解。

https://android-review.googlesource.com/#/c/98161/ implements A2DP Sink. https://android-review.googlesource.com/#/c/98161/实施A2DP Sink。 It works on Nexus 5. You can try it. 它适用于Nexus 5.你可以尝试一下。

This is actually what I'm trying to do for a long time... The reason you can't find the configuration file is because Google replaced the Bluetooth stack from BlueZ with a new stack built by Google and Broadcom. 这实际上是我想要做的很长时间......你无法找到配置文件的原因是因为谷歌用Blue和Google构建的新堆栈取代了BlueZ的蓝牙堆栈。 The new stack uses a different configuration file, which I don't know how to tinker with. 新堆栈使用不同的配置文件,我不知道如何修补。

If you are serious about it, the closest thing I found to start with is the official introduction for the bluetooth framework on Android: https://source.android.com/devices/bluetooth.html 如果你认真对待它,我发现最接近的是Android上的蓝牙框架官方介绍: https//source.android.com/devices/bluetooth.html

There are lots of changes happened in Android OS over the time. 随着时间的推移,Android操作系统发生了很多变化。

As of Android O (Android 8.*), sink profiles are partially supported by Google. 从Android O(Android 8. *)开始,Google会部分支持接收器配置文件。 Such as Audio sink will easily work if enabled in profile. 如果在配置文件中启用,音频接收器将很容易工作。 It looks like the higher layer of BT is kind of implementation complete at the framework, which is in the form of App ie packages/app/Bluetooth (with some bugs but still works). 看起来BT的更高层是在框架中完成的一种实现,它是以App的形式,即packages/app/Bluetooth (有一些错误但仍然有效)。 But all profiles are not completed at framework lower layer via HAL interfaces which is btif framework (such as btif_rc.cpp , etc which you can look at Android source) and which is the replacement to older Bluez stack by Google. 但是所有配置文件都没有在框架下层通过HAL接口完成,这是btif框架(例如btif_rc.cpp等,你可以查看Android源代码),这是Google替代旧的Bluez堆栈。

As I said BT sink is partially implemented and is in work in progress state. 正如我所说,BT接收器部分实现并处于正在进行中状态。 BT sink such as Audio will easily work if enabled as sink profile but not all such as AVRCP will not work. 如果作为接收器配置文件启用,则诸如音频的BT接收器将很容易工作,但并非所有诸如AVRCP都不起作用。 At present, I saw the issue with AOSP code that incoming traffic from the remote device to Android works but outgoing traffic from Android to the remote device doesn't work (upon which AVRCP profile works) as remote device object is not maintained in the stack and so JNI calls from app/Bluetooth fails with null device at btif_*.cpp files. 目前,我看到了AOSP代码的问题,从远程设备到Android的传入流量工作但从Android到远程设备的传出流量不起作用(AVRCP配置文件工作),因为远程设备对象未在堆栈中维护所以来自app / Bluetooth的JNI调用在btif_*.cpp文件中使用null设备失败。 For example, send pass-through commands doesn't work. 例如,发送传递命令不起作用。

So, we may see Bluetooth sink profiles working in future. 因此,我们可能会看到未来的蓝牙接收器配置文件。

If you want to explore more check AOSP, 如果您想了解更多信息,请查看AOSP,

  1. Services at packages/app/Bluetooth/ packages/app/Bluetooth/
  2. HAL's at system/bt/btif/ HAL在system/bt/btif/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM