添加鉴权码本地保存机制,测试成功

This commit is contained in:
kkkjtr 2025-08-22 14:14:21 +08:00
parent f0da87e943
commit 1df713942d
6 changed files with 347 additions and 8 deletions

View File

@ -11,6 +11,12 @@
#define VERSION_OP_GET 0
#define VERSION_OP_SET 1
// 鉴权码管理操作类型定义
#define AUTH_OP_GET 0 // 获取鉴权码
#define AUTH_OP_SET 1 // 设置鉴权码
#define AUTH_OP_DEL 2 // 删除鉴权码
// 景点信息
typedef struct {
double longitude; // 经度
@ -34,6 +40,16 @@ extern const char *park_desc[];
// version: 用于设置或返回版本号的指针
int attr_broadcast_manage_version(uint8_t op, uint8_t type, uint32_t* version);
// 统一的鉴权码管理接口
// op: 操作类型 (AUTH_OP_GET, AUTH_OP_SET 或 AUTH_OP_DEL)
// auth_code: 用于设置或返回鉴权码的指针
// 对于 AUTH_OP_GET: 输出参数,需要预先分配足够的内存
// 对于 AUTH_OP_SET: 输入参数,指向要设置的鉴权码字符串
// 对于 AUTH_OP_DEL: 忽略此参数
// max_len: 对于 AUTH_OP_GET: 表示 auth_code 缓冲区的最大长度
// 对于其他操作: 忽略此参数
// 返回值: 0表示成功负数表示失败
int auth_code_manage(uint8_t op, char* auth_code, uint16_t max_len);
//多文字tts景区播报专用
void safe_tts_play(const char* segments[], int count);

View File

@ -37,6 +37,7 @@
#define MAX_TTS_SEGMENT_LEN 70 // TTS每段最大长度(字符)
#define ATTRACTIONS_FILE "attr.txt" // 区域ID列表文件
#define DATA_VERSION_FILE "version.txt" // 本地数据版本文件
#define AUTH_CODE_FILE "auth_code.txt" // 鉴权码文件
static nmeaPARSER parser;
@ -91,6 +92,7 @@ const char *park_desc[] = {
static osMutexId_t attractions_mutex = NULL;
static AttractionNode* attractions_head = NULL;
static osMutexId_t version_mutex = NULL;
static osMutexId_t auth_mutex = NULL;
static BroadcastState broadcast_state = {0};
static int tts_speed = 5;
static int tts_volume = 10;
@ -174,6 +176,118 @@ int attr_broadcast_manage_version(uint8_t op, uint8_t type, uint32_t* version) {
return result;
}
// 统一的鉴权码管理接口
// op: 操作类型 (AUTH_OP_GET, AUTH_OP_SET 或 AUTH_OP_DEL)
// auth_code: 用于设置或返回鉴权码的指针
// 对于 AUTH_OP_GET: 输出参数,需要预先分配足够的内存
// 对于 AUTH_OP_SET: 输入参数,指向要设置的鉴权码字符串
// 对于 AUTH_OP_DEL: 忽略此参数
// max_len: 对于 AUTH_OP_GET: 表示 auth_code 缓冲区的最大长度
// 对于其他操作: 忽略此参数
// 返回值: 0表示成功负数表示失败
int auth_code_manage(uint8_t op, char* auth_code, uint16_t max_len) {
// 初始化互斥锁
if (auth_mutex == NULL) {
return -1;
}
osMutexAcquire(auth_mutex, osWaitForever);
int result = 0;
switch (op) {
case AUTH_OP_GET: // 获取鉴权码
if (auth_code == NULL || max_len == 0) {
result = -2; // 无效的参数
break;
}
// 检查文件是否存在
if (!cm_fs_exist(AUTH_CODE_FILE)) {
result = -3; // 文件不存在
break;
}
// 获取文件大小
int32_t file_size = cm_fs_filesize(AUTH_CODE_FILE);
if (file_size <= 0) {
result = -4; // 文件为空
break;
}
// 确保不超过提供的缓冲区大小
if (file_size >= max_len) {
result = -5; // 缓冲区太小
break;
}
// 读取文件内容
int32_t fd = cm_fs_open(AUTH_CODE_FILE, CM_FS_RB);
if (fd < 0) {
result = -6; // 文件打开失败
break;
}
if (cm_fs_read(fd, auth_code, file_size) != file_size) {
cm_fs_close(fd);
result = -7; // 读取失败
break;
}
cm_fs_close(fd);
auth_code[file_size] = '\0'; // 添加字符串终止符
DEBUG("Auth code loaded from file: %s\n", auth_code);
break;
case AUTH_OP_SET: // 设置鉴权码
if (auth_code == NULL || strlen(auth_code) == 0) {
result = -2; // 无效的参数
break;
}
// 写入鉴权码到文件
fd = cm_fs_open(AUTH_CODE_FILE, CM_FS_WB);
if (fd < 0) {
result = -8; // 文件打开失败
break;
}
uint16_t auth_len = strlen(auth_code);
if (cm_fs_write(fd, auth_code, auth_len) != auth_len) {
cm_fs_close(fd);
result = -9; // 写入失败
break;
}
cm_fs_close(fd);
DEBUG("Auth code saved to file: %s\n", auth_code);
break;
case AUTH_OP_DEL: // 删除鉴权码
if (cm_fs_exist(AUTH_CODE_FILE)) {
if (cm_fs_delete(AUTH_CODE_FILE) < 0) {
result = -10; // 删除失败
} else {
DEBUG("Auth code file deleted\n");
}
} else {
DEBUG("Auth code file does not exist, nothing to delete\n");
}
break;
default:
result = -11; // 无效的操作
break;
}
osMutexRelease(auth_mutex);
return result;
}
// 智能分段函数
SegmentedText smart_segment_text(const char* text, int max_segment_len) {
SegmentedText result = {0};
@ -876,14 +990,18 @@ void attr_broadcast_init(void) {
if (attractions_mutex == NULL) {
attractions_mutex = osMutexNew(NULL);
}
if (version_mutex == NULL) {
if (version_mutex == NULL) {
version_mutex = osMutexNew(NULL);
}
if (auth_mutex == NULL) {
auth_mutex = osMutexNew(NULL);
}
// 景点文件是否存在
if(1 == cm_fs_exist(ATTRACTIONS_FILE))
{
DEBUG("file exist\n");
DEBUG("attraction file exist\n");
}
else {
@ -908,6 +1026,20 @@ void attr_broadcast_init(void) {
attr_broadcast_manage_version(VERSION_OP_SET, VERSION_TYPE_ATTRACTION, &init_version);
attr_broadcast_manage_version(VERSION_OP_SET, VERSION_TYPE_FENCE, &init_version);
}
//鉴权码本地文件是否存在
if(1 == cm_fs_exist(AUTH_CODE_FILE))
{
DEBUG("attraction file exist\n");
}
else {
int32_t fd = cm_fs_open(AUTH_CODE_FILE, CM_FS_WB);
if (fd >= 0) {
DEBUG("Created empty auth code file\n");
}
}
// 初始化状态
memset(&broadcast_state, 0, sizeof(broadcast_state));

View File

@ -61,8 +61,11 @@ static int jt808_BodyParse(void *Prsmsg_body, PrsResult_t *Result){
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;
}
@ -484,7 +487,7 @@ static int jt808_BodyParse(void *Prsmsg_body, PrsResult_t *Result){
if (packet_count == 0) {
// 无数据需要更新
update_manager_no_update();
update_manager_complete();
JT808_DEBUG("No data to update\n");
Result->Rsp_result = Msg_ok;
} else {

View File

@ -47,7 +47,7 @@ int jt808_pkg_send(MessageID_t Msg_ID, uint32_t timeout){
// JT808_DEBUG("send pkg_msg:%04x\n", Msg_ID);
if(osOK == osMessageQueuePut(jt808_send_msg_queue, &send_pkg_msg, 0, 0)){ //将数据送入发送队列
return 0;
}
else
{
@ -61,7 +61,7 @@ void jt808_pkg_handle(uint8_t *receive_buf, uint16_t receive_len) {
// 1. 解析协议数据
if (0 == jt808_msg_parse(receive_buf, receive_len, &PrsResult)) {
// 2. 提取接收到的消息ID和流水号 这地方根据消息id分两种情况 一种是平台应答 另一种是平台指令 平台应答需要判断结构体里的id和流水号
if (PrsResult.msg_head.msg_id == ID_Plat_GenResp || PrsResult.msg_head.msg_id == ID_Term_RegResp || PrsResult.msg_head.msg_id == ID_data_update_reply)
if (PrsResult.msg_head.msg_id == ID_Plat_GenResp /*|| PrsResult.msg_head.msg_id == ID_Term_RegResp */|| PrsResult.msg_head.msg_id == ID_data_update_reply)
{
uint16_t recv_msg_id = PrsResult.Rsp_msg_id;
uint16_t recv_flow_num = PrsResult.Rsp_flow_num;

View File

@ -931,7 +931,7 @@ void jt808_set_term_param_init(void){
// memcpy(jt808_term_param_item.big_term_attr_resp.term_ICCID+4, jt808_term_param_item.phone_BCDnum, 6); // 终端手机号码 但是你照这个来云端收到的iccid全是因为BCDnum参数本身没有初始化
char str_hw_ver[] = "1.0.0"; // 硬件版本
char str_fw_ver[] = "1.2.0"; // 固件版本 原本为1.0.0
char str_fw_ver[] = "1.2.1"; // 固件版本 原本为1.0.0
jt808_term_param_item.big_term_attr_resp.hw_ver_len = strlen(str_hw_ver); // 硬件版本长度
jt808_term_param_item.big_term_attr_resp.fw_ver_len = strlen(str_fw_ver); // 固件版本长度
memcpy(jt808_term_param_item.big_term_attr_resp.str_hw_ver, str_hw_ver, strlen(str_hw_ver)); // 硬件版本

View File

@ -3,6 +3,7 @@
#include "cm_modem.h"
#include "cm_pm.h"
#include "jt808_msg_pkg.h"
#include "jt808_msg_parse.h"
#include "jt808_pkg_transmit.h"
@ -10,8 +11,10 @@
#include "tcp_client.h"
#include "app_common.h"
#include "local_tts.h"
#include "attr_broadcast.h"
#define TCP_CLIENT_ENABLE 0
#define TCP_CLIENT_ENABLE 1
#if TCP_CLIENT_ENABLE
#include "app_uart.h"
@ -27,6 +30,45 @@ osSemaphoreId_t netconn_disconnect_sem = NULL; // 断开连接信号量
#define RECV_MAX_LEN (1024) // 接收最大长度
// 修改后的检查鉴权码文件函数
static int check_auth_code_file(void)
{
char auth_code[64] = {0}; // 假设鉴权码最大长度为63字符
int ret = auth_code_manage(AUTH_OP_GET, auth_code, sizeof(auth_code));
if (ret != 0) {
DEBUG("No valid auth code file found: %d\n", ret);
return ret;
}
// 检查鉴权码是否有效(至少有一定长度)
size_t auth_len = strlen(auth_code);
if (auth_len < 4) { // 假设有效鉴权码至少4字符
DEBUG("Auth code is too short to be valid\n");
auth_code_manage(AUTH_OP_DEL, NULL, 0); // 删除无效文件
return -6;
}
// 将鉴权码设置到全局参数中
if (PrsResult.term_param_item->big_auth_info.str_auth_code != NULL) {
jt808_free(PrsResult.term_param_item->big_auth_info.str_auth_code);
PrsResult.term_param_item->big_auth_info.str_auth_code = NULL;
}
PrsResult.term_param_item->big_auth_info.str_auth_code = (char *)jt808_malloc(strlen(auth_code) + 1);
if (!PrsResult.term_param_item->big_auth_info.str_auth_code) {
DEBUG("Memory allocation failed for auth code\n");
return -4;
}
// 使用与解析代码相同的方式先memset清零再memcpy复制数据
memset(PrsResult.term_param_item->big_auth_info.str_auth_code, 0, auth_len + 1);
memcpy(PrsResult.term_param_item->big_auth_info.str_auth_code, auth_code, auth_len);
DEBUG("Auth code loaded from file: %s\n", auth_code);
return 0;
}
// TCP接收线程
static void tcp_recv_task(void){
int ret = 0;
@ -55,6 +97,13 @@ static void tcp_recv_task(void){
DEBUG("tcp_read recv too long:%d\n", ret);
ret = RECV_MAX_LEN;
}
DEBUG("Raw TCP recv:%d\n", ret);
for(int i = 0; i < ret; i++){
DEBUG("%02X ", buf[i]);
}
DEBUG("\n");
// 处理接收到的数据
jt808_pkg_handle(buf, ret);
memset(buf, 0, sizeof(buf));
@ -75,6 +124,142 @@ static void tcp_recv_task(void){
}
}
static void net_manage_task(void *arg) {
DEBUG("net_manage_task!\r\n");
int ret = 0;
cm_cereg_state_t cereg_state = {0};
uint8_t error_time_out = 0;
while(1) {
// 等待插入SIM卡并建立网络连接
while(1) {
osDelay(1000/5);
error_time_out++;
if(error_time_out > 15) { // 超时退出
DEBUG("network connect timeout!\n");
local_tts_text_play("网络异常,5秒后重启!",0,0);
osDelay(5000/5);
cm_pm_reboot();
}
if(0 == cm_modem_get_cpin()) { // 插入SIM卡
DEBUG("sim card ready!\r\n");
} else {
DEBUG("waiting for sim card...\r\n");
}
if(0 == cm_modem_get_cereg_state(&cereg_state)) { // 获取PS网络注册状态
DEBUG("cereg_state:%d\n",cereg_state.state); // 注册状态
if(cereg_state.state == 1) { // 已注册
DEBUG("network ready\n");
local_tts_text_play("网络正常!",0,0);
break;
} else {
DEBUG("waiting for network...\n");
}
} else {
DEBUG("cereg_get_state fail!\n\n");
}
}
TCP_CONNECT:
error_time_out = 0;
// 连接服务器
do {
osDelay(1000/5);
error_time_out++;
if(error_time_out > 15) { // 超时退出
DEBUG("network connect timeout!\n");
local_tts_text_play("服务器连接失败,重连中...",0,0);
}
} while(0 != tcp_client_connect((char *)(PrsResult.term_param_item->set_term_param.MainServerAddr),
PrsResult.term_param_item->set_term_param.ServerPort));
DEBUG("tcp_client_connect success!\r\n");
// 先检查是否有有效的鉴权码文件
int auth_file_valid = check_auth_code_file();
if(auth_file_valid == 0) {
// 有有效的鉴权码,直接进行鉴权
DEBUG("Using saved auth code, skipping registration\n");
for(uint8_t i = 0; i < 5; i++) {
osDelay(200/5);
ret = jt808_pkg_send(ID_Term_Auth, 5000/5); // 终端鉴权 超时10S
if(0 == ret) {
DEBUG("send ID_Term_Auth success!\n");
break;
} else {
DEBUG("send ID_Term_Auth fail:%d!\n", ret);
if((ret == -1) || (i == 4)) { // 5次尝试都失败
// 鉴权失败,可能是鉴权码已过期,删除文件并重新注册
auth_code_manage(AUTH_OP_DEL, NULL, 0);
goto REGISTRATION_PROCESS;
}
}
}
} else {
REGISTRATION_PROCESS:
// 没有有效的鉴权码,执行正常注册流程
for(uint8_t i = 0; i < 3; i++) { // 发送3次注册
ret = jt808_pkg_send(ID_Term_Reg, 5000/5); // 注册终端 超时8S
if(0 == ret) { // 0成功1车辆已被注册2数据库中无该车辆3终端已被注册4数据库中无该终端
DEBUG("send ID_Term_Reg success!\n");
// 等待注册应答并处理(包括保存鉴权码到文件)
osDelay(2000/5);
// 然后进行鉴权
for(uint8_t j = 0; j < 5; j++) {
osDelay(1000/5);
ret = jt808_pkg_send(ID_Term_Auth, 5000/5); // 终端鉴权 超时10S
if(0 == ret) {
DEBUG("send ID_Term_Auth success!\n");
break;
} else {
DEBUG("send ID_Term_Auth fail:%d!\n", ret);
if((ret == -1) || (j == 4)) {
goto TCP_DISCONNECT;
}
}
}
break;
} else {
local_tts_text_play("设备未绑定,注册异常", 0, 0);
osDelay(10000/5);
DEBUG("send ID_Term_Reg fail:%d!\n", ret);
if(ret == -1) { // 发送失败
goto TCP_DISCONNECT;
}
}
if(i == 2 && ret != 0) { // 3次尝试都失败
goto TCP_DISCONNECT; // 跳转重连
}
}
}
jt808_pkg_send(ID_GetTermAttrResp, 0); // 发送终端属性查询应答包
jt808_Autoreport_param_start(); // 开启自动上报参数设置
led_set_event(EVENT_NETWORK_READY); // 网络连接成功
DEBUG("NetwarK connected!\r\n");
local_tts_text_play("服务器已连接",0,0);
osSemaphoreAcquire(netconn_disconnect_sem, osWaitForever); // 等待断开连接信号
TCP_DISCONNECT:
jt808_Autoreport_param_stop(); // 停止自动上报参数设置
led_set_event(EVENT_NETWORK_DISCONNECT); // 网络断开连接
DEBUG("NetwarK disconnected!\r\n");
local_tts_text_play("服务器已断开",0,0);
// 关闭TCP连接
tcp_client_close();
// 跳转回TCP连接部分重新尝试连接
goto TCP_CONNECT;
}
}
// TCP连接 // host:服务地址port:服务端口
int tcp_client_connect(const char *host, int port) {
int ret = 0;
@ -143,7 +328,7 @@ void tcp_client_close(void){
// 网络管理线程
static void net_manage_task(void *arg){
/*static void net_manage_task(void *arg){
// osThreadState_t state;
DEBUG("net_manage_task!\r\n");
@ -200,6 +385,7 @@ TCP_DISABLE:
if(0 == ret){ // 0成功1车辆已被注册2数据库中无该车辆3终端已被注册4数据库中无该终端
DEBUG("send ID_Term_Reg success!\n");
for(uint8_t i = 0; i < 5; i++){
osDelay(1000/5);
ret =jt808_pkg_send(ID_Term_Auth,5000/5);//终端鉴权 超时10S
if(0 == ret){
DEBUG("send ID_Term_Auth success!\n");
@ -241,6 +427,8 @@ TCP_DISABLE:
}
}
*/
void tcp_client_init(void){
osThreadAttr_t net_manage_task_attr={
.name = "net_manage_task",