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

1. 精讲蓝牙协议栈(Bluetooth Stack):SPP/A2DP/AVRCP/HFP/PBAP/IAP2/HID/MAP/OPP/PAN/GATTC/GATTS/HOGP等协议理论

2. 欢迎大家关注和订阅,【蓝牙协议栈】和【Android Bluetooth Stack】专栏会持续更新中.....敬请期待!

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: 283
    Frame 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: 12
    Data
    [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 Protocol
    Length: 8
    CID: L2CAP Signaling Channel (0x0001)
    Command: Connection Request
        Command Code: Connection Request (0x02)
        Command Identifier: 0x0f
        Command Length: 4
        PSM: 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: 12
    Data
    [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 Protocol
    Length: 8
    CID: L2CAP Signaling Channel (0x0001)
    Command: Connection Request
        Command Code: Connection Request (0x02)
        Command Identifier: 0x0f
        Command Length: 4
        PSM: 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: 289
    Frame 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: 16
    Data
    [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 Protocol
    Length: 12
    CID: L2CAP Signaling Channel (0x0001)
    Command: Connection Response
        Command Code: Connection Response (0x03)
        Command Identifier: 0x0f
        Command Length: 8
        Destination 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: 353
    Frame 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: 20
    Data
    [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 Protocol
    Length: 16
    CID: Dynamically Allocated Channel (0x004b)
    [Connect in frame: 283]
    [Service: Audio Source (0x110a)]
    [PSM: AVDTP (0x0019)]
Bluetooth AVDTP Protocol
    Signal: 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: 0x0
    INT SEID [2 - Audio Source]
        0000 10.. = INT SEID: 2
        .... ..00 = RFA: 0x0
    Capabilities
        Service: Media Transport
            Service Category: Media Transport (0x01)
            Length of Service Category: 0x00
        Service: Media Codec - Audio MPEG-2,4 AAC
            Service Category: Media Codec (0x07)
            Length of Service Category: 0x08
            0000 .... = Media Type: Audio (0x0)
            .... 0000 = RFA: 0x0
            Media 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: 0x0
            0... .... = 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: True
            0... .... = 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: 0x0
            0... .... .... .... .... .... = 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: 12
    Data
    [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 Protocol
    Length: 8
    CID: L2CAP Signaling Channel (0x0001)
    Command: Connection Request
        Command Code: Connection Request (0x02)
        Command Identifier: 0x17
        Command Length: 4
        PSM: 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: 16
    Data
    [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 Protocol
    Length: 12
    CID: L2CAP Signaling Channel (0x0001)
    Command: Connection Response
        Command Code: Connection Response (0x03)
        Command Identifier: 0x17
        Command Length: 8
        Destination 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),代表了接收;

  • 46
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
蓝牙协议栈(Bluetooth stack)是指在蓝牙设备上运行的软件组件,用于实现蓝牙通信的各个层次。蓝牙协议栈通常由多个层次组成,包括物理层、链路层、协议层和应用层。每个层次都有特定的功能和责任,协同工作以实现蓝牙设备之间的通信。 在Android系统中,蓝牙协议栈被称为bluedroid。它是Android系统中的一个重要组件,负责管理蓝牙设备的连接、数据传输和其他蓝牙相关功能。\[1\]而在Ubuntu系统中,蓝牙协议栈使用的是bluez。它是一个开源的蓝牙协议栈,提供了丰富的API和工具,用于开发和调试蓝牙应用程序。\[1\] 蓝牙协议栈的实现需要遵循蓝牙标准规范,这些规范由蓝牙技术联盟(Bluetooth SIG)制定。蓝牙协议栈的源代码可以通过一些书籍或从蓝牙技术联盟的官方网站下载。例如,《蓝牙协议及其源代码分析》是一本介绍蓝牙协议栈的书籍,其中提供了蓝牙协议栈的源代码分析和相关文档。\[2\] 对于想学习蓝牙协议栈的人来说,拥有一套开发板是非常有帮助的。开发板可以用于实验和调试蓝牙协议栈,帮助理解蓝牙通信的原理和实现。同时,学习蓝牙协议栈也可以为修改和定制现有的协议栈提供基础。\[3\] #### 引用[.reference_title] - *1* [BlueDroid软件协议栈架构](https://blog.csdn.net/mouse1598189/article/details/87858779)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [蓝牙协议栈(Bluetooth stack)简介](https://blog.csdn.net/pan0755/article/details/107857793)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [吐血推荐历史最全的蓝牙协议栈介绍](https://blog.csdn.net/XiaoXiaoPengBo/article/details/107466841)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风云说通信

支持小编为您创造更多干货,谢谢

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值