增加 APP 0x40 查询版本功能

This commit is contained in:
2026-09-11 18:48:00 +08:00
parent 01887c32b6
commit 1972a1fb58
8 changed files with 155 additions and 34 deletions
@@ -2,13 +2,14 @@
* @file usr_le_api.h
* @brief usr_le_code 对外 API(广播 / 收发 / 配网 / MCU 帧转发)
* @author cyWu <1917507415@qq.com>
* @date 2026.08.15
* @version V1.3.0
* @date 2026.09.11
* @version V1.4.0
* @history
* - V1.0.0, 2026.08.03, cyWu, 首次发布
* - V1.1.0, 2026.08.06, cyWu, 增加 MCU 帧 BLE 发送接口,解耦模组桥
* - V1.2.0, 2026.08.13, cyWu, P1:复位前断连停广播;0x41 走 cmd100 上报
* - V1.3.0, 2026.08.15, cyWu, 连接查询/写配对/BLE 发送收口到本头文件
* - V1.4.0, 2026.09.11, cyWu, 增加强制 RUNCMD_V2 应答发送,供 APP 0x40 回 0x41
******************************************************************************/
#ifndef __USR_LE_API_H__
@@ -46,6 +47,14 @@ void usr_le_data_recieve(uint8_t *data, uint16_t len);
*/
uint8_t usr_le_send_mcu_frame(uint8_t *data, uint16_t len);
/**
* @brief 将 55AA 帧作为 RUNCMD_V2 应答发出(不走 REPORTCMD_V2
* @param data 完整 55AA 帧
* @param len 帧长度
* @note APP 主动 0x40 问版本时,0x41 必须对上这次 RUNCMD,不能走网关上报
*/
uint8_t usr_le_send_mcu_frame_rsp(uint8_t *data, uint16_t len);
/**
* @brief 进入配对/配网模式
* @note 清配对信息,置 usr_goto_pair=1,发绑定广播(非回连)
@@ -2,11 +2,12 @@
* @file usr_le_recieve.c
* @brief BLE 收包入口:bleproto 解析后转交 mcu_bridge / 组应答
* @author cyWu <1917507415@qq.com>
* @date 2026.08.15
* @version V1.1.0
* @date 2026.09.11
* @version V1.2.0
* @history
* - V1.0.0, 2026.08.03, cyWu, 首次发布
* - V1.1.0, 2026.08.15, cyWu, 只经 mcu_bridge.h 访问桥;JSON OTA 废弃
* - V1.2.0, 2026.09.11, cyWu, 增加 usr_le_send_mcu_frame_rspAPP 0x40 回 0x41
******************************************************************************/
#include "system/includes.h"
@@ -294,16 +295,15 @@ static void usr_run_cmd_code_v2(ble_proto_packet_t *runcmd_par, u8 usr_msg_id)
* @brief 将 MCU 协议帧封装为 bleproto V2 后通过 BLE 发送
* @param data 55AA 完整帧
* @param len 帧长度
* @note 主动上报(0x07/0x34/0x38/0x41) → REPORTCMD_V2;其余 → RUNCMD_V2 应答
* @param as_report 1=REPORTCMD_V2 主动上报,0=RUNCMD_V2 应答
* @return 1=已交给协议栈,0=参数非法/超长/CCC 未就绪/组包失败
*/
uint8_t usr_le_send_mcu_frame(u8 *data, u16 len)
static uint8_t usr_le_send_mcu_frame_ex(u8 *data, u16 len, u8 as_report)
{
ble_proto_packet_t pkt;
bleproto_appdata_header_t hdr;
u8 v2_buf[MCU_FRAME_MAX_LEN + USR_LE_V2_WRAP_OVERHEAD];
u8 mcu_cmd;
u8 is_active_send;
int plen;
int elen;
@@ -324,7 +324,6 @@ uint8_t usr_le_send_mcu_frame(u8 *data, u16 len)
}
mcu_cmd = data[MCU_FRAME_OFF_CMD];
is_active_send = usr_le_is_gateway_report_cmd(mcu_cmd);
memset(&pkt, 0, sizeof(pkt));
memset(&hdr, 0, sizeof(hdr));
@@ -332,7 +331,7 @@ uint8_t usr_le_send_mcu_frame(u8 *data, u16 len)
hdr.datafmt = BLEPROTO_APPDATA_DATAFMT_JSON;
hdr.encrypt = 0;
if (is_active_send)
if (as_report)
{
hdr.msgtype = BLEPROTO_APPDATA_MSGTYPE_REQ;
hdr.msgid = 0;
@@ -363,7 +362,7 @@ uint8_t usr_le_send_mcu_frame(u8 *data, u16 len)
elen = bleproto_appdata_wrap_raw(txbuf, sizeof(txbuf), &hdr, v2_buf, (uint16_t)plen);
printf("usr_le_send_mcu_frame cmd=0x%02X active=%d encode_len=%d msgid=%d\n",
mcu_cmd, is_active_send, elen, hdr.msgid);
mcu_cmd, as_report, elen, hdr.msgid);
if (elen <= 0)
{
return 0;
@@ -373,3 +372,31 @@ uint8_t usr_le_send_mcu_frame(u8 *data, u16 len)
printf_buf(txbuf, elen);
return 1;
}
/**
* @brief 按命令字选择上报或应答通道
* @param data 55AA 完整帧
* @param len 帧长度
* @return 1=已交给协议栈,0=失败
*/
uint8_t usr_le_send_mcu_frame(u8 *data, u16 len)
{
u8 as_report = 0;
if (data && len >= MCU_FRAME_OVERHEAD)
{
as_report = usr_le_is_gateway_report_cmd(data[MCU_FRAME_OFF_CMD]);
}
return usr_le_send_mcu_frame_ex(data, len, as_report);
}
/**
* @brief 强制走 RUNCMD_V2 应答(APP 0x40 回 0x41
* @param data 55AA 完整帧
* @param len 帧长度
* @return 1=已交给协议栈,0=失败
*/
uint8_t usr_le_send_mcu_frame_rsp(u8 *data, u16 len)
{
return usr_le_send_mcu_frame_ex(data, len, 0);
}
@@ -2,12 +2,13 @@
* @file mcu_business.c
* @brief 业务门面实现
* @author cyWu <1917507415@qq.com>
* @date 2026.08.13
* @version V1.1.0
* @date 2026.09.11
* @version V1.3.0
* @history
* - V1.0.0, 2026.08.12, cyWu, 取代原 mcu_link,编排三个业务子模块
* - V1.1.0, 2026.08.13, cyWu, 编排 P1 管理/对时/版本
* - V1.2.0, 2026.08.15, cyWu, 编排 P2 OTA;版本周期在 OTA 时让路
* - V1.3.0, 2026.09.11, cyWu, APP 0x40 查询版本转 mcu_version
******************************************************************************/
#include "system/includes.h"
@@ -186,6 +187,15 @@ void mcu_business_on_mcu_info_ack(const uint8_t *frame, uint16_t len)
mcu_version_on_mcu_info_ack(frame, len);
}
/**
* @brief APP 0x40
* @param sn 序列号
*/
void mcu_business_on_app_get_mcu_info(uint8_t sn)
{
mcu_version_on_app_query(sn);
}
/**
* @brief 网关 ACK
* @param success 成功
@@ -2,13 +2,14 @@
* @file mcu_business.h
* @brief 业务门面:协调身份 / 配网 / 连接 / 管理 / 对时 / 版本
* @author cyWu <1917507415@qq.com>
* @date 2026.08.13
* @version V1.2.0
* @date 2026.09.11
* @version V1.3.0
* @history
* - V1.0.0, 2026.08.12, cyWu, 取代原 mcu_link,供协议层(mcu_protocol
* 单点调用;协议层不直接依赖 identity/pairing/link_status 三个子模块
* - V1.1.0, 2026.08.13, cyWu, 接入 P1 管理/对时/版本子模块
* - V1.2.0, 2026.08.15, cyWu, 接入 P2 OTA;协议层只经本门面访问 OTA
* - V1.3.0, 2026.09.11, cyWu, APP 主动 0x40 查询版本走门面,不转 UART
******************************************************************************/
#ifndef __MCU_BUSINESS_H__
@@ -114,6 +115,12 @@ void mcu_business_on_network_time(uint64_t unix_s, int32_t gmtoff_s);
*/
void mcu_business_on_mcu_info_ack(const uint8_t *frame, uint16_t len);
/**
* @brief APP 主动 0x40 查询版本(不转 UART)
* @param sn APP 请求序列号
*/
void mcu_business_on_app_get_mcu_info(uint8_t sn);
/**
* @brief 网关 REPORTCMD_V2 应答
* @param success 1=成功
@@ -337,12 +337,12 @@ static void mcu_ota_handle_notify(const uint8_t *frame, uint16_t len)
return;
}
if (mcu_ota_ble_ver_low(s_ota.ver))
{
mcu_ota_reply_app_result(MCU_CMD_OTA_NOTIFY_ACK, sn,
MCU_RESULT_OTA_VER_LOW);
return;
}
// if (mcu_ota_ble_ver_low(s_ota.ver))
// {
// mcu_ota_reply_app_result(MCU_CMD_OTA_NOTIFY_ACK, sn,
// MCU_RESULT_OTA_VER_LOW);
// return;
// }
ret = usr_ota_start(s_ota.file_size, s_ota.file_crc32);
if (ret == USR_OTA_ERR_SPACE)
@@ -2,10 +2,11 @@
* @file mcu_version.c
* @brief 版本业务实现:拉 MCU 信息并按 SOC 0x41 上报网关
* @author cyWu <1917507415@qq.com>
* @date 2026.08.13
* @version V1.0.0
* @date 2026.09.11
* @version V1.1.0
* @history
* - V1.0.0, 2026.08.13, cyWu, 首次发布
* - V1.1.0, 2026.09.11, cyWu, APP 主动 0x40:缓存组 SOC 0x41 走 RUNCMD 应答
******************************************************************************/
#include "system/includes.h"
@@ -88,6 +89,29 @@ static uint8_t mcu_version_tx_fetch(void)
return 1;
}
/**
* @brief 组 SOC 0x41 载荷
* @param payload 输出 10 字节
* @param result Result
*/
static void mcu_version_fill_soc_payload(uint8_t payload[MCU_VER_SOC_PAYLOAD_LEN],
uint8_t result)
{
payload[0] = result;
payload[1] = MCU_BLE_FW_VER_MAJOR;
payload[2] = MCU_BLE_FW_VER_MINOR;
payload[3] = MCU_BLE_FW_VER_PATCH;
if (s_ver.cached)
{
memcpy(&payload[4], s_ver.mcu_ver, 3);
memcpy(&payload[7], s_ver.hw_ver, 3);
}
else
{
memset(&payload[4], 0, 6);
}
}
/**
* @brief 组 SOC 0x41 并走 cmd 100 上报
* @return 1=已发出,0=失败
@@ -110,12 +134,7 @@ static uint8_t mcu_version_tx_report(void)
return 0;
}
payload[0] = MCU_RESULT_OK;
payload[1] = MCU_BLE_FW_VER_MAJOR;
payload[2] = MCU_BLE_FW_VER_MINOR;
payload[3] = MCU_BLE_FW_VER_PATCH;
memcpy(&payload[4], s_ver.mcu_ver, 3);
memcpy(&payload[7], s_ver.hw_ver, 3);
mcu_version_fill_soc_payload(payload, MCU_RESULT_OK);
s_ver.report_sn++;
total = mcu_frame_pack(frame, sizeof(frame), MCU_CMD_GET_MCU_INFO_ACK,
@@ -286,6 +305,41 @@ void mcu_version_on_mcu_info_ack(const uint8_t *frame, uint16_t len)
(void)mcu_version_tx_report();
}
/**
* @brief APP 主动 0x40:用缓存回 SOC 0x41(RUNCMD 应答,不改上报状态机)
* @param sn APP 请求序列号
*/
void mcu_version_on_app_query(uint8_t sn)
{
uint8_t payload[MCU_VER_SOC_PAYLOAD_LEN];
uint8_t frame[MCU_FRAME_MAX_LEN];
int32_t total;
uint8_t result;
result = s_ver.cached ? MCU_RESULT_OK : MCU_RESULT_FAIL;
mcu_version_fill_soc_payload(payload, result);
total = mcu_frame_pack(frame, sizeof(frame), MCU_CMD_GET_MCU_INFO_ACK,
sn, payload, MCU_VER_SOC_PAYLOAD_LEN);
if (total <= 0)
{
log_error("APP 0x40 pack 0x41 fail");
return;
}
if (usr_le_send_mcu_frame_rsp(frame, (uint16_t)total) == 0)
{
log_error("APP 0x40 send 0x41 fail");
return;
}
log_info("APP 0x40 -> 0x41 sn=%u result=0x%02X ble=%u.%u.%u mcu=%u.%u.%u hw=%u.%u.%u",
sn, result,
payload[1], payload[2], payload[3],
payload[4], payload[5], payload[6],
payload[7], payload[8], payload[9]);
}
/**
* @brief 网关 ACKMCU 0x07 优先消费,版本上报绝不回 MCU 0x08
* @param success 成功
@@ -2,10 +2,11 @@
* @file mcu_version.h
* @brief 版本业务:UART 0x40/0x41 拉 MCU 信息,SOC 0x41 上报网关
* @author cyWu <1917507415@qq.com>
* @date 2026.08.13
* @version V1.0.0
* @date 2026.09.11
* @version V1.1.0
* @history
* - V1.0.0, 2026.08.13, cyWu, 首次发布(P10x40/0x41 + SOC 0x41
* - V1.1.0, 2026.09.11, cyWu, APP 主动 0x40:用缓存组 SOC 0x41 应答
******************************************************************************/
#ifndef __MCU_VERSION_H__
@@ -36,6 +37,13 @@ void mcu_version_periodic(void);
*/
void mcu_version_on_mcu_info_ack(const uint8_t *frame, uint16_t len);
/**
* @brief APP 主动 0x40:用缓存组 SOC 0x41,按请求 SN 应答
* @param sn APP 请求序列号
* @note 有缓存 Result=0;无缓存仍填 BLE 版本,MCU/HW 填 0Result=失败
*/
void mcu_version_on_app_query(uint8_t sn);
/**
* @brief 网关对 REPORTCMD_V2 的应答
* @param success 1=网关成功 ACK
@@ -2,8 +2,8 @@
* @file mcu_protocol.c
* @brief MCU 接入协议引擎实现
* @author cyWu <1917507415@qq.com>
* @date 2026.08.13
* @version V1.2.0
* @date 2026.09.11
* @version V1.3.0
* @history
* - V1.0.0, 2026.08.12, cyWu, 从 mcu_bridge.c 拆出(历史版本见原文件):
* 事件队列 + 独立任务驱动、LP target、心跳/透传重传均原样保留
@@ -11,6 +11,7 @@
* MCU 自身已有超时重发机制,模组侧只记 SN 转发+等 ACK 回 0x08
* 去掉 report_pending 整包缓存与 mcu_protocol_check_report_pending()
* - V1.2.0, 2026.08.13, cyWu, P1 管理命令分发、pending 发送、网络时间入队
* - V1.3.0, 2026.09.11, cyWu, APP 0x40 本地回 0x41,禁止透传到 UART
******************************************************************************/
#include "system/includes.h"
@@ -705,6 +706,11 @@ static void mcu_protocol_handle_app_frame(const uint8_t *data, uint16_t len)
log_info("ignore APP OTA dir cmd=0x%02X", cmd);
return;
case MCU_CMD_GET_MCU_INFO:
/* APP 问版本:模组用缓存回 SOC 0x41,不要把 0x40 转给 MCU */
mcu_business_on_app_get_mcu_info(sn);
return;
case MCU_CMD_CONTROL:
if (mcu_business_ota_is_active()) {
mcu_protocol_reply_app_result(MCU_CMD_CONTROL_ACK, sn, MCU_RESULT_BUSY);