当前位置: 首页 > news >正文

BLE配网协议 - 分包、组包和重传功能指南

概述

本文档详细介绍了BLE配网协议中新增的MTU分包、组包和重传功能。这些功能确保在BLE连接的MTU限制下,能够可靠地传输大数据包。

功能特性

1. MTU适配

  • 动态MTU设置: 支持20-512字节的MTU范围
  • 自动分片判断: 根据MTU大小自动判断是否需要分片
  • 最优分片计算: 智能计算最少分片数量

2. 数据分包

  • 分片类型: 支持单包、首片、中间片、尾片四种类型
  • 分片标识: 每个分片包含唯一ID和总分片数信息
  • 数据完整性: 包含原始数据长度和偏移信息
  • 最大分片数: 支持最多32个分片

3. 数据组包

  • 分片接收: 支持乱序接收分片
  • 重复检测: 自动检测和忽略重复分片
  • 完整性验证: 确保所有分片接收完成后才进行重组
  • 内存管理: 自动管理重组缓冲区

4. 可靠重传

  • 自动重传: 支持最多3次重传
  • 超时机制: 可配置的重传超时时间
  • ACK确认: 支持确认机制停止重传
  • 资源清理: 自动清理超时的重传信息

协议格式

分片头格式

typedef struct __attribute__((packed)) {uint8_t  frag_type:2;   // 分片类型 (0:单包, 1:首片, 2:中间片, 3:尾片)uint8_t  frag_id:6;     // 分片ID (0-63)uint8_t  total_frags;   // 总分片数uint16_t total_len;     // 原始数据总长度uint16_t frag_offset;   // 当前分片在原始数据中的偏移
} ble_prov_frag_header_t;

分片帧格式

+--------+--------+--------+--------+--------+--------+
| Header | Version|  CMD   |  SEQ   |    Length       |
+--------+--------+--------+--------+--------+--------+
|              分片头 (6字节)                        |
+--------+--------+--------+--------+--------+--------+
|                分片数据                            |
+--------+--------+--------+--------+--------+--------+
|     CRC16      |  Tail  |
+--------+--------+--------+

API接口

1. MTU设置

/*** 设置MTU大小* @param parser 解析器实例* @param mtu_size MTU大小 (20-512字节)* @return 0成功,其他失败*/
int ble_prov_set_mtu(ble_prov_parser_t *parser, uint16_t mtu_size);

2. 数据分片

/*** 数据分片* @param parser 解析器实例* @param cmd 命令类型* @param data 原始数据* @param data_len 数据长度* @param fragments 输出分片数组* @param frag_lens 分片长度数组* @param frag_count 分片数量* @return 0成功,其他失败*/
int ble_prov_fragment_data(ble_prov_parser_t *parser, uint8_t cmd, const uint8_t *data, uint16_t data_len, uint8_t ***fragments, uint16_t **frag_lens, uint8_t *frag_count);

3. 发送分片

/*** 发送分片数据* @param parser 解析器实例* @param fragments 分片数组* @param frag_lens 分片长度数组* @param frag_count 分片数量* @param send_func 发送函数* @return 0成功,其他失败*/
int ble_prov_send_fragments(ble_prov_parser_t *parser, uint8_t **fragments, uint16_t *frag_lens, uint8_t frag_count, int (*send_func)(const uint8_t *data, uint16_t len));

4. 处理分片

/*** 处理接收到的分片* @param parser 解析器实例* @param frame 协议帧* @return 0成功,1所有分片接收完成,其他失败*/
int ble_prov_process_fragment(ble_prov_parser_t *parser, const ble_prov_frame_t *frame);

5. 重组数据

/*** 重组分片数据* @param parser 解析器实例* @param seq 序列号* @param data 输出重组数据* @param data_len 数据长度* @return 0成功,其他失败*/
int ble_prov_reassemble_data(ble_prov_parser_t *parser, uint8_t seq, uint8_t **data, uint16_t *data_len);

6. 重传管理

/*** 添加重传信息*/
int ble_prov_add_retry(ble_prov_parser_t *parser, const uint8_t *frame_data, uint16_t frame_len, uint8_t seq, uint32_t timeout_ms);/*** 处理ACK确认*/
int ble_prov_process_ack(ble_prov_parser_t *parser, uint8_t seq);/*** 检查并处理重传*/
void ble_prov_check_retries(ble_prov_parser_t *parser, uint32_t current_time, int (*send_func)(const uint8_t *data, uint16_t len));

使用示例

发送端示例

#include "ble_provisioning_protocol.h"// 发送函数
int my_ble_send(const uint8_t *data, uint16_t len) {// 实际的BLE发送实现return ble_gatt_write(data, len);
}void send_large_data(const uint8_t *data, uint16_t data_len) {ble_prov_parser_t parser;uint8_t buffer[1024];ble_prov_config_t config = {0};// 初始化解析器ble_prov_parser_init(&parser, &config, buffer, sizeof(buffer));// 设置MTUble_prov_set_mtu(&parser, 20);  // 20字节MTU// 检查是否需要分片if (ble_prov_need_fragmentation(data_len, parser.mtu_size)) {uint8_t **fragments = NULL;uint16_t *frag_lens = NULL;uint8_t frag_count = 0;// 分片数据int ret = ble_prov_fragment_data(&parser, BLE_PROV_CMD_HANDSHAKE, data, data_len,&fragments, &frag_lens, &frag_count);if (ret == 0) {// 发送分片ble_prov_send_fragments(&parser, fragments, frag_lens, frag_count, my_ble_send);// 清理内存for (int i = 0; i < frag_count; i++) {free(fragments[i]);}free(fragments);free(frag_lens);}} else {// 直接发送uint8_t frame_buf[256];int frame_len = ble_prov_build_frame(frame_buf, sizeof(frame_buf),BLE_PROV_CMD_HANDSHAKE, 1,data, data_len);if (frame_len > 0) {my_ble_send(frame_buf, frame_len);}}
}

接收端示例

void handle_received_frame(const ble_prov_frame_t *frame) {static ble_prov_parser_t parser;static bool parser_initialized = false;if (!parser_initialized) {uint8_t buffer[1024];ble_prov_config_t config = {0};ble_prov_parser_init(&parser, &config, buffer, sizeof(buffer));parser_initialized = true;}// 检查是否为分片数据if (frame->length >= sizeof(ble_prov_frag_header_t)) {ble_prov_frag_header_t *frag_header = (ble_prov_frag_header_t*)frame->payload;if (frag_header->frag_type != BLE_PROV_FRAG_SINGLE) {// 处理分片int ret = ble_prov_process_fragment(&parser, frame);if (ret == 1) {// 所有分片接收完成,重组数据uint8_t *reassembled_data = NULL;uint16_t reassembled_len = 0;ret = ble_prov_reassemble_data(&parser, frame->seq, &reassembled_data, &reassembled_len);if (ret == 0) {// 处理重组后的完整数据process_complete_data(frame->cmd, reassembled_data, reassembled_len);free(reassembled_data);}}return;}}// 处理非分片数据process_complete_data(frame->cmd, frame->payload, frame->length);
}

重传处理示例

void periodic_retry_check(void) {static ble_prov_parser_t parser;uint32_t current_time = get_current_time_ms();// 检查并处理重传ble_prov_check_retries(&parser, current_time, my_ble_send);// 清理超时的分片ble_prov_cleanup_fragments(&parser, current_time);
}void handle_ack_received(uint8_t seq) {static ble_prov_parser_t parser;// 处理ACK,停止对应序列号的重传ble_prov_process_ack(&parser, seq);
}

配置参数

默认配置

#define BLE_PROV_DEFAULT_MTU        20      // 默认BLE MTU大小
#define BLE_PROV_MAX_MTU            512     // 最大MTU大小
#define BLE_PROV_MIN_MTU            20      // 最小MTU大小
#define BLE_PROV_MAX_FRAGMENTS      32      // 最大分片数量
#define BLE_PROV_FRAGMENT_TIMEOUT   3000    // 分片超时时间(ms)
#define BLE_PROV_MAX_RETRIES        3       // 最大重传次数
#define BLE_PROV_RETRY_TIMEOUT      1000    // 重传超时时间(ms)

性能优化建议

  1. MTU设置: 根据实际BLE连接协商的MTU值设置,避免不必要的分片
  2. 缓冲区大小: 根据最大数据包大小合理设置缓冲区
  3. 超时时间: 根据网络环境调整重传和分片超时时间
  4. 内存管理: 及时清理不再使用的分片和重传信息

错误处理

常见错误码

  • -1: 参数错误或内存分配失败
  • -2: 分片不完整
  • 0: 操作成功
  • 1: 所有分片接收完成

故障排除

  1. 分片失败: 检查MTU设置和数据长度
  2. 重组失败: 确保所有分片都已接收
  3. 重传过多: 检查网络连接和超时设置
  4. 内存泄漏: 确保正确释放分片和重传缓冲区

测试验证

运行分包功能测试程序:

make -f ble_prov_Makefile run-frag

测试包括:

  • 分包功能测试
  • 组包功能测试
  • 重传功能测试
  • 超时清理测试

版本历史

  • v1.1.0: 新增MTU分包、组包和重传功能
  • v1.0.0: 基础BLE配网协议实现

许可证

本项目采用MIT许可证,详见LICENSE文件。

http://www.dtcms.com/a/409952.html

相关文章:

  • MediaHuman YouTube to MP3 多语便携版:高效音频提取工具
  • Java 数组的定义与使用
  • 自建站有哪些站点wordpress前台压缩图片
  • R语言中的获取函数与替换函数
  • 微前端中iframe集成方式与使用微前端框架方式对比
  • 【NOI】在信奥赛中 什么是函数交互题?
  • 电脑上怎么做网站963中华室内设计网
  • Python调用优云智算安装的ComfyUI服务器
  • ACA云原生工程师认证知识点脑图
  • 用 Flink 打造事件驱动流式应用从 DataStream 到 ProcessFunction
  • MySQL学习笔记05:MySQL 索引原理与优化实战指南
  • 【提示工程】Ch2(续)-提示技术(Prompt Technique)
  • 嵌入式软件知识点汇总(day2)
  • QT中QStackedWidget控件功能及应用
  • 网络爬虫(上)
  • 论文精读(六):微服务系统服务依赖发现技术综述
  • 农业推广网站建设企业商城网站建设价格
  • 教师做班级网站手机网站打开微信号
  • 司法审计师:在数字与法律之间行走的“侦探”
  • google drive 怎么断点续传下载?
  • 基于STM32单片机的温湿度臭氧二氧化碳检测OneNET物联网云平台设计
  • LeetCode 面试经典 150_哈希表_快乐数(45_202_C++_简单)(哈希表;快慢指针)
  • K8S部署的ELK分片问题解决,报错:unexpected error while indexing monitoring document
  • Atlas Mapper 教程系列 (7/10):单元测试与集成测试
  • 众智FlagOS 1.5发布:统一开源大模型系统软件栈,更全面、AI赋能更高效
  • 理解 mvcc
  • 【网络编程】TCP 粘包处理:手动序列化反序列化与报头封装的完整方案
  • 数据库MVCC
  • 如何用AI工具开发一个轻量化CRM系统(七):AI生成pytest测试脚本
  • qData:一站式开源数据中台