BLE批量数据选L2CAP CoC还是GATT:分帧、信用与平台支持
从兼容性和背压选择承载
传日志或固件镜像时,问题不是“L2CAP是否比蓝牙快”。GATT流量与LE面向连接信道都使用蓝牙栈,共享无线约束。应先判断目标手机及嵌入式栈是否提供所需接口、应用能否正确处理背压,以及是否仍需GATT承担发现和控制。本文以Bluetooth Core 6.0和Zephyr 3.7.0为明确基线,比较GATT与LE Credit Based Flow Control信道,不默认支持增强型信用流控,也不声称取得任何吞吐优势实测。 涉及产品资格声明时,应核对SIG的Core 6.0页面及强制更新;本文不是合规检查清单。

比较抽象能力,而不是包长口号
GATT提供服务和特征操作,Nordic服务与特征指南可作为该模型的一手入门资料。批量协议能够使用这些操作,但必须遵守所选过程的长度和流控信号。LE CoC则提供独立面向连接数据通道。Core 6.0 L2CAP区分限制SDU的接收MTU,以及限制协议数据负载的MPS;二者都不是PHY速率,也不直接保证应用块大小。不能拿最小配置GATT与精心调优CoC比较,再把差距写成承载本身的必然性质;比较必须使用相同安全、无线条件与业务负载。
逐平台核对双方角色
Android的createL2capChannel接口在API 29引入,使用远端PSM创建安全的出站LE CoC套接字,这不代表更旧手机或任意固件支持。Apple的WWDC2017 Core Bluetooth资料记录CBL2CAPChannel从iOS 11及macOS 10.13提供输入输出流,实际部署还需核对当前SDK可用性与生命周期行为。嵌入式侧应确认监听端和发起端能力、安全策略、缓冲配置及出货栈版本。仅看到编译符号不算完成互通验证,应保留角色、系统版本、SDK及信道打开结果矩阵。
发现端点,再协商业务契约
客户端需要正确的服务端点标识,常见形式为PSM,不能把曾经取得的动态值当成永久常量。可以通过小型GATT控制服务,在产品访问策略下发布能力并提供当前端点。开始传输前协商批量协议版本、最大应用消息、传输编号和安全要求。对端不支持CoC时,采用已定义的GATT降级路径,并保持相同授权及完整性要求;安全打开失败不能静默改成不安全连接。还需规定重启或重连后何时重新读取能力,避免过时端点造成难以解释的传输故障。
不要把SDU等同手机流读取
L2CAP具有SDU边界,但平台可能在其上暴露流抽象。手机应用不能假定一次读取就是完整消息,也不能假定一次写入由单个回调全部消耗。应定义版本、消息类型、有界负载长度、传输编号及负载组成的应用帧。增量解析,先验证长度再分配内存,并处理半个头部及一个输入缓冲包含多个帧的情况。字节序必须明确,不支持版本应被拒绝;还要限制未完成帧的缓存和等待时间,避免慢速输入持续占用内存。镜像或日志还需要与威胁模型相符的应用完整性检查和明确完成确认;链路加密本身不证明目标文件已经完整保存。
信用代表接收容量,不是完成确认
Core 6.0的LE信用机制每发送一个K-frame消耗一个信用,并非按应用消息或字节计数。接收方在有能力时补充信用,因此零信用应产生背压,不能忙循环重试或无限复制排队。Zephyr 3.7.0 L2CAP接口说明发送可能因信用不足阻塞,接收回调运行于RX线程,不宜长期阻塞。应遵守该版本缓冲所有权和异步完成规则,不能一边阻塞负责释放接收资源的线程,一边等待依赖这些资源的发送完成。信用归还仍不表示业务已提交到持久化存储。
中断与降级不能造成重复提交
传输编号和接收方持久化进度,应与已经提交到本地套接字的字节数分开。断线后取消旧异步任务,确认接收端真正提交了哪些块,再决定续传。若从CoC降级至GATT,应保留同一逻辑传输编号和幂等块语义,或先执行明确丢弃流程后重来;不要让两种承载同时竞争写同一个文件。接收端应拒绝矛盾偏移、长度或内容标识,为临时存储和过期传输设上限,并确保取消会释放信道缓冲。这些应用要求不会由CoC信用或ATT响应自动提供。
验收比较完整且可恢复的工作量
两种承载使用相同负载、安全状态、连接条件及设备组合。覆盖最低支持系统、不支持CoC、安全被拒、慢消费者、接收队列满、半帧断线、过时PSM、取消和重启。只有实际测量后才报告有效提交字节、耗时、内存峰值和能量,失败传输也必须纳入结果。本文仅提供矩阵,没有性能数字。兼容性和背压模型符合产品需求时可选择CoC,GATT覆盖面及实现简洁性更有价值时则保留它。最终决策应基于完整、可恢复的传输,而不是醒目的MTU数字或一次成功打开回调。