本篇blog继续以结合日志的形式来分析A2DP,以手机连接上耳机后,播放音乐为例,来分析A2DP的过程,
后续还有blog,通过耳机控制音乐播放的暂停、播放来分析AVRCP的过程,可以阅读https://blog.csdn.net/hihan_5/article/details/127259818。
本章基于Advanced Audio Distribution Profile 1.4 – Bluetooth® Technology Website。
高级音频分发规范 (A2DP) 定义了实现以单声道(mono)、立体声(stereo)或多声道(multi-channel)模式分发高质量音频内容的协议和程序。因此,术语“高级音频(advanced audio)”应与“蓝牙音频(Bluetooth audio)”区分开来,后者表示在蓝牙核心规范第 2 卷 B 部分第 9 节中定义的 SCO 通道上的窄带语音分布。
一个典型的用例是将音乐内容从立体声音乐播放器流式传输到耳机或扬声器。音频数据以适当的格式压缩,以有效利用有限的带宽。
A2DP 专注于音频流,而视频分发配置文件 (VDP) 指定视频流。对这两种配置文件的支持可以分发带有高质量音频的视频内容。 VDP中描述了视频和音频流的使用案例。
另请注意,A2DP 不包括远程控制功能。设备可以通过实现 A2DP 和所描述的控制配置文件来支持远程控制功能,例如,在音频/视频远程控制配置文件 (AVRCP) 的使用场景中。
如图 1.1 所示,A2DP 取决于通用访问配置文件 (GAP) 以及通用音频/视频分发配置文件 (GAVDP),后者定义了设置音频/视频流所需的程序。 A2DP 定义了特定于音频流的参数和过程。
音频/视频分发传输协议 (AVDTP) 由一个用于协商流参数的信令实体和一个处理流本身的传输实体组成,这部分详见下一章。
图 2.1 所示的应用层是设备定义应用服务和传输服务参数的实体。实体还将音频流数据调整为定义的数据包格式,反之亦然。
Source源 (SRC) – 当设备充当传送到微微网 SNK 的数字音频流的源时,它就是 SRC。
Sink接收器 (SNK) – 当设备充当从同一微微网上的 SRC 传送的数字音频流的接收器时,它就是 SNK
这里需要注意另外一个概念INT和ACP。
发起一个过程的设备被认为是这个过程的INT。 被寻址的设备是过程的 ACP。
流的 INT/ACP 的角色独立于设备作为 SRC/SNK 的角色。
A/V 传输协议中的 INT 和 ACP 角色不应与底层 L2CAP 层中的相应角色混淆。
如果远程设备的 AVDTP 版本未知,则设备应执行 SDP 查询以获取远程设备上的 AVDTP 版本。这应在执行 GAVDP_ConnectionEstablishment 过程之前执行。这是必需的,因为音频流设置过程中的某些命令取决于 AVDTP 版本。
当设备被安排开始流式传输音频内容时,设备首先需要建立流式连接。在这样的设置过程中,设备选择最合适的音频流参数。配置了两种服务;一是应用服务能力,二是传输服务能力。 (有关详细信息,请参阅 AVDTP 中的第 4.4 节。)此配置文件指定了这些信令过程所需的特定于音频的参数。
A2DP的应用服务能力包括音频编解码能力和内容保护能力。传输服务能力由 AVDTP 提供,以便更智能地处理流数据包,这些服务的适当配置增加了通道吞吐量。
一旦建立流连接并执行 GAVDP 中的 Start Streaming 过程,SRC 和 SNK 都处于 STREAMING 状态,其中 SRC (SNK) 准备好发送(接收)音频流。 (参见 GAVDP 中的第 3.1 节。)SRC 使用发送音频流过程将音频数据发送到 SNK,而 SNK 又使用接收音频流过程来接收音频数据。这些过程的框图和创建的数据包格式如图 3.1 所示。
再次注意,设备应处于 STREAMING 状态以发送/接收音频流。如果 SRC/SNK 计划发送/接收音频流,而状态仍处于 OPEN,则 SRC/SNK 应启动 GAVDP 中定义的 Start Streaming 过程。
在发送音频流过程中,如果需要,SRC 将在信令会话中将数据编码为选定的格式。然后,SRC 的应用层应将编码数据适配为定义的媒体有效载荷格式。
SNK 的 AVDTP 实体应使用选定的传输服务从传输通道接收流数据。
这一章讲AVDTP,即音频/视频分发传输协议。基于A/V Distribution Transport Protocol 1.3 – Bluetooth® Technology Website。
图 2.1 显示了 AVDTP、蓝牙协议栈和上层如何集成在一起。 AVDTP 向上层公开了三个接口,向蓝牙协议栈公开了两个接口。为了检索 A/V 设备详细信息,上层使用蓝牙协议栈提供的 SDP 接口。
当 A/V 应用程序通过蓝牙链路传输音频和/或视频流时,AVDTP 执行 A/V 参数协商。基于此协商的结果,A/V 应用程序传输音频和/或视频内容。
上图展示的各个接口描述如下表所示:
图 5.1 显示了 AVDTP 的内部架构。各个模块的功能参考AVDTP文档。
信令过程需要一对互连设备之间的 ACL 链路。
事务在通信设备之间建立的面向连接的通道上执行,由双向异步消息交换组成。
L2CAP 通道用于信令,由 L2CAP 信令命令建立和释放。为 L2CAP 处理的 AVDTP 事务分配特定的协议/服务多路复用器 (PSM) 值。
下图是通用信令命令和响应信号的格式。
(1)Transaction Label
事务标签为来自 INT 的每个未完成的事务指定一个唯一标签。事务标签字段的长度为四位。在 ACP 侧,信令命令帧中接收到的事务标签应作为相应信令响应帧中返回的事务标签。
(2)Packet Type
当信令消息相对于信道的 MTU 要求过大时,发送方应将信令消息分段。发送者也可以决定对消息进行分段以节省资源。该字段指示信令消息由单包或多包组成。在多包情况下,该字段还指示信令消息的包类型(开始包、继续包或结束包)。
(3)Message Type
在每个命令包上,消息类型字段指定信令命令的命令类型。在每个信令响应包上,Message Type 字段指定了 ACP 上相应信令命令的结果。
表8.6为信令ID值:
其信令描述为:
AVDTP 遵循 L2CAP 中定义的事务模型。
图 6.3 显示了管理流连接的总体过程。任何一个或两个设备都可以发起一个流,包括流配置过程、延迟报告过程、流建立过程和流开始过程。
图6.4概述了流端点状态机。不同状态的定义和详细描述见AVDTP第 9 节。当 ACP 拒绝一个 INT 命令时,它应通过回退到该(本地)过程的初始状态来完成该过程。在收到 ACP 一方的拒绝后,INT 应通过回退到该(本地)程序的初始状态来完成该程序
传输过程需要先在一对互连设备之间建立的 ACL 链接。事务在通信设备之间的链路上可用的面向连接的通道上执行。
AVDTP 提供给上层的基本服务只提供信令和媒体流。图 7.1 显示了 AVDTP 和 L2CAP 的配置。两个较低的接口暴露给 L2CAP;这两个接口承载信令包(Signalling Packets)和媒体传输包(Media Packets)。
为了建立流,上层请求信令实体发现、配置和建立流。建立流后,上层可以发送或接收流媒体,取决于流是SRC还是SNK。
信令传输的流程在前面已经讲过了,这部分讲媒体传输。
图 7.2 显示了Media Packet Header格式。媒体包头有 12 个字节的强制字段(带有 SSRC 字段)和可选字段(CSRC)。 SSRC 字段仅用于组播应用,因为 SSRC 字段标识特定媒体传输会话上的源节点 ID。
各个部分的含义如下所示:
以一台手机连接蓝牙耳机听歌为例。
SDP查询AVDTP协议的详细情况;
通过SEP discovery流程,来发现对端设备SEP;
SRC发起Get All Capabilities流程,来获取SNK的服务性能,包括应用层和传输层;
基于获取的SNK所支持的服务,SRC选择相对双方最适合的音频流参数,发起Stream Configuration流程,来完成音频流参数配置;
双方设备通过Stream Establishment流程来建立L2CAP信道,并进入open状态;
本例中,Slave为SNK,Master为SRC。日志资源:https://download.csdn.net/download/hihan_5/86758384。
Frame#605 606是一次Request和Response的过程。
PSM 0x0019表示AVDTP。
SEP架构如下所示,DISCOVER的过程就是去发现对端设备的SEP。
在示例中,首先,Slave发起了DISCOVER流程。本次的流程中,SNK作为INT,SRC作为ACP。
Frame#656为SNK发起的DISCOVER Command。
AVDTP的表8.8为SEP Discovery Response message 格式,RFA表示Reserved for Future Additions,具有此名称的位应设置为零。接收器应忽略这些位。TSEP表示Type Source or Sink。Media Type参考Assigned Numbers | Bluetooth® Technology Website的Audio/Video部分,其他的Field的含义还是很清楚的。
Frame#660为Master(SRC)回复的Response,表明了自己在本次流程中的ACP身份,有3个Media type为audio的SEP。
后来,SRC又作为INT发起了SEP DISCOVER.
Frame#723是SNK作为ACP回复的,它支持4个Media type为Audio的SEP。
查询到对端的SEP后,就要去问候对端的能力了,你行不行?
这里减少一点篇幅,就贴ACP回复给INT的Frame。
首先是SNK询问SRC的回复。
Frame#680 688 697,说明了SRC支持的编码器有SBC、MPEG-2,4 AAC和供应商特定编码器。
关于供应商特定编码器,在A2DP的4.7节有说明。Vendor ID参考Assigned Numbers | Bluetooth® Technology Website的Company Identifiers部分。
我们看Frame#697的Codec Info Element: 0x 2d 01 00 00 aa 00 3c 03,按照上图的格式,转换为从高位到低位阅读的顺序就是:03 3c 00 aa 00 00 01 2d。
经过查询0x012d表示Sony Corporation。
剩下来的部分,可以看下面这段代码的解释。0x00012d表示Sony ID,0x00aa表示Sony Specific Codec Id for LDAC,0x033c表示支持Dual Channel(双声道)和Stereo(立体声),支持采样率频率44.1kHz、48kHz、88.2kHz和96kHz。即这个支持的供应商特定编码器就是LDAC。
// external/libldac/inc/ldacBT.h
/* Codec Specific Information Elements for LDAC
* (based on "LDAC Specification of Bluetooth A2DP Rev.2.0.1")
* | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
* service_caps[4] | SONY ID | Octet0
* service_caps[5] | SONY ID | Octet1
* service_caps[6] | SONY ID | Octet2
* service_caps[7] | SONY ID | Octet3
* service_caps[8] | SONY Specific Codec ID | Octet4
* service_caps[9] | SONY Specific Codec ID | Octet5
* service_caps[A] | RFA | Sampling Frequency | Octet6
* service_caps[B] | RFA | Channel Mode ID | Octet7
*/
#define LDACBT_MEDIA_CODEC_SC_SZ (10+2)
/* [Octet 0-3] Vendor ID for SONY */
#define LDACBT_VENDOR_ID0 0x2D
#define LDACBT_VENDOR_ID1 0x01
#define LDACBT_VENDOR_ID2 0x0
#define LDACBT_VENDOR_ID3 0x0
/* [Octet 4-5] Vendor Specific A2DP Codec ID for LDAC */
#define LDACBT_CODEC_ID0 0xAA
#define LDACBT_CODEC_ID1 0x00
/* [Octet 6]
* [b7,b6] : RFA
* Reserved for future additions.
* Bits with this designation shall be set to zero.
* Receivers shall ignore these bits.
* -----------------------------------------------------
* [b5-b0] : Sampling frequency and its associated bit field in LDAC are shown below.
* | 5 | 4 | 3 | 2 | 1 | 0 |
* | o | | | | | | 44100
* | | o | | | | | 48000
* | | | o | | | | 88200
* | | | | o | | | 96000
* | | | | | o | | 176400
* | | | | | | o | 192000
*
*/
/* Support for 44.1kHz sampling frequency */
#define LDACBT_SAMPLING_FREQ_044100 0x20
/* Support for 48kHz sampling frequency */
#define LDACBT_SAMPLING_FREQ_048000 0x10
/* Support for 88.2kHz sampling frequency */
#define LDACBT_SAMPLING_FREQ_088200 0x08
/* Support for 96kHz sampling frequency */
#define LDACBT_SAMPLING_FREQ_096000 0x04
/* Support for 176.4kHz sampling frequency */
#define LDACBT_SAMPLING_FREQ_176400 0x02
/* Support for 192kHz sampling frequency */
#define LDACBT_SAMPLING_FREQ_192000 0x01
/* [Octet 7]
* [b7-b3] : RFA
* Reserved for future additions.
* Bits with this designation shall be set to zero.
* Receivers shall ignore these bits.
* ------------------------------------------------------
* [b2-b0] : Channel mode and its associated bit field in LDAC are shown below.
* | 2 | 1 | 0 |
* | o | | | MONO
* | | o | | DUAL CHANNEL
* | | | o | STEREO
*/
/* Support for MONO */
#define LDACBT_CHANNEL_MODE_MONO 0x04
/* Support for DUAL CHANNEL */
#define LDACBT_CHANNEL_MODE_DUAL_CHANNEL 0x02
/* Support for STEREO */
#define LDACBT_CHANNEL_MODE_STEREO 0x01
其次是SRC询问SNK的回复,Frame#738 755 790 829,说明了SNK支持的解码器有SBC、MPEG-2,4 AAC、LDAC(该耳机LDAC解码器支持立体声、采样率频率支持44.1kHz、48kHz和96kHz),还有个华为的某个解码器(没查到具体的,有查到的读者可以评论下)。
SNK知道SRC的capability后,选择一个最佳的configuration发给SRC。
LDAC是双方都支持的Codec,选择立体声配置,采样率96kHz。
AVDTP_OPEN_CMD 用于为配置的 SEP 建立传输通道。 INT 打开流,必要时打开相关的传输通道。
下图贴了Stream start和suspend的过程。
前面的步骤都属于Audio Stream Setup,音频数据的传输属于Audio Stream。
按理说看AVDTP的HCI日志中,是能看到AVDTP type不为signal的其他帧,但是只看到了信令,那media packet是怎么发送到耳机的呢。
本设备使用的是高通的手机,高通现在的架构是这样实现的:不通过Transport Session去发送Media packet,而是audio芯片直接将Media发送到bt芯片。