# FileTransferProtocol **Repository Path**: GKoSon/FileTransferProtocol ## Basic Information - **Project Name**: FileTransferProtocol - **Description**: 本仓库是协议文档 非可执行代码 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-05-13 - **Last Updated**: 2026-11-04 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 文件传输协议规范(V1.0) ## 一、协议概述 本协议定义**文件请求者**(嵌入式设备,如 MCU/SOC)与**文件提供者**(上位机,如 PC/手机/云平台)之间的文件传输规范。 协议采用 ASCII 文本帧格式,适用于串口、BLE 等低带宽透传通道。 - **传输模式**:上位机发起 随后下位主导 - **编码格式**:ASCII 字符串 - **适用场景**:固件升级(OTA)、配置文件下发 ## 二、角色定义 | 角色 | 设备类型 | 职责 | | -------------- | ---------------------- | -------------------------------- | | **文件请求者** | MCU / SOC 嵌入式设备 | 发起文件请求,接收并写入文件数据 | | **文件提供者** | 笔记本 / 手机 / 云平台 | 提供文件信息,响应请求并下发数据 | ## 三、帧结构定义 所有报文均由 `HEAD`、`BODY`、`TAIL` 三部分组成。 | 字段分类 | 字段名称 | 长度(字节) | 格式/取值 | 说明 | | -------- | -------- | ---------- | ---------------- | ---------- | | **HEAD** | TYPE | 4 | `0001`~`0004` | 帧类型标识 | | **HEAD** | LEN | 4 | `0000`~`9999` | BODY 长度 | | **BODY** | VALUE | 等于 LEN | 见下方帧类型说明 | 负载数据 | | **TAIL** | CRC16 | 2 | 十六进制 ASCII | 可以不实现 | > **注**:当 LEN 为 `FFFF` 时,表示无 BODY 且无 TAIL。 ## 四、帧类型定义 | TYPE | 名称 | BODY 格式 | 说明 | | ------ | ---------- | --------- | -------------------------------------------- | | `0001` | 文件信息帧 | JSON | 包含文件元数据(文件名、大小、MD5、版本等) | | `0002` | 文件请求帧 | JSON | 请求文件参数(起始地址`addr`、长度 `len`) | | `0003` | 文件内容帧 | Bin | 文件原始二进制数据 | | `0004` | 文件结束帧 | JSON | 包含传输结果状态(`status`: 0 成功, 1 失败) | ## 五、交互时序流程 【文件提供者】 【文件请求者】 │ │ │ 1. 0001 文件信息帧 │ ├────────────────────────────────────────>│ │ │ │ 2. 0002 文件请求帧 │ │<────────────────────────────────────────┤ │ │ │ 3. 0003 文件内容帧 │ ├────────────────────────────────────────>│ │ │ │ 4. 0002 文件请求帧(下一块) │ │<────────────────────────────────────────┤ │ │ │ 5. 0003 文件内容帧 │ ├────────────────────────────────────────>│ │ │ │ 6. 0004 文件结束帧 │ │<────────────────────────────────────────┤ ## 六、蓝牙分包传输 ### 6.1 背景 当文件提供者为手机(BLE 设备)时,受蓝牙链路 MTU 限制(例如 BT24S 模块 MTU=256 字节,扣除 ATT 开销后单包有效载荷为 253 字节), 单帧无法承载较大数据块。因此需要对 `0003` 文件内容帧进行**分片传输**,由提供者分包发送,请求者接收后组包还原。 ### 6.2 分片帧格式(TXV) 在蓝牙分包场景下,`0003` 帧的头部结构由 **TLV** 调整为 **TXV**: | 字段 | 长度 | 格式 | 说明 | | ---- | ------ | ---------------------- | ---------------------- | | TYPE | 4 字节 | `0003` | 帧类型标识,保持不变 | | X | 4 字节 | `NNMM`(十进制 ASCII) | 分片描述,见下文 | | BODY | 可变 | 原始二进制数据 | 本分片所携带的文件片段 | | TAIL | 2 字节 | CRC16(可选) | 同普通帧 | > **注**:`X` 字段替代了普通帧中的 `LEN` 字段,因此分片帧的总头部仍为 8 字节。 ### 6.3 X 字段定义 `X` 字段由两个 2 字节子字段拼接而成,均为十进制 ASCII 码(范围 `00` \~ `99`): | 子字段 | 位数 | 含义 | 示例 | | ------ | ---- | -------------------------- | ---------------- | | NN | 2 | 当前分片序号(从 00 开始) | `00`、`01`…`15` | | MM | 2 | 本块总分片数量 | `16` | **示例**:`0016` 表示第 0 片,共 16 片;`1516` 表示第 15 片(最后一片),共 16 片。 ### 6.4 分片计算规则 | 参数 | 值 | 说明 | | ------------------- | ------------ | ------------------ | | BLE MTU | 256 字节 | 链路层最大传输单元 | | ATT 开销 | 3 字节 | 操作码等 | | 单包有效载荷 | 253 字节 | `256 - 3` | | 分片帧头部 | 8 字节 | `TYPE(4) + X(4)` | | **每分片最大 BODY** | **245 字节** | `253 - 8` | **计算公式**:
### 6.5 传输示例 假设请求者申请一块 **3920 字节**的数据: * 总分片数 = `ceil(3920 / 245) = 16` * 每片 BODY 长度:前 15 片各 245 字节,最后一片 `3920 - 15×245 = 245` 字节(恰好整除) * 每帧总长度:`8 + 245 = 253` 字节(等于单包有效载荷上限) 手机依次发送以下 16 帧(省略 TAIL):
请求者收到后,根据 `NN` 将 BODY 填入缓冲区的对应偏移(`offset = NN × 245`),当收到 `NN == MM-1` 时判定本块收齐,进行组包写入。 ### 6.6 与其他帧的关系 * **0001(文件信息帧)**、**0002(文件请求帧)**、**0004(文件结束帧)** 主动限制在 MTU内即可,仍使用标准 TLV 格式(HEAD = TYPE + LEN)。 * 仅 `0003` 在蓝牙分包场景下切换为 TXV 格式 ## 七、扩展到全部蓝牙协议 基于 TLV 帧结构,协议可扩展至文件传输之外的其他交互场景。 目前项目已实现以下报文类型,覆盖文件传输、参数配置、设备控制等功能。 ### 7.1 完整帧类型一览 | TYPE | 名称 | 方向 | BODY 格式 | 预期应答 | 说明 | | ------ | ---------- | --------- | ------------------ | -------------- | ----------------------------------------- | | `0001` | 文件信息帧 | 手机→MCU | JSON | `0002` | 下发文件元数据(文件名、大小、MD5、版本) | | `0002` | 文件请求帧 | MCU→手机 | JSON | `0003` | 请求一块数据`{"addr":0,"len":3920}` | | `0003` | 文件内容帧 | 手机→MCU | Bin(或 TXV 分片) | `0002`或`0004` | 传输文件数据;蓝牙场景下使用 TXV 分包 | | `0004` | 文件结束帧 | MCU→手机 | JSON | 无 | 报告传输结果`{"status":0}` | | `0005` | 写设备参数 | 手机→MCU | JSON | `0006` | 写入配置项(如上报间隔、阈值等) | | `0006` | 写参数应答 | MCU→手机 | JSON | 无 | 返回写入结果`{"result":0}` | | `0007` | 读设备参数 | 手机→MCU | JSON | `0008` | 请求读取指定参数`{"key":"..."}` | | `0008` | 读参数应答 | MCU→手机 | JSON | 无 | 返回参数值`{"key":"...","value":"..."}` | | `0009` | 复位设备 | 手机→MCU | 无(BODY 可为空) | 无需应答 | 触发设备软件复位 | | `0010` | 擦除数据库 | 手机→MCU | 无(BODY 可为空) | 无需应答 | 清除设备内部存储(如 FlashDB) | ### 7.2 交互说明 * **文件传输类**(0001~0004)的交互时序已在第五节描述,蓝牙分包场景下 `0003` 使用 TXV 格式(详见第六节)。 * **参数读写类**(0005~0008)采用标准的 TLV 格式(HEAD = TYPE + LEN),BODY 为 JSON 字符串,单帧即可完成,无需分包。 * **控制类**(0009、0010)BODY 可为空(LEN = `0000`),设备收到后立即执行相应操作,无需回复。 ### 7.3 协议扩展原则 1. **所有帧均遵守统一的 HEAD + BODY + TAIL 结构**(TAIL 可选)。 2. **新命令的 TYPE 从 `0011` 开始递增**,避免与现有编号冲突。 3. **BODY 优先使用 JSON 格式**,便于解析和扩展。 4. **命令帧不参与文件传输的分包逻辑**(因其数据量远小于 MTU),始终以单帧形式发送。 ## 八、2016-11-04 更新:统一帧格式编码 ### 8.1 背景与问题 在原有设计中,只有 `0003` 使用 TXV(分片)格式,其他帧(0001、0002、0004 等)均使用 TLV 格式。 这导致两种模式并存,MCU 需要根据帧类型(0003)和传输介质(BLE)来双重判断解析方式,逻辑不够清晰。 本次更新引入**统一的帧格式编码规则**,通过 **TYPE 字段的第一个字符**来区分传输模式,使解析逻辑更简洁、更具扩展性。 ### 8.2 新 TYPE 编码规则 TYPE 仍为 4 位十进制 ASCII 码(`0000`\~`9999`),但其**最高位(千位)**被赋予特殊含义: | 千位数字 | 含义 | 帧格式 | 适用场景 | | -------- | -------- | ---------------------------- | ---------------------------------- | | **0** | 标准模式 | **TLV**(Type-Length-Value) | 串口一次性发送,数据量小,无需分片 | | **1** | 分片模式 | **TXV**(Type-X-Value) | BLE 等低带宽通道,需要分片传输 | > **核心思想**:`0` 开头 = TLV(原始协议),`1` 开头 = TXV(分片协议)。 ### 8.3 新增帧类型定义 基于上述规则,`0003` 被拆分为以下三种具体类型: | TYPE | 名称 | 帧格式 | BODY 格式 | 说明 | | ------ | ------------------------ | ------ | --------- | ------------------------------------------------ | | `0003` | 文件内容帧(TLV) | TLV | Bin | 串口一次性发送,适合 4KB 以下小文件 | | `1003` | 文件内容帧(TXV-普通片) | TXV | Bin | BLE 分片传输,普通数据分片(每片 ≤ 245B) | | `1103` | 文件内容帧(TXV-最后片) | TXV | Bin | BLE 分片传输,**最后一个分片**,用于标记本块结束 | > **注**:`1003` 与 `1103` 的区别仅在于**十位数字**(`0`=普通片,`1`=最后片),它们共同构成一次完整的蓝牙分片传输。 ### 8.4 分片标识(X 字段)复用 `1003` 和 `1103` 仍使用 TXV 格式,其 `X` 字段(4 字节)定义与第六节一致: | X 字段 | 含义 | | ------ | ---------------------- | | `NN` | 当前分片序号(00\~99) | | `MM` | 本块总分片数(00\~99) | **分片结束判定**: * **普通片**(`1003`):接收方根据 `NN` 填充缓冲区,等待后续分片。 * **最后片**(`1103`):接收方判定本块所有分片已收齐,立即进行组包写入。 ### 8.5 请求逻辑简化 采用新编码后,**MCU 无需关心传输介质**,只需按固定块大小请求数据: * MCU 固定请求 **4096 字节**(`{"addr":0,"len":4096}`)。 * 文件提供者(QT)自动根据当前通道(BLE/串口)选择帧格式: * **串口**:使用 `0003`(TLV),一次性下发 4096 字节。 * **BLE**:使用 `1003`/`1103`(TXV),自动计算分片数并逐片下发。 **BLE 分片示例**(请求 4096 字节):
> QT 自动将 4096 字节分为 **16 片 245B + 1 片 176B**,共 17 包发送。MCU 收到 `1103` 即知本块传输完成。 ### 8.6 兼容性说明 * **向下兼容**:旧设备仍可使用 `0003`(TLV)进行串口传输,不受影响。 * **新模式识别**:MCU 通过判断 TYPE 的千位数字(`0` 或 `1`)自动切换解析逻辑: * `0xxx` → 按 TLV 解析(LEN 字段表示 BODY 长度)。 * `1xxx` → 按 TXV 解析(X 字段表示分片信息)。 * **扩展性**:未来如需新增其他传输模式(如加密分片),可继续扩展千位数字(`2xxx`、`3xxx` 等)。 ### 8.7 更新后的完整帧类型表 | TYPE | 名称 | 帧格式 | 方向 | BODY 格式 | 预期应答 | 说明 | | -------------- | ---------------------- | ------ | --------- | --------- | ---------------- | ------------------ | | `0001` | 文件信息帧 | TLV | 手机→MCU | JSON | `0002` | 文件元数据 | | `0002` | 文件请求帧 | TLV | MCU→手机 | JSON | `0003`/`1003` | 请求数据块 | | `0003` | 文件内容帧(TLV) | TLV | 手机→MCU | Bin | `0002`/`0004` | 串口一次性发送 | | `1003` | 文件内容帧(TXV-普通) | TXV | 手机→MCU | Bin | `0002`/`0004` | BLE 分片,普通片 | | `1103` | 文件内容帧(TXV-最后) | TXV | 手机→MCU | Bin | `0002`/`0004` | BLE 分片,最后一片 | | `0004` | 文件结束帧 | TLV | MCU→手机 | JSON | 无 | 传输结果 | | `0005`\~`0010` | 参数/控制命令 | TLV | 双向 | JSON/空 | `0006`/`0008`/无 | 见第七章 | ---