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

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

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

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

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

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

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

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