添加离线tts功能、adc检测,油门pwm功能 zsxfly20241108
This commit is contained in:
parent
eda386aa78
commit
28ea8d867c
|
|
@ -3,9 +3,19 @@
|
||||||
#include "cm_os.h"
|
#include "cm_os.h"
|
||||||
#include "nmea/nmea.h"
|
#include "nmea/nmea.h"
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
uint16_t flow_num; // 流水号
|
||||||
|
nmeaINFO info; // GPS信息
|
||||||
|
nmeaPOS dpos; // 经纬度
|
||||||
|
} gps_data_t;
|
||||||
|
|
||||||
|
extern gps_data_t gps_data;
|
||||||
|
|
||||||
|
|
||||||
void gps_config_init(void);
|
void gps_config_init(void);
|
||||||
/* 关闭串口 */
|
/* 关闭串口 */
|
||||||
void gps_config_close(void);
|
void gps_config_close(void);
|
||||||
|
|
||||||
|
void GMTconvert(nmeaTIME *SourceTime, nmeaTIME *ConvertTime, uint8_t GMT, uint8_t AREA);
|
||||||
|
|
||||||
#endif /* GPS_CONFIG_H */
|
#endif /* GPS_CONFIG_H */
|
||||||
|
|
@ -26,54 +26,79 @@ static osThreadId_t GPS_ThreadId = NULL; //串口数据接收、解析任务Hand
|
||||||
static void* gps_uart_sem = NULL; //串口数据接收、解析任务信号量
|
static void* gps_uart_sem = NULL; //串口数据接收、解析任务信号量
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief trace 在解码时输出捕获的GPS语句
|
||||||
|
* @param str: 要输出的字符串,str_size:数据长度
|
||||||
|
* @retval 无
|
||||||
|
*/
|
||||||
|
void trace(const char *str, int str_size){
|
||||||
|
// app_printf("\r\nTrace: ");
|
||||||
|
// cm_uart_write(CM_UART_DEV_0, (void*)str, str_size, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief error 在解码出错时输出提示消息
|
||||||
|
* @param str: 要输出的字符串,str_size:数据长度
|
||||||
|
* @retval 无
|
||||||
|
*/
|
||||||
|
void error(const char *str, int str_size){
|
||||||
|
// app_printf("\r\nError: ");
|
||||||
|
// cm_uart_write(CM_UART_DEV_0, (void*)str, str_size, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief error 在解码出错时输出提示消息
|
||||||
|
* @param str: 要输出的字符串,str_size:数据长度
|
||||||
|
* @retval 无
|
||||||
|
*/
|
||||||
|
// void gps_info(const char *str, int str_size){
|
||||||
|
// app_printf("\r\nInfo: ");
|
||||||
|
// cm_uart_write(CM_UART_DEV_0, (void*)str, str_size, 1000);
|
||||||
|
// }
|
||||||
|
|
||||||
|
gps_data_t gps_data;
|
||||||
|
static nmeaPARSER parser;
|
||||||
|
|
||||||
/* 串口接收处理任务,平时使用信号量挂起,当收到接收事件后,释放信号量以触发读取任务 */
|
/* 串口接收处理任务,平时使用信号量挂起,当收到接收事件后,释放信号量以触发读取任务 */
|
||||||
static void gps_TaskHandle(void *param){
|
static void gps_TaskHandle(void *param){
|
||||||
int temp_len = 0;
|
int temp_len = 0;
|
||||||
int it = 0;
|
int it = 0;
|
||||||
// nmeaPOS dpos;
|
|
||||||
nmeaINFO info;
|
|
||||||
nmeaPARSER parser;
|
|
||||||
|
|
||||||
nmea_zero_INFO(&info);
|
/* 设置用于输出调试信息的函数 */
|
||||||
|
nmea_property()->trace_func = &trace;
|
||||||
|
nmea_property()->error_func = &error;
|
||||||
|
// nmea_property()->info_func = &gps_info;
|
||||||
|
|
||||||
|
gps_data.flow_num =0;
|
||||||
|
nmea_zero_INFO(&gps_data.info);
|
||||||
nmea_parser_init(&parser);
|
nmea_parser_init(&parser);
|
||||||
while(1){
|
while(1){
|
||||||
if(gps_uart_sem != NULL){
|
if(gps_uart_sem != NULL){
|
||||||
osSemaphoreAcquire(gps_uart_sem, osWaitForever);//阻塞
|
osSemaphoreAcquire(gps_uart_sem, osWaitForever);//阻塞
|
||||||
}
|
}
|
||||||
temp_len = cm_uart_read(GPS_URAT, (void*)&gps_rev_data[gps_rev_len], GPS_BUF_LEN, 1000);
|
temp_len = cm_uart_read(GPS_URAT, (void*)&gps_rev_data[gps_rev_len], GPS_BUF_LEN, 1000);
|
||||||
if(temp_len > 0){
|
gps_rev_len += temp_len;
|
||||||
|
if(gps_rev_len > 480){
|
||||||
nmea_parse(&parser, gps_rev_data, temp_len, &info);
|
nmea_parse(&parser, gps_rev_data, gps_rev_len, &gps_data.info);
|
||||||
// nmea_info2pos(&info, &dpos);
|
nmea_info2pos(&gps_data.info, &gps_data.dpos);
|
||||||
|
gps_data.flow_num++;
|
||||||
// app_printf(
|
|
||||||
// "%03d, Lat: %f, Lon: %f, Sig: %d, Fix: %d, RL= %d\n",
|
|
||||||
// it++, dpos.lat, dpos.lon, info.sig, info.fix, temp_len
|
|
||||||
// );
|
|
||||||
app_printf(
|
app_printf(
|
||||||
"%03d, Lat: %f, Lon: %f, Sig: %d, Fix: %d, RL= %d\n",
|
"\nGPS:%03d,Lat:%.02f,Lon:%.02f,Sig:%d,Fix:%d,RL=%d\n",
|
||||||
it++, info.lat, info.lon, info.sig, info.fix, temp_len
|
it++, gps_data.info.lat, gps_data.info.lon, gps_data.info.sig, gps_data.info.fix, gps_rev_len
|
||||||
);
|
);
|
||||||
// cm_uart_write(CM_UART_DEV_0, gps_rev_data, temp_len, 1000);
|
|
||||||
memset((void*)gps_rev_data, 0, temp_len);
|
if((gps_data.info.fix == 1)||(gps_data.info.sig == 0)){ // 不可用
|
||||||
|
// app_printf("GPS no locate!\n");
|
||||||
|
led_set_event(EVENT_GPS_NO_LOCATE);
|
||||||
|
}else{
|
||||||
|
// app_printf("GPS locate success!\n");
|
||||||
|
led_set_event(EVENT_GPS_LOCATE_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset((void*)gps_rev_data, 0, gps_rev_len);
|
||||||
temp_len = 0;
|
temp_len = 0;
|
||||||
gps_rev_len = 0;
|
gps_rev_len = 0;
|
||||||
}
|
}
|
||||||
// temp_len = cm_uart_read(GPS_URAT, (void*)&gps_rev_data[gps_rev_len], GPS_BUF_LEN - gps_rev_len, 1000);
|
|
||||||
// if(gps_rev_len < GPS_BUF_LEN){
|
|
||||||
// gps_rev_len += temp_len;
|
|
||||||
// }else{
|
|
||||||
// gps_rev_len = 0;
|
|
||||||
// }
|
|
||||||
// app_printf("uart rev data len = %d\n", gps_rev_len);
|
|
||||||
|
|
||||||
// if (gps_uart_sem != NULL && (strstr(gps_rev_data, "\r\n"))){
|
|
||||||
// //处理收到数据事件
|
|
||||||
// cm_uart_write(GPS_URAT, gps_rev_data, gps_rev_len, 1000);
|
|
||||||
|
|
||||||
// memset((void*)gps_rev_data, 0, sizeof(gps_rev_data));
|
|
||||||
// gps_rev_len = 0;
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
// nmea_parser_destroy(&parser);
|
// nmea_parser_destroy(&parser);
|
||||||
}
|
}
|
||||||
|
|
@ -138,7 +163,7 @@ void gps_config_init(void){
|
||||||
// 串口接收处理任务
|
// 串口接收处理任务
|
||||||
osThreadAttr_t gps_task_attr = {0};
|
osThreadAttr_t gps_task_attr = {0};
|
||||||
gps_task_attr.name = "gps_uart_task";
|
gps_task_attr.name = "gps_uart_task";
|
||||||
gps_task_attr.stack_size = 2048;
|
gps_task_attr.stack_size = 4096 * 4;
|
||||||
gps_task_attr.priority= osPriorityNormal;
|
gps_task_attr.priority= osPriorityNormal;
|
||||||
|
|
||||||
GPS_ThreadId= osThreadNew(gps_TaskHandle, 0, &gps_task_attr);
|
GPS_ThreadId= osThreadNew(gps_TaskHandle, 0, &gps_task_attr);
|
||||||
|
|
@ -161,3 +186,115 @@ void gps_config_close(void){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 判断闰年(仅针对于2000以后的年份)
|
||||||
|
// iYear 两位年数
|
||||||
|
// 1:为闰年 0:为平年
|
||||||
|
static uint8_t IsLeapYear(uint8_t iYear){
|
||||||
|
uint16_t Year;
|
||||||
|
Year = 2000 + iYear;
|
||||||
|
if ((Year & 3) == 0){
|
||||||
|
return ((Year % 400 == 0) || (Year % 100 != 0));
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 格林尼治时间换算世界各时区时间
|
||||||
|
// *DT: 表示日期时间的数组 格式 YY,MM,DD,HH,MM,SS
|
||||||
|
// GMT: 时区数
|
||||||
|
// AREA: 1(+)东区 W0(-)西区
|
||||||
|
void GMTconvert(nmeaTIME *SourceTime, nmeaTIME *ConvertTime, uint8_t GMT, uint8_t AREA){
|
||||||
|
uint32_t YY, MM, DD, hh, mm, ss; // 年月日时分秒暂存变量
|
||||||
|
|
||||||
|
if (GMT == 0)
|
||||||
|
return; // 如果处于0时区直接返回
|
||||||
|
if (GMT > 12)
|
||||||
|
return; // 时区最大为12 超过则返回
|
||||||
|
|
||||||
|
YY = SourceTime->year; // 获取年
|
||||||
|
MM = SourceTime->mon; // 获取月
|
||||||
|
DD = SourceTime->day; // 获取日
|
||||||
|
hh = SourceTime->hour; // 获取时
|
||||||
|
mm = SourceTime->min; // 获取分
|
||||||
|
ss = SourceTime->sec; // 获取秒
|
||||||
|
|
||||||
|
if(AREA){ // 东(+)时区处理
|
||||||
|
if(hh + GMT < 24){
|
||||||
|
hh += GMT; // 如果与格林尼治时间处于同一天则仅加小时即可
|
||||||
|
}else{ // 如果已经晚于格林尼治时间1天则进行日期处理
|
||||||
|
hh = hh + GMT - 24; // 先得出时间
|
||||||
|
if(MM == 1 || MM == 3 || MM == 5 || MM == 7 || MM == 8 || MM == 10){ // 大月份(12月单独处理)
|
||||||
|
if(DD < 31){
|
||||||
|
DD++;
|
||||||
|
}else{
|
||||||
|
DD = 1;
|
||||||
|
MM++;
|
||||||
|
}
|
||||||
|
}else if(MM == 4 || MM == 6 || MM == 9 || MM == 11){ // 小月份2月单独处理)
|
||||||
|
if(DD < 30){
|
||||||
|
DD++;
|
||||||
|
}else{
|
||||||
|
DD = 1;
|
||||||
|
MM++;
|
||||||
|
}
|
||||||
|
}else if (MM == 2){ // 处理2月份
|
||||||
|
if((DD == 29) || (DD == 28 && IsLeapYear(YY) == 0)){ // 本来是闰年且是2月29日 或者不是闰年且是2月28日
|
||||||
|
DD = 1;
|
||||||
|
MM++;
|
||||||
|
}else{
|
||||||
|
DD++;
|
||||||
|
}
|
||||||
|
}else if (MM == 12){ // 处理12月份
|
||||||
|
if (DD < 31){
|
||||||
|
DD++;
|
||||||
|
}else{ // 跨年最后一天
|
||||||
|
DD = 1;
|
||||||
|
MM = 1;
|
||||||
|
YY++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if(hh >= GMT){
|
||||||
|
hh -= GMT; // 如果与格林尼治时间处于同一天则仅减小时即可
|
||||||
|
}else{ // 如果已经早于格林尼治时间1天则进行日期处理
|
||||||
|
hh = hh + 24 - GMT; // 先得出时间
|
||||||
|
if(MM == 2 || MM == 4 || MM == 6 || MM == 8 || MM == 9 || MM == 11){ // 上月是大月份(1月单独处理)
|
||||||
|
if(DD > 1){
|
||||||
|
DD--;
|
||||||
|
}else{
|
||||||
|
DD = 31;
|
||||||
|
MM--;
|
||||||
|
}
|
||||||
|
}else if(MM == 5 || MM == 7 || MM == 10 || MM == 12){ // 上月是小月份2月单独处理)
|
||||||
|
if(DD > 1){
|
||||||
|
DD--;
|
||||||
|
}else{
|
||||||
|
DD = 30;
|
||||||
|
MM--;
|
||||||
|
}
|
||||||
|
}else if(MM == 3){ // 处理上个月是2月份
|
||||||
|
if((DD == 1) && IsLeapYear(YY) == 0){ // 不是闰年
|
||||||
|
DD = 28;
|
||||||
|
MM--;
|
||||||
|
}else{
|
||||||
|
DD--;
|
||||||
|
}
|
||||||
|
}else if(MM == 1){ // 处理1月份
|
||||||
|
if(DD > 1){
|
||||||
|
DD--;
|
||||||
|
}else{ // 新年第一天
|
||||||
|
DD = 31;
|
||||||
|
MM = 12;
|
||||||
|
YY--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ConvertTime->year = YY; // 更新年
|
||||||
|
ConvertTime->mon = MM; // 更新月
|
||||||
|
ConvertTime->day = DD; // 更新日
|
||||||
|
ConvertTime->hour = hh; // 更新时
|
||||||
|
ConvertTime->min = mm; // 更新分
|
||||||
|
ConvertTime->sec = ss; // 更新秒
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
CUSTOM_MAIN_DIR := custom/adc_dac
|
||||||
|
|
||||||
|
OC_FILES += $(CUSTOM_MAIN_DIR)/src/adc_dac.c
|
||||||
|
|
||||||
|
INC += -I'$(CUSTOM_MAIN_DIR)/inc'
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
#ifndef __ADC_DAC_H__
|
||||||
|
#define __ADC_DAC_H__
|
||||||
|
#include "cm_os.h"
|
||||||
|
|
||||||
|
|
||||||
|
void adc_dac_init(void);
|
||||||
|
|
||||||
|
#endif //__ADC_DAC_H__
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
#include "adc_dac.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "cm_adc.h"
|
||||||
|
#include "cm_gpio.h"
|
||||||
|
#include "cm_iomux.h"
|
||||||
|
#include "cm_pwm.h"
|
||||||
|
|
||||||
|
#define ADC_DAC_DEBUG_ENABLE 1
|
||||||
|
|
||||||
|
#if ADC_DAC_DEBUG_ENABLE
|
||||||
|
#include "app_uart.h"
|
||||||
|
#define DEBUG(fmt, args...) app_printf("[ADC]" fmt, ##args)
|
||||||
|
#else
|
||||||
|
#define DEBUG(fmt, arg...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define PWM0_IOMUX CM_IOMUX_PIN_74, CM_IOMUX_FUNC_FUNCTION1
|
||||||
|
#define PWM1_IOMUX CM_IOMUX_PIN_75, CM_IOMUX_FUNC_FUNCTION1
|
||||||
|
#define PWM2_IOMUX CM_IOMUX_PIN_21, CM_IOMUX_FUNC_FUNCTION2
|
||||||
|
#define PWM3_IOMUX 0, 0
|
||||||
|
|
||||||
|
osThreadId_t adc_dac_TaskHandle = NULL;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
ADC_power = 0,
|
||||||
|
ADC_acc = 1,
|
||||||
|
}adc_chx_t;
|
||||||
|
|
||||||
|
int32_t get_voltage(adc_chx_t chx){
|
||||||
|
int32_t voltage = 0;
|
||||||
|
if(chx == ADC_acc){
|
||||||
|
cm_gpio_set_level(CM_GPIO_NUM_20, 1);
|
||||||
|
}else if(chx == ADC_power){
|
||||||
|
cm_gpio_set_level(CM_GPIO_NUM_20, 0);
|
||||||
|
}else{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
osDelay(1);//5ms
|
||||||
|
if(0 != cm_adc_read(CM_ADC_0,&voltage)){
|
||||||
|
DEBUG("ADC read fail\r\n");
|
||||||
|
voltage = 0;
|
||||||
|
}
|
||||||
|
// cm_gpio_set_level(CM_GPIO_NUM_20, 1); //恢复默认状态
|
||||||
|
return voltage;
|
||||||
|
}
|
||||||
|
|
||||||
|
void adc_dac_task(void *argument){
|
||||||
|
while(1){
|
||||||
|
DEBUG("ADC_acc:%d\r\n",get_voltage(ADC_acc));
|
||||||
|
DEBUG("ADC_power:%d\r\n\n",get_voltage(ADC_power));
|
||||||
|
osDelay(500/5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void adc_dac_init(void){
|
||||||
|
cm_gpio_cfg_t cfg = {0};
|
||||||
|
cfg.direction = CM_GPIO_DIRECTION_OUTPUT;
|
||||||
|
cfg.pull = CM_GPIO_PULL_UP;
|
||||||
|
cm_iomux_set_pin_func(CM_IOMUX_PIN_86, CM_IOMUX_FUNC_FUNCTION2);//初始化之前一定要先设置引脚复用
|
||||||
|
cm_gpio_init(CM_GPIO_NUM_20, &cfg);
|
||||||
|
cm_gpio_set_level(CM_GPIO_NUM_20, 1);
|
||||||
|
|
||||||
|
// pwm init
|
||||||
|
cm_iomux_set_pin_func(PWM0_IOMUX);
|
||||||
|
if(0 != cm_pwm_set_clk(CM_PWM_DEV_0, CM_PWM_CLK_12800K)){//时钟源选择需要放在open之前
|
||||||
|
DEBUG("pwm0 set clk fail\r\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(0 != cm_pwm_open_ns(CM_PWM_DEV_0, 100000,30000)){ //设置频率为10KHz,占空比为30%
|
||||||
|
DEBUG("pwm0 open error\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
osThreadAttr_t adc_dac_task_attr = {0};
|
||||||
|
adc_dac_task_attr.name = "adc_dac_task";
|
||||||
|
adc_dac_task_attr.stack_size = 1024;
|
||||||
|
adc_dac_task_attr.priority = osPriorityNormal;
|
||||||
|
|
||||||
|
adc_dac_TaskHandle = osThreadNew((osThreadFunc_t)adc_dac_task,0,&adc_dac_task_attr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -7,4 +7,7 @@ include $(CUSTOM_DIR)/custom_main/custom_main.mk
|
||||||
include $(CUSTOM_DIR)/nmealib/nmealib.mk
|
include $(CUSTOM_DIR)/nmealib/nmealib.mk
|
||||||
include $(CUSTOM_DIR)/GPS/gps.mk
|
include $(CUSTOM_DIR)/GPS/gps.mk
|
||||||
include $(CUSTOM_DIR)/jt808/jt808.mk
|
include $(CUSTOM_DIR)/jt808/jt808.mk
|
||||||
|
include $(CUSTOM_DIR)/tcp_client/tcp_client.mk
|
||||||
|
include $(CUSTOM_DIR)/adc_dac/adc_dac.mk
|
||||||
|
include $(CUSTOM_DIR)/local_tts/local_tts.mk
|
||||||
endif
|
endif
|
||||||
|
|
@ -43,8 +43,24 @@ typedef enum{
|
||||||
RET_SUCCESS = 0
|
RET_SUCCESS = 0
|
||||||
}CM_RET_E;
|
}CM_RET_E;
|
||||||
|
|
||||||
|
typedef enum{
|
||||||
|
EVENT_NETWORK_READY = 0x00000001,
|
||||||
|
EVENT_NETWORK_DISCONNECT = 0x00000002,
|
||||||
|
EVENT_GPS_LOCATE_SUCCESS = 0x00000004,
|
||||||
|
EVENT_GPS_NO_LOCATE = 0x00000008,
|
||||||
|
EVENT_ERROR = 0x80000000,
|
||||||
|
}led_event_t;
|
||||||
|
|
||||||
|
typedef union{
|
||||||
|
struct{
|
||||||
|
uint8_t network_ready : 1;
|
||||||
|
uint8_t gps_ready : 1;
|
||||||
|
uint8_t reserved : 6;
|
||||||
|
};
|
||||||
|
uint32_t val8;
|
||||||
|
}led_status_t;
|
||||||
|
|
||||||
|
void led_set_event(led_event_t event);
|
||||||
|
|
||||||
#endif /* __APP_COMMON_H__ */
|
#endif /* __APP_COMMON_H__ */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,88 +12,281 @@
|
||||||
#include "cm_rtc.h"
|
#include "cm_rtc.h"
|
||||||
#include "cm_gpio.h"
|
#include "cm_gpio.h"
|
||||||
#include "cm_iomux.h"
|
#include "cm_iomux.h"
|
||||||
// #include "cm_demo_i2c.h"
|
#include "cm_modem.h"
|
||||||
// #include "cm_demo_adc.h"
|
|
||||||
// #include "cm_demo_spi.h"
|
|
||||||
// #include "cm_demo_lcd.h"
|
|
||||||
// #include "cm_demo_gpio.h"
|
|
||||||
// #include "cm_demo_keypad.h"
|
|
||||||
// #include "cm_demo_pwm.h"
|
|
||||||
// #include "cm_demo_pm.h"
|
|
||||||
// #include "cm_demo_http.h"
|
|
||||||
// #include "cm_demo_mqtt.h"
|
|
||||||
// #include "cm_demo_ntp.h"
|
|
||||||
// #include "cm_demo_fota.h"
|
|
||||||
// #include "cm_demo_audio.h"
|
|
||||||
// #include "cm_demo_virt_at.h"
|
|
||||||
// #include "cm_demo_lbs.h"
|
|
||||||
// #include "cm_demo_tts.h"
|
|
||||||
// #include "cm_modem.h"
|
|
||||||
// #include "cm_demo_cJSON.h"
|
|
||||||
// #include "cm_demo_sd.h"
|
|
||||||
// #include "cm_demo_gnss.h"
|
|
||||||
// #include "cm_demo_aliyun.h"
|
|
||||||
// #include "cm_demo_wifiscan.h"
|
|
||||||
// #include "cm_demo_camera.h"
|
|
||||||
// #include "cm_demo_ftp.h"
|
|
||||||
// #include "cm_demo_lwip.h"
|
|
||||||
// #include "cm_demo_ssl.h"
|
|
||||||
#include "app_uart.h"
|
#include "app_uart.h"
|
||||||
#include "gps_config.h"
|
#include "gps_config.h"
|
||||||
#include "client_manager.h"
|
#include "app_common.h"
|
||||||
#include "jt808_packager.h"
|
|
||||||
|
#include "jt808_msg_pkg.h"
|
||||||
|
#include "jt808_msg_parse.h"
|
||||||
|
#include "jt808_pkg_transmit.h"
|
||||||
|
#include "tcp_client.h"
|
||||||
|
|
||||||
|
#include "local_tts.h"
|
||||||
|
|
||||||
|
#define SECOND_OF_DAY (24*60*60)
|
||||||
|
|
||||||
|
typedef struct cm_tm {
|
||||||
|
int tm_sec; /* 秒 – 取值区间为[0,59] */
|
||||||
|
int tm_min; /* 分 - 取值区间为[0,59] */
|
||||||
|
int tm_hour; /* 时 - 取值区间为[0,23] */
|
||||||
|
int tm_mday; /* 一个月中的日期 - 取值区间为[1,31] */
|
||||||
|
int tm_mon; /* 月份 */
|
||||||
|
int tm_year; /* 年份 */
|
||||||
|
}cm_tm_t;
|
||||||
|
|
||||||
|
// static const char * weekday[] = {"Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"};
|
||||||
|
// static const char DayOfMon[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
|
||||||
|
|
||||||
|
|
||||||
osThreadId_t OC_APP_TaskHandle;
|
osThreadId_t OC_APP_TaskHandle;
|
||||||
|
|
||||||
|
|
||||||
|
// void oc_ring_cb(unsigned char *param)
|
||||||
|
// {
|
||||||
|
// if(0 == strncmp((char *)param, "\r\nRING",6))//来电提示
|
||||||
|
// {
|
||||||
|
// app_printf("oc_ring_cb:%s\n",param);
|
||||||
|
// }
|
||||||
|
// else if (0 == strncmp((char *)param, "\r\n+CLCC:",8)) //来电信息
|
||||||
|
// {
|
||||||
|
// app_printf("oc_ring_cb:%s\n",param);
|
||||||
|
// }
|
||||||
|
// else if(0 == strncmp((char *)param, "\r\nNO CARRIER",12))//对方挂断
|
||||||
|
// {
|
||||||
|
// app_printf("oc_ring_cb:%s\n",param);
|
||||||
|
// }
|
||||||
|
// if (0 == strncmp((char *)param, "\r\n+CMTI:",8))//短信信息
|
||||||
|
// {
|
||||||
|
// app_printf("message:%s\n",param);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// static void cm_sec_to_date(long lSec, cm_tm_t *tTime)
|
||||||
|
// {
|
||||||
|
// unsigned short i,j,iDay;
|
||||||
|
// unsigned long lDay;
|
||||||
|
|
||||||
|
// lDay = lSec / SECOND_OF_DAY;
|
||||||
|
// lSec = lSec % SECOND_OF_DAY;
|
||||||
|
|
||||||
|
// i = 1970;
|
||||||
|
// while(lDay > 365)
|
||||||
|
// {
|
||||||
|
// if(((i%4==0)&&(i%100!=0)) || (i%400==0))
|
||||||
|
// {
|
||||||
|
// lDay -= 366;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// lDay -= 365;
|
||||||
|
// }
|
||||||
|
// i++;
|
||||||
|
// }
|
||||||
|
// if((lDay == 365) && !(((i%4==0)&&(i%100!=0)) || (i%400==0)))
|
||||||
|
// {
|
||||||
|
// lDay -= 365;
|
||||||
|
// i++;
|
||||||
|
// }
|
||||||
|
// tTime->tm_year = i;
|
||||||
|
// for(j=0;j<12;j++)
|
||||||
|
// {
|
||||||
|
// if((j==1) && (((i%4==0)&&(i%100!=0)) || (i%400==0)))
|
||||||
|
// {
|
||||||
|
// iDay = 29;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// iDay = DayOfMon[j];
|
||||||
|
// }
|
||||||
|
// if(lDay >= iDay) lDay -= iDay;
|
||||||
|
// else break;
|
||||||
|
// }
|
||||||
|
// tTime->tm_mon = j+1;
|
||||||
|
// tTime->tm_mday = lDay+1;
|
||||||
|
// tTime->tm_hour = ((lSec / 3600))%24;//这里注意,世界时间已经加上北京时间差8,
|
||||||
|
// tTime->tm_min = (lSec % 3600) / 60;
|
||||||
|
// tTime->tm_sec = (lSec % 3600) % 60;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// static uint8_t cm_time_to_weekday(cm_tm_t *t)
|
||||||
|
// {
|
||||||
|
// uint32_t u32WeekDay = 0;
|
||||||
|
// uint32_t u32Year = t->tm_year;
|
||||||
|
// uint8_t u8Month = t->tm_mon;
|
||||||
|
// uint8_t u8Day = t->tm_mday;
|
||||||
|
// if(u8Month < 3U)
|
||||||
|
// {
|
||||||
|
// /*D = { [(23 x month) / 9] + day + 4 + year + [(year - 1) / 4] - [(year - 1) / 100] + [(year - 1) / 400] } mod 7*/
|
||||||
|
// u32WeekDay = (((23U * u8Month) / 9U) + u8Day + 4U + u32Year + ((u32Year - 1U) / 4U) - ((u32Year - 1U) / 100U) + ((u32Year - 1U) / 400U)) % 7U;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// /*D = { [(23 x month) / 9] + day + 4 + year + [year / 4] - [year / 100] + [year / 400] - 2 } mod 7*/
|
||||||
|
// u32WeekDay = (((23U * u8Month) / 9U) + u8Day + 4U + u32Year + (u32Year / 4U) - (u32Year / 100U) + (u32Year / 400U) - 2U ) % 7U;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (0U == u32WeekDay)
|
||||||
|
// {
|
||||||
|
// u32WeekDay = 7U;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return (uint8_t)u32WeekDay;
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
void print_network_info(void){
|
||||||
|
cm_cereg_state_t cereg_state = {0};
|
||||||
|
|
||||||
|
if(0 == cm_modem_get_cpin()){
|
||||||
|
app_printf("sim card ready!\r\n\n");
|
||||||
|
}else{
|
||||||
|
app_printf("sim card not ready!\r\n\n");
|
||||||
|
}
|
||||||
|
if(0 ==cm_modem_get_cereg_state(&cereg_state)){ // 获取PS网络注册状态
|
||||||
|
app_printf("cereg_state:%d\n",cereg_state.state); // 注册状态
|
||||||
|
}else{
|
||||||
|
app_printf("cereg_get_state fail!\n\n");
|
||||||
|
}
|
||||||
|
if(cm_modem_get_pdp_state(1) == 1){ //网络就绪
|
||||||
|
app_printf("network ready\n");
|
||||||
|
}else{
|
||||||
|
app_printf("waiting for network...\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
led_status_t led_status = {0};
|
||||||
|
osEventFlagsId_t LED_EventFlags = NULL;
|
||||||
|
|
||||||
void my_appimg_enter(char *param){
|
void my_appimg_enter(char *param){
|
||||||
int isRegistered=0;
|
|
||||||
int isAuthenticated=0;
|
|
||||||
unsigned int v_alarm_value = 0;
|
|
||||||
unsigned int v_status_value = 0;
|
|
||||||
|
|
||||||
|
LED_EventFlags =osEventFlagsNew(NULL);
|
||||||
|
if(NULL == LED_EventFlags){
|
||||||
|
app_printf("LED_EventFlags create fail\n");
|
||||||
|
// return;
|
||||||
|
}
|
||||||
cm_gpio_cfg_t cfg = {0};
|
cm_gpio_cfg_t cfg = {0};
|
||||||
|
|
||||||
cfg.direction = CM_GPIO_DIRECTION_OUTPUT;
|
cfg.direction = CM_GPIO_DIRECTION_OUTPUT;
|
||||||
cfg.pull = CM_GPIO_PULL_UP;
|
cfg.pull = CM_GPIO_PULL_UP;
|
||||||
|
|
||||||
cm_iomux_set_pin_func(CM_IOMUX_PIN_16, CM_IOMUX_FUNC_FUNCTION1);//初始化之前一定要先设置引脚复用
|
cm_iomux_set_pin_func(CM_IOMUX_PIN_16, CM_IOMUX_FUNC_FUNCTION1);//初始化之前一定要先设置引脚复用
|
||||||
|
cm_gpio_init(CM_GPIO_NUM_0, &cfg);
|
||||||
|
cm_gpio_set_level(CM_GPIO_NUM_0, 0);
|
||||||
|
|
||||||
cm_gpio_init(0, &cfg);
|
// cm_iomux_set_pin_func(CM_IOMUX_PIN_77, CM_IOMUX_FUNC_FUNCTION2);//初始化之前一定要先设置引脚复用
|
||||||
cm_gpio_set_level(0, 1);
|
// cm_gpio_init(CM_GPIO_NUM_13, &cfg);
|
||||||
|
// cm_gpio_set_level(CM_GPIO_NUM_13, 0);
|
||||||
|
|
||||||
app_uart_init();
|
app_uart_init();
|
||||||
gps_config_init();
|
|
||||||
app_printf("Hello, world!\r\n");
|
app_printf("Hello, world!\r\n");
|
||||||
initSystemParameters(0);
|
// adc_dac_init();
|
||||||
//设置手机号(唯一识别id)
|
local_tts_init();
|
||||||
setUUID();
|
|
||||||
//终端注册
|
local_tts_mute(0);// 取消静音
|
||||||
if(isRegistered == 0){
|
local_tts_volume(10); // 设置音量为5
|
||||||
jt808TerminalRegister(&isRegistered);
|
local_tts_set(8, 15, CM_LOCAL_TTS_DIGIT_AUTO);
|
||||||
if(isRegistered==0){
|
|
||||||
// system_reboot();
|
while(1){
|
||||||
// continue;
|
|
||||||
|
cm_gpio_set_level(CM_GPIO_NUM_0, 1);
|
||||||
|
local_tts_text_play("欢迎使用莱昂特智能终端设备...。",0 ,osWaitForever); // 0:表示自动计算字符串长度,10000表示最大等待时间
|
||||||
|
// osDelay(3000/5);
|
||||||
|
cm_gpio_set_level(CM_GPIO_NUM_0, 0);
|
||||||
|
// osDelay(3000/5);
|
||||||
|
local_tts_text_play("欢迎使用游园猫,您的专属智能向导。",0 ,osWaitForever); // 0:表示自动计算字符串长度,10000表示最大等待时间
|
||||||
}
|
}
|
||||||
|
//--------------------------------------------
|
||||||
|
{
|
||||||
|
// cm_tm_t t;
|
||||||
|
// int i;
|
||||||
|
int ret;
|
||||||
|
char buf[CM_VER_LEN] = {0};
|
||||||
|
int pdp_time_out=0;
|
||||||
|
cm_fs_system_info_t info = {0, 0};
|
||||||
|
cm_heap_stats_t stats = {0};
|
||||||
|
app_printf("\n\n\n\n\n");
|
||||||
|
app_printf("CM OpenCPU Starts\n");
|
||||||
|
cm_sys_get_cm_ver(buf, CM_VER_LEN);
|
||||||
|
app_printf("SDK VERSION:%s\n", buf);
|
||||||
|
cm_fs_getinfo(&info);
|
||||||
|
cm_mem_get_heap_stats(&stats);
|
||||||
|
app_printf("fs total:%d,remain:%d\n", info.total_size, info.free_size);
|
||||||
|
app_printf("heap total:%d,remain:%d\n",stats.total_size,stats.free);
|
||||||
|
|
||||||
|
// app_printf("waiting for network...\n");
|
||||||
|
// while(1){
|
||||||
|
// if(pdp_time_out>10){
|
||||||
|
// app_printf("network timeout\n");
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// if(cm_modem_get_pdp_state(1) == 1){
|
||||||
|
// app_printf("network ready\n");
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// osDelay(200);
|
||||||
|
// pdp_time_out++;
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
||||||
|
// -----------------------------------------------------
|
||||||
|
jt808_set_term_param_init();
|
||||||
|
jt808_init();
|
||||||
|
tcp_client_init();
|
||||||
|
gps_config_init();
|
||||||
|
|
||||||
|
uint32_t led_event = 0;
|
||||||
|
while(1){
|
||||||
|
led_event = osEventFlagsWait(LED_EventFlags, 0x0000000f, osFlagsWaitAny, 0); //0等待
|
||||||
|
if (led_event & 0x80000000) { // 错误处理
|
||||||
|
// app_printf("led task error\n");
|
||||||
|
}else if(led_event & EVENT_NETWORK_READY){ // 网络就绪
|
||||||
|
app_printf("led network ready\n");
|
||||||
|
led_status.network_ready = 1;
|
||||||
|
}else if(led_event & EVENT_NETWORK_DISCONNECT){ // 网络断开
|
||||||
|
app_printf("led network disconnect\n");
|
||||||
|
led_status.network_ready = 0;
|
||||||
|
}else if(led_event & EVENT_GPS_LOCATE_SUCCESS){ // GPS定位成功
|
||||||
|
app_printf("led GPS locate success\n");
|
||||||
|
led_status.gps_ready = 1;
|
||||||
|
}else if(led_event & EVENT_GPS_NO_LOCATE){ // GPS无定位
|
||||||
|
app_printf("led GPS no locate\n");
|
||||||
|
led_status.gps_ready = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(led_status.network_ready && led_status.gps_ready){ // 网络就绪,GPS定位成功
|
||||||
|
cm_gpio_set_level(CM_GPIO_NUM_0, 1); // 常亮
|
||||||
|
osDelay(1000/5);//300ms
|
||||||
|
}else if(led_status.network_ready && (0 ==led_status.gps_ready)){ // 网络就绪,GPS无定位
|
||||||
|
cm_gpio_set_level(CM_GPIO_NUM_0, 1);
|
||||||
|
osDelay(500/5);//300ms
|
||||||
|
cm_gpio_set_level(CM_GPIO_NUM_0, 0);
|
||||||
|
osDelay(500/5);//300ms
|
||||||
|
}else if((0 ==led_status.network_ready) && led_status.gps_ready){ // 网络断开,GPS定位成功
|
||||||
|
for(int i=0;i<5;i++){ // 快闪500ms,灭500ms
|
||||||
|
cm_gpio_set_level(CM_GPIO_NUM_0, 1);
|
||||||
|
osDelay(100/5);//300ms
|
||||||
|
cm_gpio_set_level(CM_GPIO_NUM_0, 0);
|
||||||
|
osDelay(100/5);//300ms
|
||||||
|
}
|
||||||
|
cm_gpio_set_level(CM_GPIO_NUM_0, 0);
|
||||||
|
osDelay(500/5);//300ms
|
||||||
|
}else{ // 网络断开,GPS无定位
|
||||||
|
cm_gpio_set_level(CM_GPIO_NUM_0, 1); // 快闪
|
||||||
|
osDelay(100/5);//300ms
|
||||||
|
cm_gpio_set_level(CM_GPIO_NUM_0, 0);
|
||||||
|
osDelay(100/5);//300ms
|
||||||
}
|
}
|
||||||
//终端鉴权
|
|
||||||
if(isAuthenticated == 0){
|
|
||||||
jt808TerminalAuthentication(&isAuthenticated);
|
|
||||||
if(isAuthenticated==0){
|
|
||||||
// system_reboot();
|
|
||||||
// continue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//设置位置上报警报位、状态位
|
void led_set_event(led_event_t event){
|
||||||
initLocationInfo(v_alarm_value, v_status_value);
|
if(NULL == LED_EventFlags){
|
||||||
setStatusBit();
|
app_printf("LED_EventFlags is NULL\n");
|
||||||
while(1){
|
return;
|
||||||
osDelay(200/5);//300ms
|
|
||||||
cm_gpio_set_level(0, 1);
|
|
||||||
osDelay(200/5);//300ms
|
|
||||||
cm_gpio_set_level(0, 0);
|
|
||||||
// app_printf("Hello, world!\r\n");
|
|
||||||
}
|
}
|
||||||
|
osEventFlagsSet(LED_EventFlags, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -101,11 +294,10 @@ int cm_opencpu_entry(char * param)
|
||||||
{
|
{
|
||||||
osThreadAttr_t app_task_attr = {0};
|
osThreadAttr_t app_task_attr = {0};
|
||||||
app_task_attr.name = "main_task";
|
app_task_attr.name = "main_task";
|
||||||
app_task_attr.stack_size = 4096 * 2;
|
app_task_attr.stack_size = 4096 * 4;
|
||||||
app_task_attr.priority = osPriorityNormal;
|
app_task_attr.priority = osPriorityNormal;
|
||||||
|
|
||||||
OC_APP_TaskHandle = osThreadNew((osThreadFunc_t)my_appimg_enter,0,&app_task_attr);
|
OC_APP_TaskHandle = osThreadNew((osThreadFunc_t)my_appimg_enter,0,&app_task_attr);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
#ifndef _JT808_CONFIG_H_
|
||||||
|
#define _JT808_CONFIG_H_
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "jt808_util.h"
|
||||||
|
|
||||||
|
#define JT808_DEBUG_ENABLE 1
|
||||||
|
|
||||||
|
#if JT808_DEBUG_ENABLE
|
||||||
|
#include "app_uart.h"
|
||||||
|
#define JT808_DEBUG(fmt, args...) app_printf("[JT808]" fmt, ##args)
|
||||||
|
#else
|
||||||
|
#define JT808_DEBUG(fmt, arg...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#include "cm_mem.h"
|
||||||
|
#define jt808_malloc(size) cm_malloc(size)
|
||||||
|
#define jt808_realloc(ptr, size) cm_realloc(ptr, size)
|
||||||
|
#define jt808_free(ptr) cm_free(ptr)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
#ifndef _JT808_DEBUG_H_
|
|
||||||
#define _JT808_DEBUG_H_
|
|
||||||
|
|
||||||
#define JT808_DEBUG_ENABLE 1
|
|
||||||
|
|
||||||
#if JT808_DEBUG_ENABLE
|
|
||||||
#include "app_uart.h"
|
|
||||||
#define JT808_DEBUG(fmt, args...) app_printf("[JT808]" fmt, ##args)
|
|
||||||
#else
|
|
||||||
#define JT808_DEBUG(fmt, arg...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __JT808_PKG_PARSE__
|
||||||
|
#define __JT808_PKG_PARSE__
|
||||||
|
#include "jt808_protocol.h"
|
||||||
|
#include "jt808_set_TermParam.h"
|
||||||
|
#include "jt808_config.h"
|
||||||
|
|
||||||
|
#pragma pack(1)
|
||||||
|
// 解析结果以及终端参数项
|
||||||
|
typedef struct{
|
||||||
|
uint16_t Rsp_flow_num; //应答流水号
|
||||||
|
uint16_t Rsp_msg_id; // 应答消息ID
|
||||||
|
uint8_t Rsp_result; // 应答结果
|
||||||
|
MsgHead_t msg_head; // 解析的消息头
|
||||||
|
Term_Param_item_t *term_param_item; // 终端参数项
|
||||||
|
}PrsResult_t;
|
||||||
|
#pragma pack()
|
||||||
|
|
||||||
|
// ------------------------------- 全局变量声明 ----------
|
||||||
|
extern PrsResult_t PrsResult; // 解析结果以及终端参数项
|
||||||
|
|
||||||
|
int jt808_msg_parse(const uint8_t *BufferReceive, uint16_t length, PrsResult_t *PrsResult);
|
||||||
|
|
||||||
|
#endif // __JT808_PKG_PARSE__
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
#ifndef __JT808_PKG_PKG__
|
||||||
|
#define __JT808_PKG_PKG__
|
||||||
|
#include "jt808_protocol.h"
|
||||||
|
#include "jt808_config.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t *buf; // 打包后的消息帧
|
||||||
|
uint16_t len; // 打包后的消息帧长度
|
||||||
|
} JT808MsgESC_t;
|
||||||
|
|
||||||
|
// 消息帧打包 (会自动为msgEscape->buf分配合适长度的内存,注意释放)
|
||||||
|
int jt808_msg_pkg(MessageID_t Msg_ID, JT808MsgESC_t *msgEscape);
|
||||||
|
|
||||||
|
#endif // __JT808_PKG_PKG__
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
#ifndef _JT808_PKG_TRANSMIT_H_
|
||||||
|
#define _JT808_PKG_TRANSMIT_H_
|
||||||
|
#include "jt808_msg_pkg.h"
|
||||||
|
#include "jt808_msg_parse.h"
|
||||||
|
#include "jt808_config.h"
|
||||||
|
#include "tcp_client.h"
|
||||||
|
|
||||||
|
// #pragma pack(1)
|
||||||
|
typedef struct{
|
||||||
|
uint16_t msg_id;
|
||||||
|
uint32_t timeout; //超时时间,单位ms
|
||||||
|
}pkg_msg_t;
|
||||||
|
// #pragma pack()
|
||||||
|
|
||||||
|
// 原型 :int tcp_client_send(const char *buf, int len);
|
||||||
|
#ifdef __TCP_CLIENT_H__
|
||||||
|
#define PKG_SEND(__buf, __len) tcp_client_send(__buf, __len)
|
||||||
|
#else
|
||||||
|
#define PKG_SEND(__buf, __len) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern PrsResult_t PrsResult;
|
||||||
|
|
||||||
|
// 触发消息发送
|
||||||
|
int jt808_pkg_send(MessageID_t Msg_ID, uint32_t timeout);
|
||||||
|
|
||||||
|
// 接收处理 (放入TCP接收回调中)
|
||||||
|
void jt808_pkg_handle(uint8_t *receive_buf, uint16_t receive_len);
|
||||||
|
|
||||||
|
// jt808协议初始化
|
||||||
|
int jt808_init(void);
|
||||||
|
|
||||||
|
#endif // _JT808_PKG_TRANSMIT_H_
|
||||||
|
|
@ -0,0 +1,331 @@
|
||||||
|
#ifndef __JT808_PROTOCOL__
|
||||||
|
#define __JT808_PROTOCOL__
|
||||||
|
#include "jt808_config.h"
|
||||||
|
|
||||||
|
// 已支持的消息ID
|
||||||
|
typedef enum {
|
||||||
|
ID_Term_GenResp = 0x0001, // 终端通用应答
|
||||||
|
ID_Plat_GenResp = 0x8001, // 平台通用应答
|
||||||
|
ID_Term_HB = 0x0002, // 终端心跳
|
||||||
|
ID_FillPktReq = 0x8003, // 补传分包请求
|
||||||
|
ID_Term_Reg = 0x0100, // 终端注册
|
||||||
|
ID_Term_RegResp = 0x8100, // 终端注册应答
|
||||||
|
ID_Term_Logout = 0x0003, // 终端注销
|
||||||
|
ID_Term_Auth = 0x0102, // 终端鉴权
|
||||||
|
ID_SetTermParams = 0x8103, // 设置终端参数
|
||||||
|
ID_GetTermParams = 0x8104, // 查询终端参数
|
||||||
|
ID_GetTermParamsResp = 0x0104, // 查询终端参数应答
|
||||||
|
ID_Term_Ctrl = 0x8105, // 终端控制
|
||||||
|
ID_GetSpecificTermParams = 0x8106,// 查询指定终端参数
|
||||||
|
ID_GetTermAttr = 0x8107, // 查询终端属性
|
||||||
|
ID_GetTermAttrResp = 0x0107, // 查询终端属性应答
|
||||||
|
ID_Term_Upgrade = 0x8108, // 下发终端升级包
|
||||||
|
ID_Term_UpgradeResult = 0x0108, // 终端升级结果通知
|
||||||
|
ID_LocReport = 0x0200, // 位置信息汇报
|
||||||
|
ID_GetLocInfo = 0x8201, // 位置信息查询
|
||||||
|
ID_GetLocInfoResp = 0x0201, // 位置信息查询应答
|
||||||
|
ID_LocTrackingCtrl = 0x8202, // 临时位置跟踪控制
|
||||||
|
ID_TxtMsgdelivery = 0x8300, // 文本信息下发
|
||||||
|
ID_Car_Ctrl = 0x8500, // 车辆控制
|
||||||
|
ID_Car_CtrlResp = 0x0500, // 车辆控制应答
|
||||||
|
} MessageID_t;
|
||||||
|
|
||||||
|
#pragma pack(1)
|
||||||
|
// ----------------------------- 协议消息体结构体定义 ----------
|
||||||
|
// 终端通用应答体(0x0001)
|
||||||
|
typedef struct {
|
||||||
|
uint16_t msg_flow_num; // 对应的平台消息的流水号
|
||||||
|
uint16_t msg_id_ack; // 对应的平台消息的 ID
|
||||||
|
uint8_t result; // 结果 0:成功/确认;1:失败;2:消息有误;3:不支持
|
||||||
|
}Term_GenResp_t;
|
||||||
|
|
||||||
|
// 平台通用应答体(0x8001)
|
||||||
|
typedef struct {
|
||||||
|
uint16_t msg_flow_num; // 对应的终端消息的流水号
|
||||||
|
uint16_t msg_id_ack; // 对应的终端消息的 ID
|
||||||
|
uint8_t result; // 结果 0:成功/确认;1:失败;2:消息有误;3:不支持
|
||||||
|
}Plat_GenResp_t;
|
||||||
|
|
||||||
|
// 终端心跳体(0x0002空包)
|
||||||
|
|
||||||
|
// 补传分包请求体(0x8003)
|
||||||
|
typedef struct {
|
||||||
|
uint16_t msg_flow_num; // 对应要求补传的原始消息第一包的消息流水号
|
||||||
|
uint8_t Total_num; // 重传包总数
|
||||||
|
uint16_t *pkt_seq; // 重传包序号顺序排列,如“包 ID1 包 ID2包 IDn”。
|
||||||
|
}FillPktReq_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
none_plate = 0, // 无牌照
|
||||||
|
blue_plate = 1, // 蓝牌
|
||||||
|
yellow_plate = 2, // 黄牌
|
||||||
|
black_plate = 3, // 黑牌
|
||||||
|
white_plate = 4, // 白牌
|
||||||
|
green_plate = 5, // 绿牌
|
||||||
|
other_plate = 6, // 其他牌照
|
||||||
|
}plate_type_t;
|
||||||
|
// 终端注册体(0x0100)
|
||||||
|
typedef struct {
|
||||||
|
uint16_t province_id;// 省域ID
|
||||||
|
uint16_t city_id;// 市县域ID
|
||||||
|
uint8_t manufacturer_id[5];// 制造商ID, 固定5个字节
|
||||||
|
uint8_t term_model[20];// 终端型号, 固定20个字节, 位数不足后补0x00
|
||||||
|
uint8_t term_id[7];// 终端ID, 固定7个字节, 位数不足后补0x00
|
||||||
|
uint8_t car_plate_color;// 车牌颜色, 0表示未上牌
|
||||||
|
uint8_t car_plate_num[10];// 车辆标识, 仅在上牌时使用
|
||||||
|
}Term_RegInfo_t;
|
||||||
|
|
||||||
|
// 终端注册应答体(0x8100)
|
||||||
|
typedef struct {
|
||||||
|
uint16_t msg_flow_num; // 对应的终端注册消息的流水号
|
||||||
|
uint8_t result; // 0:成功;1:车辆已被注册;2:数据库中无该车辆;3:终端已被注册;4:数据库中无该终端
|
||||||
|
// uint8_t *str_auth_code; //只有在成功后才有该字段
|
||||||
|
}Term_RegResp_t;
|
||||||
|
|
||||||
|
// 终端注销体(0x0003空包)
|
||||||
|
|
||||||
|
// 终端鉴权体(0x0102)
|
||||||
|
typedef struct {
|
||||||
|
void *str_auth_code; //只有在成功后才有该字段
|
||||||
|
}Term_Auth_t;
|
||||||
|
|
||||||
|
// 终端参数项数据结构体
|
||||||
|
typedef struct TermParamlist_t{
|
||||||
|
uint32_t param_id; // 参数ID
|
||||||
|
uint8_t param_len; // 参数长度
|
||||||
|
void *param_value; // 参数值
|
||||||
|
struct TermParamlist_t *next; // 下一个参数项
|
||||||
|
}TermParamlist_t;
|
||||||
|
// 设置终端参数体(0x8103)
|
||||||
|
typedef struct {
|
||||||
|
uint8_t param_Total_num; // 参数总数
|
||||||
|
TermParamlist_t *param_list; // 参数项列表
|
||||||
|
}SetTermParams_t;
|
||||||
|
|
||||||
|
// 查询终端参数体(0x8104空包)
|
||||||
|
|
||||||
|
// 查询指定终端参数体(0x8106)
|
||||||
|
typedef struct {
|
||||||
|
uint8_t param_Total_num; // 参数总数
|
||||||
|
uint32_t *param_id_list; // 参数ID列表
|
||||||
|
}GetSpecificTermParams_t;
|
||||||
|
|
||||||
|
// 查询终端参数应答体(0x0104)
|
||||||
|
typedef struct {
|
||||||
|
uint16_t msg_flow_num; // 对应的终端参数查询消息的流水号
|
||||||
|
uint8_t param_Total_num; // 参数总数
|
||||||
|
TermParamlist_t *param_list; // 参数项列表
|
||||||
|
}GetTermParamsResp_t;
|
||||||
|
|
||||||
|
// 终端控制命令字
|
||||||
|
typedef union {
|
||||||
|
struct{
|
||||||
|
uint8_t _0 : 1; //
|
||||||
|
uint8_t _1 : 1; // 无线升级
|
||||||
|
uint8_t _2 : 1; // 控制终端连接指定服务器
|
||||||
|
uint8_t _3 : 1; // 终端关机
|
||||||
|
uint8_t _4 : 1; // 终端复位
|
||||||
|
uint8_t _5 : 1; // 终端恢复出厂设置
|
||||||
|
uint8_t _6 : 1; // 关闭数据通信
|
||||||
|
uint8_t _7 : 1; // 关闭所有无线通信
|
||||||
|
};
|
||||||
|
uint8_t val8;
|
||||||
|
}Term_Ctrl_Cmd_t;
|
||||||
|
// 终端控制体(0x8105)
|
||||||
|
typedef struct {
|
||||||
|
Term_Ctrl_Cmd_t com_word; //命令字
|
||||||
|
uint8_t *str_cmd_params; //命令参数每个 STRING 字段先按 GBK 编码处理后再组成消息
|
||||||
|
}Term_Ctrl_t;
|
||||||
|
|
||||||
|
// 查询终端属性体(0x8107空包)
|
||||||
|
|
||||||
|
// 查询终端属性应答体(0x0107)
|
||||||
|
typedef struct {
|
||||||
|
uint16_t term_type; // 终端类型
|
||||||
|
uint8_t manufacturer_id[5];// 制造商ID, 固定5个字节
|
||||||
|
uint8_t term_model[20];// 终端型号, 固定20个字节, 位数不足后补0x00
|
||||||
|
uint8_t term_id[7];// 终端ID, 固定7个字节, 位数不足后补0x00
|
||||||
|
uint8_t term_ICCID[10];// ICCID,
|
||||||
|
uint8_t hw_ver_len;// 终端硬件版本号长度
|
||||||
|
uint8_t *str_hw_ver;// 终端硬件版本号
|
||||||
|
uint8_t fw_ver_len;// 终端固件版本号长度
|
||||||
|
uint8_t *str_fw_ver;// 终端固件版本号
|
||||||
|
uint8_t GnssModule_attr;// GNSS模块属性
|
||||||
|
uint8_t CommModule_attr;// 通讯模块属性
|
||||||
|
}GetTermAttrResp_t;
|
||||||
|
|
||||||
|
// 下发终端升级包体(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;// 升级包
|
||||||
|
}Term_Upgrade_t;
|
||||||
|
|
||||||
|
// 终端升级结果通知体(0x0108)
|
||||||
|
typedef struct {
|
||||||
|
uint8_t upgrade_type; // 升级类型 0:终端,12:道路运输证 IC 卡读卡器,52:北斗卫星定位模块
|
||||||
|
uint8_t upgrade_result; // 结果 0:成功,1:失败,2:取消
|
||||||
|
}Term_UpgradeResult_t;
|
||||||
|
|
||||||
|
// 报警标志位
|
||||||
|
typedef union{
|
||||||
|
struct{
|
||||||
|
uint32_t sos : 1;// bit_0 紧急报警,触动报警开关后触/收到应答后清零
|
||||||
|
uint32_t overspeed : 1;// bit_1 超速报警
|
||||||
|
uint32_t fatigue : 1;// bit_2 疲劳驾驶
|
||||||
|
uint32_t early_warning : 1;// bit_3 危险预警
|
||||||
|
uint32_t gnss_fault : 1;// bit_4 GNSS模块发生故障
|
||||||
|
uint32_t gnss_antenna_cut : 1; // bit_5 GNSS天线未接或被剪断
|
||||||
|
uint32_t gnss_antenna_shortcircuit : 1;// bit_6 GNSS天线短路
|
||||||
|
uint32_t power_low : 1;// bit_7 终端主电源欠压
|
||||||
|
uint32_t power_cut : 1;// bit_8 终端主电源掉电
|
||||||
|
uint32_t lcd_fault : 1;// bit_9 终端LCD或显示器故障
|
||||||
|
uint32_t tts_fault : 1;// bit_10 TTS模块故障
|
||||||
|
uint32_t camera_fault : 1;// bit_11 摄像头故障
|
||||||
|
uint32_t transport_license_IC_card_fault : 1;// bit_12 道路运输证 IC 卡模块故障
|
||||||
|
uint32_t overspeed_notice : 1; // bit_1 超速预警
|
||||||
|
uint32_t fatigue_notice : 1;// bit_2 疲劳驾驶预警
|
||||||
|
uint32_t retain1 : 3;// 保留3位
|
||||||
|
uint32_t day_drive_overtime : 1;// bit_18 当天累计驾驶超时
|
||||||
|
uint32_t stop_driving_overtime : 1;// bit_19 超时停车
|
||||||
|
uint32_t in_out_area : 1;// bit_20 进出区域.收到应答后清零
|
||||||
|
uint32_t in_out_road : 1; // bit_21 进出路线.收到应答后清零
|
||||||
|
uint32_t road_drive_time : 1;// bit_22 路段行驶时间不足/过长.收到应答后清零
|
||||||
|
uint32_t road_deviate : 1;// bit_23 路线偏离报警
|
||||||
|
uint32_t vss_fault : 1;// bit_24 车辆VSS故障
|
||||||
|
uint32_t oil_fault : 1;// bit_25 车辆油量异常
|
||||||
|
uint32_t car_alarm : 1;// bit_26 车辆被盗(通过车辆防盗器)
|
||||||
|
uint32_t car_acc_alarm : 1;// bit_27 车辆非法点火.收到应答后清零
|
||||||
|
uint32_t car_move : 1;// bit_28 车辆非法位移.收到应答后清零
|
||||||
|
uint32_t collision : 1;// 碰撞报警
|
||||||
|
uint32_t rollover : 1;// 侧翻报警
|
||||||
|
uint32_t Illegal_opendoor : 1;// 非法开门报警(终端未设置区域时,不判断非法开门)/收到应答后清零
|
||||||
|
};
|
||||||
|
uint32_t val32;
|
||||||
|
}LocAlarm_t;
|
||||||
|
// 状态位
|
||||||
|
typedef union{
|
||||||
|
struct{
|
||||||
|
uint32_t acc : 1;// ACC开关, 0:ACC关; 1:ACC开
|
||||||
|
uint32_t positioning : 1;// 定位标志, 0:未定位; 1:定位
|
||||||
|
uint32_t sn_latitude : 1;// 纬度半球, 0:北纬: 1:南纬
|
||||||
|
uint32_t ew_longitude : 1;// 经度半球, 0:东经; 1:西经
|
||||||
|
uint32_t operation : 1; // 0:运营状态; 1:停运状态
|
||||||
|
uint32_t gps_encrypt : 1;// 0:经纬度未经保密插件加密; 1:经纬度已经保密插件加密
|
||||||
|
uint32_t retain1 : 2;// 保留2位
|
||||||
|
uint32_t trip_status : 2;// 00: 空车; 01: 半载; 10: 保留; 11: 满载
|
||||||
|
uint32_t oil_cut : 1;// 0:车辆油路正常; 1:车辆油路断开
|
||||||
|
uint32_t circuit_cut : 1;// 0:车辆电路正常; 1:车辆电路断开
|
||||||
|
uint32_t door_lock : 1;// 0:车门解锁; 1: 车门加锁
|
||||||
|
uint32_t door1_status : 1;// 0:门1 关; 1: 门1 开; (前门)
|
||||||
|
uint32_t door2_status : 1;// 0:门2 关; 1: 门2 开; (中门)
|
||||||
|
uint32_t door3_status : 1;// 0:门 3 关; 1: 门 3 开; (后门)
|
||||||
|
|
||||||
|
uint32_t door4_status : 1;// 0:门 4 关; 1: 门 4 开; (驾驶席门)
|
||||||
|
uint32_t door5_status : 1;// 0:门 5 关; 1: 门 5 开; (自定义)
|
||||||
|
uint32_t gps_en : 1;// 0: 未使用 GPS 卫星进行定位; 1: 使用 GPS 卫星进行定位
|
||||||
|
uint32_t beidou_en : 1;// 0: 未使用北斗卫星进行定位; 1: 使用北斗卫星进行定位
|
||||||
|
uint32_t glonass_en : 1;// 0: 未使用 GLONASS 卫星进行定位; 1: 使用 GLONASS 卫星进行定位
|
||||||
|
uint32_t galileo_en : 1;// 0: 未使用 Galileo 卫星进行定位; 1: 使用 Galileo 卫星进行定位
|
||||||
|
uint32_t retain2 : 10;// 保留10位
|
||||||
|
};
|
||||||
|
uint32_t val32;
|
||||||
|
}LocStatus_t;
|
||||||
|
// 位置信息汇报消息体
|
||||||
|
typedef struct{
|
||||||
|
LocAlarm_t alarm_flag; // 报警标志
|
||||||
|
LocStatus_t status; // 状态
|
||||||
|
uint32_t latitude; // 纬度
|
||||||
|
uint32_t longitude; // 经度
|
||||||
|
uint16_t altitude; // 高度
|
||||||
|
uint16_t speed; // 速度
|
||||||
|
uint16_t direction; // 方向
|
||||||
|
uint8_t BCDtime[6]; // 时间YY-MM-DD-hh-mm-ss(GMT+8 时间,本标准中之后涉及的时间均采用此时区)
|
||||||
|
}Loc_basic_info_t;
|
||||||
|
typedef enum{
|
||||||
|
MileageID = 0x01,// 里程, 1/10km, 对应车上里程表读数, DWORD
|
||||||
|
OilMassID = 0x02,// 油量, 1/10L, 对应车上油量表读数, WORD
|
||||||
|
TachographSpeedID = 0x03,// 行驶记录功能获取的速度, 1/10km/h, WORD
|
||||||
|
AlarmCountID = 0x04,// 需要人工确认报警事件的 ID, 从 1 开始计数, WORD
|
||||||
|
OverSpeedAlarmID = 0x11,// 超速报警附加信息, BYTE or BYTE+DWORD
|
||||||
|
AccessAreaAlarmID = 0x12,// 进出区域/路线报警附加信息, BYTE+DWORD+BYTE
|
||||||
|
DrivingTimeAlarmID = 0x13,// 路段行驶时间不足/过长报警附加信息, DWORD+WORD+BYTE
|
||||||
|
VehicleSignalStatusID = 0x25,// 扩展车辆信号状态位, DWORD
|
||||||
|
IoStatusID = 0x2A,// IO 状态位, WORD
|
||||||
|
AnalogQuantityID = 0x2B,// 模拟量, DWORD
|
||||||
|
NetworkQuantityID = 0x30,// 无线通信网络信号强度, BYTE
|
||||||
|
GnssSatellitesID = 0x31,// GNSS 定位卫星数, BYTE
|
||||||
|
CustomInformationLengthID = 0xE0,// 后续自定义信息长度, BYTE
|
||||||
|
}addi_infoID_t;
|
||||||
|
// 位置附加信息
|
||||||
|
typedef struct Loc_addi_info_t{
|
||||||
|
uint8_t msg_id; // 附加消息ID
|
||||||
|
uint8_t msg_len; // 附加消息长度
|
||||||
|
void *msg; // 附加消息内容
|
||||||
|
struct Loc_addi_info_t *next; // 下一个附加信息
|
||||||
|
}Loc_addi_info_t;
|
||||||
|
// 位置信息汇报体(0x0200)
|
||||||
|
typedef struct{
|
||||||
|
Loc_basic_info_t basic_info; // 基本信息
|
||||||
|
Loc_addi_info_t *addi_info; // 附加信息
|
||||||
|
}LocReport_t;
|
||||||
|
|
||||||
|
// 位置信息查询体(0x8201空包)
|
||||||
|
|
||||||
|
// 位置信息查询应答体(0x0201)
|
||||||
|
typedef struct {
|
||||||
|
uint16_t msg_flow_num; // 对应的位置信息查询消息的流水号
|
||||||
|
LocReport_t *loc_info; // 位置信息
|
||||||
|
}GetLocInfoResp_t;
|
||||||
|
|
||||||
|
// 临时位置跟踪控制体(0x8202)
|
||||||
|
typedef struct {
|
||||||
|
uint16_t time_intv; // 时间间隔
|
||||||
|
uint32_t eff_time; // 追踪有效时间,单位为秒(s)
|
||||||
|
}LocTrackingCtrl_t;
|
||||||
|
|
||||||
|
// ------------------------------ 协议帧结构体定义 ----------
|
||||||
|
// 转义相关标识
|
||||||
|
typedef enum {
|
||||||
|
PSIGN = 0x7E, // 标识位
|
||||||
|
PESC = 0x7D, // 转义标识
|
||||||
|
PESC_SIGN = 0x02, // 0x7E<-->0x7D后紧跟一个0x02
|
||||||
|
PESC_ESCAPE = 0x01, // 0x7D<-->0x7D后紧跟一个0x01
|
||||||
|
} ProtocolEscapeFlag;
|
||||||
|
|
||||||
|
// 消息体属性
|
||||||
|
typedef union {
|
||||||
|
struct {
|
||||||
|
uint16_t msgbodylen : 10;// 消息体长度, 占用10bit
|
||||||
|
uint16_t encrypt : 3;// 数据加密方式, 当此三位都为0, 表示消息体不加密, 当第10位为1, 表示消息体经过RSA算法加密
|
||||||
|
uint16_t packet : 1;// 分包标记
|
||||||
|
uint16_t retain : 2;// 保留2位
|
||||||
|
};
|
||||||
|
uint16_t val16;
|
||||||
|
}MsgBodyAttr_t;
|
||||||
|
|
||||||
|
// 消息头
|
||||||
|
typedef struct {
|
||||||
|
uint16_t msg_id;// 消息ID
|
||||||
|
MsgBodyAttr_t msgbody_attr;// 消息体属性
|
||||||
|
uint8_t phone_BCDnum[6];// 终端手机号
|
||||||
|
uint16_t msg_flow_num;// 消息流水号
|
||||||
|
uint16_t total_packet;// 总包数, 分包情况下使用
|
||||||
|
uint16_t packet_seq;// 当前包序号, 分包情况下使用
|
||||||
|
}MsgHead_t;
|
||||||
|
|
||||||
|
// 消息结构体
|
||||||
|
typedef struct {
|
||||||
|
uint8_t Head_SIGN; // 头标识位
|
||||||
|
MsgHead_t msg_head; // 消息头
|
||||||
|
void *p_msg_body; // 消息体
|
||||||
|
uint8_t BCC_Check; // BCC校验码
|
||||||
|
uint8_t Tail_SIGN; // 尾标识位
|
||||||
|
}JT808_2013_MsgFrame_t;
|
||||||
|
|
||||||
|
#pragma pack()
|
||||||
|
|
||||||
|
#endif // __JT808_PROTOCOL__
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
#ifndef JT808_SET_TERM_PARAM_H_
|
||||||
|
#define JT808_SET_TERM_PARAM_H_
|
||||||
|
#include "jt808_protocol.h"
|
||||||
|
#include "jt808_config.h"
|
||||||
|
|
||||||
|
#pragma pack(1)
|
||||||
|
// 终端参数设置项参数ID
|
||||||
|
typedef enum {
|
||||||
|
HeartBeatInterval = 0x0001,// DWORD, 终端心跳发送间隔(s)
|
||||||
|
MainServerAddr = 0x0013,//STRING, 主服务器地址,IP 或域名
|
||||||
|
ServerPort = 0x0018,//DWORD, 服务器 TCP 端口
|
||||||
|
DefaultTimeReportInterval = 0x0029,// DWORD, 缺省时间汇报间隔
|
||||||
|
InflexionAngle = 0x0030,// DWORD, 拐点补传角度, < 180°
|
||||||
|
MaxSpeed = 0x0055,// DWORD, 最高速度, km/h.
|
||||||
|
ProvinceID = 0x0081,// WORD, 车辆所在的省域 ID
|
||||||
|
CityID = 0x0082,// WORD, 车辆所在的市域 ID
|
||||||
|
CarPlateNum = 0x0083,//STRING, 公安交通管理部门颁发的机动车号牌
|
||||||
|
CarPlateColor = 0x0084,//车牌颜色,按照 JT/T415-2006 的 5.4.12
|
||||||
|
}set_TermParamID_t;
|
||||||
|
typedef struct{
|
||||||
|
uint32_t HeartBeatInterval;// DWORD, 终端心跳发送间隔(s)
|
||||||
|
uint8_t MainServerAddr[50];//STRING, 主服务器地址,IP 或域名
|
||||||
|
uint32_t ServerPort;//DWORD, 服务器 TCP 端口
|
||||||
|
uint32_t DefaultTimeReportInterval;// DWORD, 缺省时间汇报间隔
|
||||||
|
uint32_t InflexionAngle;// DWORD, 拐点补传角度, < 180°
|
||||||
|
uint32_t MaxSpeed;// DWORD, 最高速度, km/h
|
||||||
|
uint16_t ProvinceID;// WORD, 车辆所在的省域 ID
|
||||||
|
uint16_t CityID;// WORD, 车辆所在的市域 ID
|
||||||
|
uint8_t CarPlateNum[10];//STRING, 公安交通管理部门颁发的机动车号牌
|
||||||
|
uint8_t CarPlateColor;//车牌颜色,按照 JT/T415-2006 的 5.4.12
|
||||||
|
}set_TermParam_t;
|
||||||
|
|
||||||
|
// big_标记的参数需以大端方式存储,需手动转换为大端
|
||||||
|
typedef struct {// 终端参数项
|
||||||
|
uint8_t phone_BCDnum[6];// 终端手机号
|
||||||
|
uint16_t msg_flow_num;// 累加的消息流水号
|
||||||
|
Term_RegInfo_t big_reg_info; // 注册信息
|
||||||
|
Term_Auth_t big_auth_info; // 终端鉴权信息
|
||||||
|
set_TermParam_t set_term_param; // 设置终端参数
|
||||||
|
GetSpecificTermParams_t big_specific_params; // 解析出的待查询指定终端参数列表
|
||||||
|
Term_Ctrl_t big_ctrl_info; // 解析出的终端控制信息
|
||||||
|
Term_Upgrade_t big_upgrade_info; // 解析出的升级信息
|
||||||
|
LocReport_t big_loc_report; // 位置信息汇报
|
||||||
|
LocTrackingCtrl_t big_loc_tracking_ctrl; // 临时位置跟踪控制
|
||||||
|
}Term_Param_item_t;
|
||||||
|
#pragma pack()
|
||||||
|
|
||||||
|
extern Term_Param_item_t jt808_term_param_item;
|
||||||
|
|
||||||
|
extern osThreadFunc_t Autoreport_param_ThreadId;
|
||||||
|
|
||||||
|
// 控制车辆状态
|
||||||
|
void jt808_Set_CarStatus(uint8_t status);
|
||||||
|
|
||||||
|
// 获取车辆状态
|
||||||
|
uint8_t jt808_Get_CarStatus(void);
|
||||||
|
|
||||||
|
// 设置终端参数
|
||||||
|
int jt808_setTermParam(set_TermParamID_t param_id, void *param, uint8_t param_len);
|
||||||
|
|
||||||
|
// 启动自动上报参数
|
||||||
|
void jt808_Autoreport_param_start(void);
|
||||||
|
|
||||||
|
// 停止自动上报参数
|
||||||
|
void jt808_Autoreport_param_stop(void);
|
||||||
|
|
||||||
|
// 初始化终端参数
|
||||||
|
void jt808_set_term_param_init(void);
|
||||||
|
|
||||||
|
#endif // JT808_SET_TERM_PARAM_H_
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
|
||||||
|
#ifndef JT808_UTIL_H_
|
||||||
|
#define JT808_UTIL_H_
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <string.h>
|
||||||
|
// #include <vector>
|
||||||
|
|
||||||
|
// 双字节大小端交换
|
||||||
|
uint16_t Swap16(uint16_t val16);
|
||||||
|
// 四字节大小端交换
|
||||||
|
uint32_t Swap32(uint32_t val32);
|
||||||
|
// 异或校验
|
||||||
|
uint8_t BCC_Check(const uint8_t *src, uint32_t len);
|
||||||
|
|
||||||
|
|
||||||
|
// 十进制转BCD码
|
||||||
|
uint8_t DecToBcd(uint8_t Dec);
|
||||||
|
|
||||||
|
// BCD码转十进制
|
||||||
|
uint8_t BcdToDec(uint8_t Bcd);
|
||||||
|
|
||||||
|
// 原始字符串转BCD码 //奇数位时,首位BCD码前面补0
|
||||||
|
uint8_t *rawStrToBcd(uint8_t *bcd, const uint8_t *str, uint16_t str_len);
|
||||||
|
|
||||||
|
// BCD转字符串,自动去掉bcd码前导零
|
||||||
|
// bcdlen 为bcd码字节数
|
||||||
|
uint8_t *BcdToStr(uint8_t *str, const uint8_t *bcd, int bcd_len);
|
||||||
|
|
||||||
|
// 原始BCD数据转字符串
|
||||||
|
// strlen 为原始BCD数据字节数
|
||||||
|
uint8_t *rawBcdToStr(uint8_t *str, const uint8_t *bcd, int bcd_len);
|
||||||
|
|
||||||
|
#endif // JT808_UTIL_H_
|
||||||
|
|
@ -263,7 +263,7 @@ struct ProtocolParameter
|
||||||
struct LocationTrackingControl location_tracking_control;
|
struct LocationTrackingControl location_tracking_control;
|
||||||
|
|
||||||
// 升级信息.
|
// 升级信息.
|
||||||
struct UpgradeInfo upgrade_info;
|
struct UpgradeInfo big_upgrade_info;
|
||||||
// 补传分包信息.
|
// 补传分包信息.
|
||||||
struct FillPacket fill_packet;
|
struct FillPacket fill_packet;
|
||||||
|
|
||||||
|
|
@ -298,7 +298,7 @@ struct ProtocolParameter
|
||||||
struct LocationTrackingControl location_tracking_control;
|
struct LocationTrackingControl location_tracking_control;
|
||||||
|
|
||||||
// 解析出的升级信息.
|
// 解析出的升级信息.
|
||||||
struct UpgradeInfo upgrade_info;
|
struct UpgradeInfo big_upgrade_info;
|
||||||
// 解析出的补传分包信息.
|
// 解析出的补传分包信息.
|
||||||
struct FillPacket fill_packet;
|
struct FillPacket fill_packet;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,19 @@
|
||||||
|
|
||||||
CUSTOM_MAIN_DIR := custom/jt808
|
CUSTOM_MAIN_DIR := custom/jt808
|
||||||
|
|
||||||
OC_FILES += $(CUSTOM_MAIN_DIR)/src/bcd.c
|
# OC_FILES += $(CUSTOM_MAIN_DIR)/src/bcd.c
|
||||||
OC_FILES += $(CUSTOM_MAIN_DIR)/src/client_manager.c
|
# OC_FILES += $(CUSTOM_MAIN_DIR)/src/client_manager.c
|
||||||
OC_FILES += $(CUSTOM_MAIN_DIR)/src/gbk_utf8.c
|
# OC_FILES += $(CUSTOM_MAIN_DIR)/src/gbk_utf8.c
|
||||||
OC_FILES += $(CUSTOM_MAIN_DIR)/src/jt808_packager.c
|
# OC_FILES += $(CUSTOM_MAIN_DIR)/src/jt808_packager.c
|
||||||
OC_FILES += $(CUSTOM_MAIN_DIR)/src/jt808_parser.c
|
# OC_FILES += $(CUSTOM_MAIN_DIR)/src/jt808_parser.c
|
||||||
OC_FILES += $(CUSTOM_MAIN_DIR)/src/location_report.c
|
# OC_FILES += $(CUSTOM_MAIN_DIR)/src/location_report.c
|
||||||
OC_FILES += $(CUSTOM_MAIN_DIR)/src/set_terminal_parameter.c
|
# OC_FILES += $(CUSTOM_MAIN_DIR)/src/set_terminal_parameter.c
|
||||||
OC_FILES += $(CUSTOM_MAIN_DIR)/src/terminal_register.c
|
# OC_FILES += $(CUSTOM_MAIN_DIR)/src/terminal_register.c
|
||||||
OC_FILES += $(CUSTOM_MAIN_DIR)/src/util.c
|
# OC_FILES += $(CUSTOM_MAIN_DIR)/src/util.c
|
||||||
|
OC_FILES += $(CUSTOM_MAIN_DIR)/src/jt808_util.c
|
||||||
|
OC_FILES += $(CUSTOM_MAIN_DIR)/src/jt808_msg_pkg.c
|
||||||
|
OC_FILES += $(CUSTOM_MAIN_DIR)/src/jt808_msg_parse.c
|
||||||
|
OC_FILES += $(CUSTOM_MAIN_DIR)/src/jt808_pkg_transmit.c
|
||||||
|
OC_FILES += $(CUSTOM_MAIN_DIR)/src/jt808_set_TermParam.c
|
||||||
|
|
||||||
INC += -I'$(CUSTOM_MAIN_DIR)/inc'
|
INC += -I'$(CUSTOM_MAIN_DIR)/inc'
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
#include "bcd.h"
|
#include "bcd.h"
|
||||||
#include "jt808_debug.h"
|
#include "jt808_config.h"
|
||||||
|
|
||||||
unsigned char HexToBcd(unsigned char src)
|
unsigned char HexToBcd(unsigned char src)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
#include "bcd.h"
|
#include "bcd.h"
|
||||||
#include "jt808_packager.h"
|
#include "jt808_packager.h"
|
||||||
#include "jt808_parser.h"
|
#include "jt808_parser.h"
|
||||||
#include "jt808_debug.h"
|
#include "jt808_config.h"
|
||||||
|
|
||||||
uint8_t Non_transliterated_receive[1024];
|
uint8_t Non_transliterated_receive[1024];
|
||||||
struct ProtocolParameter parameter_;
|
struct ProtocolParameter parameter_;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
#include "gbk_utf8.h"
|
#include "gbk_utf8.h"
|
||||||
#include "jt808_debug.h"
|
#include "jt808_config.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
namespace libjt808
|
namespace libjt808
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,183 @@
|
||||||
|
#include "jt808_msg_parse.h"
|
||||||
|
#include "jt808_pkg_transmit.h"
|
||||||
|
|
||||||
|
PrsResult_t PrsResult;
|
||||||
|
|
||||||
|
// 消息体解析
|
||||||
|
static int jt808_BodyParse(void *Prsmsg_body, PrsResult_t *PrsResult){
|
||||||
|
switch (PrsResult->msg_head.msg_id){
|
||||||
|
case ID_Plat_GenResp:{// 平台通用应答
|
||||||
|
memcpy(&(PrsResult->Rsp_flow_num), Prsmsg_body, sizeof(Plat_GenResp_t));
|
||||||
|
// 转小端
|
||||||
|
PrsResult->Rsp_flow_num = Swap16(PrsResult->Rsp_flow_num);
|
||||||
|
PrsResult->Rsp_msg_id = Swap16(PrsResult->Rsp_msg_id);
|
||||||
|
// PrsResult->Rsp_result = PrsResult->Rsp_result;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ID_FillPktReq:{// 补传分包请求
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ID_Term_RegResp:{// 终端注册应答
|
||||||
|
PrsResult->Rsp_flow_num = (uint16_t)(((uint8_t *)Prsmsg_body)[0] << 8) | (((uint8_t *)Prsmsg_body)[1]);
|
||||||
|
PrsResult->Rsp_result = ((uint8_t *)Prsmsg_body)[2];
|
||||||
|
if(PrsResult->Rsp_result == 0){ // 成功时,读取鉴权码
|
||||||
|
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(PrsResult->msg_head.msgbody_attr.msgbodylen - 3 +1); // 加1是为了加上结束符
|
||||||
|
if(PrsResult->term_param_item->big_auth_info.str_auth_code == NULL){
|
||||||
|
JT808_DEBUG("[%s,%s] malloc failed\r\n", __FUNCTION__,__LINE__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memset(PrsResult->term_param_item->big_auth_info.str_auth_code, 0, PrsResult->msg_head.msgbody_attr.msgbodylen - 3 +1);
|
||||||
|
memcpy(PrsResult->term_param_item->big_auth_info.str_auth_code, Prsmsg_body + 3 , PrsResult->msg_head.msgbody_attr.msgbodylen - 3);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ID_SetTermParams:{// 设置终端参数
|
||||||
|
PrsResult->term_param_item->big_specific_params.param_Total_num = ((uint8_t *)Prsmsg_body)[0]; // 总参数个数
|
||||||
|
uint16_t param_lenoffset = 1;
|
||||||
|
for(int i = 0; i < PrsResult->term_param_item->big_specific_params.param_Total_num; i++){
|
||||||
|
// 设置终端参数
|
||||||
|
jt808_setTermParam(Swap32(*(uint32_t *)(Prsmsg_body + param_lenoffset)), // 参数ID
|
||||||
|
(void *)(Prsmsg_body + param_lenoffset + 5), // 参数值
|
||||||
|
*((uint8_t*)(Prsmsg_body + param_lenoffset + 4))); // 参数长度
|
||||||
|
param_lenoffset += 5 + (*((uint8_t*)(Prsmsg_body + param_lenoffset + 4))); // 参数ID(4) + 参数长度(1) + 参数值(n)
|
||||||
|
}
|
||||||
|
|
||||||
|
jt808_pkg_send(ID_Term_GenResp, 0);// 发送终端通用应答
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ID_GetTermParams:{// 查询终端参数
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ID_GetSpecificTermParams:{// 查询指定终端参数
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ID_Term_Ctrl:{// 终端控制
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ID_GetTermAttr:{// 查询终端属性
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ID_Term_Upgrade:{// 下发终端升级包
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ID_GetLocInfo:{// 位置信息查询
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ID_LocTrackingCtrl:{// 临时位置跟踪控制
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ID_Car_Ctrl:{// 车辆控制
|
||||||
|
|
||||||
|
jt808_pkg_send(ID_Car_CtrlResp, 0);// 发送车辆控制应答,设置本消息无发送应答
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:{
|
||||||
|
return -2; // 没有对应的消息体解析函数
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// jt808协议包处理
|
||||||
|
int jt808_msg_parse(const uint8_t *BufferReceive, uint16_t length, PrsResult_t *PrsResult){
|
||||||
|
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(&PrsResult->msg_head, para_Buffer + 1, sizeof(MsgHead_t) - ((para_Buffer[3] & 0x02)==0? 4 : 0));
|
||||||
|
PrsResult->msg_head.msg_id = Swap16(PrsResult->msg_head.msg_id);// 消息ID
|
||||||
|
PrsResult->msg_head.msgbody_attr.val16 = Swap16(PrsResult->msg_head.msgbody_attr.val16);// 消息体属性
|
||||||
|
PrsResult->msg_head.msg_flow_num = Swap16(PrsResult->msg_head.msg_flow_num);// 消息流水号
|
||||||
|
PrsResult->msg_head.total_packet = Swap16(PrsResult->msg_head.total_packet);// 总包数, 分包情况下使用
|
||||||
|
PrsResult->msg_head.packet_seq = Swap16(PrsResult->msg_head.packet_seq);// 当前包序号, 分包情况下使用
|
||||||
|
|
||||||
|
// 消息体解析
|
||||||
|
if(0 != jt808_BodyParse((void *)(para_Buffer + 1 + sizeof(MsgHead_t) - ((para_Buffer[3] & 0x02)==0? 4 : 0)) ,PrsResult)){
|
||||||
|
JT808_DEBUG("error jt808_BodyParse\r\n");
|
||||||
|
// 释放内存
|
||||||
|
jt808_free(para_Buffer);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 释放内存
|
||||||
|
jt808_free(para_Buffer);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,253 @@
|
||||||
|
#include "jt808_msg_pkg.h"
|
||||||
|
#include "jt808_msg_parse.h"
|
||||||
|
|
||||||
|
// 协议消息体打包(会自动为p_msg_body分配合适长度的内存,注意释放)
|
||||||
|
static int jt808_BodyPackage(JT808_2013_MsgFrame_t *p_MsgFrame, MessageID_t Msg_ID){
|
||||||
|
if(PrsResult.term_param_item == NULL){
|
||||||
|
JT808_DEBUG("[%s,%s] term_param_item is NULL \r\n", __FUNCTION__,__LINE__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
p_MsgFrame->msg_head.msgbody_attr.encrypt = 0;// 数据加密方式
|
||||||
|
p_MsgFrame->msg_head.msgbody_attr.packet = 0;// 分包标记
|
||||||
|
p_MsgFrame->msg_head.msgbody_attr.retain = 0;// 保留2位
|
||||||
|
|
||||||
|
p_MsgFrame->msg_head.total_packet = 0;// 总包数, 分包情况下使用
|
||||||
|
p_MsgFrame->msg_head.packet_seq = 0;// 当前包序号, 分包情况下使用
|
||||||
|
// 填充消息体
|
||||||
|
switch(Msg_ID){
|
||||||
|
case ID_Term_GenResp:{ // 终端通用应答
|
||||||
|
p_MsgFrame->msg_head.msgbody_attr.msgbodylen = sizeof(Term_GenResp_t);// 消息体长度
|
||||||
|
|
||||||
|
// 定义大端结构体
|
||||||
|
Term_GenResp_t *big_term_reg_resp = (Term_GenResp_t *)jt808_malloc(sizeof(Term_GenResp_t));
|
||||||
|
if(big_term_reg_resp == NULL){
|
||||||
|
JT808_DEBUG("[%s,%s] malloc failed \r\n", __FUNCTION__,__LINE__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memset(big_term_reg_resp, 0, sizeof(Term_GenResp_t));
|
||||||
|
// 大小端转换
|
||||||
|
big_term_reg_resp->msg_flow_num = Swap16(PrsResult.Rsp_flow_num); // 返回消息应答结果
|
||||||
|
big_term_reg_resp->msg_id_ack = Swap16(PrsResult.Rsp_msg_id);
|
||||||
|
big_term_reg_resp->result = PrsResult.Rsp_result;
|
||||||
|
p_MsgFrame->p_msg_body = (void *)big_term_reg_resp;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ID_Term_HB:{ // 终端心跳
|
||||||
|
p_MsgFrame->msg_head.msgbody_attr.msgbodylen = 0;// 消息体长度
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ID_Term_Reg:{ // 终端注册
|
||||||
|
p_MsgFrame->msg_head.msgbody_attr.msgbodylen = sizeof(Term_RegInfo_t);// 消息体长度
|
||||||
|
|
||||||
|
// 定义大端结构体
|
||||||
|
Term_RegInfo_t *big_term_reg = (Term_RegInfo_t *)jt808_malloc(sizeof(Term_RegInfo_t));
|
||||||
|
if(big_term_reg == NULL){
|
||||||
|
JT808_DEBUG("[%s,%s] malloc failed \r\n", __FUNCTION__,__LINE__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// memset(big_term_reg, 0, sizeof(Term_RegInfo_t));
|
||||||
|
memcpy(big_term_reg, &PrsResult.term_param_item->big_reg_info, sizeof(Term_RegInfo_t)); // 复制注册信息内容
|
||||||
|
p_MsgFrame->p_msg_body = (void *)big_term_reg;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ID_Term_Logout:{ // 终端注销
|
||||||
|
p_MsgFrame->msg_head.msgbody_attr.msgbodylen = 0;// 消息体长度
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ID_Term_Auth:{ // 终端鉴权
|
||||||
|
// JT808_DEBUG("ID_Term_Auth\r\n");
|
||||||
|
p_MsgFrame->msg_head.msgbody_attr.msgbodylen = strlen(PrsResult.term_param_item->big_auth_info.str_auth_code);// 消息体长度
|
||||||
|
if((NULL == PrsResult.term_param_item->big_auth_info.str_auth_code) || (1 >= p_MsgFrame->msg_head.msgbody_attr.msgbodylen)){
|
||||||
|
JT808_DEBUG("[%s,%s] auth_code len is 0 \r\n", __FUNCTION__,__LINE__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
void *str_auth_code = jt808_malloc(p_MsgFrame->msg_head.msgbody_attr.msgbodylen);
|
||||||
|
if(str_auth_code == NULL){
|
||||||
|
JT808_DEBUG("[%s,%s] malloc failed \r\n", __FUNCTION__,__LINE__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// memset(str_auth_code, 0, p_MsgFrame->msg_head.msgbody_attr.msgbodylen);
|
||||||
|
JT808_DEBUG("auth_code:%d,%s\r\n",strlen(PrsResult.term_param_item->big_auth_info.str_auth_code),
|
||||||
|
PrsResult.term_param_item->big_auth_info.str_auth_code);
|
||||||
|
memcpy(str_auth_code, PrsResult.term_param_item->big_auth_info.str_auth_code, p_MsgFrame->msg_head.msgbody_attr.msgbodylen);
|
||||||
|
p_MsgFrame->p_msg_body = (void *)str_auth_code;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ID_GetTermParamsResp:{ // 查询终端参数应答
|
||||||
|
p_MsgFrame->msg_head.msgbody_attr.msgbodylen = sizeof(GetTermParamsResp_t);// 消息体长度
|
||||||
|
GetTermParamsResp_t *get_term_params_resp = (GetTermParamsResp_t *)jt808_realloc(p_MsgFrame->p_msg_body, sizeof(GetTermParamsResp_t));
|
||||||
|
if(get_term_params_resp == NULL){
|
||||||
|
JT808_DEBUG("[%s,%s] malloc failed \r\n", __FUNCTION__,__LINE__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
p_MsgFrame->p_msg_body = (void *)get_term_params_resp;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ID_GetTermAttrResp:{ // 查询终端属性应答
|
||||||
|
p_MsgFrame->msg_head.msgbody_attr.msgbodylen = sizeof(GetTermAttrResp_t);// 消息体长度
|
||||||
|
GetTermAttrResp_t *get_term_attr_resp = (GetTermAttrResp_t *)jt808_realloc(p_MsgFrame->p_msg_body, sizeof(GetTermAttrResp_t));
|
||||||
|
if(get_term_attr_resp == NULL){
|
||||||
|
JT808_DEBUG("[%s,%s] malloc failed \r\n", __FUNCTION__,__LINE__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
p_MsgFrame->p_msg_body = (void *)get_term_attr_resp;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ID_Term_UpgradeResult:{ // 终端升级结果通知
|
||||||
|
p_MsgFrame->msg_head.msgbody_attr.msgbodylen = sizeof(Term_UpgradeResult_t);// 消息体长度
|
||||||
|
Term_UpgradeResult_t *term_upgrade_result = (Term_UpgradeResult_t *)jt808_realloc(p_MsgFrame->p_msg_body, sizeof(Term_UpgradeResult_t));
|
||||||
|
if(term_upgrade_result == NULL){
|
||||||
|
JT808_DEBUG("[%s,%s] malloc failed \r\n", __FUNCTION__,__LINE__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
p_MsgFrame->p_msg_body = (void *)term_upgrade_result;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ID_LocReport:{ // 位置信息汇报
|
||||||
|
p_MsgFrame->msg_head.msgbody_attr.msgbodylen = sizeof(Loc_basic_info_t);// 消息体长度
|
||||||
|
Loc_addi_info_t *p_loc_addi_info = PrsResult.term_param_item->big_loc_report.addi_info;
|
||||||
|
while(p_loc_addi_info != NULL){ // 计算附加信息长度
|
||||||
|
p_MsgFrame->msg_head.msgbody_attr.msgbodylen += p_loc_addi_info->msg_len + 2;
|
||||||
|
p_loc_addi_info = p_loc_addi_info->next;
|
||||||
|
}
|
||||||
|
uint8_t *loc_report_buf = (uint8_t *)jt808_malloc(p_MsgFrame->msg_head.msgbody_attr.msgbodylen);
|
||||||
|
if(loc_report_buf == NULL){
|
||||||
|
JT808_DEBUG("[%s,%s] malloc failed \r\n", __FUNCTION__,__LINE__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memcpy(loc_report_buf, &PrsResult.term_param_item->big_loc_report, sizeof(Loc_basic_info_t)); // 复制基本信息内容
|
||||||
|
p_loc_addi_info = PrsResult.term_param_item->big_loc_report.addi_info;
|
||||||
|
uint16_t loc_report_offset = sizeof(Loc_basic_info_t);
|
||||||
|
uint8_t loc_len = 0;
|
||||||
|
while(p_loc_addi_info != NULL){ // 填充附加信息内容
|
||||||
|
loc_len= p_loc_addi_info->msg_len + 2;
|
||||||
|
memcpy(loc_report_buf + loc_report_offset, &p_loc_addi_info->msg_id, 2);
|
||||||
|
memcpy(loc_report_buf + loc_report_offset + 2, p_loc_addi_info->msg, p_loc_addi_info->msg_len);
|
||||||
|
loc_report_offset += loc_len;
|
||||||
|
p_loc_addi_info = p_loc_addi_info->next;
|
||||||
|
}
|
||||||
|
p_MsgFrame->p_msg_body = (void *)loc_report_buf;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ID_GetLocInfoResp:{ // 查询位置信息应答
|
||||||
|
p_MsgFrame->msg_head.msgbody_attr.msgbodylen = sizeof(GetLocInfoResp_t);// 消息体长度
|
||||||
|
GetLocInfoResp_t *get_loc_info_resp = (GetLocInfoResp_t *)jt808_realloc(p_MsgFrame->p_msg_body, sizeof(GetLocInfoResp_t));
|
||||||
|
if(get_loc_info_resp == NULL){
|
||||||
|
JT808_DEBUG("[%s,%s] malloc failed \r\n", __FUNCTION__,__LINE__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
p_MsgFrame->p_msg_body = (void *)get_loc_info_resp;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return -2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 消息帧打包 (会自动为msgEscape->buf分配合适长度的内存,注意释放)
|
||||||
|
int jt808_msg_pkg(MessageID_t Msg_ID, JT808MsgESC_t *msgEscape){
|
||||||
|
JT808_2013_MsgFrame_t big_MsgFrame;// 定义大端消息帧
|
||||||
|
|
||||||
|
JT808_DEBUG("BodyPackage ID:0x%04X\r\n", Msg_ID);
|
||||||
|
big_MsgFrame.p_msg_body = NULL;
|
||||||
|
if(0 != jt808_BodyPackage(&big_MsgFrame, Msg_ID)){// 填充消息体 (注意释放p_msg_body内存)
|
||||||
|
JT808_DEBUG("jt808_BodyPackage failed\r\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// 计算消息帧总长度
|
||||||
|
uint16_t msg_total_len = 1 + sizeof(MsgHead_t) - (1 ==big_MsgFrame.msg_head.msgbody_attr.packet ? 0 : 4);
|
||||||
|
uint16_t msgbody_len =big_MsgFrame.msg_head.msgbody_attr.msgbodylen;
|
||||||
|
msg_total_len += msgbody_len + 2;
|
||||||
|
JT808_DEBUG("total_len:%d,len:%d\r\n", msg_total_len, msgbody_len);
|
||||||
|
|
||||||
|
big_MsgFrame.Head_SIGN = PSIGN;
|
||||||
|
big_MsgFrame.Tail_SIGN = PSIGN;
|
||||||
|
|
||||||
|
// 大端转换
|
||||||
|
big_MsgFrame.msg_head.msg_id = Swap16(Msg_ID);// 消息ID
|
||||||
|
big_MsgFrame.msg_head.msgbody_attr.val16 = Swap16(big_MsgFrame.msg_head.msgbody_attr.val16);
|
||||||
|
memcpy(big_MsgFrame.msg_head.phone_BCDnum, PrsResult.term_param_item->phone_BCDnum, 6);
|
||||||
|
big_MsgFrame.msg_head.msg_flow_num = Swap16(PrsResult.term_param_item->msg_flow_num);// 消息流水号
|
||||||
|
big_MsgFrame.msg_head.total_packet = Swap16(big_MsgFrame.msg_head.total_packet);// 总包数, 分包情况下使用
|
||||||
|
big_MsgFrame.msg_head.packet_seq = Swap16(big_MsgFrame.msg_head.total_packet);// 当前包序号, 分包情况下使用
|
||||||
|
|
||||||
|
uint8_t *msg_buf = (uint8_t *)jt808_malloc(msg_total_len);
|
||||||
|
if(msg_buf == NULL){
|
||||||
|
JT808_DEBUG("[%s,%s] malloc failed \r\n", __FUNCTION__,__LINE__);
|
||||||
|
if(big_MsgFrame.p_msg_body != NULL){ // 释放消息体内存(必要操作)
|
||||||
|
jt808_free(big_MsgFrame.p_msg_body);
|
||||||
|
big_MsgFrame.p_msg_body = NULL;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// 填充头标识和消息头
|
||||||
|
memcpy(msg_buf, &big_MsgFrame.Head_SIGN, msg_total_len - msgbody_len - 2);
|
||||||
|
// 填充消息体
|
||||||
|
if(0 < msgbody_len && big_MsgFrame.p_msg_body != NULL){
|
||||||
|
memcpy(msg_buf + (msg_total_len - msgbody_len - 2), big_MsgFrame.p_msg_body, msgbody_len);
|
||||||
|
}
|
||||||
|
// 计算BCC校验码
|
||||||
|
big_MsgFrame.BCC_Check = BCC_Check(msg_buf + 1, msg_total_len - 2 - 1);
|
||||||
|
memcpy(msg_buf + msg_total_len - 2, &big_MsgFrame.BCC_Check, 2);
|
||||||
|
|
||||||
|
//// DEBUG
|
||||||
|
// app_printf("JT808_2013_MsgFrame_t:\r\n");
|
||||||
|
// for (size_t i = 0; i < msg_total_len - msgbody_len - 2; i++){
|
||||||
|
// app_printf("%02X ", *((uint8_t *)(&big_MsgFrame) + i));
|
||||||
|
// }
|
||||||
|
// app_printf("\r\n");
|
||||||
|
// for (size_t i = 0; i < msgbody_len; i++){
|
||||||
|
// app_printf("%02X ", *((uint8_t *)big_MsgFrame.p_msg_body + i));
|
||||||
|
// }
|
||||||
|
// app_printf("\r\n");
|
||||||
|
// for (size_t i = 0; i < 2; i++){
|
||||||
|
// app_printf("%02X ", *((uint8_t *)(&big_MsgFrame.BCC_Check) + i));
|
||||||
|
// }
|
||||||
|
// app_printf("\r\n");
|
||||||
|
|
||||||
|
if(big_MsgFrame.p_msg_body != NULL){ // 释放消息体内存(必要操作)
|
||||||
|
jt808_free(big_MsgFrame.p_msg_body);
|
||||||
|
big_MsgFrame.p_msg_body = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 7E 转义处理
|
||||||
|
uint16_t escape_len = 0;
|
||||||
|
for(uint16_t i = 1; i < msg_total_len - 1; i++){
|
||||||
|
if(msg_buf[i] == PSIGN || msg_buf[i] == PESC){
|
||||||
|
escape_len++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
msgEscape->buf = (uint8_t *)jt808_malloc(msg_total_len + escape_len);
|
||||||
|
uint16_t offset_num = 0;
|
||||||
|
msgEscape->buf[0] = PSIGN;
|
||||||
|
msgEscape->buf[msg_total_len + escape_len - 1] = PSIGN;
|
||||||
|
|
||||||
|
for(uint16_t i = 1; i < msg_total_len - 1; i++){
|
||||||
|
if(msg_buf[i] == PSIGN){
|
||||||
|
msgEscape->buf[i + offset_num++] = PESC;
|
||||||
|
msgEscape->buf[i + offset_num] = PESC_SIGN;
|
||||||
|
}else if(msg_buf[i] == PESC){
|
||||||
|
msgEscape->buf[i + offset_num++] = PESC;
|
||||||
|
msgEscape->buf[i + offset_num] = PESC_ESCAPE;
|
||||||
|
}else {
|
||||||
|
msgEscape->buf[i + offset_num] = msg_buf[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jt808_free(msg_buf);
|
||||||
|
|
||||||
|
// 返回消息帧总长度
|
||||||
|
msgEscape->len = msg_total_len + escape_len;
|
||||||
|
|
||||||
|
app_printf("msgEscape->buf:%d\r\n", msg_total_len + escape_len);
|
||||||
|
for(uint16_t i = 0; i < msg_total_len + escape_len; i++){
|
||||||
|
app_printf("%02X ", *(msgEscape->buf + i));
|
||||||
|
}
|
||||||
|
|
||||||
|
app_printf("\r\n");
|
||||||
|
// jt808_free(msgEscape->buf);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "terminal_parameter.h"
|
#include "terminal_parameter.h"
|
||||||
#include "client_manager.h"
|
#include "client_manager.h"
|
||||||
#include "jt808_debug.h"
|
#include "jt808_config.h"
|
||||||
|
|
||||||
// 所有终端数据打包命令.
|
// 所有终端数据打包命令.
|
||||||
unsigned short kTerminalPackagerCMD[PACKAGER_NUM] = {
|
unsigned short kTerminalPackagerCMD[PACKAGER_NUM] = {
|
||||||
|
|
@ -391,7 +391,12 @@ int jt808MsgEscape()
|
||||||
BufferSend[RealBufferSendSize - 1] = 0x00;
|
BufferSend[RealBufferSendSize - 1] = 0x00;
|
||||||
|
|
||||||
outBufferSize = RealBufferSendSize * 2;
|
outBufferSize = RealBufferSendSize * 2;
|
||||||
outBuffer = (unsigned char *)malloc(outBufferSize);
|
outBuffer = (unsigned char *)jt808_malloc(outBufferSize);
|
||||||
|
if(outBuffer == NULL)
|
||||||
|
{
|
||||||
|
JT808_DEBUG("[%s] malloc failed \r\n", __FUNCTION__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (Escape_C(BufferSend, RealBufferSendSize, outBuffer, &outBufferSize) < 0)
|
if (Escape_C(BufferSend, RealBufferSendSize, outBuffer, &outBufferSize) < 0)
|
||||||
{
|
{
|
||||||
|
|
@ -407,7 +412,7 @@ int jt808MsgEscape()
|
||||||
|
|
||||||
if (outBuffer != NULL)
|
if (outBuffer != NULL)
|
||||||
{
|
{
|
||||||
free(outBuffer);
|
jt808_free(outBuffer);
|
||||||
outBuffer = NULL;
|
outBuffer = NULL;
|
||||||
}
|
}
|
||||||
#ifdef __JT808_DEBUG
|
#ifdef __JT808_DEBUG
|
||||||
|
|
@ -507,8 +512,7 @@ int jt808FramePackage(struct ProtocolParameter *para)
|
||||||
JT808_DEBUG("[Write buffersend end PROTOCOL_SIGN] OK !\r\n");
|
JT808_DEBUG("[Write buffersend end PROTOCOL_SIGN] OK !\r\n");
|
||||||
#endif
|
#endif
|
||||||
// 6、处理转义.
|
// 6、处理转义.
|
||||||
if (jt808MsgEscape() < 0)
|
if (jt808MsgEscape() < 0){
|
||||||
{
|
|
||||||
JT808_DEBUG("[jt808MsgEscape] FAILED");
|
JT808_DEBUG("[jt808MsgEscape] FAILED");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
#include "client_manager.h"
|
#include "client_manager.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "bcd.h"
|
#include "bcd.h"
|
||||||
#include "jt808_debug.h"
|
#include "jt808_config.h"
|
||||||
|
|
||||||
// 所有终端解析命令.
|
// 所有终端解析命令.
|
||||||
unsigned short kTerminalParserCMD[PARSER_NUM] = {
|
unsigned short kTerminalParserCMD[PARSER_NUM] = {
|
||||||
|
|
@ -172,7 +172,7 @@ int handle_kTerminalRegisterResponse(struct ProtocolParameter *para)
|
||||||
if (para->parse.respone_result == kRegisterSuccess)
|
if (para->parse.respone_result == kRegisterSuccess)
|
||||||
{
|
{
|
||||||
len_code = para->parse.msg_head.msgbody_attr.bit.msglen - 3;
|
len_code = para->parse.msg_head.msgbody_attr.bit.msglen - 3;
|
||||||
para->parse.authentication_code = (unsigned char *)malloc((len_code + 1) * sizeof(unsigned char));
|
para->parse.authentication_code = (unsigned char *)jt808_malloc((len_code + 1) * sizeof(unsigned char));
|
||||||
memcpy(para->parse.authentication_code, &(BufferReceive[pos + 3]), len_code);
|
memcpy(para->parse.authentication_code, &(BufferReceive[pos + 3]), len_code);
|
||||||
|
|
||||||
JT808_DEBUG("[%s] authentication_code = %s\r\n", __FUNCTION__, para->parse.authentication_code);
|
JT808_DEBUG("[%s] authentication_code = %s\r\n", __FUNCTION__, para->parse.authentication_code);
|
||||||
|
|
@ -281,9 +281,9 @@ int handle_kTerminalUpgrade(struct ProtocolParameter *para)
|
||||||
pos = MSGBODY_PACKET_POS;
|
pos = MSGBODY_PACKET_POS;
|
||||||
}
|
}
|
||||||
|
|
||||||
para->upgrade_info.upgrade_type = BufferReceive[pos++];
|
para->big_upgrade_info.upgrade_type = BufferReceive[pos++];
|
||||||
|
|
||||||
memset(para->upgrade_info.manufacturer_id, 0, sizeof(para->upgrade_info.manufacturer_id));
|
memset(para->big_upgrade_info.manufacturer_id, 0, sizeof(para->big_upgrade_info.manufacturer_id));
|
||||||
for (i = 0; i < 5; i++)
|
for (i = 0; i < 5; i++)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -398,7 +398,15 @@ int jt808FrameParse(const unsigned char *in, unsigned int in_len, struct Protoco
|
||||||
memcpy(BufferReceive, in, in_len);
|
memcpy(BufferReceive, in, in_len);
|
||||||
RealBufferReceiveSize = in_len;
|
RealBufferReceiveSize = in_len;
|
||||||
outBufferSize = RealBufferReceiveSize;
|
outBufferSize = RealBufferReceiveSize;
|
||||||
outBuffer = (unsigned char *)malloc(outBufferSize * sizeof(unsigned char));
|
if(outBufferSize < 1){
|
||||||
|
JT808_DEBUG("outBufferSize < 1\r\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
outBuffer = (unsigned char *)jt808_malloc(outBufferSize * sizeof(unsigned char));
|
||||||
|
if(outBuffer == NULL){
|
||||||
|
JT808_DEBUG("[%s] malloc failed \r\n", __FUNCTION__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
memset(outBuffer, 0, outBufferSize);
|
memset(outBuffer, 0, outBufferSize);
|
||||||
|
|
||||||
#ifdef __JT808_DEBUG
|
#ifdef __JT808_DEBUG
|
||||||
|
|
@ -445,7 +453,7 @@ int jt808FrameParse(const unsigned char *in, unsigned int in_len, struct Protoco
|
||||||
// 释放缓存
|
// 释放缓存
|
||||||
if (outBuffer != NULL)
|
if (outBuffer != NULL)
|
||||||
{
|
{
|
||||||
free(outBuffer);
|
jt808_free(outBuffer);
|
||||||
outBuffer = NULL;
|
outBuffer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,106 @@
|
||||||
|
#include "jt808_pkg_transmit.h"
|
||||||
|
|
||||||
|
static osThreadId_t jt808_pkg_send_ThreadId;
|
||||||
|
static osMessageQueueId_t jt808_send_msg_queue = NULL;
|
||||||
|
static osSemaphoreId_t jt808_send_ack_sem = NULL; // 发送成功应答信号量
|
||||||
|
static osSemaphoreId_t jt808_parse_ok_sem = NULL; // 解析完成信号量
|
||||||
|
|
||||||
|
// 触发消息发送
|
||||||
|
int jt808_pkg_send(MessageID_t Msg_ID, uint32_t timeout){
|
||||||
|
pkg_msg_t send_pkg_msg={0};
|
||||||
|
send_pkg_msg.msg_id = Msg_ID;
|
||||||
|
send_pkg_msg.timeout = timeout;
|
||||||
|
JT808_DEBUG("send pkg_msg:%04x\n", Msg_ID);
|
||||||
|
if(osOK == osMessageQueuePut(jt808_send_msg_queue, &send_pkg_msg, 0, 0)){ //
|
||||||
|
if(0 < timeout){ // 阻塞等待发送回应
|
||||||
|
|
||||||
|
osStatus_t ret =osSemaphoreAcquire(jt808_send_ack_sem, timeout);
|
||||||
|
if(ret == osOK){
|
||||||
|
return PrsResult.Rsp_result; // 发送成功应答
|
||||||
|
JT808_DEBUG("send ack success\n");
|
||||||
|
}else if(ret == osErrorTimeout){
|
||||||
|
JT808_DEBUG("send ack timeout\n");
|
||||||
|
return -1;// 发送失败
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
JT808_DEBUG("osMessageQueuePut fail\n");
|
||||||
|
return -1;// 发送失败
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 接收处理 (放入TCP接收回调中)
|
||||||
|
void jt808_pkg_handle(uint8_t *receive_buf, uint16_t receive_len){
|
||||||
|
if(0 ==jt808_msg_parse(receive_buf, receive_len, &PrsResult)){ // 解析协议数据
|
||||||
|
osSemaphoreRelease(jt808_parse_ok_sem); // 释放解析完成信号量
|
||||||
|
JT808_DEBUG("jt808_msg_parse success\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发送任务
|
||||||
|
static void jt808_pkg_send_task(void *arg){
|
||||||
|
pkg_msg_t send_pkg_msg={0};
|
||||||
|
JT808MsgESC_t MsgESC={
|
||||||
|
.buf = NULL,
|
||||||
|
.len = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
while(1){
|
||||||
|
if(osOK == osMessageQueueGet(jt808_send_msg_queue, &send_pkg_msg, NULL, osWaitForever)){
|
||||||
|
if(0 == jt808_msg_pkg(send_pkg_msg.msg_id ,&MsgESC)){ // 生成协议数据成功
|
||||||
|
// 发送数据
|
||||||
|
if(NULL == MsgESC.buf){ // 协议数据为空(发生错误)
|
||||||
|
JT808_DEBUG("MsgESC.buf is NULL:len=%d\n",MsgESC.len);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
JT808_DEBUG("tcp send %d bytes\n", MsgESC.len);
|
||||||
|
if(0 == PKG_SEND(MsgESC.buf, MsgESC.len)){ // 发送成功处理
|
||||||
|
if(NULL != jt808_parse_ok_sem){
|
||||||
|
osStatus_t ret =osSemaphoreAcquire(jt808_parse_ok_sem, send_pkg_msg.timeout);// 等待接收数据并解析完成
|
||||||
|
if(ret == osOK || 0 == send_pkg_msg.timeout){
|
||||||
|
osSemaphoreRelease(jt808_send_ack_sem); // 释放发送成功应答信号量
|
||||||
|
JT808_DEBUG("parse success\n");
|
||||||
|
if(PrsResult.term_param_item!= NULL){ // 协议参数项不为空
|
||||||
|
PrsResult.term_param_item->msg_flow_num++; // 协议流水号+1
|
||||||
|
}else{
|
||||||
|
JT808_DEBUG("PrsResult.term_param_item is NULL\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
}else if(ret == osErrorTimeout){
|
||||||
|
JT808_DEBUG("parse timeout\n");
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
JT808_DEBUG("jt808_parse_ok_sem is NULL\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(MsgESC.buf!= NULL){ // 释放发送缓存
|
||||||
|
JT808_DEBUG("jt808_free MsgESC.buf\n");
|
||||||
|
jt808_free(MsgESC.buf);
|
||||||
|
MsgESC.buf = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// jt808协议初始化
|
||||||
|
int jt808_init(void){
|
||||||
|
if(jt808_send_msg_queue == NULL){
|
||||||
|
jt808_send_msg_queue = osMessageQueueNew(1, sizeof(pkg_msg_t), NULL);
|
||||||
|
}
|
||||||
|
if(jt808_send_ack_sem == NULL){
|
||||||
|
jt808_send_ack_sem = osSemaphoreNew(1, 0, NULL);
|
||||||
|
}
|
||||||
|
if(jt808_parse_ok_sem == NULL){
|
||||||
|
jt808_parse_ok_sem = osSemaphoreNew(1, 0, NULL);
|
||||||
|
}
|
||||||
|
osThreadAttr_t jt808_pkg_send_task_attr = {
|
||||||
|
.name = "jt808_pkg_send_task",
|
||||||
|
.stack_size = 1024,
|
||||||
|
.priority = osPriorityNormal,
|
||||||
|
};
|
||||||
|
jt808_pkg_send_ThreadId = osThreadNew((osThreadFunc_t)jt808_pkg_send_task, 0, &jt808_pkg_send_task_attr);
|
||||||
|
osDelay(200); // 等待线程启动
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,294 @@
|
||||||
|
#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 "cm_sys.h"
|
||||||
|
#include "cm_sim.h"
|
||||||
|
|
||||||
|
Term_Param_item_t jt808_term_param_item; // 终端参数项
|
||||||
|
|
||||||
|
// 控制车辆状态
|
||||||
|
void jt808_Set_CarStatus(uint8_t status){
|
||||||
|
// (void)status;
|
||||||
|
// TODO: 车辆控制状态
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取车辆状态
|
||||||
|
uint8_t jt808_Get_CarStatus(void){
|
||||||
|
// TODO: 车辆控制状态
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 设置终端参数
|
||||||
|
int jt808_setTermParam(set_TermParamID_t param_id, void *param, uint8_t param_len){
|
||||||
|
switch(param_id){
|
||||||
|
case HeartBeatInterval:{
|
||||||
|
jt808_term_param_item.set_term_param.HeartBeatInterval =Swap32(*(uint32_t*)param);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MainServerAddr:{
|
||||||
|
memcpy(jt808_term_param_item.set_term_param.MainServerAddr,param,50<param_len?param_len:50);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ServerPort:{
|
||||||
|
jt808_term_param_item.set_term_param.ServerPort =Swap32(*(uint32_t*)param);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DefaultTimeReportInterval:{
|
||||||
|
jt808_term_param_item.set_term_param.DefaultTimeReportInterval =Swap32(*(uint32_t*)param);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case InflexionAngle:{
|
||||||
|
jt808_term_param_item.set_term_param.InflexionAngle =Swap32(*(uint32_t*)param);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MaxSpeed:{
|
||||||
|
jt808_term_param_item.set_term_param.MaxSpeed =Swap32(*(uint32_t*)param);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ProvinceID:{
|
||||||
|
jt808_term_param_item.set_term_param.ProvinceID =Swap16(*(uint16_t*)param);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CityID:{
|
||||||
|
jt808_term_param_item.set_term_param.CityID =Swap16(*(uint16_t*)param);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CarPlateNum:{
|
||||||
|
memcpy(jt808_term_param_item.set_term_param.CarPlateNum,param,10<param_len?param_len:10);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CarPlateColor:{
|
||||||
|
jt808_term_param_item.set_term_param.CarPlateColor =((uint8_t*)param)[0];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:{
|
||||||
|
// TODO: 未知参数
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新位置基本信息
|
||||||
|
int jt808_updateLocBasicInfo(Loc_basic_info_t *loc_basic_info){
|
||||||
|
// (void *)loc_basic_info;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
osThreadFunc_t Autoreport_param_ThreadId;
|
||||||
|
|
||||||
|
void Autoreport_param_Task(void *arg){
|
||||||
|
uint32_t count_Sec = 0;// 计数器
|
||||||
|
nmeaTIME beiJingTime; // 北京时间
|
||||||
|
|
||||||
|
while(1){
|
||||||
|
// TODO: 自动上报参数
|
||||||
|
// 1. 位置基本信息
|
||||||
|
GMTconvert(&gps_data.info.utc, &beiJingTime, 8, 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.info.lat) * 1e6);
|
||||||
|
jt808_term_param_item.big_loc_report.basic_info.longitude = Swap32(nmea_ndeg2degree(gps_data.info.lon) * 1e6);
|
||||||
|
jt808_term_param_item.big_loc_report.basic_info.altitude = Swap16(gps_data.info.elv);
|
||||||
|
jt808_term_param_item.big_loc_report.basic_info.speed = Swap16(gps_data.info.speed * 10);
|
||||||
|
jt808_term_param_item.big_loc_report.basic_info.direction = Swap16(gps_data.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.acc =0; // 0:未开启,1:已开启
|
||||||
|
jt808_term_param_item.big_loc_report.basic_info.status.positioning = (0 == gps_data.info.sig) ? 0 : 1; // 0:未定位,1:已定位
|
||||||
|
jt808_term_param_item.big_loc_report.basic_info.status.door_lock = 0; // 0:未锁车,1:已锁车
|
||||||
|
jt808_term_param_item.big_loc_report.basic_info.status.operation = 0; // 0:运营状态; 1:停运状态
|
||||||
|
jt808_term_param_item.big_loc_report.basic_info.status.circuit_cut = 0; // 0:车辆电路正常; 1:车辆电路断开
|
||||||
|
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); // 报警标志(转大端)
|
||||||
|
|
||||||
|
// jt808_term_param_item.big_loc_report.basic_info.alarm_flag.gnss_fault = 0 == gps_data.info.sig ? 1 : 0; // 0:无故障,1:有故障
|
||||||
|
if(0 == (count_Sec % jt808_term_param_item.set_term_param.HeartBeatInterval)){
|
||||||
|
if(0 == jt808_term_param_item.big_loc_report.basic_info.status.positioning){ // 未定位时发送心跳包
|
||||||
|
jt808_pkg_send(ID_Term_HB,0); // 发送心跳包 // 不接收应答
|
||||||
|
}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 = 1024,
|
||||||
|
.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){
|
||||||
|
memset(&jt808_term_param_item,0,sizeof(Term_Param_item_t));
|
||||||
|
|
||||||
|
do{ // 设置终端手机号
|
||||||
|
char cm_iccid[32] = {0};
|
||||||
|
char get_iccid_ok = 0;
|
||||||
|
int error_count = 0;
|
||||||
|
while(error_count <= 20) {
|
||||||
|
memset(cm_iccid, 0, sizeof(cm_iccid));
|
||||||
|
get_iccid_ok = 0;
|
||||||
|
cm_sim_get_iccid(cm_iccid);
|
||||||
|
// 统计有效字符
|
||||||
|
for(int i = strlen(cm_iccid) - 1; i >= 8; i--) {
|
||||||
|
if(cm_iccid[i] >= '0' && cm_iccid[i] <= '9') {
|
||||||
|
get_iccid_ok++;
|
||||||
|
}else{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JT808_DEBUG("get_iccid_ok:%d\n",get_iccid_ok);
|
||||||
|
if(get_iccid_ok == 12){ // IC CID 获取成功
|
||||||
|
JT808_DEBUG("iccid:%d,:%s\n",strlen(cm_iccid), cm_iccid);
|
||||||
|
rawStrToBcd(jt808_term_param_item.phone_BCDnum, cm_iccid+8, 12); // 终端手机号码
|
||||||
|
break;
|
||||||
|
}else{
|
||||||
|
error_count++;
|
||||||
|
JT808_DEBUG("get iccid failed count:%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++){
|
||||||
|
app_printf("%02X ",jt808_term_param_item.phone_BCDnum[i]);
|
||||||
|
}
|
||||||
|
app_printf("\n");
|
||||||
|
}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);
|
||||||
|
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{// 终端参数初始化
|
||||||
|
jt808_term_param_item.set_term_param.HeartBeatInterval = 5; // 心跳包间隔(秒)
|
||||||
|
char ServerAddr[] ="47.99.118.34"; // 车牌号码
|
||||||
|
uint32_t ServerPort = 5000; // 服务器端口
|
||||||
|
// char ServerAddr[] ="36.137.226.30"; // 车牌号码
|
||||||
|
// uint32_t ServerPort = 36204; // 服务器端口
|
||||||
|
// 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; // 车牌颜色
|
||||||
|
}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);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,93 @@
|
||||||
|
#include "jt808_util.h"
|
||||||
|
#include "jt808_config.h"
|
||||||
|
|
||||||
|
// 双字节大小端转换
|
||||||
|
uint16_t Swap16(uint16_t val16){
|
||||||
|
return (((val16 & 0x00FF) << 8) |
|
||||||
|
((val16 & 0xFF00) >> 8));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 四字节大小端转换
|
||||||
|
uint32_t Swap32(uint32_t val32){
|
||||||
|
return (((val32 & 0x000000FF) << 24) |
|
||||||
|
((val32 & 0x0000FF00) << 8) |
|
||||||
|
((val32 & 0x00FF0000) >> 8) |
|
||||||
|
((val32 & 0xFF000000) >> 24));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 异或校验
|
||||||
|
uint8_t BCC_Check(const uint8_t *src, uint32_t len)
|
||||||
|
{
|
||||||
|
uint8_t bcc_check = 0;
|
||||||
|
for(uint32_t i = 0; i < len; ++i){
|
||||||
|
bcc_check ^= src[i];
|
||||||
|
}
|
||||||
|
return bcc_check;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 十进制转BCD码
|
||||||
|
uint8_t DecToBcd(uint8_t Dec){
|
||||||
|
uint8_t temp;
|
||||||
|
temp = ((Dec / 10) << 4) + (Dec % 10);
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// BCD码转十进制
|
||||||
|
uint8_t BcdToDec(uint8_t Bcd){
|
||||||
|
uint8_t temp;
|
||||||
|
temp = (Bcd >> 4) * 10 + (Bcd & 0x0f);
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 原始字符串转BCD码 //奇数位时,首位BCD码前面补0
|
||||||
|
uint8_t *rawStrToBcd(uint8_t *bcd, const uint8_t *str, uint16_t str_len){
|
||||||
|
uint8_t *ptr = bcd;
|
||||||
|
uint8_t temp;
|
||||||
|
if (str_len % 2 != 0){
|
||||||
|
*ptr++ = DecToBcd(*str++ - '0');
|
||||||
|
}
|
||||||
|
while (*str){
|
||||||
|
temp = *str++ - '0';
|
||||||
|
temp *= 10;
|
||||||
|
temp += *str++ - '0';
|
||||||
|
*ptr++ = DecToBcd(temp);
|
||||||
|
}
|
||||||
|
return bcd;
|
||||||
|
}
|
||||||
|
|
||||||
|
// BCD转字符串,自动去掉bcd码前导零
|
||||||
|
// bcdlen 为bcd码字节数
|
||||||
|
uint8_t *BcdToStr(uint8_t *str, const uint8_t *bcd, int bcd_len){
|
||||||
|
uint8_t *ptr = str;
|
||||||
|
uint8_t temp;
|
||||||
|
int cnt = bcd_len;
|
||||||
|
while (cnt--){
|
||||||
|
temp = BcdToDec(*bcd);
|
||||||
|
*ptr++ = temp / 10 + '0';
|
||||||
|
if(str[0] == '0'){
|
||||||
|
ptr = str;
|
||||||
|
}
|
||||||
|
*ptr++ = temp % 10 + '0';
|
||||||
|
if(str[0] == '0'){
|
||||||
|
ptr = str;
|
||||||
|
}
|
||||||
|
++bcd;
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 原始BCD数据转字符串
|
||||||
|
// strlen 为原始BCD数据字节数
|
||||||
|
uint8_t *rawBcdToStr(uint8_t *str, const uint8_t *bcd, int bcd_len){
|
||||||
|
uint8_t *ptr = str;
|
||||||
|
uint8_t temp;
|
||||||
|
int cnt = bcd_len;
|
||||||
|
while (cnt--)
|
||||||
|
{
|
||||||
|
temp = BcdToDec(*bcd);
|
||||||
|
*ptr++ = temp / 10 + '0';
|
||||||
|
*ptr++ = temp % 10 + '0';
|
||||||
|
++bcd;
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
@ -1,74 +0,0 @@
|
||||||
#include "location_report.h"
|
|
||||||
#include <string.h>
|
|
||||||
#include "util.h"
|
|
||||||
#include "jt808_debug.h"
|
|
||||||
|
|
||||||
// double const v_latitude = 23.123456;
|
|
||||||
// double const v_longitude = 123.123456;
|
|
||||||
// float const v_altitude=10;
|
|
||||||
// float const v_speed=10;
|
|
||||||
// float const v_bearing=100;
|
|
||||||
// unsigned char *v_timestamp = "211221213045";
|
|
||||||
|
|
||||||
// void initGPSInfo(struct ProtocolParameter *para, unsigned int v_alarm_value,
|
|
||||||
// unsigned int v_status_value, double const v_latitude,
|
|
||||||
// double const v_longitude, float const v_altitude,
|
|
||||||
// float const v_speed, float const v_bearing,
|
|
||||||
// unsigned char *v_timestamp)
|
|
||||||
// {
|
|
||||||
// JT808_DEBUG("\n\r[initGPSInfo] OK !\n");
|
|
||||||
// //报警标志
|
|
||||||
// para->location_info.alarm.value = v_alarm_value;
|
|
||||||
// JT808_DEBUG("para->alarm.value = %d\n", para->location_info.alarm.value);
|
|
||||||
// //状态
|
|
||||||
// para->location_info.status.value = v_status_value;
|
|
||||||
// JT808_DEBUG("para->status.value = %d\n", para->location_info.status.value);
|
|
||||||
|
|
||||||
// // if (speed >= 10) //默认车速大于等于10公里时为正常行驶状态
|
|
||||||
// // {
|
|
||||||
// // isCarMoving.store(true);
|
|
||||||
// // }
|
|
||||||
// // else
|
|
||||||
// // {
|
|
||||||
// // isCarMoving.store(false);
|
|
||||||
// // }
|
|
||||||
// para->location_info.latitude = v_latitude * 1e6;
|
|
||||||
// JT808_DEBUG("para->latitude = %d\n", para->location_info.latitude);
|
|
||||||
|
|
||||||
// para->location_info.longitude = v_longitude * 1e6;
|
|
||||||
// JT808_DEBUG("para->longitude = %d\n", para->location_info.longitude);
|
|
||||||
|
|
||||||
// para->location_info.altitude = v_altitude;
|
|
||||||
// JT808_DEBUG("para->altitude = %d\n", para->location_info.altitude);
|
|
||||||
|
|
||||||
// para->location_info.speed = v_speed * 10;
|
|
||||||
// JT808_DEBUG("para->speed = %d\n", para->location_info.speed);
|
|
||||||
|
|
||||||
// para->location_info.bearing = v_bearing;
|
|
||||||
// JT808_DEBUG("para->bearing = %d\n", para->location_info.bearing);
|
|
||||||
|
|
||||||
// para->location_info.time = v_timestamp;
|
|
||||||
// JT808_DEBUG("para->time = %s\n", para->location_info.time);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// void UpdateLocation(double const latitude, double const longitude,
|
|
||||||
// float const altitude, float const speed,
|
|
||||||
// float const bearing, unsigned char *timestamp)
|
|
||||||
// {
|
|
||||||
// // if (speed >= 10) //默认车速大于等于10公里时为正常行驶状态
|
|
||||||
// // {
|
|
||||||
// // isCarMoving.store(true);
|
|
||||||
// // }
|
|
||||||
// // else
|
|
||||||
// // {
|
|
||||||
// // isCarMoving.store(false);
|
|
||||||
// // }
|
|
||||||
// para->location_info.latitude = static_cast<uint32_t>(latitude * 1e6);
|
|
||||||
// para->location_info.longitude = static_cast<uint32_t>(longitude * 1e6);
|
|
||||||
// para->location_info.altitude = static_cast<uint16_t>(altitude);
|
|
||||||
// para->location_info.speed = static_cast<uint16_t>(speed * 10);
|
|
||||||
// para->location_info.bearing = static_cast<uint16_t>(bearing);
|
|
||||||
// para->location_info.time.assign(timestamp.begin(), timestamp.end());
|
|
||||||
|
|
||||||
// // spdlog::info("[{}] [{}] 更新上报位置信息 ", libjt808::getCurrentFileName(__FILE__), __LINE__);
|
|
||||||
// }
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#include "set_terminal_parameter.h"
|
#include "set_terminal_parameter.h"
|
||||||
#include "terminal_parameter.h"
|
#include "terminal_parameter.h"
|
||||||
#include "client_manager.h"
|
#include "client_manager.h"
|
||||||
#include "jt808_debug.h"
|
#include "jt808_config.h"
|
||||||
|
|
||||||
unsigned short kParameterSettingCMD[PARA_SETTING_LIMIT] = {
|
unsigned short kParameterSettingCMD[PARA_SETTING_LIMIT] = {
|
||||||
kTerminalHeartBeatInterval, // DWORD, 终端心跳发送间隔(s).
|
kTerminalHeartBeatInterval, // DWORD, 终端心跳发送间隔(s).
|
||||||
|
|
@ -93,7 +93,7 @@ void handle_HeartBeatInterval(unsigned char *buf, unsigned char buf_len, struct
|
||||||
if ((buf == NULL) || (buf_len == 0))
|
if ((buf == NULL) || (buf_len == 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
p = (unsigned char *)malloc(sizeof(unsigned char) * buf_len);
|
p = (unsigned char *)jt808_malloc(sizeof(unsigned char) * buf_len);
|
||||||
memcpy(p, buf, buf_len);
|
memcpy(p, buf, buf_len);
|
||||||
|
|
||||||
memcpy(u32converter.u8array, p, buf_len);
|
memcpy(u32converter.u8array, p, buf_len);
|
||||||
|
|
@ -103,7 +103,7 @@ void handle_HeartBeatInterval(unsigned char *buf, unsigned char buf_len, struct
|
||||||
JT808_DEBUG("handle_HeartBeatInterval ==== %d \r\n", para->parse.terminal_parameters.HeartBeatInterval);
|
JT808_DEBUG("handle_HeartBeatInterval ==== %d \r\n", para->parse.terminal_parameters.HeartBeatInterval);
|
||||||
// FLASH_WriteByte(FLASH_ADDR , (uint8_t *) ¶->parse.terminal_parameters , sizeof(para->parse.terminal_parameters));
|
// FLASH_WriteByte(FLASH_ADDR , (uint8_t *) ¶->parse.terminal_parameters , sizeof(para->parse.terminal_parameters));
|
||||||
|
|
||||||
free(p);
|
jt808_free(p);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -114,7 +114,7 @@ void handle_MainServerAddress(unsigned char *buf, unsigned char buf_len, struct
|
||||||
if ((buf == NULL) || (buf_len == 0))
|
if ((buf == NULL) || (buf_len == 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
p = (unsigned char *)malloc(sizeof(unsigned char) * (buf_len + 1));
|
p = (unsigned char *)jt808_malloc(sizeof(unsigned char) * (buf_len + 1));
|
||||||
memcpy(p, buf, buf_len);
|
memcpy(p, buf, buf_len);
|
||||||
|
|
||||||
// 字符串注意GBK转码
|
// 字符串注意GBK转码
|
||||||
|
|
@ -122,7 +122,7 @@ void handle_MainServerAddress(unsigned char *buf, unsigned char buf_len, struct
|
||||||
memcpy(para->parse.terminal_parameters.MainServerAddress, p, buf_len);
|
memcpy(para->parse.terminal_parameters.MainServerAddress, p, buf_len);
|
||||||
// FLASH_WriteByte(FLASH_ADDR , (uint8_t *) ¶->parse.terminal_parameters , sizeof(para->parse.terminal_parameters));
|
// FLASH_WriteByte(FLASH_ADDR , (uint8_t *) ¶->parse.terminal_parameters , sizeof(para->parse.terminal_parameters));
|
||||||
JT808_DEBUG("handle_MainServerAddress ==== %s \r\n", para->parse.terminal_parameters.MainServerAddress);
|
JT808_DEBUG("handle_MainServerAddress ==== %s \r\n", para->parse.terminal_parameters.MainServerAddress);
|
||||||
free(p);
|
jt808_free(p);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -136,7 +136,7 @@ void handle_ServerPort(unsigned char *buf, unsigned char buf_len, struct Protoco
|
||||||
if ((buf == NULL) || (buf_len == 0))
|
if ((buf == NULL) || (buf_len == 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
p = (unsigned char *)malloc(sizeof(unsigned char) * buf_len);
|
p = (unsigned char *)jt808_malloc(sizeof(unsigned char) * buf_len);
|
||||||
memcpy(p, buf, buf_len);
|
memcpy(p, buf, buf_len);
|
||||||
|
|
||||||
memcpy(u32converter.u8array, p, buf_len);
|
memcpy(u32converter.u8array, p, buf_len);
|
||||||
|
|
@ -145,7 +145,7 @@ void handle_ServerPort(unsigned char *buf, unsigned char buf_len, struct Protoco
|
||||||
para->parse.terminal_parameters.ServerPort = serverPort;
|
para->parse.terminal_parameters.ServerPort = serverPort;
|
||||||
// FLASH_WriteByte(FLASH_ADDR , (uint8_t *) ¶->parse.terminal_parameters , sizeof(para->parse.terminal_parameters));
|
// FLASH_WriteByte(FLASH_ADDR , (uint8_t *) ¶->parse.terminal_parameters , sizeof(para->parse.terminal_parameters));
|
||||||
JT808_DEBUG("handle_ServerPort ==== %d \r\n", para->parse.terminal_parameters.ServerPort);
|
JT808_DEBUG("handle_ServerPort ==== %d \r\n", para->parse.terminal_parameters.ServerPort);
|
||||||
free(p);
|
jt808_free(p);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -158,7 +158,7 @@ void handle_DefaultTimeReportTimeInterval(unsigned char *buf, unsigned char buf_
|
||||||
if ((buf == NULL) || (buf_len == 0))
|
if ((buf == NULL) || (buf_len == 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
p = (unsigned char *)malloc(sizeof(unsigned char) * buf_len);
|
p = (unsigned char *)jt808_malloc(sizeof(unsigned char) * buf_len);
|
||||||
memcpy(p, buf, buf_len);
|
memcpy(p, buf, buf_len);
|
||||||
|
|
||||||
memcpy(u32converter.u8array, p, buf_len);
|
memcpy(u32converter.u8array, p, buf_len);
|
||||||
|
|
@ -174,7 +174,7 @@ void handle_DefaultTimeReportTimeInterval(unsigned char *buf, unsigned char buf_
|
||||||
para->parse.terminal_parameters.DefaultTimeReportTimeInterval = DefaultTimeReportTimeInterval;
|
para->parse.terminal_parameters.DefaultTimeReportTimeInterval = DefaultTimeReportTimeInterval;
|
||||||
// FLASH_WriteByte(FLASH_ADDR , (uint8_t *) ¶->parse.terminal_parameters , sizeof(para->parse.terminal_parameters));
|
// FLASH_WriteByte(FLASH_ADDR , (uint8_t *) ¶->parse.terminal_parameters , sizeof(para->parse.terminal_parameters));
|
||||||
JT808_DEBUG("handle_DefaultTimeReportTimeInterval ==== %d \r\n", para->parse.terminal_parameters.DefaultTimeReportTimeInterval);
|
JT808_DEBUG("handle_DefaultTimeReportTimeInterval ==== %d \r\n", para->parse.terminal_parameters.DefaultTimeReportTimeInterval);
|
||||||
free(p);
|
jt808_free(p);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -187,7 +187,7 @@ void handle_CornerPointRetransmissionAngle(unsigned char *buf, unsigned char buf
|
||||||
if ((buf == NULL) || (buf_len == 0))
|
if ((buf == NULL) || (buf_len == 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
p = (unsigned char *)malloc(sizeof(unsigned char) * buf_len);
|
p = (unsigned char *)jt808_malloc(sizeof(unsigned char) * buf_len);
|
||||||
memcpy(p, buf, buf_len);
|
memcpy(p, buf, buf_len);
|
||||||
|
|
||||||
memcpy(u32converter.u8array, p, buf_len);
|
memcpy(u32converter.u8array, p, buf_len);
|
||||||
|
|
@ -196,7 +196,7 @@ void handle_CornerPointRetransmissionAngle(unsigned char *buf, unsigned char buf
|
||||||
para->parse.terminal_parameters.CornerPointRetransmissionAngle = CornerPointRetransmissionAngle;
|
para->parse.terminal_parameters.CornerPointRetransmissionAngle = CornerPointRetransmissionAngle;
|
||||||
// FLASH_WriteByte(FLASH_ADDR , (uint8_t *) ¶->parse.terminal_parameters , sizeof(para->parse.terminal_parameters));
|
// FLASH_WriteByte(FLASH_ADDR , (uint8_t *) ¶->parse.terminal_parameters , sizeof(para->parse.terminal_parameters));
|
||||||
JT808_DEBUG("handle_DefaultTimeReportTimeInterval ==== %d \r\n", para->parse.terminal_parameters.DefaultTimeReportTimeInterval);
|
JT808_DEBUG("handle_DefaultTimeReportTimeInterval ==== %d \r\n", para->parse.terminal_parameters.DefaultTimeReportTimeInterval);
|
||||||
free(p);
|
jt808_free(p);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -209,7 +209,7 @@ void handle_MaxSpeed(unsigned char *buf, unsigned char buf_len, struct ProtocolP
|
||||||
if ((buf == NULL) || (buf_len == 0))
|
if ((buf == NULL) || (buf_len == 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
p = (unsigned char *)malloc(sizeof(unsigned char) * buf_len);
|
p = (unsigned char *)jt808_malloc(sizeof(unsigned char) * buf_len);
|
||||||
memcpy(p, buf, buf_len);
|
memcpy(p, buf, buf_len);
|
||||||
|
|
||||||
memcpy(u32converter.u8array, p, buf_len);
|
memcpy(u32converter.u8array, p, buf_len);
|
||||||
|
|
@ -218,7 +218,7 @@ void handle_MaxSpeed(unsigned char *buf, unsigned char buf_len, struct ProtocolP
|
||||||
para->parse.terminal_parameters.MaxSpeed = MaxSpeed;
|
para->parse.terminal_parameters.MaxSpeed = MaxSpeed;
|
||||||
// FLASH_WriteByte(FLASH_ADDR, (uint8_t *) ¶->parse.terminal_parameters , sizeof(para->parse.terminal_parameters));
|
// FLASH_WriteByte(FLASH_ADDR, (uint8_t *) ¶->parse.terminal_parameters , sizeof(para->parse.terminal_parameters));
|
||||||
JT808_DEBUG("handle_MaxSpeed ==== %d \r\n", para->parse.terminal_parameters.MaxSpeed);
|
JT808_DEBUG("handle_MaxSpeed ==== %d \r\n", para->parse.terminal_parameters.MaxSpeed);
|
||||||
free(p);
|
jt808_free(p);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -231,7 +231,7 @@ void handle_ProvinceID(unsigned char *buf, unsigned char buf_len, struct Protoco
|
||||||
if ((buf == NULL) || (buf_len == 0))
|
if ((buf == NULL) || (buf_len == 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
p = (unsigned char *)malloc(sizeof(unsigned char) * buf_len);
|
p = (unsigned char *)jt808_malloc(sizeof(unsigned char) * buf_len);
|
||||||
memcpy(p, buf, buf_len);
|
memcpy(p, buf, buf_len);
|
||||||
|
|
||||||
memcpy(u16converter.u8array, p, buf_len);
|
memcpy(u16converter.u8array, p, buf_len);
|
||||||
|
|
@ -240,7 +240,7 @@ void handle_ProvinceID(unsigned char *buf, unsigned char buf_len, struct Protoco
|
||||||
para->parse.terminal_parameters.ProvinceID = ProvinceID;
|
para->parse.terminal_parameters.ProvinceID = ProvinceID;
|
||||||
// FLASH_WriteByte(FLASH_ADDR , (uint8_t *) ¶->parse.terminal_parameters , sizeof(para->parse.terminal_parameters));
|
// FLASH_WriteByte(FLASH_ADDR , (uint8_t *) ¶->parse.terminal_parameters , sizeof(para->parse.terminal_parameters));
|
||||||
JT808_DEBUG("handle_ProvinceID ==== %d \r\n", para->parse.terminal_parameters.ProvinceID);
|
JT808_DEBUG("handle_ProvinceID ==== %d \r\n", para->parse.terminal_parameters.ProvinceID);
|
||||||
free(p);
|
jt808_free(p);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -253,7 +253,7 @@ void handle_CityID(unsigned char *buf, unsigned char buf_len, struct ProtocolPar
|
||||||
if ((buf == NULL) || (buf_len == 0))
|
if ((buf == NULL) || (buf_len == 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
p = (unsigned char *)malloc(sizeof(unsigned char) * buf_len);
|
p = (unsigned char *)jt808_malloc(sizeof(unsigned char) * buf_len);
|
||||||
memcpy(p, buf, buf_len);
|
memcpy(p, buf, buf_len);
|
||||||
|
|
||||||
memcpy(u16converter.u8array, p, buf_len);
|
memcpy(u16converter.u8array, p, buf_len);
|
||||||
|
|
@ -262,7 +262,7 @@ void handle_CityID(unsigned char *buf, unsigned char buf_len, struct ProtocolPar
|
||||||
para->parse.terminal_parameters.CityID = CityID;
|
para->parse.terminal_parameters.CityID = CityID;
|
||||||
// FLASH_WriteByte(FLASH_ADDR, (uint8_t *) ¶->parse.terminal_parameters , sizeof(para->parse.terminal_parameters));
|
// FLASH_WriteByte(FLASH_ADDR, (uint8_t *) ¶->parse.terminal_parameters , sizeof(para->parse.terminal_parameters));
|
||||||
JT808_DEBUG("handle_CityID ==== %d \r\n", para->parse.terminal_parameters.CityID);
|
JT808_DEBUG("handle_CityID ==== %d \r\n", para->parse.terminal_parameters.CityID);
|
||||||
free(p);
|
jt808_free(p);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -274,14 +274,14 @@ void handle_CarPlateNum(unsigned char *buf, unsigned char buf_len, struct Protoc
|
||||||
if ((buf == NULL) || (buf_len == 0))
|
if ((buf == NULL) || (buf_len == 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
p = (unsigned char *)malloc(sizeof(unsigned char) * buf_len + 1);
|
p = (unsigned char *)jt808_malloc(sizeof(unsigned char) * buf_len + 1);
|
||||||
memcpy(p, buf, buf_len);
|
memcpy(p, buf, buf_len);
|
||||||
|
|
||||||
memset(para->parse.terminal_parameters.CarPlateNum, 0, sizeof(para->parse.terminal_parameters.CarPlateNum));
|
memset(para->parse.terminal_parameters.CarPlateNum, 0, sizeof(para->parse.terminal_parameters.CarPlateNum));
|
||||||
memcpy(para->parse.terminal_parameters.CarPlateNum, p, buf_len);
|
memcpy(para->parse.terminal_parameters.CarPlateNum, p, buf_len);
|
||||||
// FLASH_WriteByte(FLASH_ADDR , (uint8_t *) ¶->parse.terminal_parameters , sizeof(para->parse.terminal_parameters));
|
// FLASH_WriteByte(FLASH_ADDR , (uint8_t *) ¶->parse.terminal_parameters , sizeof(para->parse.terminal_parameters));
|
||||||
JT808_DEBUG("handle_CarPlateNum ==== %s \r\n", para->parse.terminal_parameters.CarPlateNum);
|
JT808_DEBUG("handle_CarPlateNum ==== %s \r\n", para->parse.terminal_parameters.CarPlateNum);
|
||||||
free(p);
|
jt808_free(p);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -292,13 +292,13 @@ void handle_CarPlateColor(unsigned char *buf, unsigned char buf_len, struct Prot
|
||||||
// unsigned char write_buf[FLASH_BUFFER_SIZE] = {0};
|
// unsigned char write_buf[FLASH_BUFFER_SIZE] = {0};
|
||||||
if ((buf == NULL) || (buf_len == 0))
|
if ((buf == NULL) || (buf_len == 0))
|
||||||
return;
|
return;
|
||||||
p = (unsigned char *)malloc(sizeof(unsigned char) * buf_len + 1);
|
p = (unsigned char *)jt808_malloc(sizeof(unsigned char) * buf_len + 1);
|
||||||
memcpy(p, buf, buf_len);
|
memcpy(p, buf, buf_len);
|
||||||
|
|
||||||
para->parse.terminal_parameters.CarPlateColor = *p;
|
para->parse.terminal_parameters.CarPlateColor = *p;
|
||||||
// FLASH_WriteByte(FLASH_ADDR , (uint8_t *) ¶->parse.terminal_parameters , sizeof(para->parse.terminal_parameters));
|
// FLASH_WriteByte(FLASH_ADDR , (uint8_t *) ¶->parse.terminal_parameters , sizeof(para->parse.terminal_parameters));
|
||||||
JT808_DEBUG("handle_CarPlateColor ==== 0x%02x \r\n", para->parse.terminal_parameters.CarPlateColor);
|
JT808_DEBUG("handle_CarPlateColor ==== 0x%02x \r\n", para->parse.terminal_parameters.CarPlateColor);
|
||||||
free(p);
|
jt808_free(p);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#include "terminal_register.h"
|
#include "terminal_register.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "jt808_debug.h"
|
#include "jt808_config.h"
|
||||||
|
|
||||||
struct RegisterInfo registerInfo_;
|
struct RegisterInfo registerInfo_;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "protocol_parameter.h"
|
#include "protocol_parameter.h"
|
||||||
#include "client_manager.h"
|
#include "client_manager.h"
|
||||||
#include "jt808_debug.h"
|
#include "jt808_config.h"
|
||||||
|
|
||||||
union U16ToU8Array u16converter;
|
union U16ToU8Array u16converter;
|
||||||
union U32ToU8Array u32converter;
|
union U32ToU8Array u32converter;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
#ifndef __LOCAL_TTS_H__
|
||||||
|
#define __LOCAL_TTS_H__
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "cm_local_tts.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void local_tts_init(void);
|
||||||
|
|
||||||
|
// 静音 mute: 0-关闭 1-打开
|
||||||
|
void local_tts_mute(uint8_t mute);
|
||||||
|
|
||||||
|
// 音量设置 volume: 0-100
|
||||||
|
uint8_t local_tts_volume(uint8_t volume);
|
||||||
|
|
||||||
|
// speed: 语速,取值范围0-15,默认为5
|
||||||
|
// volume: 音量,取值范围0-15,默认为5
|
||||||
|
// mode: 0-自动模式 1-数字模式,2-数值模式
|
||||||
|
void local_tts_set(int32_t speed, int32_t volume, cm_local_tts_digit_e mode);
|
||||||
|
|
||||||
|
// 本地TTS播放
|
||||||
|
int8_t local_tts_text_play(char *text, uint8_t len, uint32_t timeout);
|
||||||
|
|
||||||
|
#endif // __LOCAL_TTS_H__
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
CUSTOM_MAIN_DIR := custom/local_tts
|
||||||
|
|
||||||
|
OC_FILES += $(CUSTOM_MAIN_DIR)/src/local_tts.c
|
||||||
|
|
||||||
|
INC += -I'$(CUSTOM_MAIN_DIR)/inc'
|
||||||
|
|
@ -0,0 +1,173 @@
|
||||||
|
#include "stdio.h"
|
||||||
|
#include "stdlib.h"
|
||||||
|
#include "cm_fs.h"
|
||||||
|
#include "cm_mem.h"
|
||||||
|
#include "cm_sys.h"
|
||||||
|
#include "cm_gpio.h"
|
||||||
|
#include "cm_iomux.h"
|
||||||
|
#include "cm_modem.h"
|
||||||
|
|
||||||
|
#include "cm_audio_player.h"
|
||||||
|
#include "cm_audio_recorder.h"
|
||||||
|
#include "cm_local_tts.h"
|
||||||
|
|
||||||
|
#include "local_tts.h"
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
#include "app_uart.h"
|
||||||
|
#define DEBUG(fmt, args...) app_printf("[tts]" fmt, ##args)
|
||||||
|
#else
|
||||||
|
#define DEBUG(fmt, arg...)
|
||||||
|
#endif
|
||||||
|
static osMessageQueueId_t local_tts_play_queue = NULL;
|
||||||
|
static osSemaphoreId_t local_tts_play_ok_sem = NULL;
|
||||||
|
|
||||||
|
/* 离线TTS回调函数 */
|
||||||
|
static void __local_tts_callback(cm_local_tts_event_e event, void *param)
|
||||||
|
{
|
||||||
|
switch(event){
|
||||||
|
case CM_LOCAL_TTS_EVENT_SYNTH_DATA:{
|
||||||
|
// cm_local_tts_synth_data_t *data = (cm_local_tts_synth_data_t *)param;
|
||||||
|
// DEBUG("[%s] SYNTH_DATA [%d] \n", data->user, data->len); //打印log操作较费时
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CM_LOCAL_TTS_EVENT_SYNTH_FAIL:
|
||||||
|
case CM_LOCAL_TTS_EVENT_SYNTH_INTERRUPT:
|
||||||
|
case CM_LOCAL_TTS_EVENT_SYNTH_FINISH:
|
||||||
|
break;
|
||||||
|
case CM_LOCAL_TTS_EVENT_PLAY_FAIL:
|
||||||
|
DEBUG("[%s] PLAY_FAIL\n", (char *)param);
|
||||||
|
break;
|
||||||
|
case CM_LOCAL_TTS_EVENT_PLAY_INTERRUPT:
|
||||||
|
DEBUG("[[%s] PLAY_INTERRUPT\n", (char *)param);
|
||||||
|
break;
|
||||||
|
case CM_LOCAL_TTS_EVENT_PLAY_FINISH:
|
||||||
|
DEBUG("[%s] PLAY_FINISH\n", (char *)param);
|
||||||
|
osSemaphoreRelease(local_tts_play_ok_sem); // 释放发送成功应答信号量
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 静音 mute: 0-关闭 1-打开
|
||||||
|
void local_tts_mute(uint8_t mute){
|
||||||
|
cm_gpio_set_level(CM_GPIO_NUM_13, mute? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 音量设置 volume: 0-100
|
||||||
|
uint8_t local_tts_volume(uint8_t volume){
|
||||||
|
uint8_t ret;
|
||||||
|
if(volume > 100){
|
||||||
|
volume = 100;
|
||||||
|
}
|
||||||
|
cm_audio_play_set_cfg(CM_AUDIO_PLAY_CFG_VOLUME, &volume); //音量设置 0-100
|
||||||
|
cm_audio_play_get_cfg(CM_AUDIO_PLAY_CFG_VOLUME, &ret);
|
||||||
|
DEBUG("[AUDIO] volume:%d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// speed: 语速,取值范围0-15,默认为5
|
||||||
|
// volume: 音量,取值范围0-15,默认为5
|
||||||
|
// mode: 0-自动模式 1-数字模式,2-数值模式
|
||||||
|
void local_tts_set(int32_t speed, int32_t volume, cm_local_tts_digit_e mode){
|
||||||
|
cm_local_tts_deinit();
|
||||||
|
|
||||||
|
cm_local_tts_cfg_t tts_cfg = {0};
|
||||||
|
tts_cfg.speed = speed;
|
||||||
|
tts_cfg.volume = volume;
|
||||||
|
tts_cfg.encode = CM_LOCAL_TTS_ENCODE_TYPE_UTF8; // 离线TTS仅支持UTF8格式
|
||||||
|
tts_cfg.digit = mode;
|
||||||
|
|
||||||
|
if(0 == cm_local_tts_init(&tts_cfg)){
|
||||||
|
DEBUG("tts set:speed %d,volume %d,encode %d,digit %d\n" , tts_cfg.speed, tts_cfg.volume, tts_cfg.encode, tts_cfg.digit);
|
||||||
|
}else{
|
||||||
|
DEBUG("tts set error\n");
|
||||||
|
}
|
||||||
|
osDelay(100/5); // 等待初始化完成
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
char *text;
|
||||||
|
uint8_t len;
|
||||||
|
}tts_play_queue_t;
|
||||||
|
|
||||||
|
// 发送本地TTS播放内容 //timeout=osWaitForever时表示等待播放完成
|
||||||
|
int8_t local_tts_text_play(char *text, uint8_t len, uint32_t timeout){
|
||||||
|
tts_play_queue_t tts_play_queue = {0};
|
||||||
|
|
||||||
|
local_tts_mute(0); // 取消静音
|
||||||
|
|
||||||
|
if(0 == len || len > strlen(text)){
|
||||||
|
len = strlen(text);
|
||||||
|
DEBUG("tts play text len > len:%d \n", len);
|
||||||
|
}
|
||||||
|
tts_play_queue.text = cm_malloc(len + 1);
|
||||||
|
if(tts_play_queue.text == NULL){
|
||||||
|
DEBUG("tts play malloc error\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memcpy(tts_play_queue.text, text, len);
|
||||||
|
tts_play_queue.text[len] = '\0';
|
||||||
|
tts_play_queue.len = len;
|
||||||
|
if(osOK != osMessageQueuePut(local_tts_play_queue, &tts_play_queue, 0, 0)){
|
||||||
|
DEBUG("tts play queue put error\n");
|
||||||
|
cm_free(tts_play_queue.text);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// 等待播放完成
|
||||||
|
osSemaphoreAcquire(local_tts_play_ok_sem, timeout);
|
||||||
|
DEBUG("tts play queue put success\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 异步播放,播放完成后播放下一条 //TODO: 待优化(暂时方案,打断播放)
|
||||||
|
static osThreadFunc_t local_tts_play_task(void *arg){
|
||||||
|
tts_play_queue_t tts_play_queue;
|
||||||
|
|
||||||
|
while(1){
|
||||||
|
if(osOK == osMessageQueueGet(local_tts_play_queue, &tts_play_queue, NULL, osWaitForever)){ //
|
||||||
|
DEBUG("tts play stop\n");
|
||||||
|
cm_local_tts_play_stop(); // 停止播放
|
||||||
|
osDelay(200/5); // 等待播放停止
|
||||||
|
if(tts_play_queue.text == NULL){
|
||||||
|
DEBUG("tts play text is null\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
DEBUG("tts play start\n");
|
||||||
|
cm_local_tts_play(tts_play_queue.text, tts_play_queue.len, __local_tts_callback,"Chinese");
|
||||||
|
cm_free(tts_play_queue.text);
|
||||||
|
tts_play_queue.text = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化
|
||||||
|
void local_tts_init(void){
|
||||||
|
cm_gpio_cfg_t cfg = {0};
|
||||||
|
cfg.direction = CM_GPIO_DIRECTION_OUTPUT;
|
||||||
|
cfg.pull = CM_GPIO_PULL_UP;
|
||||||
|
|
||||||
|
cm_iomux_set_pin_func(CM_IOMUX_PIN_77, CM_IOMUX_FUNC_FUNCTION2);//初始化之前一定要先设置引脚复用
|
||||||
|
cm_gpio_init(CM_GPIO_NUM_13, &cfg);
|
||||||
|
|
||||||
|
local_tts_mute(1); // 关闭静音
|
||||||
|
local_tts_volume(100); // 设置音量为50
|
||||||
|
|
||||||
|
local_tts_set(7, 5, CM_LOCAL_TTS_DIGIT_AUTO); // 设置TTS转换参数
|
||||||
|
|
||||||
|
if(local_tts_play_queue == NULL){
|
||||||
|
local_tts_play_queue = osMessageQueueNew(10, sizeof(tts_play_queue_t), NULL);
|
||||||
|
}
|
||||||
|
if(local_tts_play_ok_sem == NULL){
|
||||||
|
local_tts_play_ok_sem = osSemaphoreNew(1, 0, NULL);
|
||||||
|
}
|
||||||
|
osThreadAttr_t local_tts_play_thread_attr = {
|
||||||
|
.name = "local_tts_play_thread",
|
||||||
|
.stack_size = 4096 * 4,
|
||||||
|
.priority = osPriorityNormal
|
||||||
|
};
|
||||||
|
osThreadNew((osThreadFunc_t)local_tts_play_task, NULL, &local_tts_play_thread_attr);
|
||||||
|
}
|
||||||
|
|
@ -49,8 +49,8 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "cm_mem.h"
|
#include "cm_mem.h"
|
||||||
#define name_malloc(size) cm_malloc(size)
|
#define name_malloc(size) malloc(size)
|
||||||
#define name_free(ptr) cm_free(ptr)
|
#define name_free(ptr) free(ptr)
|
||||||
|
|
||||||
|
|
||||||
#endif /* __NMEA_CONFIG_H__ */
|
#endif /* __NMEA_CONFIG_H__ */
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
#ifndef __TCP_CLIENT_H__
|
||||||
|
#define __TCP_CLIENT_H__
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "string.h"
|
||||||
|
#include "cm_os.h"
|
||||||
|
|
||||||
|
#define TCP_HOST "36.137.226.30" //TCP地址 例"192.168.0.1"
|
||||||
|
#define TCP_PORT 38840 //TCP端口
|
||||||
|
|
||||||
|
// 连接TCP服务器
|
||||||
|
int tcp_client_connect(const char *host, int port);
|
||||||
|
|
||||||
|
// 发送数据到TCP服务器
|
||||||
|
int tcp_client_send(const uint8_t *buf, uint16_t len);
|
||||||
|
|
||||||
|
// 关闭TCP连接
|
||||||
|
void tcp_client_close(void);
|
||||||
|
|
||||||
|
// 初始化TCP客户端
|
||||||
|
void tcp_client_init(void);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __TCP_CLIENT_H__ */
|
||||||
|
|
@ -0,0 +1,227 @@
|
||||||
|
#include "lwip/lwip/netdb.h"
|
||||||
|
#include "lwip/lwip/sockets.h"
|
||||||
|
#include "cm_modem.h"
|
||||||
|
#include "cm_pm.h"
|
||||||
|
|
||||||
|
#include "jt808_msg_pkg.h"
|
||||||
|
#include "jt808_msg_parse.h"
|
||||||
|
#include "jt808_pkg_transmit.h"
|
||||||
|
#include "jt808_set_TermParam.h"
|
||||||
|
#include "tcp_client.h"
|
||||||
|
#include "app_common.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define TCP_CLIENT_ENABLE 1
|
||||||
|
|
||||||
|
#if TCP_CLIENT_ENABLE
|
||||||
|
#include "app_uart.h"
|
||||||
|
#define DEBUG(fmt, args...) app_printf("[TCP]" fmt, ##args)
|
||||||
|
#else
|
||||||
|
#define DEBUG(fmt, arg...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int tcp_client_sock = -1;
|
||||||
|
static osThreadId_t tcp_recv_ThreadId = NULL;
|
||||||
|
static osThreadId_t net_manage_ThreadId = NULL;
|
||||||
|
osSemaphoreId_t netconn_disconnect_sem = NULL; // 断开连接信号量
|
||||||
|
|
||||||
|
// TCP接收线程
|
||||||
|
static void tcp_recv_task(void){
|
||||||
|
int ret = 0;
|
||||||
|
fd_set sets;
|
||||||
|
struct timeval timeout;
|
||||||
|
uint8_t buf[128] = {0};
|
||||||
|
|
||||||
|
while(1){
|
||||||
|
FD_ZERO(&sets);
|
||||||
|
FD_SET(tcp_client_sock, &sets);
|
||||||
|
|
||||||
|
timeout.tv_sec = 10;
|
||||||
|
timeout.tv_usec = 0;
|
||||||
|
ret = select(tcp_client_sock + 1, &sets, NULL, NULL, &timeout);//监听套接字
|
||||||
|
if(ret > 0){ // 发生状态变化,可以进行读取、写入或者有异常事件
|
||||||
|
// DEBUG("tcp_read select ret %d\n", ret);
|
||||||
|
if(FD_ISSET(tcp_client_sock, &sets)){ // 套接字可读
|
||||||
|
ret = recv(tcp_client_sock, buf, sizeof(buf), 0);
|
||||||
|
if(ret > 0){
|
||||||
|
DEBUG("tcp_read recv:%d\n", ret);
|
||||||
|
for(int i = 0; i < ret; i++){
|
||||||
|
app_printf("%02x ", buf[i]);
|
||||||
|
}
|
||||||
|
app_printf("\n\n");
|
||||||
|
|
||||||
|
// 处理接收到的数据
|
||||||
|
jt808_pkg_handle(buf, ret);
|
||||||
|
memset(buf, 0, sizeof(buf));
|
||||||
|
}else if(ret <= 0){// 连接已断开或发生错误,客户端需要执行close操作
|
||||||
|
DEBUG("tcp_read closed %d\n", errno);
|
||||||
|
close(tcp_client_sock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else if(ret == 0){// select 等待超时
|
||||||
|
// TODO
|
||||||
|
DEBUG("tcp_read_test select timeout %d\n", errno);
|
||||||
|
}else{// 走到这时当前socket已关闭,此时select将一直报错,故而挂起线程,等待重新连接后再次恢复线程
|
||||||
|
DEBUG("tcp_recv_task Suspend %d\n", errno);
|
||||||
|
close(tcp_client_sock);
|
||||||
|
osSemaphoreRelease(netconn_disconnect_sem); // 发送断开连接信号
|
||||||
|
osThreadSuspend(tcp_recv_ThreadId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TCP连接 // host:服务地址,port:服务端口
|
||||||
|
int tcp_client_connect(const char *host, int port) {
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
tcp_client_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||||
|
if (tcp_client_sock == -1){
|
||||||
|
DEBUG("tcp socket create error\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG("tcp connect:%s, %d\n", host, port);
|
||||||
|
|
||||||
|
struct sockaddr_in server_addr;
|
||||||
|
memset(&server_addr, 0, sizeof(server_addr));
|
||||||
|
server_addr.sin_len = sizeof(server_addr);
|
||||||
|
server_addr.sin_family = AF_INET;
|
||||||
|
server_addr.sin_port = htons(port); //端口
|
||||||
|
server_addr.sin_addr.s_addr = inet_addr(host); //服务地址
|
||||||
|
|
||||||
|
ret = connect(tcp_client_sock, (const struct sockaddr *)&server_addr, sizeof(server_addr));
|
||||||
|
if (ret == -1){
|
||||||
|
DEBUG("tcp connect error\n");
|
||||||
|
close(tcp_client_sock);
|
||||||
|
return -1;
|
||||||
|
}else if (ret == 0){
|
||||||
|
/* 建立新的线程供select异步读取*/
|
||||||
|
DEBUG("tcp connect ok\n");
|
||||||
|
if (tcp_recv_ThreadId == NULL){
|
||||||
|
osThreadAttr_t tcp_recv_task_attr = {0};
|
||||||
|
tcp_recv_task_attr.name = "tcp_recv_task";
|
||||||
|
tcp_recv_task_attr.stack_size = 1024;
|
||||||
|
tcp_recv_task_attr.priority = osPriorityNormal;
|
||||||
|
|
||||||
|
tcp_recv_ThreadId = osThreadNew((osThreadFunc_t)tcp_recv_task, 0, &tcp_recv_task_attr);
|
||||||
|
}else{
|
||||||
|
DEBUG("tcp_recv_task Resume %d\n", errno);
|
||||||
|
osThreadResume(tcp_recv_ThreadId); //恢复线程
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TCP发送数据
|
||||||
|
int tcp_client_send(const uint8_t *buf, uint16_t len){ // 不可加打印
|
||||||
|
int ret = 0;
|
||||||
|
ret = send(tcp_client_sock, (char *)buf, len, 0);
|
||||||
|
if(ret < 0){
|
||||||
|
DEBUG("tcp send error\n");
|
||||||
|
// close(tcp_client_sock);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// DEBUG("tcp send %d bytes\n", ret);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tcp_client_close(void){
|
||||||
|
if(tcp_client_sock != -1){
|
||||||
|
close(tcp_client_sock);
|
||||||
|
tcp_client_sock = -1;
|
||||||
|
}
|
||||||
|
if(tcp_recv_ThreadId != NULL){
|
||||||
|
osThreadSuspend(tcp_recv_ThreadId); //挂起线程
|
||||||
|
// tcp_recv_ThreadId = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 网络管理线程
|
||||||
|
static void net_manage_task(void *arg){
|
||||||
|
// osThreadState_t state;
|
||||||
|
|
||||||
|
DEBUG("net_manage_task!\r\n");
|
||||||
|
int ret = 0;
|
||||||
|
cm_cereg_state_t cereg_state = {0};
|
||||||
|
uint8_t error_time_out = 0;
|
||||||
|
while(1){
|
||||||
|
TCP_DISABLE:
|
||||||
|
do{// 连接服务器
|
||||||
|
while(1){ // 等待插入SIM卡并建立网络连接
|
||||||
|
osDelay(1000/5);
|
||||||
|
error_time_out++;
|
||||||
|
if(error_time_out > 15){ // 超时退出
|
||||||
|
DEBUG("network connect timeout!\n");
|
||||||
|
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");
|
||||||
|
break;
|
||||||
|
}else{
|
||||||
|
DEBUG("waiting for network...\n");
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
DEBUG("cereg_get_state fail!\n\n");
|
||||||
|
}
|
||||||
|
// if(cm_modem_get_pdp_state(1) == 1){ // 网络就绪
|
||||||
|
// app_printf("network ready\n");
|
||||||
|
// }else{
|
||||||
|
// app_printf("waiting for network...\n");
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}while(0 != tcp_client_connect(PrsResult.term_param_item->set_term_param.MainServerAddr , PrsResult.term_param_item->set_term_param.ServerPort)); // 连接到TCP服务器
|
||||||
|
DEBUG("tcp_client_connect success!\r\n");
|
||||||
|
// jt808_pkg_send(ID_Term_GenResp,5000/5);
|
||||||
|
for(uint8_t i = 0; i < 3; i++){ // 发送3次注册、鉴权、参数设置、上报参数
|
||||||
|
ret =jt808_pkg_send(ID_Term_Reg,8000/5);//注册终端 超时:8S
|
||||||
|
if(0 == ret){
|
||||||
|
DEBUG("send ID_Term_Reg success!\n");
|
||||||
|
for(uint8_t i = 0; i < 3; i++){
|
||||||
|
ret =jt808_pkg_send(ID_Term_Auth,10000/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){
|
||||||
|
goto TCP_DISABLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}else{
|
||||||
|
DEBUG("send ID_Term_Reg fail:%d!\n",ret);
|
||||||
|
if(ret == -1){
|
||||||
|
goto TCP_DISABLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
jt808_Autoreport_param_start();//开启自动上报参数设置
|
||||||
|
led_set_event(EVENT_NETWORK_READY); // 网络连接成功
|
||||||
|
osSemaphoreAcquire(netconn_disconnect_sem, osWaitForever); // 等待断开连接信号
|
||||||
|
jt808_Autoreport_param_stop();//停止自动上报参数设置
|
||||||
|
led_set_event(EVENT_NETWORK_DISCONNECT); // 网络断开连接
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void tcp_client_init(void){
|
||||||
|
osThreadAttr_t net_manage_task_attr={
|
||||||
|
.name = "net_manage_task",
|
||||||
|
.stack_size = 1024,
|
||||||
|
.priority = osPriorityNormal,
|
||||||
|
};
|
||||||
|
DEBUG("tcp_client_init!\r\n");
|
||||||
|
if(netconn_disconnect_sem == NULL){
|
||||||
|
netconn_disconnect_sem = osSemaphoreNew(1, 0, NULL);
|
||||||
|
}
|
||||||
|
net_manage_ThreadId = osThreadNew((osThreadFunc_t)net_manage_task, 0, &net_manage_task_attr);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
CUSTOM_MAIN_DIR := custom/tcp_client
|
||||||
|
|
||||||
|
OC_FILES += $(CUSTOM_MAIN_DIR)/src/tcp_client.c
|
||||||
|
|
||||||
|
INC += -I'$(CUSTOM_MAIN_DIR)/inc'
|
||||||
|
|
@ -6,8 +6,16 @@
|
||||||
#include "cm_audio_player.h"
|
#include "cm_audio_player.h"
|
||||||
#include "cm_audio_common.h"
|
#include "cm_audio_common.h"
|
||||||
|
|
||||||
|
#define DEBUG_ENABLE 0
|
||||||
|
|
||||||
#define CM_TTS_FRAME_BUFFER_SIZE (320 * 50 * 10) //支持存放10秒数据,可修改
|
#if DEBUG_ENABLE
|
||||||
|
#include "app_uart.h"
|
||||||
|
#define DEBUG(fmt, args...) app_printf("[tts]" fmt, ##args)
|
||||||
|
#else
|
||||||
|
#define DEBUG(fmt, arg...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CM_TTS_FRAME_BUFFER_SIZE (320 * 50 * 60) //支持存放10秒数据,可修改
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
osThreadId_t TaskHandle; /* TTS播放管理句柄 */
|
osThreadId_t TaskHandle; /* TTS播放管理句柄 */
|
||||||
|
|
@ -39,7 +47,7 @@ static void __cm_tts_play_callback(cm_local_tts_event_e event, void *param)
|
||||||
{
|
{
|
||||||
cm_tts_play_cfg.user_cb(event, param);
|
cm_tts_play_cfg.user_cb(event, param);
|
||||||
}
|
}
|
||||||
//cm_log_printf(0, "[TTS] [%s] CM_LOCAL_TTS_EVENT_SYNTH_DATA [%d] \n", synth_data->user, synth_data->len);
|
DEBUG("[TTS] [%s] CM_LOCAL_TTS_EVENT_SYNTH_DATA [%d] \n", synth_data->user, synth_data->len);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CM_LOCAL_TTS_EVENT_SYNTH_FAIL:
|
case CM_LOCAL_TTS_EVENT_SYNTH_FAIL:
|
||||||
|
|
@ -68,7 +76,7 @@ static void __cm_tts_play_task(void *param)
|
||||||
/* 转码速度大于播放速度,故无需考虑播放速度大于转码速度情况的延迟等待问题 */
|
/* 转码速度大于播放速度,故无需考虑播放速度大于转码速度情况的延迟等待问题 */
|
||||||
while (index < cm_tts_play_cfg.TtsPcmBufLen && CM_LOCAL_TTS_STATE_WORKING == cm_tts_play_cfg.state)
|
while (index < cm_tts_play_cfg.TtsPcmBufLen && CM_LOCAL_TTS_STATE_WORKING == cm_tts_play_cfg.state)
|
||||||
{
|
{
|
||||||
//cm_log_printf(0, "%s() __%d__ Length is %d, index is %d", __func__, __LINE__, cm_tts_play_cfg.TtsPcmBufLen, index);
|
DEBUG("%s() __%d__ Length is %d, index is %d", __func__, __LINE__, cm_tts_play_cfg.TtsPcmBufLen, index);
|
||||||
|
|
||||||
/* 每200ms传10帧PCM数据 */
|
/* 每200ms传10帧PCM数据 */
|
||||||
if (index + 3200 <= cm_tts_play_cfg.TtsPcmBufLen)
|
if (index + 3200 <= cm_tts_play_cfg.TtsPcmBufLen)
|
||||||
|
|
@ -121,7 +129,7 @@ static void __cm_tts_play_task(void *param)
|
||||||
|
|
||||||
//cm_heap_stats_t stats = {0};
|
//cm_heap_stats_t stats = {0};
|
||||||
//cm_mem_get_heap_stats(&stats);
|
//cm_mem_get_heap_stats(&stats);
|
||||||
//cm_log_printf(0, "heap total:%d,remain:%d\n",stats.total_size,stats.free);
|
//DEBUG(0, "heap total:%d,remain:%d\n",stats.total_size,stats.free);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -147,7 +155,7 @@ int32_t cm_local_tts_play(const char *text, int32_t len, cm_local_tts_callback c
|
||||||
//需要判断当前是否处于播放过程中,处于播放过程中报错
|
//需要判断当前是否处于播放过程中,处于播放过程中报错
|
||||||
if (CM_LOCAL_TTS_STATE_WORKING == cm_tts_play_cfg.state)
|
if (CM_LOCAL_TTS_STATE_WORKING == cm_tts_play_cfg.state)
|
||||||
{
|
{
|
||||||
cm_log_printf(0, "%s() __%d__ TTS busy", __func__, __LINE__);
|
DEBUG("%s() __%d__ TTS busy", __func__, __LINE__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -157,7 +165,7 @@ int32_t cm_local_tts_play(const char *text, int32_t len, cm_local_tts_callback c
|
||||||
|
|
||||||
if (NULL == cm_tts_play_cfg.TtsPcmBuf)
|
if (NULL == cm_tts_play_cfg.TtsPcmBuf)
|
||||||
{
|
{
|
||||||
cm_log_printf(0, "%s() __%d__ cm_malloc() error", __func__, __LINE__);
|
DEBUG("%s() __%d__ cm_malloc() error", __func__, __LINE__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -165,11 +173,15 @@ int32_t cm_local_tts_play(const char *text, int32_t len, cm_local_tts_callback c
|
||||||
cm_audio_sample_param_t frame = {.sample_format = CM_AUDIO_SAMPLE_FORMAT_16BIT, .rate = CM_AUDIO_SAMPLE_RATE_8000HZ, .num_channels = CM_AUDIO_SOUND_MONO};
|
cm_audio_sample_param_t frame = {.sample_format = CM_AUDIO_SAMPLE_FORMAT_16BIT, .rate = CM_AUDIO_SAMPLE_RATE_8000HZ, .num_channels = CM_AUDIO_SOUND_MONO};
|
||||||
int32_t ret = cm_audio_player_stream_open(CM_AUDIO_PLAY_FORMAT_PCM, &frame); //从pipe中播放音频(开启)
|
int32_t ret = cm_audio_player_stream_open(CM_AUDIO_PLAY_FORMAT_PCM, &frame); //从pipe中播放音频(开启)
|
||||||
|
|
||||||
if (-1 == ret)
|
if (-1 == ret){
|
||||||
{
|
DEBUG("%s() __%d__ cm_audio_player_stream_open0() error, ret is %d", __func__, __LINE__, ret);
|
||||||
cm_log_printf(0, "%s() __%d__ cm_audio_player_stream_open() error, ret is %d", __func__, __LINE__, ret);
|
cm_audio_player_stream_close();
|
||||||
|
ret = cm_audio_player_stream_open(CM_AUDIO_PLAY_FORMAT_PCM, &frame); //从pipe中播放音频(开启)
|
||||||
|
if (-1 == ret){
|
||||||
|
DEBUG("%s() __%d__ cm_audio_player_stream_open1() error, ret is %d", __func__, __LINE__, ret);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (NULL == cm_tts_play_cfg.SemHandle)
|
if (NULL == cm_tts_play_cfg.SemHandle)
|
||||||
{
|
{
|
||||||
|
|
@ -177,7 +189,7 @@ int32_t cm_local_tts_play(const char *text, int32_t len, cm_local_tts_callback c
|
||||||
|
|
||||||
if (NULL == cm_tts_play_cfg.SemHandle)
|
if (NULL == cm_tts_play_cfg.SemHandle)
|
||||||
{
|
{
|
||||||
cm_log_printf(0, "%s() __%d__ osSemaphoreNew() error", __func__, __LINE__);
|
DEBUG("%s() __%d__ osSemaphoreNew() error", __func__, __LINE__);
|
||||||
cm_audio_player_stream_close();
|
cm_audio_player_stream_close();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -195,7 +207,7 @@ int32_t cm_local_tts_play(const char *text, int32_t len, cm_local_tts_callback c
|
||||||
|
|
||||||
if (NULL == cm_tts_play_cfg.TaskHandle)
|
if (NULL == cm_tts_play_cfg.TaskHandle)
|
||||||
{
|
{
|
||||||
cm_log_printf(0, "%s() __%d__ osThreadNew() error", __func__, __LINE__);
|
DEBUG("%s() __%d__ osThreadNew() error", __func__, __LINE__);
|
||||||
cm_audio_player_stream_close();
|
cm_audio_player_stream_close();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -225,11 +237,9 @@ int32_t cm_local_tts_play(const char *text, int32_t len, cm_local_tts_callback c
|
||||||
*
|
*
|
||||||
* @details 仅8M版本(ML307A-DSLN ML307A-GSLN ML305A-DS等)支持离线TTS功能
|
* @details 仅8M版本(ML307A-DSLN ML307A-GSLN ML305A-DS等)支持离线TTS功能
|
||||||
*/
|
*/
|
||||||
int32_t cm_local_tts_play_stop(void)
|
int32_t cm_local_tts_play_stop(void){
|
||||||
{
|
if (CM_LOCAL_TTS_STATE_IDLE == cm_tts_play_cfg.state){
|
||||||
if (CM_LOCAL_TTS_STATE_IDLE == cm_tts_play_cfg.state)
|
DEBUG("%s() __%d__ no TTS task", __func__, __LINE__);
|
||||||
{
|
|
||||||
cm_log_printf(0, "%s() __%d__ no TTS task", __func__, __LINE__);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue