856 lines
33 KiB
C
856 lines
33 KiB
C
#include "jt808_set_TermParam.h"
|
||
#include "gps_config.h"
|
||
#include "jt808_msg_pkg.h"
|
||
#include "jt808_msg_parse.h"
|
||
#include "jt808_pkg_transmit.h"
|
||
#include "jt808_electronic_fence.h"
|
||
#include "cm_sys.h"
|
||
#include "cm_os.h"
|
||
#include "cm_fs.h"
|
||
#include "cm_sim.h"
|
||
#include "cm_pm.h"
|
||
|
||
|
||
#include "local_tts.h"
|
||
#include "control_out.h"
|
||
#include "radar.h"
|
||
|
||
|
||
#define LOCAL_FENCE_COUNT (sizeof(local_fences) / sizeof(LocalFenceConfig_t))
|
||
|
||
Term_Param_item_t jt808_term_param_item; // 终端参数项
|
||
osMutexId_t term_param_mutex = NULL; // 终端参数项互斥锁
|
||
osMutexId_t Polygon_fence_mutex = NULL; // 多边形围栏互斥锁
|
||
|
||
static const LocalFenceConfig_t local_fences[] = {
|
||
{ // 第一个围栏 (8边形禁停区)
|
||
.area_id = 1,
|
||
.area_att = 0x0001, // 禁停区围栏
|
||
.points_num = 8,
|
||
.points = (AreaPoint_t[]){ // 使用复合字面量
|
||
{.lat = 31338039, .lng = 121342339}, // 31.338039, 121.342339
|
||
{.lat = 31345049, .lng = 121357544}, // 31.345049, 121.357544
|
||
{.lat = 31342006, .lng = 121359044}, // 31.342006, 121.359044
|
||
{.lat = 31351253, .lng = 121378608}, // 31.351253, 121.378608
|
||
{.lat = 31347419, .lng = 121389395}, // 31.347419, 121.389395
|
||
{.lat = 31339808, .lng = 121373808}, // 31.339808, 121.373808
|
||
{.lat = 31333732, .lng = 121354182}, // 31.333732, 121.354182
|
||
{.lat = 31333178, .lng = 121345380} // 31.333178, 121.345380
|
||
}
|
||
},
|
||
{ // 第二个围栏 (4边形景区)
|
||
.area_id = 2,
|
||
.area_att = 0x0002, // 景区围栏
|
||
.points_num = 4,
|
||
.points = (AreaPoint_t[]){
|
||
{.lat = 31344904, .lng = 121366191}, // 31.344904, 121.366191
|
||
{.lat = 31345361, .lng = 121367180}, // 31.345361, 121.367180
|
||
{.lat = 31344801, .lng = 121367561}, // 31.344801, 121.367561
|
||
{.lat = 31344336, .lng = 121366509} // 31.344336, 121.366509
|
||
}
|
||
},
|
||
{ // 第三个围栏 (4边形禁停区)
|
||
.area_id = 3,
|
||
.area_att = 0x0002, // 禁停区围栏
|
||
.points_num = 4,
|
||
.points = (AreaPoint_t[]){
|
||
{.lat = 31339885, .lng = 121358303}, // 31.339885, 121.358303
|
||
{.lat = 31340580, .lng = 121359765}, // 31.340580, 121.359765
|
||
{.lat = 31340179, .lng = 121359985}, // 31.340179, 121.359985
|
||
{.lat = 31339484, .lng = 121358856} // 31.339484, 121.358856
|
||
}
|
||
}
|
||
};
|
||
|
||
|
||
void load_local_fence_data(void) {
|
||
JT808_DEBUG("Loading local fence data...\n");
|
||
|
||
// 清除所有现有围栏
|
||
jt808_remove_fence_Polygon_area(0);
|
||
|
||
// 加载预置围栏
|
||
for (int i = 0; i < LOCAL_FENCE_COUNT; i++) {
|
||
const LocalFenceConfig_t *config = &local_fences[i];
|
||
|
||
// 跳过无效配置
|
||
if (config->points_num < 3) continue;
|
||
|
||
jt808_add_tail_fence_Polygon_area(
|
||
config->area_id,
|
||
config->area_att,
|
||
config->points_num,
|
||
config->points
|
||
);
|
||
|
||
|
||
}
|
||
|
||
}
|
||
|
||
|
||
// 控制车辆状态
|
||
void jt808_Set_CarStatus(uint8_t status){
|
||
// (void)status;
|
||
// TODO: 车辆控制状态
|
||
if(status & 0x80){ // 恢复厂设置
|
||
jt808_delete_TermParam(); // 删除终端参数文件
|
||
jt808_delete_Fence_area(); // 删除围栏区域文件
|
||
local_tts_text_play("即将重启系统",0,0); // 语音播报
|
||
osDelay(7000/5);
|
||
cm_pm_reboot(); // 重启系统
|
||
}
|
||
if(status & 0x70){ // 重启系统
|
||
local_tts_text_play("即将重启系统",0,0); // 语音播报
|
||
osDelay(7000/5);
|
||
cm_pm_reboot(); // 重启系统
|
||
}
|
||
sys_sta.O_door_lock = (status & 0x01)? 1 : 0; // 设置电门锁状态
|
||
sys_sta.PLT_MODE = (status & 0x02)? 1 : 0; // 平台设置的模式 //1:游客模式,0:管理模式
|
||
// sys_sta.P_Radar_EN = (status & 0x04)? 1 : 0; // 1:雷达使能,0:雷达禁止
|
||
}
|
||
|
||
// 获取车辆状态
|
||
uint8_t jt808_Get_CarStatus(void){
|
||
uint8_t status = 0;
|
||
// TODO: 车辆控制状态
|
||
status |= (sys_sta.O_door_lock? 0x01 : 0); // 门锁状态
|
||
status |= (sys_sta.PLT_MODE? 0x02 : 0); // 平台设置模式 //1:游客模式,0:管理模式
|
||
status |= (sys_sta.P_Radar_EN? 0x04 : 0); // 1:雷达使能,0:雷达禁止
|
||
|
||
return status;
|
||
}
|
||
|
||
// 串口数据下传
|
||
int8_t jt808_data_down_SeriaNet(uint8_t type, uint8_t *data, uint16_t len){
|
||
// TODO: 串口数据下传
|
||
if(type == 0x41){ // 串口1下传
|
||
JT808_DEBUG("Serial1 data: ");
|
||
for(uint16_t i = 0; i < len; i++){
|
||
JT808_DEBUG_DATA("%02X ", data[i]);
|
||
}
|
||
JT808_DEBUG_DATA("\r\n");
|
||
}else if(type == 0x42){ // 串口2下传
|
||
JT808_DEBUG("Serial2 data: ");
|
||
for(uint16_t i = 0; i < len; i++){
|
||
JT808_DEBUG_DATA("%02X ", data[i]);
|
||
}
|
||
JT808_DEBUG_DATA("\r\n");
|
||
}else{
|
||
JT808_DEBUG("[%s,%s] type error \r\n", __FUNCTION__,__LINE__);
|
||
return -1;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
// 串口数据上传 // 超时2S即发送失败,直接放弃发送
|
||
int8_t jt808_data_up_SeriaNet(uint8_t type, uint8_t *data, uint16_t len){
|
||
uint8_t ret = 0;
|
||
// TODO: 串口数据上传
|
||
if(NULL != jt808_term_param_item.big_data_up_SeriaNet.Msg_Data){
|
||
jt808_free(jt808_term_param_item.big_data_up_SeriaNet.Msg_Data);
|
||
jt808_term_param_item.big_data_up_SeriaNet.Msg_Data = NULL;
|
||
}
|
||
uint8_t *up_SeriaNet_buf = (uint8_t *)jt808_malloc(len);
|
||
if(up_SeriaNet_buf == NULL){
|
||
JT808_DEBUG("[%s,%s] malloc failed \r\n", __FUNCTION__,__LINE__);
|
||
return -1;
|
||
}
|
||
jt808_term_param_item.big_data_up_SeriaNet.Msg_type = type; // 0x41:串口1上传,0x42:串口2上传
|
||
jt808_term_param_item.big_data_up_SeriaNet.Msg_Data_Len = len;
|
||
memcpy(up_SeriaNet_buf, data, len); // 复制数据内容
|
||
jt808_term_param_item.big_data_up_SeriaNet.Msg_Data = up_SeriaNet_buf;
|
||
|
||
ret =jt808_pkg_send(ID_Data_Up,1000/5); // 发送位置信息上报包
|
||
return ret;
|
||
}
|
||
|
||
|
||
#define TTERMPARAM_FILE "TermParam.txt" // 区域ID列表文件
|
||
|
||
// 删除终端参数文件
|
||
void jt808_delete_TermParam(void){
|
||
if(1 == cm_fs_exist(TTERMPARAM_FILE)){
|
||
cm_fs_delete(TTERMPARAM_FILE);
|
||
}
|
||
}
|
||
|
||
// 获取终端参数文件状态 0:文件存在 -1:文件不存在
|
||
int jt808_get_TermParam_state(void){
|
||
if(1 == cm_fs_exist(TTERMPARAM_FILE)){
|
||
JT808_DEBUG("TermParam file exist\r\n");
|
||
return 0;
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
// 保存终端参数
|
||
static int jt808_save_TermParam(void){
|
||
int32_t fd = cm_fs_open(TTERMPARAM_FILE, CM_FS_WB);
|
||
if(fd < 0){
|
||
JT808_DEBUG("open %s failed\r\n", TTERMPARAM_FILE);
|
||
return -1;
|
||
}
|
||
cm_fs_write(fd, (void *)(&jt808_term_param_item.set_term_param), sizeof(set_TermParam_t));
|
||
cm_fs_close(fd);
|
||
JT808_DEBUG("save TermParam file size = %d == %d\r\n", sizeof(set_TermParam_t));
|
||
for(int i = 0; i < sizeof(set_TermParam_t); i++){
|
||
JT808_DEBUG_DATA("%02x ",*((char *)(&jt808_term_param_item.set_term_param)+i));
|
||
}
|
||
JT808_DEBUG_DATA("\r\n");
|
||
return 0;
|
||
}
|
||
|
||
// 加载终端参数
|
||
static int jt808_load_TermParam(void){
|
||
if(1 != cm_fs_exist(TTERMPARAM_FILE)){
|
||
JT808_DEBUG("no TermParam\r\n");
|
||
return -1;
|
||
}
|
||
int32_t fd = cm_fs_open(TTERMPARAM_FILE, CM_FS_RB);
|
||
if(fd < 0){
|
||
JT808_DEBUG("open %s failed\r\n", TTERMPARAM_FILE);
|
||
return -1;
|
||
}
|
||
int32_t file_size = cm_fs_filesize(TTERMPARAM_FILE);
|
||
if(file_size <= 0){
|
||
JT808_DEBUG("file size error\r\n");
|
||
cm_fs_close(fd);
|
||
return -2;
|
||
}
|
||
if(file_size != sizeof(set_TermParam_t)){
|
||
JT808_DEBUG("file size error\r\n");
|
||
cm_fs_close(fd);
|
||
return -3;
|
||
}else{
|
||
JT808_DEBUG("load TermParam file size = %d == %d\r\n", file_size, sizeof(set_TermParam_t));
|
||
cm_fs_read(fd, (void *)(&jt808_term_param_item.set_term_param), sizeof(set_TermParam_t));
|
||
for(int i = 0; i < sizeof(set_TermParam_t); i++){
|
||
JT808_DEBUG_DATA("%02x ",*((char *)(&jt808_term_param_item.set_term_param)+i));
|
||
}
|
||
JT808_DEBUG_DATA("\r\n");
|
||
cm_fs_close(fd);
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
// 设置终端参数
|
||
int jt808_setTermParam(set_TermParamID_t param_id, void *param, uint8_t param_len){
|
||
uint32_t param_val32 = 0;
|
||
if(param_len == 1){
|
||
param_val32 = ((uint8_t *)param)[0];
|
||
}else if(param_len == 2){
|
||
param_val32 = (((uint8_t *)param)[0] << 8) | ((uint8_t *)param)[1];
|
||
}else if(param_len == 4){
|
||
param_val32 = (((uint8_t *)param)[0] << 24) | (((uint8_t *)param)[1] << 16) | (((uint8_t *)param)[2] << 8) | ((uint8_t *)param)[3];
|
||
}
|
||
|
||
JT808_DEBUG("param_id = 0x%04X, param_val32 = 0x%04X == %d\r\n", param_id, param_val32, param_val32);
|
||
switch(param_id){
|
||
case ID_HeartBeatInterval:{
|
||
jt808_term_param_item.set_term_param.HeartBeatInterval =param_val32;
|
||
break;
|
||
}
|
||
case ID_MainServerAddr:{
|
||
memcpy(jt808_term_param_item.set_term_param.MainServerAddr,param,20<param_len?param_len:20);
|
||
break;
|
||
}
|
||
case ID_ServerPort:{
|
||
jt808_term_param_item.set_term_param.ServerPort =param_val32;
|
||
break;
|
||
}
|
||
case ID_DefaultTimeReportInterval:{
|
||
jt808_term_param_item.set_term_param.DefaultTimeReportInterval =param_val32;
|
||
break;
|
||
}
|
||
case ID_InflexionAngle:{
|
||
jt808_term_param_item.set_term_param.InflexionAngle =param_val32;
|
||
break;
|
||
}
|
||
case ID_MaxSpeed:{
|
||
jt808_term_param_item.set_term_param.MaxSpeed =param_val32;
|
||
break;
|
||
}
|
||
case ID_ProvinceID:{
|
||
jt808_term_param_item.set_term_param.ProvinceID =param_val32;
|
||
break;
|
||
}
|
||
case ID_CityID:{
|
||
jt808_term_param_item.set_term_param.CityID =param_val32;
|
||
break;
|
||
}
|
||
case ID_CarPlateNum:{
|
||
memcpy(jt808_term_param_item.set_term_param.CarPlateNum,param,10<param_len?param_len:10);
|
||
break;
|
||
}
|
||
case ID_CarPlateColor:{
|
||
jt808_term_param_item.set_term_param.CarPlateColor =param_val32 & 0xFF;
|
||
break;
|
||
}
|
||
case ID_ManagerACC:{ // 管理员模式油门0~100%
|
||
jt808_term_param_item.set_term_param.ManagerACC =param_val32 & 0xFF;
|
||
break;
|
||
}
|
||
case ID_TouristACC:{ // 游客模式油门0~100%
|
||
jt808_term_param_item.set_term_param.TouristACC =param_val32 & 0xFF;
|
||
break;
|
||
}
|
||
case ID_SpeedCutACC:{ // 自动减速油门0~100%
|
||
jt808_term_param_item.set_term_param.SpeedCutACC =param_val32 & 0xFF;
|
||
break;
|
||
}
|
||
case ID_BrakeLimit:{ //前进刹车距离
|
||
jt808_term_param_item.set_term_param.BrakeLimit =param_val32 & 0xFFFF;
|
||
break;
|
||
}
|
||
case ID_SpeedCutLimit:{ // 前进自动减速刹车距离
|
||
jt808_term_param_item.set_term_param.SpeedCutLimit =param_val32 & 0xFFFF;
|
||
break;
|
||
}
|
||
case ID_BrakeLimit_B:{ // 后退刹车距离
|
||
jt808_term_param_item.set_term_param.BrakeLimit_B =param_val32 & 0xFFFF;
|
||
break;
|
||
}
|
||
case ID_SpeedCutLimit_B:{ // 后退自动减速刹车距离
|
||
jt808_term_param_item.set_term_param.SpeedCutLimit_B =param_val32 & 0xFFFF;
|
||
break;
|
||
}
|
||
case ID_Ban_Fence_Polygon_Delay_OFF:{ // 禁止围栏报警延时关闭时间, 单位秒
|
||
jt808_term_param_item.set_term_param.Ban_Fence_Polygon_Delay_OFF =param_val32 & 0xFF;
|
||
break;
|
||
}
|
||
case ID_RadarEN:{// TODO: 雷达使能位
|
||
uint8_t radar_en = param_val32 & 0xFF;
|
||
JT808_DEBUG("RadarEN=%d", radar_en);
|
||
|
||
// 更新运行时状态(包括值2)
|
||
osMutexAcquire(radar_mutex, osWaitForever);
|
||
sys_sta.P_Radar_EN = radar_en;
|
||
osMutexRelease(radar_mutex);
|
||
|
||
// 只保存0或1到持久化参数
|
||
if(radar_en != 2) {
|
||
jt808_term_param_item.set_term_param.RadarEN = radar_en;
|
||
} else {
|
||
// 值2不保存,但可以记录日志
|
||
JT808_DEBUG("Skip saving temporary RadarEN=2 state");
|
||
}
|
||
break;
|
||
}
|
||
default:{
|
||
// TODO: 未知参数
|
||
return -1;
|
||
break;
|
||
}
|
||
}
|
||
jt808_save_TermParam(); // 保存终端参数
|
||
|
||
return 0;
|
||
}
|
||
|
||
// 更新位置基本信息
|
||
int jt808_updateLocBasicInfo(Loc_basic_info_t *loc_basic_info){
|
||
// (void *)loc_basic_info;
|
||
|
||
return 0;
|
||
}
|
||
|
||
// 增加附加信息(队尾增加)
|
||
void jt808_LocReport_add_tail_addi_info(uint8_t msg_id){
|
||
// TODO: 增加附加信息
|
||
Loc_addi_info_t *p_head =jt808_term_param_item.big_loc_report.addi_info;
|
||
while(p_head != NULL){
|
||
if(p_head->msg_id == msg_id){
|
||
// 已存在该消息ID
|
||
return;
|
||
}
|
||
p_head = p_head->next;
|
||
}
|
||
// 未找到该消息ID,增加
|
||
p_head = (Loc_addi_info_t *)jt808_malloc(sizeof(Loc_addi_info_t));
|
||
if(p_head == NULL){
|
||
JT808_DEBUG("[%s,%s] malloc failed \r\n", __FUNCTION__,__LINE__);
|
||
return;
|
||
}
|
||
if(jt808_term_param_item.big_loc_report.addi_info == NULL){
|
||
jt808_term_param_item.big_loc_report.addi_info = p_head;
|
||
}else{
|
||
Loc_addi_info_t *p_tail =jt808_term_param_item.big_loc_report.addi_info;
|
||
while(p_tail->next != NULL){
|
||
p_tail = p_tail->next;
|
||
}
|
||
p_tail->next = p_head;
|
||
}
|
||
p_head->msg_id = msg_id;
|
||
p_head->next = NULL;
|
||
|
||
// TODO: 增加附加信息
|
||
switch(msg_id){
|
||
case BAT_VoltageID:{
|
||
// 电池电压, 0.1V WORD
|
||
p_head->msg_len = 2;
|
||
p_head->msg = (void *)(&BAT_Message.Rsp_BigBat_Voltage);
|
||
break;
|
||
}
|
||
case BAT_PercentageID:{
|
||
// 电池电量 , % BYTE
|
||
p_head->msg_len = 1;
|
||
p_head->msg = (void *)(&BAT_Message.Bat_Percent);
|
||
break;
|
||
}
|
||
case Scenic_Fence_Polygon_area_ID:{
|
||
// 景区围栏多边形区域ID, DWORD
|
||
p_head->msg_len = 4;
|
||
p_head->msg = (void *)(&Rsp_Bigscenic_Fence_Polygon_area_ID);
|
||
break;
|
||
}
|
||
case Ban_Fence_Polygon_area_ID:{
|
||
// 禁止围栏多边形区域ID, DWORD
|
||
p_head->msg_len = 4;
|
||
p_head->msg = (void *)(&Rsp_Bigban_Fence_Polygon_area_ID);
|
||
break;
|
||
}
|
||
case Locked_Condition_ID:{
|
||
// 锁车状态, BYTE
|
||
p_head->msg_len = 1;
|
||
p_head->msg = (void *)(&Rsp_locked_condition);
|
||
break;
|
||
}
|
||
default:{
|
||
// TODO: 未知消息ID
|
||
jt808_free(p_head);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 移除附加信息(指定消息ID)
|
||
void jt808_LocReport_remove_addi_info(uint8_t msg_id){
|
||
Loc_addi_info_t *p_head =jt808_term_param_item.big_loc_report.addi_info;
|
||
Loc_addi_info_t *p_prev =NULL;
|
||
while(p_head != NULL){
|
||
if(p_head->msg_id == msg_id){
|
||
if(p_prev == NULL){
|
||
jt808_term_param_item.big_loc_report.addi_info = p_head->next;
|
||
}else{
|
||
p_prev->next = p_head->next;
|
||
}
|
||
jt808_free(p_head);
|
||
break;
|
||
}
|
||
p_prev = p_head;
|
||
p_head = p_head->next;
|
||
}
|
||
}
|
||
|
||
osThreadFunc_t Autoreport_param_ThreadId;
|
||
|
||
uint16_t scenic_Fence_Polygon_count = 0;
|
||
uint16_t ban_Fence_Polygon_count = 0;
|
||
uint16_t delay_off_count = 0; // 延时关闭计数
|
||
|
||
uint8_t Rsp_locked_condition = 0; // 锁车状态, BYTE
|
||
|
||
gps_data_t gps_data_msg; // GPS数据;
|
||
|
||
// 更新自动上报参数
|
||
void jt808_LocReport_param_update(void){
|
||
|
||
osMutexAcquire(term_param_mutex, osWaitForever);
|
||
|
||
nmeaTIME beiJingTime; // 北京时间
|
||
// TODO: 自动上报参数
|
||
// 1. 位置基本信息
|
||
GMTconvert(&gps_data_msg.info.utc, &beiJingTime, 8, 1);
|
||
if(beiJingTime.mon == 0){
|
||
beiJingTime.mon = 1;
|
||
}
|
||
if(beiJingTime.day == 0){
|
||
beiJingTime.day = 1;
|
||
}
|
||
// info.lat lon中的格式为[degree][min].[sec/60],使用以下函数转换成[degree].[degree]格式
|
||
jt808_term_param_item.big_loc_report.basic_info.latitude = Swap32(nmea_ndeg2degree(gps_data_msg.info.lat) * 1e6);
|
||
jt808_term_param_item.big_loc_report.basic_info.longitude = Swap32(nmea_ndeg2degree(gps_data_msg.info.lon) * 1e6);
|
||
jt808_term_param_item.big_loc_report.basic_info.altitude = Swap16(gps_data_msg.info.elv);
|
||
jt808_term_param_item.big_loc_report.basic_info.speed = Swap16(gps_data_msg.info.speed * 10);
|
||
jt808_term_param_item.big_loc_report.basic_info.direction = Swap16(gps_data_msg.info.direction);
|
||
jt808_term_param_item.big_loc_report.basic_info.BCDtime[0] =((((beiJingTime.year+1900)%2000%100/10)&0x0F)<<4) | (((beiJingTime.year+1900)%2000%10)&0x0F);
|
||
jt808_term_param_item.big_loc_report.basic_info.BCDtime[1] = (((beiJingTime.mon%100/10)&0x0F)<<4) | ((beiJingTime.mon%10)&0x0F);
|
||
jt808_term_param_item.big_loc_report.basic_info.BCDtime[2] = (((beiJingTime.day%100/10)&0x0F)<<4) | ((beiJingTime.day%10)&0x0F);
|
||
jt808_term_param_item.big_loc_report.basic_info.BCDtime[3] = (((beiJingTime.hour%100/10)&0x0F)<<4) | ((beiJingTime.hour%10)&0x0F);
|
||
jt808_term_param_item.big_loc_report.basic_info.BCDtime[4] = (((beiJingTime.min%100/10)&0x0F)<<4) | ((beiJingTime.min%10)&0x0F);
|
||
jt808_term_param_item.big_loc_report.basic_info.BCDtime[5] = (((beiJingTime.sec%100/10)&0x0F)<<4) | ((beiJingTime.sec%10)&0x0F);
|
||
|
||
jt808_term_param_item.big_loc_report.basic_info.status.val32 = 0; // 清除状态信息
|
||
jt808_term_param_item.big_loc_report.basic_info.status.positioning = (((gps_data_msg.info.fix == 1)||(gps_data_msg.info.sig == 0)) ? 0 : 1); // 0:未定位,1:已定位
|
||
jt808_term_param_item.big_loc_report.basic_info.status.acc =((1==sys_sta.O_door_lock)||(0==sys_sta.MAG_MODE)); // 1:电门锁打开,0:电门锁关闭
|
||
jt808_term_param_item.big_loc_report.basic_info.status.MAG_MODE =sys_sta.MAG_MODE;// 1:游客模式,0:管理模式
|
||
jt808_term_param_item.big_loc_report.basic_info.status.PLT_MODE =sys_sta.PLT_MODE; // 1:游客模式,0:管理模式
|
||
jt808_term_param_item.big_loc_report.basic_info.status.IO_RX_back =sys_sta.IO_RX_back; // 1:正常 0:倒车
|
||
jt808_term_param_item.big_loc_report.basic_info.status.IO_TX_brake =sys_sta.IO_TX_brake; // 1:正常 0:刹车
|
||
jt808_term_param_item.big_loc_report.basic_info.status.A_brake =sys_sta.A_brake; // 1:自动刹车,0:手动刹车
|
||
jt808_term_param_item.big_loc_report.basic_info.status.A_Speed_Cut =sys_sta.A_Speed_Cut; // 1:自动减速,0:手动减速
|
||
jt808_term_param_item.big_loc_report.basic_info.status.P_Radar_EN =sys_sta.P_Radar_EN; //2:雷达暂时关闭 1:雷达使能,0:雷达禁止
|
||
jt808_term_param_item.big_loc_report.basic_info.status.val32 = Swap32(jt808_term_param_item.big_loc_report.basic_info.status.val32); // 状态信息(转大端)
|
||
|
||
jt808_term_param_item.big_loc_report.basic_info.alarm_flag.val32 = 0; // 清除报警标志
|
||
jt808_term_param_item.big_loc_report.basic_info.alarm_flag.overspeed = 0; // bit_1 超速报警
|
||
jt808_term_param_item.big_loc_report.basic_info.alarm_flag.power_low = 0; // bit_7 终端主电源欠压
|
||
jt808_term_param_item.big_loc_report.basic_info.alarm_flag.road_deviate = 0; // bit_23 路线偏离报警
|
||
jt808_term_param_item.big_loc_report.basic_info.alarm_flag.car_move = 0; // bit_28 车辆非法位移.收到应答后清零
|
||
jt808_term_param_item.big_loc_report.basic_info.alarm_flag.val32 = Swap32(jt808_term_param_item.big_loc_report.basic_info.alarm_flag.val32); // 报警标志(转大端)
|
||
|
||
if((gps_data_msg.info.fix == 1)||(gps_data_msg.info.sig == 0)){ // 不可用// 未定位时发送心跳包
|
||
Rsp_Bigscenic_Fence_Polygon_area_ID = 0;
|
||
Rsp_Bigban_Fence_Polygon_area_ID = 0;
|
||
}else{
|
||
// 更新当前所在位置区域ID
|
||
uint32_t lat = nmea_ndeg2degree(gps_data_msg.info.lat) * 1e6;
|
||
uint32_t lng = nmea_ndeg2degree(gps_data_msg.info.lon) * 1e6;
|
||
// lat = 44939236;
|
||
// lng = 121369446;
|
||
// lat = 34939236;
|
||
// lng = 121369446;
|
||
Rsp_Bigscenic_Fence_Polygon_area_ID = Swap32(jt808_Polygon_fence_check(0x0001, lat, lng));
|
||
Rsp_Bigban_Fence_Polygon_area_ID = Swap32(jt808_Polygon_fence_check(0x0002, lat, lng));
|
||
|
||
if((1 == sys_sta.O_door_lock) || (0 == sys_sta.MAG_MODE )){ // 系统运行中
|
||
Rsp_locked_condition = 0; // 复位锁车状态
|
||
|
||
if(Rsp_Bigscenic_Fence_Polygon_area_ID == 0){ // 在景区围栏
|
||
scenic_Fence_Polygon_count++;
|
||
if(scenic_Fence_Polygon_count >= 10){
|
||
scenic_Fence_Polygon_count = 0;
|
||
local_tts_text_play("您已离开景区!",0,0);
|
||
}
|
||
}else{
|
||
scenic_Fence_Polygon_count = 0;
|
||
}
|
||
if(Rsp_Bigban_Fence_Polygon_area_ID != 0){
|
||
delay_off_count++;
|
||
if(delay_off_count >= jt808_term_param_item.set_term_param.Ban_Fence_Polygon_Delay_OFF){ // 30S
|
||
delay_off_count = 0;
|
||
sys_sta.O_door_lock = 0; // 锁车
|
||
Rsp_locked_condition = 1; // 锁车状态
|
||
local_tts_text_play("已锁车,请联系管理员解除禁止入内限制!",0,0);
|
||
}
|
||
ban_Fence_Polygon_count++;
|
||
if(ban_Fence_Polygon_count >= 10){ // 7S
|
||
ban_Fence_Polygon_count = 0;
|
||
local_tts_text_play("您已进入禁区,请尽快离开!",0,0);
|
||
}
|
||
}else{
|
||
delay_off_count = 0;
|
||
ban_Fence_Polygon_count = 0;
|
||
}
|
||
}else{
|
||
scenic_Fence_Polygon_count = 0;
|
||
ban_Fence_Polygon_count = 0;
|
||
delay_off_count = 0;
|
||
}
|
||
}
|
||
osMutexRelease(term_param_mutex);
|
||
}
|
||
|
||
void Autoreport_param_Task(void *arg){
|
||
uint32_t count_Sec = 0;// 计数器
|
||
|
||
jt808_LocReport_add_tail_addi_info(BAT_VoltageID); // 增加电池电压信息
|
||
jt808_LocReport_add_tail_addi_info(BAT_PercentageID); // 增加电池电量信息
|
||
jt808_LocReport_add_tail_addi_info(Scenic_Fence_Polygon_area_ID); // 增加景区围栏多边形区域ID信息
|
||
jt808_LocReport_add_tail_addi_info(Ban_Fence_Polygon_area_ID); // 增加景区围栏多边形区域ID信息
|
||
jt808_LocReport_add_tail_addi_info(Locked_Condition_ID);
|
||
|
||
#if 0 // 测试用
|
||
uint32_t area_ID=0;
|
||
AreaPoint_t point[4] = {
|
||
{39939236, 116369446},
|
||
{39939236, 126379446},
|
||
{49929236, 126379446},
|
||
{49929236, 116369446}
|
||
};
|
||
for(int i=0;i<4;i++){
|
||
point[i].lat = Swap32(point[i].lat);
|
||
point[i].lng = Swap32(point[i].lng);
|
||
}
|
||
jt808_add_tail_fence_Polygon_area(0x0003, 0x0001, 4, point); // 增加景区围栏多边形区域ID信息
|
||
jt808_add_tail_fence_Polygon_area(0x0004, 0x0002, 4, point); // 增加景区围栏多边形区域ID信息
|
||
|
||
// area_ID = jt808_Polygon_fence_check(0x0001, 44939236, 121369446);
|
||
// JT808_DEBUG("area_ID0:%d\n",area_ID);
|
||
// area_ID = jt808_Polygon_fence_check(0x0001, 34939236, 121369446);
|
||
// JT808_DEBUG("area_ID1:%d\n",area_ID);
|
||
// jt808_remove_fence_Polygon_area(0x0003);
|
||
// area_ID = jt808_Polygon_fence_check(0x0001, 44939236, 121369446);
|
||
// JT808_DEBUG("area_ID2:%d remove\n",area_ID);
|
||
|
||
// AreaPoint_t point1[4] = {
|
||
// {69939236, 146369446},
|
||
// {69939236, 156379446},
|
||
// {79929236, 156379446},
|
||
// {79929236, 146369446}
|
||
// };
|
||
// for(int i=0;i<4;i++){
|
||
// point1[i].lat = Swap32(point1[i].lat);
|
||
// point1[i].lng = Swap32(point1[i].lng);
|
||
// }
|
||
// jt808_add_tail_fence_Polygon_area(0x0004, 0x0001, 4, point1); // 增加景区围栏多边形区域ID信息
|
||
// area_ID = jt808_Polygon_fence_check(0x0001, 74939236, 151369446);
|
||
// JT808_DEBUG("area_ID3:%d\n\n\n",area_ID);
|
||
// area_ID = jt808_Polygon_fence_check(0x0001, 64939236, 151369446);
|
||
// JT808_DEBUG("area_ID4:%d\n\n\n",area_ID);
|
||
// jt808_remove_fence_Polygon_area(0x0004);
|
||
// area_ID = jt808_Polygon_fence_check(0x0001, 74939236, 151369446);
|
||
// JT808_DEBUG("area_ID5:%d remove\n",area_ID);
|
||
#endif
|
||
|
||
while(1){
|
||
osMutexAcquire(gps_data.mutex, osWaitForever);
|
||
memcpy(&gps_data_msg, &gps_data, sizeof(gps_data_t));
|
||
osMutexRelease(gps_data.mutex);
|
||
|
||
jt808_LocReport_param_update(); // 更新位置信息参数
|
||
|
||
// jt808_term_param_item.big_loc_report.basic_info.alarm_flag.gnss_fault = 0 == gps_data_msg.info.sig ? 1 : 0; // 0:无故障,1:有故障
|
||
if(0 == (count_Sec % jt808_term_param_item.set_term_param.HeartBeatInterval)){
|
||
if((gps_data_msg.info.fix == 1)||(gps_data_msg.info.sig == 0)){ // 不可用// 未定位时发送心跳包
|
||
jt808_pkg_send(ID_Term_HB,0); // 发送心跳包 // 不接收应答
|
||
// jt808_pkg_send(ID_LocReport,0);
|
||
// jt808_pkg_send(ID_Car_CtrlResp,0);
|
||
JT808_DEBUG("Bat_Percent:%d,Bat_Voltage:%d,Bat_STA:%X\r\n",BAT_Message.Bat_Percent,BAT_Message.Bat_Voltage,BAT_Message.Bat_STA);
|
||
}else{
|
||
jt808_pkg_send(ID_LocReport,10000/5); // 发送位置信息上报包
|
||
}
|
||
}
|
||
count_Sec++;
|
||
osDelay(1000/5); // 1S
|
||
}
|
||
}
|
||
|
||
// 启动自动上报参数
|
||
void jt808_Autoreport_param_start(void){
|
||
if(Autoreport_param_ThreadId == NULL){
|
||
osThreadAttr_t Autoreport_param_task_attr = {
|
||
.name = "Autoreport_param_Task",
|
||
.stack_size = 4096*4,
|
||
.priority = osPriorityNormal,
|
||
};
|
||
Autoreport_param_ThreadId = osThreadNew((osThreadFunc_t)Autoreport_param_Task, 0, &Autoreport_param_task_attr);
|
||
}else{
|
||
osThreadResume(Autoreport_param_ThreadId); //恢复线程
|
||
}
|
||
}
|
||
|
||
// 停止自动上报参数
|
||
void jt808_Autoreport_param_stop(void){
|
||
if(Autoreport_param_ThreadId != NULL){
|
||
osThreadSuspend(Autoreport_param_ThreadId); //挂起线程
|
||
}
|
||
}
|
||
|
||
|
||
// 初始化终端参数
|
||
void jt808_set_term_param_init(void){
|
||
int ret = 0;
|
||
|
||
term_param_mutex = osMutexNew(NULL); // 创建互斥锁
|
||
Polygon_fence_mutex = osMutexNew(NULL); // 创建互斥锁
|
||
|
||
memset(&jt808_term_param_item,0,sizeof(Term_Param_item_t));
|
||
// 加载围栏区域信息
|
||
if(0 == jt808_get_areafile_state()){
|
||
ret = jt808_load_Fence_area();
|
||
JT808_DEBUG("load fence area ret:%d\n", ret);
|
||
}
|
||
do{ // 终端属性参数初始化
|
||
jt808_term_param_item.big_term_attr_resp.term_type = Swap16(0); // 终端类型
|
||
memcpy(jt808_term_param_item.big_term_attr_resp.manufacturer_id, "LAT01", 5); // 制造商ID
|
||
memcpy(jt808_term_param_item.big_term_attr_resp.term_model, jt808_term_param_item.big_reg_info.term_model, 20); // 终端型号
|
||
memcpy(jt808_term_param_item.big_term_attr_resp.term_id, jt808_term_param_item.big_reg_info.term_id, 7); // 终端ID
|
||
// memcpy(jt808_term_param_item.big_term_attr_resp.term_ICCID+4, jt808_term_param_item.phone_BCDnum, 6); // 终端手机号码
|
||
|
||
char str_hw_ver[] = "1.0.0"; // 硬件版本
|
||
char str_fw_ver[] = "1.0.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)); // 硬件版本
|
||
memcpy(jt808_term_param_item.big_term_attr_resp.str_fw_ver, str_fw_ver, strlen(str_fw_ver)); // 固件版本
|
||
jt808_term_param_item.big_term_attr_resp.GnssModule_attr = 0x03; // GNSS模块属性
|
||
jt808_term_param_item.big_term_attr_resp.CommModule_attr = 0x01; // 通信模块属性
|
||
}while(0);
|
||
do{// 授权信息初始化
|
||
char str_auth[]="auth code error..."; // 授权码
|
||
jt808_term_param_item.big_auth_info.str_auth_code = jt808_malloc(strlen(str_auth)+1); // 授权码
|
||
if(jt808_term_param_item.big_auth_info.str_auth_code == NULL){
|
||
JT808_DEBUG("malloc auth_code failed\r\n");
|
||
}
|
||
memcpy(jt808_term_param_item.big_auth_info.str_auth_code, str_auth, strlen(str_auth)+1); // 授权码
|
||
JT808_DEBUG("auth_code:%d,%s\r\n",strlen(jt808_term_param_item.big_auth_info.str_auth_code), jt808_term_param_item.big_auth_info.str_auth_code);
|
||
// jt808_free(jt808_term_param_item.big_auth_info.str_auth_code);
|
||
// jt808_term_param_item.big_auth_info.str_auth_code = NULL;
|
||
}while(0);
|
||
do{// 终端参数初始化
|
||
if(0 == jt808_get_TermParam_state()){
|
||
ret = jt808_load_TermParam(); // 加载终端参数
|
||
JT808_DEBUG("load term param ret:%d\n", ret);
|
||
}else{
|
||
jt808_term_param_item.set_term_param.HeartBeatInterval = 30; // 心跳包间隔(秒)
|
||
#if 1
|
||
char ServerAddr[] ="47.99.118.34"; // 测试服务器地址
|
||
uint32_t ServerPort = 5000; // 服务器端口
|
||
#else
|
||
char ServerAddr[] ="106.14.30.23"; // 生产服务器地址
|
||
uint32_t ServerPort = 5000; // 服务器端口
|
||
#endif
|
||
// memset(jt808_term_param_item.set_term_param.MainServerAddr, 0, 50);
|
||
memcpy(jt808_term_param_item.set_term_param.MainServerAddr, ServerAddr, strlen(ServerAddr)+1); // 主服务器地址
|
||
jt808_term_param_item.set_term_param.ServerPort = ServerPort; // 服务器端口
|
||
jt808_term_param_item.set_term_param.DefaultTimeReportInterval = 60; // 默认时间上报间隔(秒)
|
||
jt808_term_param_item.set_term_param.InflexionAngle = 0; // 俯仰角(度)
|
||
jt808_term_param_item.set_term_param.MaxSpeed = 0; // 最大速度(km/h)
|
||
jt808_term_param_item.set_term_param.ProvinceID = 0; // 省域ID
|
||
jt808_term_param_item.set_term_param.CityID = 0; // 市域ID
|
||
jt808_term_param_item.set_term_param.CarPlateNum[0] = 0; // 车牌号码
|
||
jt808_term_param_item.set_term_param.CarPlateColor = 0; // 车牌颜色
|
||
|
||
jt808_term_param_item.set_term_param.RadarEN =1; // 雷达使能位, 0 代表关闭, 1 代表开启
|
||
jt808_term_param_item.set_term_param.ManagerACC =100; // 管理员模式油门0~100%
|
||
jt808_term_param_item.set_term_param.TouristACC =50; // 游客模式油门0~100%
|
||
jt808_term_param_item.set_term_param.SpeedCutACC =20; // 自动减速油门0~100%
|
||
jt808_term_param_item.set_term_param.BrakeLimit =1200; //前进刹车距离
|
||
jt808_term_param_item.set_term_param.SpeedCutLimit =2000; // 前进自动减速刹车距离
|
||
jt808_term_param_item.set_term_param.BrakeLimit_B =1200; // 后退刹车距离
|
||
jt808_term_param_item.set_term_param.SpeedCutLimit_B =2000; // 后退自动减速刹车距离
|
||
jt808_term_param_item.set_term_param.Ban_Fence_Polygon_Delay_OFF =30; // 禁止围栏延时锁车时间
|
||
jt808_save_TermParam(); // 保存终端参数
|
||
}
|
||
}while(0);
|
||
do{// 位置信息上报初始化
|
||
memset(&jt808_term_param_item.big_loc_report.basic_info,0,sizeof(Loc_basic_info_t));
|
||
jt808_term_param_item.big_loc_report.basic_info.status.val32 = 0; // 状态信息
|
||
jt808_term_param_item.big_loc_report.basic_info.alarm_flag.val32 = 0; // 报警标志
|
||
}while(0);
|
||
do{ // 设置终端手机号
|
||
char cm_iccid[32] = {0};
|
||
uint8_t BCD_code[13]={0};
|
||
int error_count = 0;
|
||
uint8_t operator_val=0;
|
||
|
||
while(error_count <= 20){
|
||
memset(cm_iccid, 0, sizeof(cm_iccid));
|
||
cm_sim_get_iccid(cm_iccid);
|
||
if((cm_iccid[0] == '8')&&(cm_iccid[1] == '9')&&(cm_iccid[2] == '8')&&(cm_iccid[3] == '6')&&(strlen(cm_iccid)>=19)){
|
||
operator_val =(cm_iccid[4]-'0')*10 + cm_iccid[5]-'0';
|
||
JT808_DEBUG("operator:%d,iccid:%d,:%s\n",operator_val ,strlen(cm_iccid), cm_iccid);
|
||
|
||
uint8_t start_val=strlen(cm_iccid);
|
||
if((operator_val ==0)||(operator_val ==2)||(operator_val ==4)||(operator_val ==7)){ // 中国移动
|
||
start_val -= 12;
|
||
}else if((operator_val ==1)||(operator_val ==6)||(operator_val ==9)){ // 中国联通
|
||
start_val -= 12;
|
||
}else if((operator_val ==3)||(operator_val ==11)){ // 电信
|
||
start_val -= 13;
|
||
}
|
||
for(uint8_t count =0; count < 12; count++){
|
||
if(cm_iccid[start_val + count] >= '0' && cm_iccid[start_val + count] <= '9'){
|
||
BCD_code[count] =cm_iccid[start_val + count];
|
||
}else{
|
||
BCD_code[count] ='0';
|
||
}
|
||
}
|
||
rawStrToBcd(jt808_term_param_item.phone_BCDnum, BCD_code, 12); // 终端手机号码
|
||
break;
|
||
}
|
||
error_count++;
|
||
JT808_DEBUG("get iccid failed, retry:%d\n", error_count);
|
||
osDelay(1000/5); // 根据需求设置延时
|
||
}
|
||
jt808_term_param_item.msg_flow_num =0;
|
||
JT808_DEBUG("phone_BCDnum:");
|
||
for(int i=0;i<6;i++){
|
||
JT808_DEBUG_DATA("%02X ",jt808_term_param_item.phone_BCDnum[i]);
|
||
}
|
||
JT808_DEBUG_DATA("\n");
|
||
|
||
size_t iccid_len = strlen(cm_iccid);
|
||
if(iccid_len > 0) {
|
||
// 确保不超过term_ICCID容量(10字节=20位BCD)
|
||
if(iccid_len > 20) iccid_len = 20;
|
||
|
||
// 将ASCII ICCID转换为BCD格式
|
||
uint8_t bcd_buffer[10] = {0};
|
||
ascii_to_bcd(cm_iccid, iccid_len, bcd_buffer);
|
||
|
||
// 复制到终端属性结构体
|
||
memcpy(jt808_term_param_item.big_term_attr_resp.term_ICCID,
|
||
bcd_buffer,
|
||
sizeof(jt808_term_param_item.big_term_attr_resp.term_ICCID));
|
||
}
|
||
}while(0);
|
||
do{// 注册信息初始化
|
||
char read_buf[35] = {0};
|
||
|
||
jt808_term_param_item.big_reg_info.province_id = Swap16(0); // 省域ID
|
||
jt808_term_param_item.big_reg_info.city_id = Swap16(0); // 市域ID
|
||
memcpy(jt808_term_param_item.big_reg_info.manufacturer_id, "LAT01", 5); // 制造商ID
|
||
|
||
while(0 != cm_sys_get_sn(read_buf)){
|
||
JT808_DEBUG("get sn failed\n");
|
||
osDelay(1000/5);
|
||
}
|
||
JT808_DEBUG("SN:%s\n", read_buf);
|
||
memcpy(jt808_term_param_item.big_reg_info.term_model, read_buf, 20); // 终端型号
|
||
|
||
while(0 != cm_sys_get_imei(read_buf)){
|
||
JT808_DEBUG("get imei failed\n");
|
||
osDelay(1000/5);
|
||
}
|
||
JT808_DEBUG("IMEI:%s\n", read_buf);
|
||
memcpy(jt808_term_param_item.big_reg_info.term_id, read_buf, 7); // 终端ID
|
||
|
||
jt808_term_param_item.big_reg_info.car_plate_color = blue_plate; // 车牌颜色
|
||
|
||
char CarPlateNum[] ="京A12345"; // 车牌号码
|
||
memcpy(jt808_term_param_item.big_reg_info.car_plate_num, CarPlateNum, strlen(CarPlateNum)); // 车牌号码
|
||
}while(0);
|
||
PrsResult.term_param_item =&jt808_term_param_item;// 全局变量指针指向终端参数项
|
||
|
||
// JT808_DEBUG("auth_code:%s\r\n",PrsResult.term_param_item->big_auth_info.str_auth_code);
|
||
}
|
||
|
||
// 释放终端参数
|
||
void jt808_set_term_param_free(void){
|
||
if(jt808_term_param_item.big_auth_info.str_auth_code != NULL){ // 释放授权码
|
||
jt808_free(jt808_term_param_item.big_auth_info.str_auth_code);
|
||
jt808_term_param_item.big_auth_info.str_auth_code = NULL;
|
||
}
|
||
if(jt808_term_param_item.big_specific_params.param_id_list != NULL){ // 释放特定参数列表
|
||
jt808_free(jt808_term_param_item.big_specific_params.param_id_list);
|
||
jt808_term_param_item.big_specific_params.param_id_list = NULL;
|
||
}
|
||
if(jt808_term_param_item.big_ctrl_info.str_cmd_params != NULL){ // 释放控制命令参数
|
||
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;
|
||
}
|
||
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;
|
||
p_addi_info_next = p_addi_info->next;
|
||
while(p_addi_info != NULL){ // 释放附加信息列表
|
||
jt808_free(p_addi_info);
|
||
p_addi_info = p_addi_info_next;
|
||
if(p_addi_info != NULL){
|
||
p_addi_info_next = p_addi_info->next;
|
||
}
|
||
}
|
||
PrsResult.term_param_item = NULL;
|
||
}
|