目录
[1 整体交互架构概览](#1 整体交互架构概览)
[1.1 交互流程总览](#1.1 交互流程总览)
[1.2 数据平面:PDU传输流程](#1.2 数据平面:PDU传输流程)
[1.2.1 发送路径:从ATT到空中](#1.2.1 发送路径:从ATT到空中)
[1.2.2 接收路径:从空中到ATT](#1.2.2 接收路径:从空中到ATT)
[1.3 控制平面:连接与参数管理](#1.3 控制平面:连接与参数管理)
[1.3.1 连接生命周期交互](#1.3.1 连接生命周期交互)
[1.3.2 关键参数协商流程](#1.3.2 关键参数协商流程)
[1.4 事件与通知机制](#1.4 事件与通知机制)
[1.4.1 链路层事件驱动模型](#1.4.1 链路层事件驱动模型)
[1.4.2 ATT通知/指示与链路层交互](#1.4.2 ATT通知/指示与链路层交互)
[1.5 性能优化交互](#1.5 性能优化交互)
[1.5.1 数据长度扩展交互(BLE 4.2+)](#1.5.1 数据长度扩展交互(BLE 4.2+))
[1.5.2 信道选择算法](#1.5.2 信道选择算法)
[1.6 安全交互](#1.6 安全交互)
[1.7 误处理与恢复](#1.7 误处理与恢复)
[1.7.1 丢包重传机制](#1.7.1 丢包重传机制)
[1.7.2 连接超时与监控](#1.7.2 连接超时与监控)
[2 链路层与ATT/L2CAP的协同设计](#2 链路层与ATT/L2CAP的协同设计)
[2.1 设计原则](#2.1 设计原则)
[2.3 典型交互模式](#2.3 典型交互模式)
概述
链路层(Link Layer)与ATT/L2CAP的交互是BLE协议栈的核心通信枢纽。他们三者的紧密协作,使BLE能在极低功耗下实现可靠通信,这是BLE协议栈设计的精髓所在。以下是它们之间交互的全面解析:
1 整体交互架构概览
1.1 交互流程总览

1.2 数据平面:PDU传输流程
1.2.1 发送路径:从ATT到空中

关键数据结构转换
cpp
// 数据结构转换链
typedef struct {
uint8_t opcode; // ATT操作码
uint16_t handle; // 属性句柄
uint8_t value[8]; // 数据值
} ATT_PDU; // 11字节
typedef struct {
uint16_t length; // 负载长度 = 11
uint16_t cid; // CID = 0x0004 (ATT)
ATT_PDU att_pdu; // ATT数据
} L2CAP_PDU; // 15字节
typedef struct {
uint8_t preamble; // 10101010 or 01010101
uint32_t access_addr; // 连接访问地址
uint16_t header; // LL头(LLID, NESN, SN, MD, ...)
L2CAP_PDU payload; // L2CAP PDU
uint24_t crc; // CRC24
} LL_PDU; // 25字节
1.2.2 接收路径:从空中到ATT
数据重组流程

1.3 控制平面:连接与参数管理
1.3.1 连接生命周期交互
连接建立过程

1.3.2 关键参数协商流程
MTU协商交互
cpp
// MTU协商的详细交互
void mtu_exchange_procedure(connection_t *conn) {
// 1. 客户端发送MTU交换请求
att_mtu_req_t mtu_req = {
.client_rx_mtu = DEFAULT_MTU // 默认23,可更大
};
// 通过L2CAP/链路层发送
send_att_pdu(conn, ATT_OP_MTU_REQ, &mtu_req, sizeof(mtu_req));
// 2. 服务器响应
// 链路层接收,L2CAP分发,ATT处理
// 服务器计算协商后的MTU = min(客户端MTU, 服务器MTU)
// 3. 更新L2CAP参数
l2cap_update_mtu(conn->cid, negotiated_mtu);
// 4. 影响链路层行为
if (negotiated_mtu > 27) { // 超过默认链路层有效载荷
// 可能触发链路层数据包分片
ll_update_tx_payload_size(conn->handle,
negotiated_mtu + L2CAP_HEADER_SIZE);
}
}
连接参数更新请求

1.4 事件与通知机制
1.4.1 链路层事件驱动模型
连接事件调度
cpp
// 连接事件状态机
typedef enum {
LL_STATE_SLEEP, // 休眠状态
LL_STATE_WAKEUP, // 唤醒准备
LL_STATE_RX_WINDOW, // 接收窗口
LL_STATE_TX_PREPARE, // 发送准备
LL_STATE_TX, // 发送数据
LL_STATE_WAIT_ACK, // 等待确认
LL_STATE_POST_PROCESS // 后续处理
} ll_event_state_t;
// 事件驱动处理
void ll_connection_event_handler(connection_handle_t handle) {
ll_state = LL_STATE_WAKEUP;
// 1. 检查是否有待发送数据(来自L2CAP)
if (l2cap_has_data_for_ll(handle)) {
ll_state = LL_STATE_TX_PREPARE;
pdu = l2cap_get_next_pdu(handle);
ll_transmit_pdu(pdu);
ll_state = LL_STATE_WAIT_ACK;
}
// 2. 开启接收窗口
ll_state = LL_STATE_RX_WINDOW;
if (ll_receive_pdu(&rx_pdu)) {
// 传递到L2CAP
l2cap_deliver_pdu(rx_pdu);
}
ll_state = LL_STATE_SLEEP;
}
1.4.2 ATT通知/指示与链路层交互
服务器发起通信
cpp
// 服务器主动发送通知(无需客户端轮询)
void send_attribute_notification(connection_handle_t conn,
attribute_handle_t handle,
uint8_t *value,
uint16_t length) {
// 1. ATT层构建通知PDU
att_pdu_t pdu = build_notification_pdu(handle, value, length);
// 2. L2CAP封装
l2cap_pdu_t l2cap_pdu = {
.length = pdu.size + ATT_HEADER_SIZE,
.cid = ATT_CID,
.payload = pdu
};
// 3. 检查链路层状态
if (ll_get_connection_state(conn) == CONNECTED) {
// 4. 放入发送队列,等待下一个连接事件
ll_schedule_transmission(conn, l2cap_pdu);
// 5. 在下一个连接事件中发送
// 注意:如果没有使能通知,链路层不应发送
if (is_notification_enabled(conn, handle)) {
ll_transmit_in_next_event(conn, l2cap_pdu);
}
}
}
1.5 性能优化交互
1.5.1 数据长度扩展交互(BLE 4.2+)
最大数据长度协商

1.5.2 信道选择算法
自适应跳频
cpp
// 链路层与L2CAP在跳频上的交互
void adaptive_frequency_selection(connection_handle_t conn) {
// 1. 链路层监控信道质量
channel_map_t used_channels = get_current_channel_map();
uint8_t bad_channel_list[37];
uint8_t bad_channel_count = 0;
// 2. 检测不良信道(基于CRC错误率、RSSI等)
for (int i = 0; i < 37; i++) {
if (channel_quality[i] < THRESHOLD) {
bad_channel_list[bad_channel_count++] = i;
}
}
// 3. 更新信道映射
if (bad_channel_count > 0) {
// 通知对端更新信道映射
ll_channel_map_update(conn, bad_channel_list, bad_channel_count);
// 4. L2CAP可能受影响(如果正在传输大数据)
if (l2cap_is_fragmenting(conn)) {
// 可能需要暂停并恢复传输
l2cap_handle_channel_change(conn);
}
}
}
1.6 安全交互
加密启动流程

1.7 误处理与恢复
1.7.1 丢包重传机制
链路层自动重传
cpp
// 链路层与L2CAP的重传协调
void ll_handle_packet_loss(connection_handle_t conn) {
// 链路层检测到ACK超时
if (ll_packet_not_acked(conn, pdu_sequence)) {
// 1. 链路层自动重传(最多LL_MAX_NACK次)
ll_retransmit_pdu(conn, pdu_sequence);
// 2. 超过最大重传次数
if (retry_count > LL_MAX_NACK) {
// 3. 通知L2CAP连接可能有问题
l2cap_notify_connection_issue(conn);
// 4. L2CAP可能触发上层恢复机制
if (l2cap_should_recover(conn)) {
// 例如:重新发送未确认的L2CAP PDU
l2cap_retransmit_unacked_data(conn);
}
}
}
}
// L2CAP的超时处理
void l2cap_timeout_handler(channel_id_t cid) {
// 如果ATT请求超时(无响应)
if (cid == ATT_CID) {
// 通知ATT层
att_handle_timeout();
// ATT可能决定重发请求或断开连接
if (att_retry_count_exceeded()) {
gap_terminate_connection();
}
}
}
1.7.2 连接超时与监控
连接监控交互
cpp
// 监控连接状态的交互
typedef struct {
uint32_t last_event_time;
uint16_t supervision_timeout; // 监控超时(如5秒)
uint8_t missed_events; // 错过的连接事件数
bool connection_valid;
} connection_monitor_t;
void monitor_connection_health(connection_handle_t conn) {
// 链路层监控物理连接
if (ll_missed_consecutive_events(conn) > MAX_MISSED_EVENTS) {
// 1. 链路层检测到连接丢失
ll_report_connection_loss(conn);
// 2. 通知L2CAP
l2cap_handle_connection_loss(conn);
// 3. L2CAP通知ATT和GAP
att_connection_lost(conn);
gap_connection_terminated(conn, TIMEOUT);
// 4. 清理资源
l2cap_cleanup_channels(conn);
}
}
2 链路层与ATT/L2CAP的协同设计
2.1 设计原则
事件驱动:所有交互基于连接事件,最大化睡眠时间
零拷贝设计:尽可能减少内存拷贝,PDU在各层间传递指针
异步通知:服务器可主动通知,减少轮询开销
弹性缓冲:根据MTU协商动态调整缓冲区大小
错误隔离:链路层处理物理错误,上层处理逻辑错误
2.2 优化建议
匹配连接间隔与数据速率:根据应用需求调整连接参数
合理设置MTU:平衡吞吐量与内存使用
利用通知机制:减少主动轮询,节省功耗
监控连接质量:动态调整参数适应环境变化
预处理数据:在应用层压缩数据,减少传输量
2.3 典型交互模式
| 场景 | 链路层角色 | L2CAP角色 | ATT角色 |
|---|---|---|---|
| 周期性数据采集 | 调度连接事件 | 可靠传输 | 通知机制 |
| 突发大数据传输 | 支持大包分片 | 流控管理 | 分块读写 |
| 低功耗待机 | 最大化从机延迟 | 缓冲管理 | 按需请求 |
| 多服务并发 | 单一物理信道 | 多路复用 | 服务发现 |