新增UART0 RX泵任务功能,将GPIO20接收到的串口数据按切行、剥离后以tag=UART推入ring buffer,通过HTTP /logs接口显示在网页日志面板。 接线方式:任意串口源TX连接至H1/H2的ESP_RX引脚,波特率3M 8N1。 feat(motor_ota): GD32 OTA增加包级防呆机制防止错误固件刷入 中继触发前校验gd32_ota镜像向量表身份(Gd32FlashStore::validateStoredImageIdentity), 对Bootloader包或非APP包在WiFi /ota/relay与BLE 0xF7均拒绝中继, 避免GD32 APP区被错误包擦除。新增0x87完成码用于固件身份验证失败场景。 feat(motor_state): 扩展CAN状态数据结构支持CONFIG负载 扩展motor_slot_t结构体,新增config_rx_count、config_seq和config_data字段 用于存储CONFIG帧的相关信息。CAN状态数据包大小从44B扩展到76B, 页面总数从6调整为9,支持目标值回报的配置数据传输。 fix(motor_ota): 修复OTA取消流程中的信用度管理和任务清理问题 ★ 先复位credit再发送CANCEL命令,防止传输卡住时背压导致CANCEL被拒绝。 延长取消等待时间至10s覆盖最坏情况,确保feedTask正常退出而非强制删除。 取消完成后复位credit防止锁存死锁,确保后续通信正常进行。 fix(http_server): 修复HTTP请求处理中的边界检查和安全验证 拒绝chunked请求(content_len<=0)防止无限循环,添加通道参数范围验证(ch 0~2), 在OTA中继触发前验证固件身份防止错误包刷入,使用http_json_append避免缓冲区越界。 refactor(gd32_flash): 实现GD32固件身份验证算法确保刷写安全 基于Cortex-M向量表内容实现包级身份校验,通过MSP和复位向量位置 区分APP包、Bootloader包和无效固件,为OTA安全提供基础保障。 BREAKING CHANGE: 电机状态API数据格式变更,CAN通道参数验证更严格
125 lines
4.4 KiB
C
125 lines
4.4 KiB
C
/*
|
||
* ble_ota_priv.h - BLE OTA 内部共享声明(仅 server/ble_ota*.cpp 使用)
|
||
*
|
||
* 拆分:
|
||
* ble_ota.cpp — 单例/会话/收尾/公开 API
|
||
* ble_ota_data.cpp — 乱序缓冲、数据写路径、worker
|
||
* ble_ota_host.cpp — GATT/GAP/广播/Host
|
||
*/
|
||
#pragma once
|
||
|
||
#include <string.h>
|
||
#include <inttypes.h>
|
||
#include <stdlib.h>
|
||
#include <stdio.h>
|
||
|
||
#include "freertos/FreeRTOS.h"
|
||
#include "freertos/task.h"
|
||
#include "freertos/semphr.h"
|
||
#include "freertos/queue.h"
|
||
#include "esp_err.h"
|
||
#include "esp_ota_ops.h"
|
||
#include "esp_system.h"
|
||
#include "esp_timer.h"
|
||
#include "esp_wifi.h"
|
||
|
||
#include "nimble/nimble_port.h"
|
||
#include "nimble/nimble_port_freertos.h"
|
||
#include "host/ble_hs.h"
|
||
#include "host/ble_gap.h"
|
||
#include "nimble/ble.h"
|
||
#include "services/gap/ble_svc_gap.h"
|
||
#include "services/gatt/ble_svc_gatt.h"
|
||
#include "host/ble_att.h"
|
||
|
||
#include "app_config.h"
|
||
#include "version.h"
|
||
#include "ble_ota.h"
|
||
#include "esp32_ota_core.h"
|
||
#include "ota_coordinator.h"
|
||
#include "ota_relay.h"
|
||
#include "storage/gd32_flash_store.h"
|
||
#include "health_monitor.h"
|
||
#include "monitor/debug_log.h"
|
||
|
||
#define TAG "BLE_OTA"
|
||
#define BLE_OTA_NOTIFY_ACK 0xA1
|
||
#define BLE_OTA_NOTIFY_FINISH 0xB1
|
||
#define BLE_OTA_NOTIFY_SHA256 0xC1
|
||
#define BLE_OTA_FINISH_DONE 0x02
|
||
#define BLE_OTA_FINISH_REBOOT_NOW 0x07
|
||
#define BLE_OTA_FINISH_GD32_RELAY_START 0x10
|
||
#define BLE_OTA_FINISH_GD32_RELAY_DONE 0x11
|
||
#define BLE_OTA_FINISH_ABORTED 0x20
|
||
#define BLE_ATT_ERR_OTA_BUSY 0x80
|
||
#define BLE_OTA_FINISH_ERR_FINALIZE 0x81
|
||
#define BLE_OTA_FINISH_ERR_MUTEX 0x83
|
||
#define BLE_OTA_FINISH_ERR_GD32_SIZE 0x84
|
||
#define BLE_OTA_FINISH_ERR_SHA_MISMATCH 0x85
|
||
#define BLE_OTA_FINISH_ERR_GD32_RELAY 0x86
|
||
#define BLE_OTA_FINISH_ERR_FW_IDENTITY 0x87 ///< 包身份不符(疑似 Bootloader/非 APP 包),拒绝中继
|
||
|
||
struct BleOtaDataBatch {
|
||
uint8_t *data;
|
||
size_t len;
|
||
int pool_idx; ///< 静态池槽索引(>=0 为池内,<0 为 heap malloc,需 free)
|
||
};
|
||
|
||
struct BleGd32RelayWaitCtx {
|
||
uint16_t session_id;
|
||
};
|
||
|
||
struct BleEsp32FinishCtx {
|
||
char sha_hex[65];
|
||
uint16_t session_id;
|
||
};
|
||
|
||
struct BleFinishCtxDeleter {
|
||
BleEsp32FinishCtx *p;
|
||
explicit BleFinishCtxDeleter(BleEsp32FinishCtx *ctx) : p(ctx) {}
|
||
~BleFinishCtxDeleter() { if (p) { free(p); p = nullptr; } }
|
||
BleFinishCtxDeleter(const BleFinishCtxDeleter&) = delete;
|
||
BleFinishCtxDeleter& operator=(const BleFinishCtxDeleter&) = delete;
|
||
};
|
||
|
||
extern QueueHandle_t s_otaDataQueue;
|
||
extern uint16_t s_data_out_val_handle;
|
||
extern bool s_wifi_ps_boosted;
|
||
/** GAP 连接参数回退请求标志(定义在 ble_ota_data.cpp,host 连接事件读写) */
|
||
extern bool s_conn_fallback_requested;
|
||
|
||
void drainOtaDataQueue();
|
||
/** @brief 归还 DATA_IN 静态池槽(drainOtaDataQueue / 会话清理跨 TU 调用)。 */
|
||
void ble_ota_pool_release(int idx);
|
||
void ble_ota_start_advertising(void);
|
||
void sendWindowAck(uint8_t cmd, uint16_t seq, uint32_t completed_bytes);
|
||
void sendFinishEvent(uint8_t stage, uint32_t value);
|
||
uint32_t packBleFinishValue(uint16_t session_id, uint16_t code);
|
||
void shaBytesToHexUpper(const uint8_t sha[32], char out_hex[65]);
|
||
void sendSha256Notify(const uint8_t sha[32], uint16_t session_id);
|
||
void esp32_reorder_free();
|
||
void ble_ota_session_reset(void);
|
||
void ble_ota_restore_wifi_ps(void);
|
||
void ble_ota_boost_wifi_ps(void);
|
||
void ble_ota_data_worker_task(void *pvParameters);
|
||
void ble_gd32_relay_wait_task(void *pvParameters);
|
||
int ble_ota_mbuf_to_buf(struct os_mbuf *om, uint8_t *buf, size_t buf_len);
|
||
void ble_ota_on_sync(void);
|
||
void ble_ota_on_reset(int reason);
|
||
void ble_ota_nimble_host_task(void *param);
|
||
int ble_ota_gap_event(struct ble_gap_event *event, void *arg);
|
||
uint16_t ble_ota_log_conn_params(uint16_t conn_handle, const char *phase);
|
||
int ble_ota_request_conn_params(uint16_t conn_handle, bool windows_compatible);
|
||
void ble_esp32_restart_task(void *pvParameters);
|
||
void ble_esp32_finish_and_reboot_task(void *pvParameters);
|
||
int ble_ota_ctrl_access(uint16_t conn_handle, uint16_t attr_handle,
|
||
struct ble_gatt_access_ctxt *ctxt, void *arg);
|
||
int ble_ota_data_in_access(uint16_t conn_handle, uint16_t attr_handle,
|
||
struct ble_gatt_access_ctxt *ctxt, void *arg);
|
||
int ble_ota_data_out_access(uint16_t conn_handle, uint16_t attr_handle,
|
||
struct ble_gatt_access_ctxt *ctxt, void *arg);
|
||
int ble_ota_version_access(uint16_t conn_handle, uint16_t attr_handle,
|
||
struct ble_gatt_access_ctxt *ctxt, void *arg);
|
||
|
||
extern const struct ble_gatt_svc_def gatt_ota_svcs[];
|