深入理解经典蓝牙的L2CAP协议

L2CAP 协议:

L2CAP:全称Logical Link Control and Adaptation Protocol。

核心职责:多路复用(多个上层协议共享一条 ACL 链路)、分段与重组(SAR)、QoS / 流控。

  • ACL(Asynchronous Connectionless):异步、面向数据、支持重传,L2CAP 只跑在 ACL 上。

  • SCO / eSCO((Enhanced) Synchronous Connection-Oriented):同步、面向语音,占用固定时隙,不经过 L2CAP,通常直接承载 HFP 的语音(CVSD / mSBC)。

L2CAP 跑在 ACL 之上:L2CAP 的 CID 划分只跟 ACL 相关;SCO/eSCO 是另一条独立的语音通道。

L2CAP 基本帧格式:

  • Length(2 字节,小端):Information payload 的字节数。

  • CID(2 字节,小端):Channel ID,标识本包发给哪个逻辑信道。

  • L2CAP header 共 4 字节,CID 是对端接收方的 CID(每一方独立分配自己的 CID,是本地概念)。

Signaling 命令格式:

常见 Code:CONNECTION_REQ/RSPCONFIGURATION_REQ/RSPDISCONNECTION_REQ/RSPECHO_REQINFORMATION_REQ。建立一个新 L2CAP 信道就是通过这里的 Connection Request(带上 PSM)完成的。

CID 是怎么划分的:

CID 是 16 bit,BR/EDR(经典蓝牙)的划分如下:

CID 范围 用途
0x0000 Null(保留,禁止使用)
0x0001 Signaling channel(L2CAP 信令,如连接/配置命令)
0x0002 Connectionless channel(无连接数据,广播式)
0x0003 AMP Manager Protocol(早期 AMP 用,现基本废弃)
0x0004 ~ 0x003F Reserved(保留,含 BLE 用的固定信道)
0x0040 ~ 0xFFFF Dynamically allocated(动态分配给面向连接的信道)

动态 CID 由每一方独立分配:A 建立连接时告诉 B「请把发给我的数据打到 CID=0x0041」,B 也会告诉 A 自己的 CID。所以同一条逻辑连接,两端看到的 CID 通常不一样 ------ 这就是 L2CAP header 里 CID 是「目的方 CID」的原因。

补充:BLE(LE)的固定 CID(对比记忆)

CID LE 用途
0x0004 ATT(属性协议)
0x0005 LE Signaling channel(LE 专用信令)
0x0006 SMP(安全管理协议)

注意:LE 的信令是 0x0005,而经典蓝牙的信令是 0x0001,这是两套体系。

PSM:

PSM:Protocol/Service Multiplexer,标识不同上层协议(如RFCOMM、AVDTP)。

|--------------------|----------------------------------------------|----------------------|
| PSM 值(Hex) | 协议/服务 | 用途 |
| 0x0001 | SDP | 服务发现(本文档主角) |
| 0x0003 | RFCOMM | 串口仿真(HFP/SPP/OPP 走它) |
| 0x0005 | TCS-BIN | 电话控制 |
| 0x000F | BNEP | 蓝牙网络封装(PAN) |
| 0x0011 | HID_Control | HID 控制通道 |
| 0x0013 | HID_Interrupt | HID 中断通道(键鼠数据) |
| 0x0017 | AVCTP | AVRCP 的底层控制传输 |
| 0x0019 | AVDTP | A2DP 的底层媒体传输 |
| 0x001B | AVCTP_Browsing | AVRCP 浏览通道 |
| 0x001F | ATT (over BR / EDR ) | 经典蓝牙的通道上跑 ATT |

PSM vs CID:

  • PSM(Protocol/Service Multiplexer):标识「服务」,如 SDP=0x0001、RFCOMM=0x0003、AVDTP=0x0019、AVCTP=0x0017。类似 TCP 的「端口号」,建连时用来找服务。

  • CID:连接建立后分配的动态信道标识,之后数据都用 CID 寻址(PSM 只在建连阶段出现)。

类比:PSM 像目标端口,CID 像建好连接后的 socket。

L2CAP Connection:

Destination CID,Source CID的划分,是从发送request的一端的视角确定的。

L2cap Connection request里面的带着本端的cid,叫做source cid。

response里面带着的也是对端的cid,但是它知道它是一个response,所以它回复的目的地cid,叫做source id,本端的CID叫作Destination CID。

L2CAP Connection Request:

  • Command Code: Connection Request (0x02)

  • Command Identifier: 0x03

  • Command Length: 4

  • PSM : SDP (0x0001)

  • Source CID: Dynamically Allocated Channel (0x0108)

L2CAP Connection Response:

  • Command Code: Connection Response (0x03)

  • Command Identifier: 0x03

  • Command Length: 8

  • Destination CID: Dynamically Allocated Channel (0x0040)

  • Source CID: Dynamically Allocated Channel (0x0108)

  • Result: Successful (0x0000)

  • Status: No further information available (0x0000)

L2CAP Configuration:

Configuration Request 描述的是"我这边接收侧的能力",不是发送侧,因此需要双方都发一次request。

Command: Configure Request

  • Command Code: Configure Request (0x04)

  • Command Identifier: 0x04

  • Command Length: 8

  • Destination CID: Dynamically Allocated Channel (0x0108)

  • 0000 0000 0000 000. = Reserved: 0x0000

  • .... .... .... ...0 = Continuation Flag: False

  • Option: MTU

  • Type: Maximum Transmission Unit (0x01)

  • Length: 2

  • MTU: 1024

Command: Configure Request

  • Command Code: Configure Request (0x04)

  • Command Identifier: 0x04

  • Command Length: 8

  • Destination CID: Dynamically Allocated Channel (0x0040)

  • 0000 0000 0000 000. = Reserved: 0x0000

  • .... .... .... ...0 = Continuation Flag: False

  • Option: MTU

  • Type: Maximum Transmission Unit (0x01)

  • Length: 2

  • MTU: 256

Command: Configure Response

  • Command Code: Configure Response (0x05)

  • Command Identifier: 0x04

  • Command Length: 6

  • Source CID: Dynamically Allocated Channel (0x0108)

  • 0000 0000 0000 000. = Reserved: 0x0000

  • .... .... .... ...0 = Continuation Flag: False

  • Result: Success (0x0000)

Command: Configure Response

  • Command Code: Configure Response (0x05)

  • Command Identifier: 0x04

  • Command Length: 10

  • Source CID: Dynamically Allocated Channel (0x0040)

  • 0000 0000 0000 000. = Reserved: 0x0000

  • .... .... .... ...0 = Continuation Flag: False

  • Result: Success (0x0000)

  • Option: MTU

  • Type: Maximum Transmission Unit (0x01)

  • Length: 2

  • MTU: 1024

|------|--------------------------------------|------|----------------------------------------------------------------------------------------------------------------------------|
| Type | Option 名称 | 数据长度 | 作用说明 |
| 0x01 | MTU Maximum Transmission Unit | 2B | 本方接收 MTU;告诉对端:发给我的 SDU 不能超过该值;默认 672 字节;SPP/A2DP 必带 |
| 0x02 | Flush Timeout | 2B | 冲刷超时 (ms);ACL 链路超时丢包;0xFFFF = 无限,不 flush;音频流常用 |
| 0x03 | QoS Quality of Service | 11B | QoS 流规格:服务类型、令牌桶、峰值带宽;用于申请链路带宽保障 |
| 0x04 | Retransmission And Flow Control(RFC) | 8B | 模式开关:Basic / Retransmission / Enhanced Retransmission (ERTM) / Streaming;同时配置重传次数、RTO、Monitor 超时、窗口大小;ERTM 可靠通道必带这个 option |
| 0x05 | FCS Frame Check Sequence | 1B | 0 = 关闭 FCS,1 = 开启 16 位 CRC 校验;ERTM/Streaming 模式下使用 |
| 0x06 | Extended Flow Specification | 16B | AMP 高速链路扩展 QoS;普通 BR/EDR 几乎不用 |
| 0x07 | Extended Window Size | 2B | ERTM 模式,扩展滑动窗口最大到 65535;原来 RFC 里窗口只有 0‑63,不够时启用 |

相关推荐
猫哥随身wifi6 分钟前
AI 手机越智能,随身网络越关键|AI 终端带来的网络新需求
网络·人工智能·智能手机
草莓熊Lotso1 小时前
【Redis 进阶】主从复制深度解析:从配置落地到 PSYNC 同步原理
linux·开发语言·网络·数据库·redis·缓存·php
爱学习的程序媛1 小时前
TCP / UDP 协议详解
网络·网络协议·udp·tcp·通信协议
爱学习的程序媛1 小时前
以太网协议详解
网络·网络协议·计算机网络·以太网·ethernet·通信协议
兔叭_哥1 小时前
WPS 阿里V3 全流程逆向分析与求解
网络·wps
比兔代理1 小时前
代理 IP 延迟优化全链路:从节点选型、TCP 参数到协议栈调优
网络·http·ip
终端安全笔记1 小时前
iOS 27 强制 TLS 1.2:租赁设备的注册链路会在哪一环断
android·网络·安全·ios·智能手机
llilian_162 小时前
PTP时钟服务器时间溢出隐患解决方案 1588时钟服务器 ptp服务器
大数据·网络·单片机·嵌入式硬件·51单片机
huainingning2 小时前
盈高安全准入设备与深信服实现单点登录对接配置
服务器·网络·安全
网硕互联的小客服3 小时前
如何在Ubuntu系统上查看和刷新DNS缓存?操作方法与原理解析
运维·服务器·网络·ubuntu