4G_module/custom/jt808/src/jt808_msg_parse.c

674 lines
27 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.

#include "jt808_msg_parse.h"
#include "jt808_pkg_transmit.h"
#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;
typedef int bool;
#define true 1
#define false 0
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){
switch (Result->msg_head.msg_id){
case ID_Plat_GenResp:{// 平台通用应答
Plat_GenResp_t resp_body;
//从消息体复制数据
memcpy(&resp_body, Prsmsg_body, sizeof(Plat_GenResp_t));
// 转小端
Result->Rsp_flow_num = Swap16(resp_body.msg_flow_num); // 应答流水号
Result->Rsp_msg_id = Swap16(resp_body.msg_id_ack); // 应答ID
Result->Rsp_result = resp_body.result; // 结果
break;
}
case ID_FillPktReq:{// 补传分包请求
break;
}
case ID_Term_RegResp:{// 终端注册应答
Result->Rsp_flow_num = (uint16_t)(((uint8_t *)Prsmsg_body)[0] << 8) | (((uint8_t *)Prsmsg_body)[1]);
Result->Rsp_result = ((uint8_t *)Prsmsg_body)[2];
if(Result->Rsp_result == Msg_ok){ // 成功时,读取鉴权码
if(Result->term_param_item->big_auth_info.str_auth_code != NULL){
jt808_free(Result->term_param_item->big_auth_info.str_auth_code);
Result->term_param_item->big_auth_info.str_auth_code = NULL;
}
Result->term_param_item->big_auth_info.str_auth_code = (char *)jt808_malloc(Result->msg_head.msgbody_attr.msgbodylen - 3 +1); // 加1是为了加上结束符
if(Result->term_param_item->big_auth_info.str_auth_code == NULL){
JT808_DEBUG("[%s,%s] malloc failed\r\n", __FUNCTION__,__LINE__);
return -1;
}
JT808_DEBUG("auth code =%s\r\n", Result->term_param_item->big_auth_info.str_auth_code);
memset(Result->term_param_item->big_auth_info.str_auth_code, 0, Result->msg_head.msgbody_attr.msgbodylen - 3 +1);
memcpy(Result->term_param_item->big_auth_info.str_auth_code, Prsmsg_body + 3 , Result->msg_head.msgbody_attr.msgbodylen - 3);
// 使用统一接口保存鉴权码到文件
auth_code_manage(AUTH_OP_SET, Result->term_param_item->big_auth_info.str_auth_code, 0);
}
break;
}
case ID_SetTermParams:{// 设置终端参数
Result->term_param_item->big_specific_params.param_Total_num = ((uint8_t *)Prsmsg_body)[0]; // 总参数个数
uint8_t *p_Prsmsg_body = (uint8_t *)Prsmsg_body + 1;
for(int i = 0; i < Result->term_param_item->big_specific_params.param_Total_num; i++){
// 设置终端参数
jt808_setTermParam(((uint8_t *)(p_Prsmsg_body))[0] << 24 | ((uint8_t *)(p_Prsmsg_body))[1] << 16 | ((uint8_t *)(p_Prsmsg_body))[2] << 8 | ((uint8_t *)(p_Prsmsg_body))[3], // 参数ID
(void *)(p_Prsmsg_body + 5), // 参数值
p_Prsmsg_body[4]); // 参数长度
p_Prsmsg_body += 5 + p_Prsmsg_body[4]; // 参数ID(4) + 参数长度(1) + 参数值(n)
}
Result->Rsp_flow_num = Result->msg_head.msg_flow_num;
Result->Rsp_msg_id = Result->msg_head.msg_id;
Result->Rsp_result = Msg_ok;
jt808_pkg_send(ID_Term_GenResp, 0);// 发送终端通用应答
break;
}
case ID_GetTermParams:{// 查询终端参数
Result->Rsp_flow_num = Result->msg_head.msg_flow_num;
Result->Rsp_msg_id = Result->msg_head.msg_id;
jt808_pkg_send(ID_GetTermParamsResp, 0);// 发送终端通用应答
break;
}
case ID_GetSpecificTermParams:{// 查询指定终端参数
break;
}
case ID_Term_Ctrl:{// 终端控制
break;
}
case ID_GetTermAttr:{// 查询终端属性
jt808_pkg_send(ID_GetTermAttrResp, 0);// 发送查询终端属性应答,设置本消息无发送应答
break;
}
case ID_Term_Upgrade:{// 下发终端升级包
// 确保消息体至少有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);
local_tts_text_play("软件升级流程开始,请勿断电",0,0);
local_tts_text_play("升级完成后会自动重启",0,0);
const char *url = Result->term_param_item->big_upgrade_info.file_path;
if(!is_valid_url(url)) {
JT808_DEBUG("Invalid URL: %s\n", url);
jt808_free(Result->term_param_item->big_upgrade_info.file_path);
Result->term_param_item->big_upgrade_info.file_path = NULL;
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(2000/5);
cm_fota_exec_upgrade();
}
break;
}
case ID_GetLocInfo:{// 位置信息查询
break;
}
case ID_LocTrackingCtrl:{// 临时位置跟踪控制
break;
}
case ID_TxtMsgdelivery:{// 文本信息下发
uint8_t device_volume, speed, volume, mode;
uint8_t txt_flag = ((uint8_t *)Prsmsg_body)[0];
JT808_DEBUG("ID_TxtMsgdelivery:%x\r\n", txt_flag);
Prsmsg_body = (void *)((uint8_t *)Prsmsg_body + 1); // 跳过标志位
device_volume =10*(((uint8_t *)Prsmsg_body)[0]-'0') + (((uint8_t *)Prsmsg_body)[1]-'0');
speed =10*(((uint8_t *)Prsmsg_body)[3]-'0') + (((uint8_t *)Prsmsg_body)[4]-'0');
volume =10*(((uint8_t *)Prsmsg_body)[6]-'0') + (((uint8_t *)Prsmsg_body)[7]-'0');
mode = ((uint8_t *)Prsmsg_body)[9]-'0';
Result->Rsp_result = Msg_ok;
if((((uint8_t *)Prsmsg_body)[2] == ',')&&(((uint8_t *)Prsmsg_body)[5] == ',')&&(((uint8_t *)Prsmsg_body)[8] == ',')&&(((uint8_t *)Prsmsg_body)[10] == ';')){ // 文本信息下发
if(speed > 0 && speed <= 15 && volume > 0 && volume <= 15 && mode >= 0 && mode <= 2){ // 速度、音量、模式有效
local_tts_volume(device_volume); // 设置音量大小
local_tts_set(speed, volume, mode);
}else{
JT808_DEBUG("error speed or volume or mode\r\n");
local_tts_volume(100); // 设置音量大小
local_tts_set(6, 7, CM_LOCAL_TTS_DIGIT_AUTO);
Result->Rsp_result = Msg_invalid;//消息有误
}
}else{
JT808_DEBUG("error speed or volume or mode\r\n");
local_tts_volume(100); // 设置音量大小
local_tts_set(7, 15, CM_LOCAL_TTS_DIGIT_AUTO);
Result->Rsp_result = Msg_invalid;//消息有误
}
local_tts_text_play((char *)Prsmsg_body + 11, Result->msg_head.msgbody_attr.msgbodylen -11,0); // 开始播放文本信息// 不可打断
Result->Rsp_flow_num = Result->msg_head.msg_flow_num;
Result->Rsp_msg_id = Result->msg_head.msg_id;
// Result->Rsp_result = Msg_ok;
jt808_pkg_send(ID_Term_GenResp, 0);// 发送终端通用应答
break;
}
case ID_Car_Ctrl:{// 车辆控制
if(Result->msg_head.msgbody_attr.msgbodylen == 1){ // 车辆控制
jt808_Set_CarStatus(((uint8_t *)Prsmsg_body)[0]); // 设置车辆状态
Result->Rsp_result = Msg_ok;
}else{
Result->Rsp_result = Msg_invalid;
}
Result->Rsp_flow_num = Result->msg_head.msg_flow_num;
Result->Rsp_msg_id = Result->msg_head.msg_id;
jt808_pkg_send(ID_Car_CtrlResp, 0);// 发送车辆控制应答,设置本消息无发送应答
break;
}
case ID_Set_Circle_Area:{// 设置圆形区域(0x8600)
// 检查是否在更新流程中
bool in_update = update_manager_is_active() && update_status.state == UPDATE_RECEIVING_DATA;
int ret = 0;
uint8_t *p = (uint8_t *)Prsmsg_body;
// 解析固定字段
uint32_t Area_ID = Swap32(*(uint32_t *)p);
uint16_t Area_att = Swap16(*(uint16_t *)(p + 4));
uint32_t center_lat = Swap32(*(uint32_t *)(p + 6));
uint32_t center_lon = Swap32(*(uint32_t *)(p + 10));
uint32_t radius = Swap32(*(uint32_t *)(p + 14));
// 解析景点名称字符串
uint16_t fixed_len = 18; // 前18字节是固定字段
uint16_t name_len = Result->msg_head.msgbody_attr.msgbodylen - fixed_len;
char *scenic_name = NULL;
if (name_len > 0) {
scenic_name = (char *)jt808_malloc(name_len + 1);
if (scenic_name) {
memcpy(scenic_name, p + fixed_len, name_len);
scenic_name[name_len] = '\0'; // 添加字符串终止符
}
}
// 转换为实际经纬度除以10^6
double actual_lat = (double)center_lat / 1000000.0;
double actual_lon = (double)center_lon / 1000000.0;
JT808_DEBUG("actual_lat=%f,actual_lon=%f\r\n",actual_lat,actual_lon);
// 调用区域添加函数
attr_broadcast_add_attraction(
Area_ID, // 区域ID
actual_lon, // 经度
actual_lat, // 纬度
(double)radius, // 半径(米)
scenic_name ? scenic_name : "",// 景点名称
"" // 描述(可选)
);
// 释放名称内存
if (scenic_name) jt808_free(scenic_name);
// 如果在更新流程中,标记数据包接收
if (in_update) {
update_manager_packet_received();
JT808_DEBUG("Received attr packet %d/%d\n", update_status.received_packets, update_status.expected_packets);
}
else
{
JT808_DEBUG("Direct attr packet received, please check \r\n");
}
// 设置响应结果
Result->Rsp_result = (ret == 0) ? Msg_ok : Msg_err;
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);
JT808_DEBUG("attraction data accepted\r\n");
break;
}
case ID_Delete_Circle_area:{// 删除圆形区域(0x8601)
int ret = 0;
uint8_t area_count = *((uint8_t*)Prsmsg_body); // 区域个数(1字节)
uint32_t* area_ids = (uint32_t*)((uint8_t*)Prsmsg_body + 1);
// 特殊处理0表示删除所有区域
if (area_count == 0) {
attr_broadcast_remove_all();
}
// 正常删除指定区域
else {
Result->Rsp_result = Msg_ok; //删不删干净都是ok
for (int i = 0; i < area_count; i++) {
uint32_t area_id = Swap32(area_ids[i]);
attr_broadcast_remove_attraction_by_id(area_id);
}
}
// 设置应答信息
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); // 发送终端通用应答
break;
}
case ID_Set_Polygon_area:{// 设置多边形区域
// 检查是否在更新流程中
bool in_update = update_manager_is_active() && update_status.state == UPDATE_RECEIVING_DATA;
int ret = 0;
uint32_t Area_ID; // 区域ID
uint16_t Area_att; // 区域属性
uint16_t Area_Points_Num; // 区域内点的数量
memcpy(&Area_ID, ((uint8_t *)Prsmsg_body), 4); // 区域ID
memcpy(&Area_att, ((uint8_t *)Prsmsg_body)+4, 2); // 区域属性
memcpy(&Area_Points_Num, ((uint8_t *)Prsmsg_body)+21, 2); // 区域点个数
if(Swap16(Area_Points_Num) <= 120){ // 区域点个数有效
ret = jt808_add_tail_fence_Polygon_area(Swap32(Area_ID), // 区域ID
Swap16(Area_att), // 区域属性
Swap16(Area_Points_Num), // 区域点个数
(AreaPoint_t *)(((uint8_t *)Prsmsg_body) + 23)); // 区域点坐标
if(ret == 0){
Result->Rsp_result = Msg_ok;
// 如果在更新流程中,标记数据包接收
if (in_update) {
update_manager_packet_received();
JT808_DEBUG("Received fence packet %d/%d\n", update_status.received_packets, update_status.expected_packets);
}
else
{
JT808_DEBUG("Direct fence packet received, please check\r\n");
}
}else{
Result->Rsp_result = Msg_err;
}
}else{
Result->Rsp_result = Msg_invalid;
}
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);// 发送终端通用应答
break;
}
case ID_Delete_Polygon_area:{// 删除多边形区域
int ret = 0;
uint8_t Area_ID_Num = ((uint8_t *)Prsmsg_body)[0]; // 区域ID个数
//Prsmsg_body = (void *)((uint8_t *)Prsmsg_body + 1); // 跳过1字节
uint8_t *p_id = (uint8_t *)Prsmsg_body + 1; // 指向第一个ID
Result->Rsp_result = Msg_ok;
JT808_DEBUG("Area_ID_Num=%d\r\n",Area_ID_Num);
// 区域数为0删除所有区域
if (Area_ID_Num == 0) {
if (jt808_remove_fence_Polygon_area(0) != 0) {
Result->Rsp_result = Msg_err;
}
}
else {
for(int i = 0; i < Area_ID_Num; i++){
uint32_t area_id = (p_id[0] << 24) | (p_id[1] << 16) | (p_id[2] << 8) | p_id[3];
ret = jt808_remove_fence_Polygon_area(area_id);
if(ret != 0){
Result->Rsp_result = Msg_err;
break;
}
p_id += 4;
}
}
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);// 发送终端通用应答
break;
}
case ID_Data_Down:{// 数据下行透传
jt808_data_down_SeriaNet(((uint8_t *)Prsmsg_body)[0],((uint8_t *)Prsmsg_body) + 1, Result->msg_head.msgbody_attr.msgbodylen - 1); // 透传数据
Result->Rsp_flow_num = Result->msg_head.msg_flow_num;
Result->Rsp_msg_id = Result->msg_head.msg_id;
Result->Rsp_result = Msg_ok;
jt808_pkg_send(ID_Term_GenResp, 0);// 发送终端通用应答
// JT808_DEBUG("ID_Data_Down\r\n");
break;
}
case ID_data_update_reply:{// 电子围栏/景点数量下发
if (update_manager_is_active()) {
// 检查消息体长度至少为5字节 (2+1+2)
if (Result->msg_head.msgbody_attr.msgbodylen < 5) {
JT808_DEBUG("Invalid update reply length: %d\n", Result->msg_head.msgbody_attr.msgbodylen);
Result->Rsp_result = Msg_invalid;
update_manager_fail();
} else {
uint8_t *p_body = (uint8_t *)Prsmsg_body;
// 手动组合应答流水号2字节大端
uint16_t reply_flow_num = (p_body[0] << 8) | p_body[1];
Result->Rsp_flow_num = reply_flow_num;
// 解析类型 (1字节)
uint8_t update_type = p_body[2];
// 手动组合围栏/景点数量2字节大端
uint16_t packet_count = (p_body[3] << 8) | p_body[4];
JT808_DEBUG("Update reply: type=%d, count=%d\n", update_type, packet_count);
// 验证类型是否匹配当前更新
if ((update_type == 1 && update_status.type == UPDATE_TYPE_FENCE) ||
(update_type == 2 && update_status.type == UPDATE_TYPE_ATTR)) {
if (packet_count == 0) {
// 无数据需要更新
update_manager_complete();
JT808_DEBUG("No data to update\n");
Result->Rsp_result = Msg_ok;
} else {
// 开始接收数据
update_manager_begin_receiving(packet_count);
JT808_DEBUG("Expecting %d data packets\n", packet_count);
Result->Rsp_result = Msg_ok;
}
} else {
// 类型不匹配
JT808_DEBUG("Type mismatch: msg_type=%d, current_type=%d\n",update_type, update_status.type);
Result->Rsp_result = Msg_invalid;
update_manager_fail();
}
}
} else {
Result->Rsp_result = Msg_err; // 更新管理器未激活
JT808_DEBUG("Received update reply without active update\n");
}
// 设置应答
Result->Rsp_msg_id = Result->msg_head.msg_id;
jt808_pkg_send(ID_Term_GenResp, 0);
break;
}
case ID_data_update_complete:{// 电子围栏/景点更新完成
if (update_manager_is_complete()) {
// 检查消息体长度至少为5字节 (1字节类型+4字节版本号)
if (Result->msg_head.msgbody_attr.msgbodylen < 5) {
JT808_DEBUG("Invalid update complete length: %d\n", Result->msg_head.msgbody_attr.msgbodylen);
Result->Rsp_result = Msg_invalid;
update_manager_fail();
} else {
uint8_t *p_body = (uint8_t *)Prsmsg_body;
// 解析类型 (1字节)
uint8_t update_type = p_body[0];
// 解析版本号 (4字节大端) - 使用Swap32转换
uint32_t new_version = Swap32(*(uint32_t*)(p_body+1));
JT808_DEBUG("Update complete: type=%d, version=%u\n", update_type, new_version);
// 验证类型是否匹配当前更新
if ((update_type == 1 && update_status.type == UPDATE_TYPE_FENCE) ||
(update_type == 2 && update_status.type == UPDATE_TYPE_ATTR)) {
// 更新本地版本号
attr_broadcast_manage_version(
VERSION_OP_SET,
(update_type == 1) ? VERSION_TYPE_FENCE : VERSION_TYPE_ATTRACTION,
&new_version
);
update_manager_complete();
Result->Rsp_result = Msg_ok;
} else {
JT808_DEBUG("Type mismatch: msg_type=%d, current_type=%d\n",
update_type, update_status.type);
Result->Rsp_result = Msg_invalid;
update_manager_fail();
}
}
} else {
Result->Rsp_result = Msg_err; // 更新管理器未激活
JT808_DEBUG("Received update complete without active update\n");
}
// 设置应答
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);
break;
}
default:{
return -2; // 没有对应的消息体解析函数
break;
}
}
return 0;
}
// jt808协议包处理
int jt808_msg_parse(const uint8_t *BufferReceive, uint16_t length, PrsResult_t *Result){
uint8_t *raw_Buffer = (uint8_t *)jt808_malloc(length * sizeof(uint8_t));
if(raw_Buffer == NULL){
JT808_DEBUG("[%s,%s] malloc failed \r\n", __FUNCTION__,__LINE__);
return -1;
}
memcpy(raw_Buffer, BufferReceive, length);
// // 打印原始数据
// app_printf("raw_Buffer: %d\r\n", length);
// for(int i = 0; i < length; i++){
// app_printf("%02x ", raw_Buffer[i]);
// }
// app_printf("\r\n");
// 计算需要逆转义字符的个数
uint16_t para_length = 0;
for(int i = 1; i < (length - 2); i++){
if(((raw_Buffer[i] == PESC)&&(raw_Buffer[i+1] == PESC_SIGN)) || // 7d 02 转义7e
((raw_Buffer[i] == PESC)&&(raw_Buffer[i+1] == PESC_ESCAPE))){ // 7d 01 转义7d
para_length++;
}
}
para_length =length - para_length;
uint8_t *para_Buffer = (uint8_t *)jt808_malloc(para_length * sizeof(uint8_t));
if(para_Buffer == NULL){
JT808_DEBUG("[%s,%s] malloc failed \r\n", __FUNCTION__,__LINE__);
jt808_free(raw_Buffer);
return -1;
}
para_Buffer[0] = PSIGN;
para_Buffer[para_length - 1] = PSIGN;
// 逆转义
uint16_t offset_num = 0;
for(int i = 1; i < (para_length - 1); i++){
if(((raw_Buffer[i + offset_num] == PESC)&&(raw_Buffer[i + offset_num + 1] == PESC_SIGN))){ // 7d 02 转义7e
para_Buffer[i] = PSIGN;
offset_num++;
}else if(((raw_Buffer[i + offset_num] == PESC)&&(raw_Buffer[i + offset_num + 1] == PESC_ESCAPE))){ // 7d 01 转义7d
para_Buffer[i] = PESC;
offset_num++;
}else{
para_Buffer[i] =raw_Buffer[i + offset_num];
}
}
// 释放内存
jt808_free(raw_Buffer);
if(offset_num != length - para_length){ // 转义后长度有误
JT808_DEBUG("error offset_num != length - para_length\r\n");
jt808_free(para_Buffer);
return -1;
}
// // 打印逆转义后数据
// app_printf("para_Buffer: %d\r\n", para_length);
// for(int i = 0; i < para_length; i++){
// app_printf("%02x ", para_Buffer[i]);
// }
// app_printf("\r\n");
// 异或校验
if(para_Buffer[para_length - 2] != BCC_Check(para_Buffer + 1, para_length - 2 - 1)){
JT808_DEBUG("BCC_CheckSum ERROR: %x %x\r\n",para_Buffer[para_length - 2] ,BCC_Check(para_Buffer + 1, para_length - 2 - 1));
jt808_free(para_Buffer);
return -1;
}
// 解析消息头
memcpy(&Result->msg_head, para_Buffer + 1, sizeof(MsgHead_t) - ((para_Buffer[3] & 0x02)==0? 4 : 0));
Result->msg_head.msg_id = Swap16(Result->msg_head.msg_id);// 消息ID
Result->msg_head.msgbody_attr.val16 = Swap16(Result->msg_head.msgbody_attr.val16);// 消息体属性
Result->msg_head.msg_flow_num = Swap16(Result->msg_head.msg_flow_num);// 消息流水号
Result->msg_head.total_packet = Swap16(Result->msg_head.total_packet);// 总包数, 分包情况下使用
Result->msg_head.packet_seq = Swap16(Result->msg_head.packet_seq);// 当前包序号, 分包情况下使用
JT808_DEBUG("RECV Msg_ID:0x%04X len:%d\r\n", Result->msg_head.msg_id ,para_length);
for(uint16_t i = 0; i < para_length; i++){
JT808_DEBUG_DATA("%02X ", *(para_Buffer + i));
}
JT808_DEBUG_DATA("\n");
// 消息体解析
if(0 != jt808_BodyParse((void *)(para_Buffer + 1 + sizeof(MsgHead_t) - ((para_Buffer[3] & 0x02)==0? 4 : 0)) ,Result)){
JT808_DEBUG("error jt808_BodyParse\r\n");
// 释放内存
jt808_free(para_Buffer);
return -1;
}
// 释放内存
jt808_free(para_Buffer);
return 0;
}