1.概述
ACP Stream Endpoint ID: 1
In-use: Yes
測試過程爲打開Audio連接,沒有聽音樂,人後斷開Audio連接,主要目的是爲了測試AVDTP的工作流程。
2.Frame分析
首先貼出抓取的關於AVDTP的包:
我們可以看到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 0000000000000001
前面的是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 0000000100000100 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。這是爲什麼呢???查Spec,說這個automatically-flushable會根據automatic flush timeout參數來自動刷新,還是不明白,先放着。
Frame66 Master->GET_CAPABILITIES
00000001 00000000 00000111 00000000 00000011 00000000 01000010 00000000 00010000
0000001000000100
看AVDTP的部分:
Transaction Label: 1
Signaling Identifier:
AVDTP_GET_CAPABILITIES
ACP Stream Endpoint ID:
1
注:利用DISCOVER中找到的遠端SEID=1的端口發送GET_CAPABILITIES來獲取對方信息。
這裏先講一下AVDTP的Service是如何描述的。首先分爲幾個Service category:
Frame68:Slave->GET_CAPABILITIES
RESPONSE
00000001 00100000 00010000 00000000 00001100 00000000 01000000 00000000 00010010 0000001000000001 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 0000001100000100 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 0000011000000100
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 0000000100000100 00000000 00001010 00001000ACP Stream Endpoint ID: 1
In-use: No
TSEP: SRC
ACP Stream Endpoint ID: 2In-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.總結
AVDTP連接的建立首先依賴於L2CAP連接的建立,它會在同一條ACL Link上建立兩條L2CAP Channel,一條是用來Signaling,另一條用來進行Stream,report和recovery的傳輸。Signaling的主要過程爲:1.DISCOVER
2.GET_CAPABILITIES 3.SET_CONFIGURATION 4.OPEN 5.START。SEID在DISCOVER的過程中發現,並且具有相應的service capability,這些capability在過程GET_CAPABILITY中發現,Service capability的描述爲第一個字節是所屬的Service category,然後是capability的length,最後是Service
capability的information element。然後對遠端的SEID進行configure,配置的結構依然爲service capability結構。最後Open相應的端口並START stream,就可以進行Audio Stream的傳輸了。上面的例子中,Slave也對本地進行了DISCOVER和GET_CAPBILITY
的過程,但是沒有configure和open,這個操作的目的還不清楚,但是至少沒有社呢麼壞的影響。