Files
ESP32_COMM/main/transport/protocol.h
T
小龙虾 5db3f66b8e feat(protocol): 更新SPI Link协议至v2版本并优化CAN通信
- 将SPI OTA帧格式升级为SPI Link v2,采用新的帧格式:
  | SOF0 0xA5 | SOF1 0x5A | VER 0x02 | FLAGS | SESSION 4B LE |
  TX_SEQ | ACK_SEQ | CREDIT | TYPE | LEN 2B LE | RSV 2B | PAYLOAD |
  CRC32 4B LE |
- 新增V2_OVERHEAD=20字节开销,APP最大payload为236字节,BOOT为108字节
- 修改帧类型定义:ENTER_BOOT从0xB5合并至0xB0,新增CAN业务类型0xC0~C3
- 更新CAN协议文档,支持SPI Link v2-only模式,调整最大业务payload计算
- 扩展0xC1帧功能,支持双向通信和1Hz主动推送ID快照
- 添加0xC3完整ID快照帧类型,包含seq/rx_count等完整字段
- 更新协议文档中的错误码定义和反馈payload格式

refactor(main): 重构主程序入口并添加CAN反馈任务

- 在main.cpp中添加CAN反馈任务,更新启动流程注释
- 创建createCriticalTask辅助函数,统一关键任务创建逻辑
- 调整SPI初始化顺序,确保CAN反馈任务依赖正确
- 优化错误处理机制,关键任务失败时立即重启
- 将GD32版本探测移至ota_relay任务处理
- 更新版本号至0.3.48,调整编译时间和Git哈希

config: 更新SPI和BLE配置参数

- 添加SPI主机相关配置参数,包括CS GPIO、READY GPIO等引脚定义
- 配置SPI缓冲区大小:APP为256字节,BOOT为128字节
- 更新BLE滑动窗口参数,ACK窗口设为32,数据队列深度为72
- 调整SPI工作队列大小至5120字节,增加任务堆栈监控说明
2026-07-16 23:00:15 +08:00

109 lines
3.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* protocol.h - OTA 握手辅助(nonce 扰码 + 会话密钥生命周期)
*
* 本模块刻意保持轻量(原「帧格式 / CRC16 / AES-CBC」中间件已迁出):
* - 不负责 SPI Link v2 帧 / CRC32
* - 不负责 AES 加解密(OTA 数据包 AES-ECB 在 ota_relay 内)
* - 仅提供:RNG 扰码常数、server nonce 生成、session key 存清
*
* AES 主密钥 MASTER_KEY[] 见 app_config.h。
*/
#ifndef PROTOCOL_H
#define PROTOCOL_H
#include <stdint.h>
#include <stddef.h>
#include "app_config.h"
/** @brief AES-128 / 会话密钥长度(字节)。 */
inline constexpr size_t SESSION_KEY_LEN = 16;
/**
* @brief OTA 会话密钥上下文。
*
* 仅缓存协商得到的 K_session;真正加解密在 ota_relay 中用该 key 做 AES-ECB。
*/
typedef struct {
uint8_t key[SESSION_KEY_LEN]; ///< 会话密钥 K_session(16 字节)
} session_ctx_t;
/**
* @brief OTA 握手辅助类(单例)
*
* 持有 per-boot 扰码常数 m_scrambleConst;
* sessionKeyInit / sessionKeyClear 为无状态静态工具,不依赖单例成员。
*/
class Protocol {
public:
/**
* @brief 获取 Protocol 单例实例。
* @return Protocol 单例引用。
*/
static Protocol& instance();
/**
* @brief 初始化协议层(幂等)。
*
* 使用硬件 RNG 填充 m_scrambleConst,供 scrambleGenerate 混合使用。
* 可重复调用;已初始化则直接返回。
*/
void init();
/**
* @brief 生成基于时间戳、地址和随机种子的 16 字节 server nonce。
* @param timestamp 时间戳(如 FreeRTOS tick)。
* @param mem_addr 内存地址(增加熵,通常取栈/缓冲区地址)。
* @param rand_seed 随机种子。
* @param nonce_out 输出缓冲区,至少 16 字节;为 nullptr 时直接返回。
*
* @note 非标准 KDF,仅作 OTA 握手 nonce,勿当通用密钥派生。
* @note 若尚未 init(),内部会自动调用 init()。
*/
void scrambleGenerate(uint32_t timestamp, uint32_t mem_addr,
uint32_t rand_seed, uint8_t *nonce_out);
/**
* @brief 会话密钥初始化,将密钥拷贝到会话上下文。
* @param sess 会话上下文指针。
* @param k_session 会话密钥数据(至少 SESSION_KEY_LEN 字节)。
* @return 成功返回 0,参数无效返回 -1。
*/
static int sessionKeyInit(session_ctx_t *sess, const uint8_t *k_session);
/**
* @brief 清除会话上下文中的密钥数据(抗优化擦除)。
* @param sess 会话上下文指针;为 nullptr 时忽略。
*/
static void sessionKeyClear(session_ctx_t *sess);
private:
/**
* @brief 私有默认构造函数。
*/
Protocol() = default;
/**
* @brief 私有析构函数。
*/
~Protocol() = default;
/**
* @brief 禁止复制构造。
*/
Protocol(const Protocol&) = delete;
/**
* @brief 禁止复制赋值。
*/
Protocol& operator=(const Protocol&) = delete;
/**
* @brief 抗编译器优化的内存擦除(volatile 逐字节写 0)。
* @param p 起始地址;nullptr 忽略。
* @param n 字节数。
*/
static void secureWipe(void *p, size_t n);
uint8_t m_scrambleConst[SCRAMBLE_CONST_LEN] = {0}; ///< per-boot 扰码常数(init 时 RNG 填充)
bool m_initialized = false; ///< 是否已 init
};
#endif // PROTOCOL_H