【Android】【Bluetooth Stack】蓝牙音乐协议分析之A2DP和AVRCP连接流程(超详细)

本文主要是介绍【Android】【Bluetooth Stack】蓝牙音乐协议分析之A2DP和AVRCP连接流程(超详细),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. 协议架构

上面描述的就是整体的协议架构,我们针对蓝牙音乐的协议架构分析,其中涉及到了几个协议:

其中针对业务层的逻辑,涉及到了A2DP和AVRCP协议;

1.1 AVRCP介绍

AVRCP全称:Audio/Video Remote Control Profile,即音频/视频远程控制配置文件。

AVRCP设计用于提供控制TV,Hi-Fi设备等的标准接口,此配置文件用于许可单个远程控制设备(或其他设备)控制所有用于可以接入的A/V设备。AVRCP定义了如何控制流媒体的特征。包括暂停、停止、启动重放、音量控制及其他类型的远程控制操作(其实和DLNA的指令控制类似);

AVRCP是一种在蓝牙协议栈A2DP/AVRCP上实现的控制技术;

1.2 A2DP介绍

A2DP全称:Advenced Audio Distribution Profile,即蓝牙音频传输模型协定;

A2DP规定了使用蓝牙异步传输信道方式,传输高质量音乐文件数据的协议堆栈软件和使用方法,基于该协议就能通过以蓝牙方式传输高品质的音乐。例如使用蓝牙耳机或蓝牙音响设备来收听音乐了;

针对上述的相关的协议,其实和蓝牙命令请求和响应有密切的关联;

2. Command & Event

2.1 Command

我们整理一下蓝牙音乐过程中涉及到的常见的一些Command;

ProtocolJNICommandDesc
A2dpSinkBluetoothA2dpSinkServiceJniclassInitNative初始化A2dpSink Native
A2dpSinkBluetoothA2dpSinkServiceJniconnectA2dpNative用于连接A2dp
SdpBluetoothSdpJnisdpCreateOppOpsRecordNative创建服务记录列表
SdpBluetoothSdpJnisdpSearchNative搜索服务
AvrcpBluetoothAvrcpControllerJnigetPlayerListNative获取播放列表
AvrcpBluetoothAvrcpControllerJnisendPassThroughCommandNative68:播放 70:暂停 75:下一首 76:上一首

2.2 Event

Event代表的就是上层业务层向下发送指令到底层返回的callback响应;

ProtocolJNIEventDesc
A2dpSinkBluetoothA2dpSinkServiceJnibta2dp_connection_state_callback响应A2dp服务连接
SdpBluetoothSdpJnisdp_search_callback响应sdp服务搜索结果
A2dpSinkBluetoothA2dpSinkServiceJnibta2dp_audio_config_callbackA2dp audio配置变化回调
AvrcpBluetoothAvrcpControllerJnibtavrcp_connection_state_callbackAvrcp服务连接状态回调
AvrcpBluetoothAvrcpControllerJnibtavrcp_get_rcfeatures_callback
AvrcpBluetoothAvrcpControllerJnibtavrcp_play_status_changed_callback当前播放状态变化信息回调
AvrcpBluetoothAvrcpControllerJnibtavrcp_track_changed_callbackTrackInfo信息变化回调
AvrcpBluetoothAvrcpControllerJnibtavrcp_set_addressed_player_callback设置address地址信息结果回调
AvrcpBluetoothAvrcpControllerJnibtavrcp_uids_changed_callbackuid变化回调
AvrcpBluetoothAvrcpControllerJnibtavrcp_get_folder_items_callback获取文件夹目录信息回调
AvrcpBluetoothAvrcpControllerJnibtavrcp_playerapplicationsetting_callback播放器设置结果回调
AvrcpBluetoothAvrcpControllerJnibtavrcp_playerapplicationsetting_changed_callback更换播放器结果回调
AvrcpBluetoothAvrcpControllerJnibtavrcp_available_player_changed_callback播放可行性变化回调
AvrcpBluetoothAvrcpControllerJnibtavrcp_addressed_player_update_callbackaddress信息变化回调
AvrcpBluetoothAvrcpControllerJnibtavrcp_play_position_changed_callback播放进度条信息回调
AvrcpBluetoothAvrcpControllerJnibtavrcp_passthrough_response_callback指令响应结果回调
A2dpSinkBluetoothA2dpSinkServiceJnibta2dp_audio_state_callbackA2dp audio状态变化结果回调

3. 协议分析

我们按照蓝牙音乐的播放流程逐一分析涉及到的协议;

3.1 A2dpSink 连接

这个过程中涉及到的Command和Event为:

  • Command

    • connectA2dpNative
  • Event

    • bta2dp_connection_state_callback
    • bta2dp_audio_config_callback
3.1 connectA2dpNative
3.1.1 Operation
01-01 00:07:30.619  1713  2134 I BluetoothA2dpSinkServiceJni: connectA2dpNative: sBluetoothA2dpInterface: 0x77307fd3e8
01-01 00:07:30.619  1713  1713 D A2dpSinkStateMachine: Connection state 30:AA:E4:42:C7:DD: 0->1
01-01 00:07:30.619  1713  2134 I btif_av : sink_connect_src: Peer 30:aa:e4:42:c7:dd
01-01 00:07:30.619  1713  2134 D A2dpSinkStateMachine: Exit Disconnected: 1
01-01 00:07:30.619  1713  2134 D A2dpSinkStateMachine: Enter Pending: 1
01-01 00:07:30.619  1713  1794 I bt_btif_queue: queue_int_add: adding connection request: address=30:aa:e4:42:c7:dd UUID=110B busy=false
01-01 00:07:30.619  1713  1794 I bt_btif_queue: btif_queue_connect_next: executing connection request: address=30:aa:e4:42:c7:dd UUID=110B busy=false
01-01 00:07:30.619  1713  1794 I bt_btif : connect_int: peer_address=30:aa:e4:42:c7:dd uuid=0x110b
01-01 00:07:30.619  1713  1794 D bt_btif : BtifAvPeer *BtifAvSink::FindOrCreatePeer(const RawAddress &, tBTA_AV_HNDL): peer_address=30:aa:e4:42:c7:dd bta_handle=0x0
01-01 00:07:30.619  1713  1794 I btif_av : BtifAvPeer *BtifAvSink::FindOrCreatePeer(const RawAddress &, tBTA_AV_HNDL): Create peer: peer_address=30:aa:e4:42:c7:dd bta_handle=0x41 peer_id=0
01-01 00:07:30.619  1713  1794 D bt_btif : virtual void BtifAvStateMachine::StateIdle::OnEnter(): Peer 30:aa:e4:42:c7:dd
01-01 00:07:30.619  1713  1794 W bt_btif : btif_av_get_peer_sep: No active peer found
01-01 00:07:30.619  1713  1794 I bt_btif_a2dp: btif_a2dp_on_idle: ## ON A2DP IDLE ## peer_sep = 1
01-01 00:07:30.619  1713  1794 W bt_btif : btif_av_get_peer_sep: No active peer found
01-01 00:07:30.619  1713  1794 I bt_btif_a2dp_source: btif_a2dp_source_on_idle: state=STATE_OFF
01-01 00:07:30.619  1713  1794 D bt_btif : virtual bool BtifAvStateMachine::StateIdle::ProcessEvent(uint32_t, void *): Peer 30:aa:e4:42:c7:dd : event=BTIF_AV_CONNECT_REQ_EVT(0x19) flags=0x0(None) active_peer=false
01-01 00:07:30.619  1713  1794 I bt_bta_av: BTA_AvOpen: peer 30:aa:e4:42:c7:dd handle:0x41 use_rc=true sec_mask=0x12 uuid=0x110b
01-01 00:07:30.619  1294  1294 D BTDevConnectionPolicy: Received Intent for device: 30:AA:E4:42:C7:DD android.bluetooth.a2dp-sink.profile.action.CONNECTION_STATE_CHANGED
01-01 00:07:30.620  1294  1294 D GwmBTDevConnePolicy: Received Intent for device: 30:AA:E4:42:C7:DD android.bluetooth.a2dp-sink.profile.action.CONNECTION_STATE_CHANGED
01-01 00:07:30.620  1713  2064 I bt_btif : bta_sys_event: Event 0x1209
01-01 00:07:30.620  1713  2064 D bt_btif : bta_av_do_disc_a2dp: peer_addr: 30:aa:e4:42:c7:dd use_rc: 1 switch_res:0, oc:0
01-01 00:07:30.620  1713  2064 D bt_btm  : BTM_GetRole
01-01 00:07:30.620  1713  2064 D bt_btif : bta_av_do_disc_a2dp: ok_continue: 1 wait:0x0, q_tag: 0
01-01 00:07:30.620  1713  2064 D bt_btif : bta_av_save_addr: peer=30:aa:e4:42:c7:dd recfg_sup:1, suspend_sup:1
01-01 00:07:30.620  1294  1294 D BTDevConnectionPolicy: Received BluetoothA2dpSink.ACTION_CONNECTION_STATE_CHANGED currState = 1
01-01 00:07:30.620  1713  2064 I bt_bta_av: bta_av_save_addr: reset flags old_addr=00:00:00:00:00:00 new_addr=30:aa:e4:42:c7:dd
01-01 00:07:30.620  1294  1294 E GwmBTDevConnePolicy: notifyGWMConnectionStatus currentState = 1
01-01 00:07:30.620  1713  2064 D bt_bta_av: SetAvdtpVersion: AVDTP version for 30:aa:e4:42:c7:dd set to 0x103
01-01 00:07:30.620  1713  2064 D bt_btif : bta_dm_pm_cback: st(2), id(18), app(0)
01-01 00:07:30.620  1294  1294 D GwmBTDevConnePolicy: notifyGWMConnectionStatus() Ignoring state: 1
01-01 00:07:30.620  1713  2064 D bt_btif : bta_av_do_disc_a2dp: Initiate SDP discovery for peer 30:aa:e4:42:c7:dd : uuid_int=0x110b sdp_uuid=0x110a
01-01 00:07:30.620  1713  2064 I a2dp_api: A2DP_FindService: peer: 30:aa:e4:42:c7:dd UUID: 0x110a
01-01 00:07:30.620  1713  2064 I bt_sdp  : sdp_conn_originate: SDP - Originate started for peer 30:aa:e4:42:c7:dd
01-01 00:07:30.620  1713  2064 D bt_l2cap: l2cu_allocate_ccb: cid 0x0000
01-01 00:07:30.620  1713  2064 D bt_l2cap: l2cu_enqueue_ccb CID: 0x0043  priority: 2
01-01 00:07:30.620  1713  2064 D bt_l2cap: l2c_link_adjust_chnl_allocation
01-01 00:07:30.620  1713  2064 I bt_l2cap: CID:0x0041 FCR Mode:0 Priority:2 TxDataRate:1 RxDataRate:1 Quota:200
01-01 00:07:30.620  1713  2064 I bt_l2cap: CID:0x0043 FCR Mode:0 Priority:2 TxDataRate:1 RxDataRate:1 Quota:200
01-01 00:07:30.620  1713  2064 I bt_l2cap: L2CAP - LCID: 0x0043  st: CLOSED  evt: UPPER_LAYER_CONNECT_REQ
01-01 00:07:30.620  1713  2064 D bt_btm  : btm_sec_l2cap_access_req() is_originator:1, 0x3090e688, psm=0x0001
01-01 00:07:30.620  1713  2064 I bt_btm  : btm_find_or_alloc_dev
01-01 00:07:30.620  1713  2064 D bt_btm  : btm_sec_is_serv_level0: PSM: 0x0001 -> mode 4 level 0 service
01-01 00:07:30.620  1713  2064 D bt_l2cap: l2c_link_sec_comp2: status=17, p_ref_data=0x773090e688, BD_ADDR=30:aa:e4:42:c7:dd
01-01 00:07:30.620  1713  2064 I bt_l2cap: L2CAP - LCID: 0x0043  st: CLOSED  evt: SECURITY_COMPLETE
01-01 00:07:30.620  1713  2064 D bt_l2cap: TotalWin=6,Hndl=0x2,Quota=8,Unack=2,RRQuota=0,RRUnack=0
01-01 00:07:30.620  1713  2064 D bt_l2cap: RR scan pri=2, lcid=0x0041, q_cout=0
01-01 00:07:30.620  1713  2064 D bt_l2cap: RR scan pri=2, lcid=0x0043, q_cout=0
01-01 00:07:30.620  1713  2064 I bt_l2cap: L2CAP - L2CA_conn_req(psm: 0x0001) returned CID: 0x0043
01-01 00:07:30.620  1713  1794 D bt_btif : virtual void BtifAvStateMachine::StateIdle::OnExit(): Peer 30:aa:e4:42:c7:dd
01-01 00:07:30.620  1713  1794 D bt_btif : virtual void BtifAvStateMachine::StateOpening::OnEnter(): Peer 30:aa:e4:42:c7:dd
01-01 00:07:30.620  1713  1794 I btif_av : btif_report_connection_state: peer_address=30:aa:e4:42:c7:dd state=1
01-01 00:07:30.620  1713  1794 I BluetoothA2dpSinkServiceJni: bta2dp_connection_state_callback
………………
01-01 00:07:30.915  1713  1794 I BluetoothA2dpSinkServiceJni: bta2dp_audio_config_callback
01-01 00:07:31.103  1713  1794 I BluetoothA2dpSinkServiceJni: bta2dp_connection_state_callback

通过上述log,我们可以知道,当上层发送了connect A2dp指令之后,底层将该请求添加到了bt_btif_queue队列中了,然后等待该queue中执行的执行;

然后通过bta2dp_audio_config_callback和bta2dp_connection_state_callback接收到connect的结果反馈;

3.1.2 Protocol

connectA2dpNative 协议分析

Frame 283: 17 bytes on wire (136 bits), 17 bytes captured (136 bits)Encapsulation type: Bluetooth H4 with linux header (99)Arrival Time: Jan  1, 2020 00:07:30.685660000 CST[Time shift for this packet: 0.000000000 seconds]Epoch Time: 1577808450.685660000 seconds[Time delta from previous captured frame: 0.000557000 seconds][Time delta from previous displayed frame: 0.000557000 seconds][Time since reference or first frame: 8.423062000 seconds]Frame Number: 283Frame Length: 17 bytes (136 bits)Capture Length: 17 bytes (136 bits)[Frame is marked: False][Frame is ignored: False]Point-to-Point Direction: Sent (0)[Protocols in frame: bluetooth:hci_h4:bthci_acl:btl2cap]
Bluetooth[Source: BarrotTe_50:67:20 (04:7f:0e:50:67:20)][Destination: HuaweiDe_42:c7:dd (30:aa:e4:42:c7:dd)]
Bluetooth HCI H4[Direction: Sent (0x00)]HCI Packet Type: ACL Data (0x02)
Bluetooth HCI ACL Packet.... 0000 0000 0010 = Connection Handle: 0x002..10 .... .... .... = PB Flag: First Automatically Flushable Packet (2)00.. .... .... .... = BC Flag: Point-To-Point (0)Data Total Length: 12Data[Connect in frame: 109][Source BD_ADDR: BarrotTe_50:67:20 (04:7f:0e:50:67:20)][Source Device Name: HAVAL_6720][Source Role: Master (1)][Destination BD_ADDR: HuaweiDe_42:c7:dd (30:aa:e4:42:c7:dd)][Destination Device Name: dupz][Destination Role: Slave (2)][Last Role Change in Frame: 107][Current Mode: Active Mode (0)][Last Mode Change in Frame: 109]
Bluetooth L2CAP ProtocolLength: 8CID: L2CAP Signaling Channel (0x0001)Command: Connection RequestCommand Code: Connection Request (0x02)Command Identifier: 0x0fCommand Length: 4PSM: AVDTP (0x0019)Source CID: Dynamically Allocated Channel (0x0045)[Service: Audio Source (0x110a)]

首先我们先分析一下:

Bluetooth[Source: BarrotTe_50:67:20 (04:7f:0e:50:67:20)][Destination: HuaweiDe_42:c7:dd (30:aa:e4:42:c7:dd)]
  • Source:代表了指令的发起方,即指令发送者,BarrotTe_50:67:20,代表了车机端,04:7f:0e:50:67:20为车机端的蓝牙地址;
  • Destination:代表了指令的接收方,HuaweiDe_42:c7:dd,代表了手机端,30:aa:e4:42:c7:dd为手机端的蓝牙地址;
Bluetooth HCI H4[Direction: Sent (0x00)]HCI Packet Type: ACL Data (0x02)
  • HCI H4:代表了UART的transport,这一块涉及到的是Transport层,用于实现Host和Controller的交互;

H4是UART传输中最简单的一个Transport,只是在HCI raw data的前面加一个type就行。

H4定义了5种类型的packet type:

HCI packet typeHCI packet indicatorDesc
HCI Command packet0x01由蓝牙协议栈发送给芯片的命令
HCI ACL Data packet0x02蓝牙协议栈跟蓝牙芯片双向交互的普通数据
HCI Synchronous Data packet0x03蓝牙芯片跟蓝牙协议栈双向交互的通话/语音识别等音频数据
HCI Event packet0x04由蓝牙芯片上报给蓝牙协议栈的事件
HCI ISO Data packet0x05LE audio用的数据包格式(这部分是在core 5.2才添加的)
  • Sent (0x00):代表了发送,一共有两个类型的发送方式:一种是单独的包(00);一种是连续的包(01 10 11);
Bluetooth HCI ACL Packet.... 0000 0000 0010 = Connection Handle: 0x002..10 .... .... .... = PB Flag: First Automatically Flushable Packet (2)00.. .... .... .... = BC Flag: Point-To-Point (0)Data Total Length: 12Data[Connect in frame: 109][Source BD_ADDR: BarrotTe_50:67:20 (04:7f:0e:50:67:20)][Source Device Name: HAVAL_6720][Source Role: Master (1)][Destination BD_ADDR: HuaweiDe_42:c7:dd (30:aa:e4:42:c7:dd)][Destination Device Name: dupz][Destination Role: Slave (2)][Last Role Change in Frame: 107][Current Mode: Active Mode (0)][Last Mode Change in Frame: 109]

上面描述了BT Device Master和Slave的信息

  • Master

    • Source BD_ADDR:车机端蓝牙地址
    • Source Device Name:车机端蓝牙名称
    • Source Role:车机端角色
  • Slave

    • Destination BD_ADDR:手机端蓝牙地址
    • Destination Device Name:手机端蓝牙名称
    • Destination Role:手机端蓝牙角色
Bluetooth L2CAP ProtocolLength: 8CID: L2CAP Signaling Channel (0x0001)Command: Connection RequestCommand Code: Connection Request (0x02)Command Identifier: 0x0fCommand Length: 4PSM: AVDTP (0x0019)Source CID: Dynamically Allocated Channel (0x0045)[Service: Audio Source (0x110a)]
  • CID:Channel Identifiers,通道标识符,这里使用了Signaling Channel (0x0001)
  • Command Code:命令code
  • Command Identifier:命令标识符
  • PSM:代表给什么协议来建立l2cap连接,这里使用了AVDTP,对应了上述架构图中A2DP协议下关联了AVDTP协议;
  • Source CID:Source Channel Identifiers;
  • Service: Audio Source (0x110a):表明了在该过程中需要启动的Service;

bta2dp_connection_state_callback

Frame 289: 21 bytes on wire (168 bits), 21 bytes captured (168 bits)Encapsulation type: Bluetooth H4 with linux header (99)Arrival Time: Jan  1, 2020 00:07:30.707200000 CST[Time shift for this packet: 0.000000000 seconds]Epoch Time: 1577808450.707200000 seconds[Time delta from previous captured frame: 0.000283000 seconds][Time delta from previous displayed frame: 0.000283000 seconds][Time since reference or first frame: 8.444602000 seconds]Frame Number: 289Frame Length: 21 bytes (168 bits)Capture Length: 21 bytes (168 bits)[Frame is marked: False][Frame is ignored: False]Point-to-Point Direction: Received (1)[Protocols in frame: bluetooth:hci_h4:bthci_acl:btl2cap]
Bluetooth[Source: HuaweiDe_42:c7:dd (30:aa:e4:42:c7:dd)][Destination: BarrotTe_50:67:20 (04:7f:0e:50:67:20)]
Bluetooth HCI H4[Direction: Rcvd (0x01)]HCI Packet Type: ACL Data (0x02)
Bluetooth HCI ACL Packet.... 0000 0000 0010 = Connection Handle: 0x002..10 .... .... .... = PB Flag: First Automatically Flushable Packet (2)00.. .... .... .... = BC Flag: Point-To-Point (0)Data Total Length: 16Data[Connect in frame: 109][Source BD_ADDR: HuaweiDe_42:c7:dd (30:aa:e4:42:c7:dd)][Source Device Name: dupz][Source Role: Slave (2)][Destination BD_ADDR: BarrotTe_50:67:20 (04:7f:0e:50:67:20)][Destination Device Name: HAVAL_6720][Destination Role: Master (1)][Last Role Change in Frame: 107][Current Mode: Active Mode (0)][Last Mode Change in Frame: 109]
Bluetooth L2CAP ProtocolLength: 12CID: L2CAP Signaling Channel (0x0001)Command: Connection ResponseCommand Code: Connection Response (0x03)Command Identifier: 0x0fCommand Length: 8Destination CID: Dynamically Allocated Channel (0x004b)Source CID: Dynamically Allocated Channel (0x0045)Result: Successful (0x0000)Status: No further information available (0x0000)

在这个Response响应中,Result的值为:Successful,表示A2DPSinkService已经连接成功;

bta2dp_audio_config_callback

Frame 353: 25 bytes on wire (200 bits), 25 bytes captured (200 bits)Encapsulation type: Bluetooth H4 with linux header (99)Arrival Time: Jan  1, 2020 00:07:30.915044000 CST[Time shift for this packet: 0.000000000 seconds]Epoch Time: 1577808450.915044000 seconds[Time delta from previous captured frame: 0.000876000 seconds][Time delta from previous displayed frame: 0.000876000 seconds][Time since reference or first frame: 8.652446000 seconds]Frame Number: 353Frame Length: 25 bytes (200 bits)Capture Length: 25 bytes (200 bits)[Frame is marked: False][Frame is ignored: False]Point-to-Point Direction: Sent (0)[Protocols in frame: bluetooth:hci_h4:bthci_acl:btl2cap:btavdtp]
Bluetooth[Source: BarrotTe_50:67:20 (04:7f:0e:50:67:20)][Destination: HuaweiDe_42:c7:dd (30:aa:e4:42:c7:dd)]
Bluetooth HCI H4[Direction: Sent (0x00)]HCI Packet Type: ACL Data (0x02)
Bluetooth HCI ACL Packet.... 0000 0000 0010 = Connection Handle: 0x002..10 .... .... .... = PB Flag: First Automatically Flushable Packet (2)00.. .... .... .... = BC Flag: Point-To-Point (0)Data Total Length: 20Data[Connect in frame: 109][Source BD_ADDR: BarrotTe_50:67:20 (04:7f:0e:50:67:20)][Source Device Name: HAVAL_6720][Source Role: Master (1)][Destination BD_ADDR: HuaweiDe_42:c7:dd (30:aa:e4:42:c7:dd)][Destination Device Name: dupz][Destination Role: Slave (2)][Last Role Change in Frame: 107][Current Mode: Active Mode (0)][Last Mode Change in Frame: 109]
Bluetooth L2CAP ProtocolLength: 16CID: Dynamically Allocated Channel (0x004b)[Connect in frame: 283][Service: Audio Source (0x110a)][PSM: AVDTP (0x0019)]
Bluetooth AVDTP ProtocolSignal: SetConfiguration (Command)1000 .... = Transaction: 0x8.... 00.. = Packet Type: Single (0x0).... ..00 = Message Type: Command (0x0)00.. .... = RFA: 0x0..00 0011 = Signal: SetConfiguration (0x03)ACP SEID [2 - Audio Source]0000 10.. = ACP SEID: 2.... ..00 = RFA: 0x0INT SEID [2 - Audio Source]0000 10.. = INT SEID: 2.... ..00 = RFA: 0x0CapabilitiesService: Media TransportService Category: Media Transport (0x01)Length of Service Category: 0x00Service: Media Codec - Audio MPEG-2,4 AACService Category: Media Codec (0x07)Length of Service Category: 0x080000 .... = Media Type: Audio (0x0).... 0000 = RFA: 0x0Media Codec Audio Type: MPEG-2,4 AAC (0x02)1... .... = MPEG2 AAC LC: True.0.. .... = MPEG4 AAC LC: False..0. .... = MPEG4 AAC LTP: False...0 .... = MPEG4 AAC Scalable: False.... 0000 = RFA: 0x00... .... = Sampling Frequency 8000 Hz: False.0.. .... = Sampling Frequency 11025 Hz: False..0. .... = Sampling Frequency 12000 Hz: False...0 .... = Sampling Frequency 16000 Hz: False.... 0... = Sampling Frequency 22050 Hz: False.... .0.. = Sampling Frequency 24000 Hz: False.... ..0. = Sampling Frequency 32000 Hz: False.... ...1 = Sampling Frequency 44100 Hz: True0... .... = Sampling Frequency 48000 Hz: False.0.. .... = Sampling Frequency 64000 Hz: False..0. .... = Sampling Frequency 88200 Hz: False...0 .... = Sampling Frequency 96000 Hz: False.... 0... = Channels 1: False.... .1.. = Channels 2: True.... ..00 = RFA: 0x00... .... .... .... .... .... = VBR Supported: False.000 0010 1110 1110 0000 0000 = Bit Rate: 0x02ee00

Bluetooth AVDTP Protocol 协议块中的 Capabilities 中,描述了Audio Source的多个信息:

  • Service: Media Transport

  • Service: Media Codec

    • Media Type:Audio

    • Media Codec Audio Type:MPEG-2,4 AAC

    • Sampling rate:44100 Hz

    • Channel:CHANNEL_OUT_STEREO

    • Bit Rate(码率):0x02ee00

    • 码率类型:

      • VBR:可变码率编码
      • CBR:恒定码率编码
3.2 AVRCP 连接

在Avrcp协议中涉及到了AVCTP协议;

AVCTP协议描述了蓝牙设备间Audio/Video的控制信号交换的格式和机制,他是一个总体的协议,具体的控制信息由其指定的协议(AVRCP)实现,AVCTP协议本身只指定控制Command和Response的总体的格式;

……………………
Bluetooth[Source: BarrotTe_50:67:20 (04:7f:0e:50:67:20)][Destination: HuaweiDe_42:c7:dd (30:aa:e4:42:c7:dd)]
Bluetooth HCI H4[Direction: Sent (0x00)]HCI Packet Type: ACL Data (0x02)
Bluetooth HCI ACL Packet.... 0000 0000 0010 = Connection Handle: 0x002..10 .... .... .... = PB Flag: First Automatically Flushable Packet (2)00.. .... .... .... = BC Flag: Point-To-Point (0)Data Total Length: 12Data[Connect in frame: 109][Source BD_ADDR: BarrotTe_50:67:20 (04:7f:0e:50:67:20)][Source Device Name: HAVAL_6720][Source Role: Master (1)][Destination BD_ADDR: HuaweiDe_42:c7:dd (30:aa:e4:42:c7:dd)][Destination Device Name: dupz][Destination Role: Slave (2)][Last Role Change in Frame: 107][Current Mode: Active Mode (0)][Last Mode Change in Frame: 109]
Bluetooth L2CAP ProtocolLength: 8CID: L2CAP Signaling Channel (0x0001)Command: Connection RequestCommand Code: Connection Request (0x02)Command Identifier: 0x17Command Length: 4PSM: AVCTP-Control (0x0017)Source CID: Dynamically Allocated Channel (0x0048)[Service: A/V Remote Control Target (0x110c)]

上述为AVCTP-Control建立L2CAP连接的Command,对应H4的Sent (0x00);

……………………
Bluetooth[Source: HuaweiDe_42:c7:dd (30:aa:e4:42:c7:dd)][Destination: BarrotTe_50:67:20 (04:7f:0e:50:67:20)]
Bluetooth HCI H4[Direction: Rcvd (0x01)]HCI Packet Type: ACL Data (0x02)
Bluetooth HCI ACL Packet.... 0000 0000 0010 = Connection Handle: 0x002..10 .... .... .... = PB Flag: First Automatically Flushable Packet (2)00.. .... .... .... = BC Flag: Point-To-Point (0)Data Total Length: 16Data[Connect in frame: 109][Source BD_ADDR: HuaweiDe_42:c7:dd (30:aa:e4:42:c7:dd)][Source Device Name: dupz][Source Role: Slave (2)][Destination BD_ADDR: BarrotTe_50:67:20 (04:7f:0e:50:67:20)][Destination Device Name: HAVAL_6720][Destination Role: Master (1)][Last Role Change in Frame: 107][Current Mode: Active Mode (0)][Last Mode Change in Frame: 109]
Bluetooth L2CAP ProtocolLength: 12CID: L2CAP Signaling Channel (0x0001)Command: Connection ResponseCommand Code: Connection Response (0x03)Command Identifier: 0x17Command Length: 8Destination CID: Dynamically Allocated Channel (0x005d)Source CID: Dynamically Allocated Channel (0x0048)Result: Successful (0x0000)Status: No further information available (0x0000)

上述为AVCTP-Control建立L2CAP连接的Response,Result为Successful,对应H4的Rcvd (0x01),代表了接收;

这篇关于【Android】【Bluetooth Stack】蓝牙音乐协议分析之A2DP和AVRCP连接流程(超详细)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/822787

相关文章

Security OAuth2 单点登录流程

单点登录(英语:Single sign-on,缩写为 SSO),又译为单一签入,一种对于许多相互关连,但是又是各自独立的软件系统,提供访问控制的属性。当拥有这项属性时,当用户登录时,就可以获取所有系统的访问权限,不用对每个单一系统都逐一登录。这项功能通常是以轻型目录访问协议(LDAP)来实现,在服务器上会将用户信息存储到LDAP数据库中。相同的,单一注销(single sign-off)就是指

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

W外链微信推广短连接怎么做?

制作微信推广链接的难点分析 一、内容创作难度 制作微信推广链接时,首先需要创作有吸引力的内容。这不仅要求内容本身有趣、有价值,还要能够激起人们的分享欲望。对于许多企业和个人来说,尤其是那些缺乏创意和写作能力的人来说,这是制作微信推广链接的一大难点。 二、精准定位难度 微信用户群体庞大,不同用户的需求和兴趣各异。因此,制作推广链接时需要精准定位目标受众,以便更有效地吸引他们点击并分享链接

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

SWAP作物生长模型安装教程、数据制备、敏感性分析、气候变化影响、R模型敏感性分析与贝叶斯优化、Fortran源代码分析、气候数据降尺度与变化影响分析

查看原文>>>全流程SWAP农业模型数据制备、敏感性分析及气候变化影响实践技术应用 SWAP模型是由荷兰瓦赫宁根大学开发的先进农作物模型,它综合考虑了土壤-水分-大气以及植被间的相互作用;是一种描述作物生长过程的一种机理性作物生长模型。它不但运用Richard方程,使其能够精确的模拟土壤中水分的运动,而且耦合了WOFOST作物模型使作物的生长描述更为科学。 本文让更多的科研人员和农业工作者

MOLE 2.5 分析分子通道和孔隙

软件介绍 生物大分子通道和孔隙在生物学中发挥着重要作用,例如在分子识别和酶底物特异性方面。 我们介绍了一种名为 MOLE 2.5 的高级软件工具,该工具旨在分析分子通道和孔隙。 与其他可用软件工具的基准测试表明,MOLE 2.5 相比更快、更强大、功能更丰富。作为一项新功能,MOLE 2.5 可以估算已识别通道的物理化学性质。 软件下载 https://pan.quark.cn/s/57

C++——stack、queue的实现及deque的介绍

目录 1.stack与queue的实现 1.1stack的实现  1.2 queue的实现 2.重温vector、list、stack、queue的介绍 2.1 STL标准库中stack和queue的底层结构  3.deque的简单介绍 3.1为什么选择deque作为stack和queue的底层默认容器  3.2 STL中对stack与queue的模拟实现 ①stack模拟实现

Java 连接Sql sever 2008

Java 连接Sql sever 2008 /Sql sever 2008 R2 import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; public class TestJDBC