A2DP和AVRCP是传统蓝牙的两种高层应用协议。一般来讲,在市面的应用产品中,支持A2DP的蓝牙产品都有支持AVRCP。
那么,两者是怎样配合使用?又各自扮演者什么角色呢?又是分别如何实现的呢?
1)A2DP,Advanced Audio Distribution Profile。规定了使用蓝牙非同步传输信道方式,传输高质量音频护具的协议栈软件及使用方法。例如可以使用立体声蓝牙耳机来收听来自音乐播放器的音乐;
2)AVRCP,Audio Video Remote Control Profile。顾名思义,是指遥控功能,定义了控制音频 视频流的特征及协议。一般包括pause,stop,replay,音量控制等远程控制操作。例如,使用蓝牙耳机可以暂停,切换下一曲等操作来控制音乐播放器。
1. A2DP的实现
1)A2DP Profile定义了高质量音频数据传输的协议和过程,包括立体声和单声道数据的传输。这里的高质量音频指的是单声道(Mono)和立体声(Sterco)的音频,主要区别于蓝牙SCO链路上传输的普通语音,当然也不包括环绕声。
也就是说:A2DP的音质与bluetooth audio是有区别的。Bluetooth audio只能提供voice的音质,而A2DP能提供mono或stereo的音质。前者传输于SCO Channel上,而后者则传输于ACL Channel上。
2)A2DP的典型应用是将音乐播放器的音频数据发送到耳机或音箱。由于蓝牙提供的带宽较窄,音频数据可能需要进行有效的压缩才能保证接收端的实时播放。
3) A2DP的实现依赖于GAVDP和GAP,在GAVDP中定义了流连接的建立过程,在A2DP中定义流的参数和编、解码过程。
4)A2DP定义了两个 role: SRC:音频数据流的源;SNK:音频数据流的接收者。
5)A2DP建立在AVDTP传输协议的基础之上,AVDTP规定了链接是如何建立的,连接建立好之后,音频数据经过压缩之后,便可以收发了。音频数据是双向的。
PCM码流,需要很大的带宽,即低效又费电,不适合无线传输。因此需要编码压缩之后,再进行传输。
A2DP要求SRC和SNK至少要支持低于复杂度自带编解码(Low Complexity Subband Codec,SBC)标准。
MPEG-1 Audio,Mpeg-2 Audio,MPEG-2,4高级音频编码(Advanced-4 -http://www.paper.edu.cn Audio Coding,ACC)和自适应变换音频编码(Adaptive Transform Acoustic Coding,ATRAC)这几种音频编码标准是可选的。
除此之外的其他编码标准称为“非A2DP编码(Non-A2DP Codec),例如CSR家的APTX,FastStream等,注意:
如果SRC端以非A2DP Codec格式发送流数据到SNK,而SNK不支持非A2DP Codec格式的话,SRC会重新以SBC方式编码再发送。
其中,低复杂度自带编解码(SBC)是专门为蓝牙音视频设计的,它可以在中等传码率下获得较高的音频质量,并且具有较低的计算复杂度。
在信令交互的过程中,需要发现蓝牙设备的SEP并获得其服务能力,如果SEP具有SBC解码能力,那么需要对SBC有关参数进行配置,相关参数如下:
采样频率(48K,44.1K,32K,16K)
声道模式(Mono,Dual Channel,Stereo)块长度(4,8,12,16)
子带(4,8)
分配方法(SNR、LOUDNES)
BitPool(2~250)
决定传码率的编解码信息包含于SBC数据帧头部,并且和音频数据流一起被不断的发送 到SNK
目前A2DP只定义了点对点的音频传输,没有定义广播式的音频传输,可能是由于速率的原因。
由于射频信号的传输、数据流的编、解码等,在SRC和SNK之间有延迟(例如高通参考设计设置为500ms)。
音频数据速率必须小于蓝牙连接的比特率。
2. AVDTP--A2DP的基础协议
1)概念:
(1) AVDTP(AUDIO/VIDEO DISTRIBUTION TRANSPORT PROTOCOL)。是用来描述音频/视频在蓝牙设备间的传输的协议,是A2DP协议的基础协议,其在协议栈中的位置如下:
AVDTP协议建立在connection-oriented L2CAP channel上,只能支持point-to-point signaling。
(2)Stream代表两个A/V设备之间流多媒体数据的端到端的逻辑连接。
(3)Stream End Point (SEP):应用程序通过这个接口提供Transport Services and AV capabilities来建立Stream。
(4)Stream End Point Identifier (SEID):标识Stream End Point的。
(5)Stream Context (SC):两端设备都有的关于Stream的信息。
(6)Stream Handle (SH):主要是暴露给用于程序使用的。
(7)Media Packets, Recovery Packets, and Reporting Packets:根据三种不同的数据类型,有这三种数据包。其中,Basic Service会用到Basic service,Report service会用到Reporting Packets,Recovery service会用到Recovery Packets,此外Multiplexing service会用到Media Packets和其余一种或两种Packet。
(8)Transport Session:一条stream可以分解为多个transport sessions,每个transport session对应一个AVDTP的packet category ,which means Media, Recovery, or Reporting packets。
(9)Transport Session Identifier (TSID):标识Transport Session。
(10)Transport Channel:通常和一个L2CAP Channel对应。不用AVDTP Multiplexing Mode时,一条Transport Channel只传输一个transport session;用transport session的情况下,一条Transport Channel可以传输多个 transport session(media,report或者recovery)。
(11)Transport Channel Identifier (TCID):标识Transport Channel,唯一关联一条L2CAP channel。
2)A2DP的连接:
AVDTP连接的建立首先依赖于L2CAP连接的建立,它会在同一条ACL Link上建立两条L2CAP Channel,一条是用来Signaling,另一条用来进行Stream,report和recovery的传输。
(1)Signaling的主要过程为:1.DISCOVER 2.GET_CAPABILITIES 3.SET_CONFIGURATION 4.OPEN 5.START。
>1. 首先使用Stream_End_Point_Discover命令发现ACP中的流端点,主要工作是要去查询远
端的蓝牙设备(需要远端蓝牙设备的地址,这个地址是唯一的)可以提供的SEP ,每个SEP
可以提供一些服务。
远端的蓝牙设备会返回一个respond,respond包含一些信息,最重到是有多少个SEID,媒体服务类型等信 息并不十分重要,服务类型可以通过Get_Capablities来获得。然后从中选择将要建立的流端点。发送 Stream_End_Point_Discover命令之后,会获得很多个SEID,
>2. 然后就要发送Get_Capabilites命令来获得每个SEP所能提供的服务。(一个SEID代表一个SEP)具体的服 务类型,以及字段detail 参见AVDTP 的手册。我们感兴趣的是,蓝牙设备(例如蓝牙头戴式设备)是否拥 有SBC解码的能力,A2DP规定,蓝牙立体声耳机必须支持SBC解码,其他的解码方式是可选的,有关SBC 的内容要参见A2DP协议。
>3. 再使用Set_Configuration命令对流端点进行配置,通过Get_Capabilites,可以知道 SEP 可
以支持的服务,然后根据服务类型再进行一下具体的配置。需要配置音频的声道,采样率等
信息。当然配置的时候,要给出SEID参数,指明对哪个SEP进行配置。
>4. 最后就是启动流Stream_Start,如果某个SEP 具有Audio Media的服务,那么打开一个stream,给出SEID参 数,stream 是对应某个SEP。开启stream之后,就可以利用write 系统调用向socket里写音频数据了,写的 时候不需要再指明具体的SEID。
链路建立好之后,就可以进行数据传输,建链的过程,属于AVDTP 协议的内容, 而传输的内容要符合A2DP的规定,当然 A2DP 与AVDTP是密不可分的。
(2)State Machine如下,共有6个状态:IDLE、Configured、OPEN、STREAMING、Closing、Aborting。
其中:
>1. IDLE状态指的是流连接没有建立但L2CAP信道已经打开;
>2. Configured状态指SEP的配置完成;
>3. OPEN状态指流连接已经建立;
>4. STREAMING状态指参数已经配置完毕,进行流的分发。
>5. Closing状态指关闭SEP的状态
>6. Aborting状态指Abort流连接
(3)Procedure汇总
Stream End Point Discovery:远端设备提供支持的SEP列表和media Type。
Get All Capabilities:Using the SEID as a reference, the local device can query the service capabilities of the remote SEP。
Stream Configuration:By referencing both the local and the remote SEID, the local device (the INT) configures the SEP of the remote device (the ACP)。
Stream Get Configuration:etrieve the last capabilities settings performed by the remote device on the SEP。
Stream Establishment:The opening of a transport session, while referencing the remote SEID, includes, if necessary, the establishment of a new Transport Channel。
Stream Start:After the Stream Establishment is complete, the Start Streaming procedure causes the streaming to start; i.e., Media (Reporting, Recovery) packets can be exchanged。
Stream Release:initiated by the upper layer within a device; a signal is sent indicating
that a stream end-point be closed.
Stream Suspend:挂起。
Stream Reconfigure:对Stream进行配置。
Stream Reconfigure:再次配置。
Security Control:对AV data transmitted over a Bluetooth 提供protection。
Abort:用于两个设备的同步。
General Reject:对包含invalid Signal Identifier的Command进行的response。
Delay Reporting:provide an initial delay report required for synchronized audio/video playback。
结合(2)和(3)假设两个设备分别为A,B,则状态转移简述:
设备B的AVDTP处于idle状态。
设备A向设备B发送AVDTP_DISCOVER,获取设备B的SEP List。
设备A向设备B发送AVDTP_GET_CAPABILITYS,设备B返回CAPABILITY。
设备A的upper layer选定SEP后,向设备B发送SET CONFIGURATION。如果SEP已被使用,则重新选定SEP并重复此过程。如果此SEP未被使用,则配置成功。此时AVDTP的状态变成configured。
设备A向设备B发送AVDTP_OPEN,设备B进入open状态。
设备A向设备B发送AVDTP_START,设备B进入streaming状态。设备B也可发送同一指令给设备A,也能进入streaming状态。
设备A向设备B发送AVDTP_SUSPEND,设备B进入open状态。
设备A向设备B发送AVDTP_CLOSE,设备B进入closing状态,再转移到idle状态。
设备B处在open状态,设备A向设备B发送AVDTP_RECONFIGURE,重新配置成功后,设备A向设备B发送AVDTP_START,设备B进入streaming状态
(4)Transport Procedures
分为三种Service:Basic Service,Reporting Service,Recovery Service和Multiplexing Service。
>1. Basic Service只提供signaling 和media streaming。Media Packet Format如下图:参数定义如下:
>2. Reporting packet格式如下:
注意:如果不使用multiplexing mode ,一个PDU包含一个meida或者reporting或者recovery packet
每个transport session 使用不同的L2CAP Channel。如果使用Multiplexing Service,则一个transport channel上可能有好几种transport transport,需要AL header 来进行区分。
(5)signaling message
一个Signal Fragmentation的实例:
Signal command and response headers:
参数Message Type:
(6)HCI Log包分析:
>1. 在L2CAP层抓取,分别由Maste和Slave建立了两条关于AVDTP的L2CAP连接,并完成了configure的过程,如下:
我们可以看到AVDTP的主要Signaling的过程:
1.DISCOVER 2.GET_CAPABILITIES 3.SET_CONFIGURATION 4.OPEN 5.START
下面分析一下具体的内容:
Frame62:Master->AVDTP_DISCOVER
00000001 00000000 00000110 00000000 00000010 00000000 01000010 00000000 00000000 00000001
前面的是HCI和L2CAP的封装,这里也顺带看一下吧。
首先是HCI的:
Connection Handle:00000001 00000000 = 0x01 = 1
Broadcast Flag: No broadcast, point-to-point
Packet Boundary Flag: First non-automatically-flushable L2CAP packet
Total Length: 0x06 = 6
L2CAP部分:
PDU Length: 0x02 = 2
Channel ID: 0x0042 //注意:这个ID是远端Slave的CID
AVDTP部分:
Transaction Label: 0
Packet Type: Single Packet
Message Type: Command
Signaling Identifier: AVDTP_DISCOVER
注:这就是一个Master发出的Discover command
Frame65:Slave->AVDTP_DISCOVER RESPONSE
00000001 00100000 00001000 00000000 00000100 00000000 01000000 00000000 00000010 00000001 00000100 00000000
HCI和L2CAP简单看下,主要看AVDTP分部分:
Packet Boundary Flag: First automatically-flushable L2CAP packet
Channel ID: 0x0040 //注意:这个ID是本地Master的CID
Message Type: Response Accept
Signaling Identifier: AVDTP_DISCOVER
ACP Stream Endpoint ID: 1
In-use: No
TSEP: SRC
Media Type: Audio //由bluetooth分配的bumber
注:具体的resposne结构可以参考AVDTP的Spec。这个主要是远端的Slave响应本地的AVDTP_DISCOVER command,本地接收的CID为0x40,发现了远端Slave的一个值为1的SEID,而且没有使用。需要指出的是,packet baoundary flag为 automatically-flushable L2CAP packet,而AVDTP_DISCOVER command中为non-automatically-flushable L2CAP packet。
Frame66 Master->GET_CAPABILITIES
00000001 00000000 00000111 00000000 00000011 00000000 01000010 00000000 00010000 00000010 00000100
看AVDTP的部分:
Transaction Label: 1
Signaling Identifier: AVDTP_GET_CAPABILITIES
ACP Stream Endpoint ID: 1
注:利用DISCOVER中找到的远端SEID=1的端口发送GET_CAPABILITIES来获取对方信息。
>2. 这里先讲一下AVDTP的Service是如何描述的。首先分为几个Service category:
其次,Service是以以下结构来进行描述的:
即第一个字节是所属的Service category,然后是capability的length,最后是Service capability的information element。
然后继续分析:
Frame68:Slave->GET_CAPABILITIES RESPONSE
00000001 00100000 00010000 00000000 00001100 00000000 01000000 00000000 00010010 00000010 00000001 00000000 00000111 00000110 00000000 00000000 00100001 00010101 00000010 00110101
看AVDTP的部分:
Service Category: Media Transport
Length Of Service Capability (LOSC): 0
Service Category: Media Codec
Length Of Service Capability (LOSC): 6
information element部分:参考IETF RFC3550 / RFC1889标准。这里大概的信息是SBC编码,44100采样率等。
注:这里获取的是远端SEID的Media Transport和media codec信息。
Frame69:Master->SET_CONFIGURATION
00000001 00000000 00010010 00000000 00001110 00000000 01000010 00000000 00100000 00000011 00000100 00001000 00000001 00000000 00000111 00000110 00000000 00000000 00100001 00010101 00000010 00110101
ACP Stream Endpoint ID: 1
INT Stream Endpoint ID: 2
Service Category: Media Transport
Length Of Service Capability (LOSC): 0
Service Category: Media Codec
Length Of Service Capability (LOSC): 6
注:主要是对远端的Slave进行configure,貌似没怎么配置,不和get-capability的一样嘛。。。
Frame71:Slave->SET_CONFIGURATION RESPONSE
注:远端Slave接受了configure
Frame72:Master->OPEN
00000001 00000000 00000111 00000000 00000011 00000000 01000010 00000000 00110000 00000110 00000100
ACP Stream Endpoint ID: 1
注:打开远端的SEID=1的端口。
Frame73:Slave->DISCOVER
注:远端的Slave向本地的master发送discover command。Spec上貌似没有写是否需要双向的discover,不过这样貌似也没有什么坏处不是吗
Frame74:Master DISCOVER RESPONSE
00000001 00000000 00001010 00000000 00000110 00000000 01000010 00000000 00000010 00000001 00000100 00000000 00001010 00001000
ACP Stream Endpoint ID: 1
In-use: No
TSEP: SRC
ACP Stream Endpoint ID: 2
In-use: Yes
TSEP: SNK
注:本地的Master有两个SEID,其中SEID1未使用,可作为SRC,SEID2正在使用,可作为SNK。
Frame76 Slave->OPEN RESPONSE
注:对Frame72的回应,接受了本地Master的打开端口的command。
Frame79是远端Slave的GET_CAPABLIYY command,本地Master在Frame89回应。
Frame88:Master-〉START
注:本地Master开始Stream。
Frame92:Slave->START RESPONSE
注:远端Slave接受了START的command,做出resposne。
Frame93:Slave->SUSPEND
注:远端Slave挂起本地SEID=2的端口。
Frame94:Master SUSPEND RESPONSE
注:本地接受SEID=2的端口挂起。
Frame134:Master->CLOSE
注:本地UI上手动断开AVDTP连接,出发本地MASTER的CLOSE command,关闭了本地SEID=1的端口。远端Slave在Frame138接受了这个命令。
3. AVRCP:将在A2DP & AVRCP,蓝牙音频协议的兄弟组合(2)中总结。