Files
小龙虾 ebb3dcdf38 feat(debug_log): 新增UART0 RX泵任务支持串口日志转发
新增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通道参数验证更严格
2026-09-01 02:49:34 +08:00

125 lines
4.4 KiB
C
Raw Permalink 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.
/*
* 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[];