增加OTA功能,待修改双工框架并修改电子围栏、景点数据下发逻辑

This commit is contained in:
kkkjtr 2025-08-08 14:44:14 +08:00
parent f551d38609
commit 7709d118d2
5 changed files with 147 additions and 17 deletions

View File

@ -14,7 +14,7 @@
#include "gps_config.h"
#include "local_tts.h"
#if 0
#if 1
#include "app_uart.h"
#define DEBUG(fmt, args...) app_printf("[GPS]" fmt, ##args)
#else

View File

@ -6,7 +6,7 @@
#include <stdlib.h>
#include "jt808_util.h"
#define JT808_DEBUG_ENABLE 0
#define JT808_DEBUG_ENABLE 1
#if JT808_DEBUG_ENABLE
#include "app_uart.h"

View File

@ -169,12 +169,10 @@ typedef struct {
// 下发终端升级包体0x8108
typedef struct {
uint8_t upgrade_type; // 升级类型
uint8_t manufacturer_id[5];// 制造商ID, 固定5个字节
uint8_t ver_len;// 版本号长度
uint8_t *str_ver;// 版本号
uint32_t upgrade_pkg_len;// 升级包长度 单位为 BYTE
uint8_t *str_upgrade_pkg;// 升级包
uint8_t upgrade_type; // 升级类型1字节
uint16_t file_crc; // 文件CRC2字节
uint8_t path_len; // 文件路径长度1字节
char *file_path; // 文件路径字符串
}Term_Upgrade_t;
// 终端升级结果通知体0x0108

View File

@ -3,9 +3,28 @@
#include "local_tts.h"
#include "jt808_electronic_fence.h"
#include "attr_broadcast.h"
#include "cm_fota.h"
#include "cm_fs.h"
#include <stdbool.h>
PrsResult_t PrsResult;
static void __cm_fota_cb(cm_fota_error_e error)
{
JT808_DEBUG("[FOTA] error code is %d\r\n", error);
}
// 检查URL是否以http://或https://开头
static bool is_valid_url(const char *url) {
if(!url) return false;
// 检查基本协议
if(strncmp(url, "http://", 7) == 0) return true;
if(strncmp(url, "https://", 8) == 0) return true;
return false;
}
// 消息体解析
static int jt808_BodyParse(void *Prsmsg_body, PrsResult_t *Result){
@ -75,7 +94,120 @@ static int jt808_BodyParse(void *Prsmsg_body, PrsResult_t *Result){
}
case ID_Term_Upgrade:{// 下发终端升级包
break;
// 确保消息体至少有4字节升级类型1+CRC2+路径长度1
if (Result->msg_head.msgbody_attr.msgbodylen < 4) {
JT808_DEBUG("Upgrade msg too short: %d bytes\n",
Result->msg_head.msgbody_attr.msgbodylen);
Result->Rsp_result = Msg_invalid;
} else {
uint8_t *p_body = (uint8_t *)Prsmsg_body;
// 解析固定字段
uint8_t upgrade_type = p_body[0]; // 升级类型1字节
uint16_t file_crc = (p_body[1] << 8) | p_body[2]; // 文件CRC2字节
uint8_t path_len = p_body[3]; // 路径长度1字节
// 移动到路径开始位置
p_body += 4;
// 验证路径长度是否匹配
if ((path_len + 4) != Result->msg_head.msgbody_attr.msgbodylen) {
JT808_DEBUG("Path len mismatch: expected %d, actual %d\n",
path_len, Result->msg_head.msgbody_attr.msgbodylen - 4);
Result->Rsp_result = Msg_invalid;
} else {
// 释放旧路径内存(如果有)
if (Result->term_param_item->big_upgrade_info.file_path != NULL) {
jt808_free(Result->term_param_item->big_upgrade_info.file_path);
Result->term_param_item->big_upgrade_info.file_path = NULL;
}
// 分配新路径内存
Result->term_param_item->big_upgrade_info.file_path = (char *)jt808_malloc(path_len + 1);
if (Result->term_param_item->big_upgrade_info.file_path == NULL) {
JT808_DEBUG("File path malloc failed (%d bytes)\n", path_len + 1);
Result->Rsp_result = Msg_err;
} else {
// 复制并添加终止符
memcpy(Result->term_param_item->big_upgrade_info.file_path, p_body, path_len);
Result->term_param_item->big_upgrade_info.file_path[path_len] = '\0';
// 更新升级信息
Result->term_param_item->big_upgrade_info.upgrade_type = upgrade_type;
Result->term_param_item->big_upgrade_info.file_crc = file_crc;
Result->term_param_item->big_upgrade_info.path_len = path_len;
JT808_DEBUG("Received upgrade cmd: type=%u, crc=0x%04X, path=%s\n",
upgrade_type, file_crc, Result->term_param_item->big_upgrade_info.file_path);
Result->Rsp_result = Msg_ok;
}
}
}
// 设置应答并发送通用应答
Result->Rsp_flow_num = Result->msg_head.msg_flow_num;
Result->Rsp_msg_id = Result->msg_head.msg_id;
jt808_pkg_send(ID_Term_GenResp, 0);
// 启动升级处理流程(同步执行)
// start_upgrade_process(&Result->big_upgrade_info);
const char *url = Result->term_param_item->big_upgrade_info.file_path;
if(!is_valid_url(url)) {
JT808_DEBUG("Invalid URL: %s\n", url);
break; // 不继续升级
}
int ret = 0;
cm_fota_set_ota_plan(CM_FOTA_ASR_PLAN_MINI_INTEGRATE);
cm_fota_res_callback_register((cm_fota_result_callback)__cm_fota_cb);
ret = cm_fota_set_url(Result->term_param_item->big_upgrade_info.file_path); //设置url路径
if(0 != ret)
{
JT808_DEBUG("url error\r\n");
}
else
{
JT808_DEBUG("url right\r\n");
cm_fs_system_info_t fs_info = {0, 0};
cm_fs_getinfo(&fs_info);
JT808_DEBUG("free size =%u",fs_info.free_size);
/* 文件系统剩余空间为0时不建议执行升级关键文件系统操作可能会失败 */
if (0 == fs_info.free_size)
{
JT808_DEBUG("insufficient space left in the file system\r\n");
break;
}
#define MIN_FOTA_SPACE (4 * 1024) // 512KB
if(fs_info.free_size < MIN_FOTA_SPACE) {
JT808_DEBUG("Insufficient space: %u < %u\n",
fs_info.free_size, MIN_FOTA_SPACE);
break;
}
cm_fota_info_t info = {0};
cm_fota_read_config(&info);
if (CM_FOTA_TYPE_HTTP_HTTPS == info.fixed_info.fota_mode)
{
JT808_DEBUG("HTTP server [%s]\r\n", info.fixed_info.url);
}
else
{
JT808_DEBUG("HTTP server error\r\n");
break;
}
osDelay(200/5);
cm_fota_exec_upgrade();
}
break;
}
case ID_GetLocInfo:{// 位置信息查询

View File

@ -879,14 +879,14 @@ void jt808_set_term_param_free(void){
jt808_free(jt808_term_param_item.big_ctrl_info.str_cmd_params);
jt808_term_param_item.big_ctrl_info.str_cmd_params = NULL;
}
if(jt808_term_param_item.big_upgrade_info.str_upgrade_pkg != NULL){ // 释放残留升级包内存
jt808_free(jt808_term_param_item.big_upgrade_info.str_upgrade_pkg);
jt808_term_param_item.big_upgrade_info.str_upgrade_pkg = NULL;
}
if(jt808_term_param_item.big_upgrade_info.str_ver != NULL){ // 释放升级版本号
jt808_free(jt808_term_param_item.big_upgrade_info.str_ver);
jt808_term_param_item.big_upgrade_info.str_ver = NULL;
if(jt808_term_param_item.big_upgrade_info.file_path != NULL){ // 释放升级包路径名称
jt808_free(jt808_term_param_item.big_upgrade_info.file_path);
jt808_term_param_item.big_upgrade_info.file_path = NULL;
}
// if(jt808_term_param_item.big_upgrade_info.str_ver != NULL){ // 释放升级版本号
// jt808_free(jt808_term_param_item.big_upgrade_info.str_ver);
// jt808_term_param_item.big_upgrade_info.str_ver = NULL;
// }
Loc_addi_info_t *p_addi_info; // 附加信息
Loc_addi_info_t *p_addi_info_next; // 附加信息下一个节点
p_addi_info = jt808_term_param_item.big_loc_report.addi_info;