添加第三方jt808协议库 zsxfly20241013
This commit is contained in:
parent
e3baeaa47f
commit
3093935b23
|
|
@ -0,0 +1,2 @@
|
|||
/.vscode/
|
||||
out/
|
||||
|
|
@ -6,4 +6,5 @@ ifeq ($(strip $(DEMO_SUPPORT)),n)
|
|||
include $(CUSTOM_DIR)/custom_main/custom_main.mk
|
||||
include $(CUSTOM_DIR)/nmealib/nmealib.mk
|
||||
include $(CUSTOM_DIR)/GPS/gps.mk
|
||||
include $(CUSTOM_DIR)/jt808/jt808.mk
|
||||
endif
|
||||
|
|
@ -40,10 +40,17 @@
|
|||
// #include "cm_demo_ssl.h"
|
||||
#include "app_uart.h"
|
||||
#include "gps_config.h"
|
||||
#include "client_manager.h"
|
||||
#include "jt808_packager.h"
|
||||
|
||||
osThreadId_t OC_APP_TaskHandle;
|
||||
|
||||
void my_appimg_enter(char *param){
|
||||
int isRegistered=0;
|
||||
int isAuthenticated=0;
|
||||
unsigned int v_alarm_value = 0;
|
||||
unsigned int v_status_value = 0;
|
||||
|
||||
cm_gpio_cfg_t cfg = {0};
|
||||
|
||||
cfg.direction = CM_GPIO_DIRECTION_OUTPUT;
|
||||
|
|
@ -57,10 +64,33 @@ void my_appimg_enter(char *param){
|
|||
app_uart_init();
|
||||
gps_config_init();
|
||||
app_printf("Hello, world!\r\n");
|
||||
initSystemParameters(0);
|
||||
//设置手机号(唯一识别id)
|
||||
setUUID();
|
||||
//终端注册
|
||||
if(isRegistered == 0){
|
||||
jt808TerminalRegister(&isRegistered);
|
||||
if(isRegistered==0){
|
||||
// system_reboot();
|
||||
// continue;
|
||||
}
|
||||
}
|
||||
//终端鉴权
|
||||
if(isAuthenticated == 0){
|
||||
jt808TerminalAuthentication(&isAuthenticated);
|
||||
if(isAuthenticated==0){
|
||||
// system_reboot();
|
||||
// continue;
|
||||
}
|
||||
}
|
||||
|
||||
//设置位置上报警报位、状态位
|
||||
initLocationInfo(v_alarm_value, v_status_value);
|
||||
setStatusBit();
|
||||
while(1){
|
||||
osDelay(300/5);//300ms
|
||||
osDelay(200/5);//300ms
|
||||
cm_gpio_set_level(0, 1);
|
||||
osDelay(300/5);//300ms
|
||||
osDelay(200/5);//300ms
|
||||
cm_gpio_set_level(0, 0);
|
||||
// app_printf("Hello, world!\r\n");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
|
||||
|
||||
#ifndef JT808_BCD_H_
|
||||
#define JT808_BCD_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
|
||||
unsigned char HexToBcd(unsigned char src);
|
||||
unsigned char BcdToHex(unsigned char src);
|
||||
unsigned char *jt808StringToBcdCompress(const unsigned char *src, unsigned char *dst, int srclen);
|
||||
unsigned char *jt808BcdToStringCompress(const unsigned char *src, unsigned char *dst, int srclen);
|
||||
unsigned char *jt808BcdToStringCompressFillingZero(const unsigned char *src, unsigned char *dst, int srclen);
|
||||
|
||||
// uint8_t HexToBcd(uint8_t const &src);
|
||||
// uint8_t BcdToHex(uint8_t const &src);
|
||||
// uint8_t *StringToBcdCompress(const uint8_t *src, uint8_t *dst, const int & srclen);
|
||||
// uint8_t *BcdToStringCompress(const uint8_t *src, uint8_t *dst, const int & srclen);
|
||||
// uint8_t *BcdToStringCompressFillingZero(const uint8_t *src, uint8_t *dst, const int &srclen);
|
||||
// int StringToBcd(std::string const &in, std::vector<uint8_t> *out);
|
||||
// int BcdToString(std::vector<uint8_t> const &in, std::string *out);
|
||||
// int BcdToStringFillZero(std::vector<uint8_t> const &in, std::string *out);
|
||||
|
||||
|
||||
#endif // JT808_BCD_H_
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
#ifndef JT808_CLIENT_MANAGER_H_
|
||||
#define JT808_CLIENT_MANAGER_H_
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "cm_os.h"
|
||||
|
||||
//#define __JT808_DEBUG
|
||||
#define FLASH_ADDR (uint32_t)0x0803c000
|
||||
//#define ID_FLASH_ADDR (uint32_t)0x0803b800
|
||||
#define FLASH_BUFFER_SIZE 128
|
||||
|
||||
#define JT808_delay_ms(_ms) osDelay(_ms/5);//ms
|
||||
|
||||
extern struct ProtocolParameter parameter_;
|
||||
|
||||
void setTerminalPhoneNumber(const char *phone_num, unsigned int phoneSize);
|
||||
|
||||
/******************************************************************************
|
||||
* @description: 数据打包并发送接口
|
||||
* @param {unsigned int} msg_id 消息ID
|
||||
* @return {*}
|
||||
* @author: ZTL
|
||||
*******************************************************************************/
|
||||
int packagingAndSendMessage(unsigned int msg_id);
|
||||
|
||||
/******************************************************************************
|
||||
* @description: 数据打包接口
|
||||
* @param {unsigned int} msg_id JT808消息ID
|
||||
* @param { unsigned int} *realBufSize 用于记录实际打包待发送的buffer长度
|
||||
* @return {0}成功 {-1}失败
|
||||
* @author: ZTL
|
||||
*******************************************************************************/
|
||||
int packagingMessage(unsigned int msg_id);
|
||||
|
||||
/******************************************************************************
|
||||
* @description: 从终端打包器命令数组中查找是否有当前相应的消息ID,以便根据该命令数组中的消息ID调用相应的接口
|
||||
* @param {unsigned int} msg_id 消息ID
|
||||
* @return {0}失败 {1}成功
|
||||
* @author: ZTL
|
||||
*******************************************************************************/
|
||||
int findMsgIDFromTerminalPackagerCMD(unsigned int msg_id);
|
||||
int findParameterIDFromArray(unsigned int para_id);
|
||||
int parsingMessage(const unsigned char *in, unsigned int in_len);
|
||||
int jt808TerminalRegister(int *isRegistered);
|
||||
int jt808TerminalAuthentication(int *isAuthenticated);
|
||||
int jt808LocationReport(void);
|
||||
int jt808TerminalLogOut(void);
|
||||
int jt808TerminalHeartBeat(void);
|
||||
int jt808TerminalUpgradeResultReport(void);
|
||||
int jt808TerminalGeneralResponse(void);
|
||||
void setTerminalId(const char *TerminalId, unsigned int lenTerminalId);
|
||||
void setStatusBit(void);
|
||||
int FlashWrite(void);
|
||||
void setUUID(void);
|
||||
int IPFlashWrite(void);
|
||||
void File_upload(void);
|
||||
void initSystemParameters(int i);
|
||||
void initLocationInfo(unsigned int v_alarm_value, unsigned int v_status_value);
|
||||
void updateLocation(double const v_latitude, double const v_longitude, float const v_altitude,
|
||||
float const v_speed, float const v_bearing, unsigned char *v_timestamp);
|
||||
|
||||
#endif // JT808_CLIENT_MANAGER_H_
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
|
||||
|
||||
#ifndef JT808_GBK_UTF8_H_
|
||||
#define JT808_GBK_UTF8_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
/*
|
||||
namespace libjt808
|
||||
{
|
||||
#ifdef _WIN32
|
||||
std::string GbkToUtf8(const char *src_str);
|
||||
std::string Utf8ToGbk(const char *src_str);
|
||||
#else
|
||||
int GbkToUtf8(char *str_str, size_t src_len, char *dst_str, size_t dst_len);
|
||||
int Utf8ToGbk(char *src_str, size_t src_len, char *dst_str, size_t dst_len);
|
||||
#endif
|
||||
|
||||
std::string gbk_to_utf8_str(const std::vector<uint8_t> &gbk_src);
|
||||
std::string gbk_to_utf8_str(const std::string &str_gbk_src);
|
||||
}
|
||||
s
|
||||
|
||||
|
||||
*/
|
||||
#endif // JT808_GBK_UTF8_H_
|
||||
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
#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,19 @@
|
|||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define PACKAGER_NUM 9 //终端打包器命令相应消息ID数量
|
||||
#define BUFFER_SIZE_SEND 1024 // buffer size 发送缓存大小
|
||||
|
||||
#include "protocol_parameter.h"
|
||||
#include "terminal_register.h"
|
||||
#include "bcd.h"
|
||||
|
||||
|
||||
extern unsigned short kTerminalPackagerCMD[PACKAGER_NUM];
|
||||
extern unsigned char BufferSend[BUFFER_SIZE_SEND]; //发送缓存
|
||||
extern unsigned int RealBufferSendSize;
|
||||
|
||||
int jt808FramePackage(struct ProtocolParameter *para);
|
||||
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
|
||||
|
||||
#ifndef JT808_PARSER_H_
|
||||
#define JT808_PARSER_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "protocol_parameter.h"
|
||||
|
||||
#define PARSER_NUM 9
|
||||
#define BUFFER_SIZE_RECEIVE 1024 // buffer size 发送缓存大小
|
||||
|
||||
extern unsigned short kTerminalParserCMD[PARSER_NUM];
|
||||
|
||||
int jt808FrameParse(const unsigned char *in, unsigned int in_len, struct ProtocolParameter *para);
|
||||
|
||||
#endif // JT808_PARSER_H_
|
||||
|
|
@ -0,0 +1,333 @@
|
|||
#include <stdint.h>
|
||||
// 报警标志位
|
||||
union AlarmBit
|
||||
{
|
||||
struct
|
||||
{
|
||||
// bit_0 紧急报瞥触动报警开关后触发.收到应答后清零
|
||||
unsigned int sos : 1;
|
||||
// bit_1 超速报警.
|
||||
unsigned int overspeed : 1;
|
||||
// bit_2 疲劳驾驶.
|
||||
unsigned int fatigue : 1;
|
||||
// bit_3 危险预警.
|
||||
unsigned int early_warning : 1;
|
||||
// bit_4 GNSS模块发生故障.
|
||||
unsigned int gnss_fault : 1;
|
||||
// bit_5 GNSS天线未接或被剪断.
|
||||
unsigned int gnss_antenna_cut : 1;
|
||||
// bit_6 GNSS天线短路.
|
||||
unsigned int gnss_antenna_shortcircuit : 1;
|
||||
// bit_7 终端主电源欠压.
|
||||
unsigned int power_low : 1;
|
||||
// bit_8 终端主电源掉电.
|
||||
unsigned int power_cut : 1;
|
||||
// bit_9 终端LCD或显示器故障.
|
||||
unsigned int lcd_fault : 1;
|
||||
// bit_10 TTS模块故障.
|
||||
unsigned int tts_fault : 1;
|
||||
// bit_11 摄像头故障.
|
||||
unsigned int camera_fault : 1;
|
||||
|
||||
// // OBD故障码.
|
||||
// unsigned int obd_fault_code : 1;
|
||||
// // 保留5位.
|
||||
// unsigned int retain1 : 5;
|
||||
|
||||
// bit_12 道路运输证 IC 卡模块故障.
|
||||
unsigned int transport_license_IC_card_fault : 1;
|
||||
|
||||
// bit_1 超速预警.
|
||||
unsigned int overspeed_notice : 1;
|
||||
// bit_2 疲劳驾驶预警.
|
||||
unsigned int fatigue_notice : 1;
|
||||
|
||||
// 保留3位.
|
||||
unsigned int retain1 : 3;
|
||||
|
||||
// bit_18 当天累计驾驶超时.
|
||||
unsigned int day_drive_overtime : 1;
|
||||
// bit_19 超时停车.
|
||||
unsigned int stop_driving_overtime : 1;
|
||||
// bit_20 进出区域.收到应答后清零
|
||||
unsigned int in_out_area : 1;
|
||||
// bit_21 进出路线.收到应答后清零
|
||||
unsigned int in_out_road : 1;
|
||||
// bit_22 路段行驶时间不足/过长.收到应答后清零
|
||||
unsigned int road_drive_time : 1;
|
||||
// bit_23 路线偏离报警.
|
||||
unsigned int road_deviate : 1;
|
||||
// bit_24 车辆VSS故障.
|
||||
unsigned int vss_fault : 1;
|
||||
// bit_25 车辆油量异常.
|
||||
unsigned int oil_fault : 1;
|
||||
// bit_26 车辆被盗(通过车辆防盗器).
|
||||
unsigned int car_alarm : 1;
|
||||
// bit_27 车辆非法点火.收到应答后清零
|
||||
unsigned int car_acc_alarm : 1;
|
||||
// bit_28 车辆非法位移.收到应答后清零
|
||||
unsigned int car_move : 1;
|
||||
// 碰撞侧翻报警.
|
||||
unsigned int collision : 1;
|
||||
// 保留2位.
|
||||
unsigned int retain2 : 2;
|
||||
} bit;
|
||||
unsigned int value;
|
||||
};
|
||||
|
||||
// 状态位
|
||||
union StatusBit
|
||||
{
|
||||
struct
|
||||
{
|
||||
// ACC开关, 0:ACC关; 1:ACC开.
|
||||
unsigned int acc : 1;
|
||||
// 定位标志, 0:未定位; 1:定位.
|
||||
unsigned int positioning : 1;
|
||||
// 纬度半球, 0:北纬: 1:南纬.
|
||||
unsigned int sn_latitude : 1;
|
||||
// 经度半球, 0:东经; 1:西经.
|
||||
unsigned int ew_longitude : 1;
|
||||
// 0:运营状态; 1:停运状态.
|
||||
unsigned int operation : 1; // 0:运营状态; 1:停运状态.
|
||||
// 0:经纬度未经保密插件加密; 1:经纬度已经保密插件加密.
|
||||
unsigned int gps_encrypt : 1;
|
||||
// 保留2位.
|
||||
unsigned int retain1 : 2;
|
||||
// 00: 空车; 01: 半载; 10: 保留; 11: 满载.
|
||||
unsigned int trip_status : 2;
|
||||
// 0:车辆油路正常; 1:车辆油路断开.
|
||||
unsigned int oil_cut : 1;
|
||||
// 0:车辆电路正常; 1:车辆电路断开.
|
||||
unsigned int circuit_cut : 1;
|
||||
// 0:车门解锁; 1: 车门加锁.
|
||||
unsigned int door_lock : 1;
|
||||
// 0:门1 关; 1: 门1 开; (前门).
|
||||
unsigned int door1_status : 1;
|
||||
// 0:门2 关; 1: 门2 开; (中门).
|
||||
unsigned int door2_status : 1;
|
||||
// 0:门 3 关; 1: 门 3 开; (后门).
|
||||
unsigned int door3_status : 1;
|
||||
// 0:门 4 关; 1: 门 4 开; (驾驶席门).
|
||||
unsigned int door4_status : 1;
|
||||
// 0:门 5 关; 1: 门 5 开; (自定义).
|
||||
unsigned int door5_status : 1;
|
||||
// 0: 未使用 GPS 卫星进行定位; 1: 使用 GPS 卫星进行定位.
|
||||
unsigned int gps_en : 1;
|
||||
// 0: 未使用北斗卫星进行定位; 1: 使用北斗卫星进行定位.
|
||||
unsigned int beidou_en : 1;
|
||||
// 0: 未使用 GLONASS 卫星进行定位; 1: 使用 GLONASS 卫星进行定位.
|
||||
unsigned int glonass_en : 1;
|
||||
// 0: 未使用 Galileo 卫星进行定位; 1: 使用 Galileo 卫星进行定位.
|
||||
unsigned int galileo_en : 1;
|
||||
// 保留10位.
|
||||
unsigned int retain2 : 10;
|
||||
} bit;
|
||||
unsigned int value;
|
||||
};
|
||||
|
||||
// 位置基本信息数据.
|
||||
struct LocationBasicInformation
|
||||
{
|
||||
// 报警标志 4B
|
||||
union AlarmBit alarm;
|
||||
// 状态位定义 4B
|
||||
union StatusBit status;
|
||||
// 纬度(以度为单位的纬度值乘以10的6次方, 精确到百万分之一度) 4B
|
||||
unsigned int latitude;
|
||||
// 经度(以度为单位的纬度值乘以10的6次方, 精确到百万分之一度) 4B
|
||||
unsigned int longitude;
|
||||
// 海拔高度, 单位为米(m) 2B
|
||||
unsigned short altitude;
|
||||
// 速度 1/10km/h 2B
|
||||
unsigned short speed;
|
||||
// 方向 0-359,正北为0, 顺时针 2B
|
||||
unsigned short bearing;
|
||||
// 时间, "YYMMDDhhmmss"(GMT+8时间, 本标准之后涉及的时间均采用此时区).12B
|
||||
// std::string time;
|
||||
unsigned char time[13];
|
||||
};
|
||||
|
||||
// 扩展车辆信号状态位
|
||||
union ExtendedVehicleSignalBit
|
||||
{
|
||||
struct
|
||||
{
|
||||
// 近光灯信号
|
||||
unsigned int near_lamp : 1;
|
||||
// 远光灯信号
|
||||
unsigned int farl_amp : 1;
|
||||
// 右转向灯信号
|
||||
unsigned int right_turn_lamp : 1;
|
||||
// 左转向灯信号
|
||||
unsigned int left_turn_lamp : 1;
|
||||
// 制动信号
|
||||
unsigned int breaking : 1;
|
||||
// 倒档信号
|
||||
unsigned int reversing : 1;
|
||||
// 雾灯信号
|
||||
unsigned int fog_lamp : 1;
|
||||
// 示廓灯
|
||||
unsigned int outline_lamp : 1;
|
||||
// 喇叭信号
|
||||
unsigned int horn : 1;
|
||||
// 空调状态
|
||||
unsigned int air_conditioner : 1;
|
||||
// 空挡信号
|
||||
unsigned int neutral : 1;
|
||||
// 缓速器工作
|
||||
unsigned int retarder : 1;
|
||||
// ABS 工作
|
||||
unsigned int abs : 1;
|
||||
// 加热器工作
|
||||
unsigned int heater : 1;
|
||||
// 离合器状态
|
||||
unsigned int clutch : 1;
|
||||
// 保留17位.
|
||||
unsigned int retain : 17;
|
||||
} bit;
|
||||
unsigned int value;
|
||||
};
|
||||
|
||||
// 位置信息上报附加项ID.
|
||||
enum LocationExtensionId
|
||||
{
|
||||
// 里程, 1/10km, 对应车上里程表读数, DWORD
|
||||
kMileage = 0x01,
|
||||
// 油量, 1/10L, 对应车上油量表读数, WORD
|
||||
kOilMass = 0x02,
|
||||
// 行驶记录功能获取的速度, 1/10km/h, WORD
|
||||
kTachographSpeed = 0x03,
|
||||
// 需要人工确认报警事件的 ID, 从 1 开始计数, WORD
|
||||
kAlarmCount = 0x04,
|
||||
// 超速报警附加信息, BYTE or BYTE+DWORD
|
||||
kOverSpeedAlarm = 0x11,
|
||||
// 进出区域/路线报警附加信息, BYTE+DWORD+BYTE
|
||||
kAccessAreaAlarm = 0x12,
|
||||
// 路段行驶时间不足/过长报警附加信息, DWORD+WORD+BYTE
|
||||
kDrivingTimeAlarm = 0x13,
|
||||
// 扩展车辆信号状态位, DWORD
|
||||
kVehicleSignalStatus = 0x25,
|
||||
// IO 状态位, WORD
|
||||
kIoStatus = 0x2A,
|
||||
// 模拟量, DWORD
|
||||
kAnalogQuantity = 0x2B,
|
||||
// 无线通信网络信号强度, BYTE
|
||||
kNetworkQuantity = 0x30,
|
||||
// GNSS 定位卫星数, BYTE
|
||||
kGnssSatellites = 0x31,
|
||||
// 后续自定义信息长度, BYTE
|
||||
kCustomInformationLength = 0xE0,
|
||||
// 定位解状态, BYTE
|
||||
kPositioningStatus = 0xEE,
|
||||
|
||||
//称重信息ID
|
||||
kWeightInfo = 0xF3,
|
||||
|
||||
// 视频报警上报
|
||||
kAlarm_video = 0x14, // 视频相关报警,附加信息长度 4B
|
||||
kAlarm_video_Signal_Lost = 0x15, // 视频信号丢失报警状态,附加信息长度 4B
|
||||
kAlarm_video_Signal_Occlusion = 0x16, // 视频信号遮挡报警状态,附加信息长度 4B
|
||||
kAlarm_Memory_Bad = 0x17, // 存储器故障报警状态,附加信息长度 2B
|
||||
kAlarm_Abnormal_Drive_Behavior = 0x18, // 异常驾驶行为报警详细描述,附加信息长度 2B
|
||||
|
||||
};
|
||||
|
||||
// 位置信息附加项存储定义: key: itemid, value: itemvalue.
|
||||
// using LocationExtensions = std::map<unsigned char , std::vector<unsigned char >>;
|
||||
|
||||
// 超速报警附加信息位置类型, BYTE.
|
||||
enum kOverSpeedAlarmLocationType
|
||||
{
|
||||
// 0:无特定位置.
|
||||
kOverSpeedAlarmNoSpecificLocation = 0x0,
|
||||
// 1:圆形区域.
|
||||
kOverSpeedAlarmCircularArea,
|
||||
// 2:矩形区域.
|
||||
kOverSpeedAlarmRectangleArea,
|
||||
// 3:多边形区域.
|
||||
kOverSpeedAlarmPolygonArea,
|
||||
// 4:路段.
|
||||
kOverSpeedAlarmRoadSection
|
||||
};
|
||||
|
||||
// 进出区域/路线报警附加信息消息体位置类型, BYTE.
|
||||
enum kAccessAreaAlarmLocationType
|
||||
{
|
||||
// 1:圆形区域.
|
||||
kAccessAreaAlarmCircularArea,
|
||||
// 2:矩形区域.
|
||||
kAccessAreaAlarmRectangleArea,
|
||||
// 3:多边形区域.
|
||||
kAccessAreaAlarmPolygonArea,
|
||||
// 4:路线.
|
||||
kOverSpeedAlarmRoute
|
||||
};
|
||||
|
||||
// 进出区域/路线报警附加信息消息体方向类型, BYTE.
|
||||
enum kAccessAreaAlarmDirectionType
|
||||
{
|
||||
// 进入区域.
|
||||
kAccessAreaAlarmInArea = 0x0,
|
||||
// 离开区域.
|
||||
kAccessAreaAlarmOutArea
|
||||
};
|
||||
|
||||
// IO 状态位
|
||||
union IoStatusBit
|
||||
{
|
||||
struct
|
||||
{
|
||||
// 深度休眠状态
|
||||
unsigned short deep_rmancy : 1;
|
||||
// 休眠状态
|
||||
unsigned short dormancy : 1;
|
||||
// 保留14位.
|
||||
unsigned short retain : 14;
|
||||
} bit;
|
||||
unsigned short value;
|
||||
};
|
||||
|
||||
// 临时位置跟踪控制信息.
|
||||
struct LocationTrackingControl
|
||||
{
|
||||
// 时间间隔.
|
||||
unsigned short interval;
|
||||
// 单位为秒(s), 有效时间.
|
||||
unsigned int tracking_time;
|
||||
};
|
||||
/*
|
||||
// 设置超速报警附加信息消息体.
|
||||
int SetOverSpeedAlarmBody(unsigned char const &location_type,
|
||||
unsigned int const &area_route_id,
|
||||
std::vector<unsigned char > *out);
|
||||
|
||||
// 获得超速报警报警附加信息消息体.
|
||||
int GetOverSpeedAlarmBody(std::vector<unsigned char > const &out,
|
||||
unsigned char *location_type,
|
||||
unsigned int *area_route_id);
|
||||
|
||||
// 设置进出区域/路线报警附加信息消息体.
|
||||
int SetAccessAreaAlarmBody(unsigned char const &location_type,
|
||||
unsigned int const &area_route_id,
|
||||
unsigned char const &direction,
|
||||
std::vector<unsigned char > *out);
|
||||
|
||||
// 获得进出区域/路线报警附加信息消息体.
|
||||
int GetAccessAreaAlarmBody(std::vector<unsigned char > const &out,
|
||||
unsigned char *location_type,
|
||||
unsigned int *area_route_id,
|
||||
unsigned char *direction);
|
||||
*/
|
||||
|
||||
// void initGPSInfo(struct ProtocolParameter *para);
|
||||
// void initGPSInfo(struct LocationBasicInformation *para);
|
||||
// void UpdateLocation(double const latitude, double const longitude, float const altitude, float const speed,
|
||||
// float const bearing, unsigned char *timestamp);
|
||||
|
||||
// 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);
|
||||
|
||||
|
|
@ -0,0 +1,315 @@
|
|||
#ifndef JT808_PROTOCOL_PARAMETER_H_
|
||||
#define JT808_PROTOCOL_PARAMETER_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "location_report.h"
|
||||
#include "terminal_parameter.h"
|
||||
#include "terminal_control.h"
|
||||
|
||||
// #define PACKAGER_NUM 9
|
||||
// #define PARSER_NUM 9
|
||||
|
||||
// 已支持的协议命令.
|
||||
enum SupportedCommands
|
||||
{
|
||||
kTerminalGeneralResponse = 0x0001, // 终端通用应答.
|
||||
kPlatformGeneralResponse = 0x8001, // 平台通用应答.
|
||||
kTerminalHeartBeat = 0x0002, // 终端心跳.
|
||||
kFillPacketRequest = 0x8003, // 补传分包请求.
|
||||
kTerminalRegister = 0x0100, // 终端注册.
|
||||
kTerminalRegisterResponse = 0x8100, // 终端注册应答.
|
||||
kTerminalLogOut = 0x0003, // 终端注销.
|
||||
kTerminalAuthentication = 0x0102, // 终端鉴权.
|
||||
kSetTerminalParameters = 0x8103, // 设置终端参数.
|
||||
kGetTerminalParameters = 0x8104, // 查询终端参数.
|
||||
kGetSpecificTerminalParameters = 0x8106, // 查询指定终端参数.
|
||||
kGetTerminalParametersResponse = 0x0104, // 查询终端参数应答.
|
||||
kTerminalControl = 0x8105, //终端控制
|
||||
kTerminalUpgrade = 0x8108, // 下发终端升级包.
|
||||
kTerminalUpgradeResultReport = 0x0108, // 终端升级结果通知.
|
||||
kLocationReport = 0x0200, // 位置信息汇报.
|
||||
kGetLocationInformation = 0x8201, // 位置信息查询.
|
||||
kGetLocationInformationResponse = 0x0201, // 位置信息查询应答.
|
||||
kLocationTrackingControl = 0x8202, // 临时位置跟踪控制.
|
||||
|
||||
};
|
||||
|
||||
// // 所有应答命令.
|
||||
// unsigned short kResponseCommand[] = {
|
||||
// kTerminalGeneralResponse, //终端通用应答
|
||||
// kPlatformGeneralResponse, //平台通用应答
|
||||
// kTerminalRegisterResponse, //终端注册应答
|
||||
// kGetTerminalParametersResponse, //查询终端参数应答
|
||||
// kGetLocationInformationResponse, //位置信息查询应答
|
||||
// };
|
||||
|
||||
// // 所有终端解析命令.
|
||||
// unsigned short kTerminalParserCMD[PARSER_NUM] = {
|
||||
// kPlatformGeneralResponse, //平台通用应答
|
||||
// kFillPacketRequest, // 补传分包请求.
|
||||
// kTerminalRegisterResponse, // 终端注册应答.
|
||||
// kSetTerminalParameters, // 设置终端参数.
|
||||
// kGetTerminalParameters, // 查询终端参数.
|
||||
// kGetSpecificTerminalParameters, // 查询指定终端参数.
|
||||
// kTerminalControl, //终端控制
|
||||
// kTerminalUpgrade, // 下发终端升级包.
|
||||
// kGetLocationInformation, // 位置信息查询.
|
||||
// };
|
||||
|
||||
// // 所有终端数据打包命令.
|
||||
// unsigned short kTerminalPackagerCMD[PACKAGER_NUM] = {
|
||||
// kTerminalGeneralResponse, // 终端通用应答.
|
||||
// kTerminalHeartBeat, // 终端心跳.
|
||||
// kTerminalRegister, // 终端注册.
|
||||
// kTerminalLogOut, // 终端注销.
|
||||
// kTerminalAuthentication, // 终端鉴权.
|
||||
// kGetTerminalParametersResponse, // 查询终端参数应答.
|
||||
// kTerminalUpgradeResultReport, // 终端升级结果通知.
|
||||
// kLocationReport, // 位置信息汇报.
|
||||
// kGetLocationInformationResponse, // 位置信息查询应答.
|
||||
// };
|
||||
|
||||
// 车牌颜色.
|
||||
enum VehiclePlateColor
|
||||
{
|
||||
kVin = 0x0, // 车辆未上牌.
|
||||
kBlue,
|
||||
kYellow,
|
||||
kBlack,
|
||||
kWhite,
|
||||
kOther
|
||||
};
|
||||
|
||||
// 通用应答结果.
|
||||
enum GeneralResponseResult
|
||||
{
|
||||
kSuccess = 0x0, // 成功/确认.
|
||||
kFailure = 0x1, // 失败.
|
||||
kMessageHasWrong =0x2, // 消息有误.
|
||||
kNotSupport = 0x3, // 不支持.
|
||||
kAlarmHandlingConfirmation = 0x4, // 报警处理确认, 仅平台应答使用.
|
||||
};
|
||||
|
||||
// 注册应答结果.
|
||||
enum RegisterResponseResult
|
||||
{
|
||||
kRegisterSuccess = 0x0, // 成功.
|
||||
kVehiclesHaveBeenRegistered = 0x1, // 车辆已被注册.
|
||||
kNoSuchVehicleInTheDatabase =0x2, // 数据库中无该车辆.
|
||||
kTerminalHaveBeenRegistered = 0x3, // 终端已被注册.
|
||||
kNoSuchTerminalInTheDatabase = 0x4, // 数据库中无该终端.
|
||||
};
|
||||
|
||||
// 消息体属性.
|
||||
union MsgBodyAttribute
|
||||
{
|
||||
struct
|
||||
{
|
||||
// 消息体长度, 占用10bit.
|
||||
unsigned short msglen : 10;
|
||||
// 数据加密方式, 当此三位都为0, 表示消息体不加密,
|
||||
// 当第10位为1, 表示消息体经过RSA算法加密.
|
||||
unsigned short encrypt : 3;
|
||||
// 分包标记.
|
||||
unsigned short packet : 1;
|
||||
// 保留2位.
|
||||
unsigned short retain : 2;
|
||||
} bit;
|
||||
unsigned short u16val;
|
||||
};
|
||||
|
||||
// 消息内容起始位置.
|
||||
enum MsgBodyPos
|
||||
{
|
||||
MSGBODY_NOPACKET_POS = 13, // 短消息体消息内容起始位置.SMS
|
||||
MSGBODY_PACKET_POS = 17, // 长消息体消息内容起始位置.
|
||||
};
|
||||
|
||||
// 转义相关标识.
|
||||
enum ProtocolEscapeFlag
|
||||
{
|
||||
PROTOCOL_SIGN = 0x7E, // 标识位.
|
||||
PROTOCOL_ESCAPE = 0x7D, // 转义标识.
|
||||
PROTOCOL_ESCAPE_SIGN = 0x02, // 0x7E<-->0x7D后紧跟一个0x02.
|
||||
PROTOCOL_ESCAPE_ESCAPE = 0x01, // 0x7D<-->0x7D后紧跟一个0x01.
|
||||
};
|
||||
|
||||
// 消息头.
|
||||
struct MsgHead
|
||||
{
|
||||
// 消息ID.
|
||||
unsigned short msg_id;
|
||||
// 消息体属性.
|
||||
union MsgBodyAttribute msgbody_attr;
|
||||
// 终端手机号.
|
||||
unsigned char phone_num[13];
|
||||
// 消息流水号.
|
||||
unsigned short msg_flow_num;
|
||||
// 总包数, 分包情况下使用.
|
||||
unsigned short total_packet;
|
||||
// 当前包编号, 分包情况下使用.
|
||||
unsigned short packet_seq;
|
||||
};
|
||||
|
||||
// 注册信息.
|
||||
struct RegisterInfo
|
||||
{
|
||||
// 省域ID.
|
||||
unsigned short province_id;
|
||||
|
||||
// 市县域ID.
|
||||
unsigned short city_id;
|
||||
|
||||
// 制造商ID, 固定5个字节.
|
||||
unsigned char manufacturer_id[5];
|
||||
|
||||
// 终端型号, 固定20个字节, 位数不足后补0x00.
|
||||
unsigned char terminal_model[20];
|
||||
|
||||
// 终端ID, 固定7个字节, 位数不足后补0x00.
|
||||
unsigned char terminal_id[7];
|
||||
|
||||
// 车牌颜色, 0表示未上牌.
|
||||
unsigned char car_plate_color;
|
||||
|
||||
// 车辆标识, 仅在上牌时使用.
|
||||
unsigned char car_plate_num[12];
|
||||
};
|
||||
|
||||
//struct RegisterID
|
||||
//{
|
||||
// unsigned char PhoneNumber[20];
|
||||
// unsigned char TerminalId[20];
|
||||
//};
|
||||
|
||||
// 升级类型.
|
||||
enum kTerminalUpgradeType
|
||||
{
|
||||
// 终端.
|
||||
kTerminal = 0x0,
|
||||
// 道路运输证 IC 卡读卡器
|
||||
kICCardReader = 0xc,
|
||||
// 北斗卫星定位模块.
|
||||
kGNSS = 0x34,
|
||||
};
|
||||
|
||||
// 升级结果.
|
||||
enum kTerminalUpgradeResultType
|
||||
{
|
||||
// 终端升级成功.
|
||||
kTerminalUpgradeSuccess = 0x0,
|
||||
// 终端升级失败.
|
||||
kTerminalUpgradeFailed,
|
||||
// 终端升级取消.
|
||||
kTerminalUpgradeCancel
|
||||
};
|
||||
|
||||
// 升级信息.
|
||||
struct UpgradeInfo
|
||||
{
|
||||
// 升级类型.
|
||||
unsigned char upgrade_type;
|
||||
// 升级结果.
|
||||
unsigned char upgrade_result;
|
||||
// 制造商ID, 固定5个字节.
|
||||
unsigned char manufacturer_id[5];
|
||||
// 升级版本号.
|
||||
const char *version_id;
|
||||
// 升级包总长度.
|
||||
unsigned int upgrade_data_total_len;
|
||||
// 升级数据包.
|
||||
char *upgrade_data;
|
||||
};
|
||||
|
||||
// 补传分包信息.
|
||||
struct FillPacket
|
||||
{
|
||||
// 分包数据首包的消息流水号.
|
||||
unsigned short first_packet_msg_flow_num;
|
||||
// 需要重传包的ID.
|
||||
const char packet_id[50];
|
||||
};
|
||||
|
||||
// 协议格式、各消息ID等相关参数.
|
||||
struct ProtocolParameter
|
||||
{
|
||||
unsigned char respone_result;
|
||||
unsigned short respone_msg_id;
|
||||
unsigned short respone_flow_num;
|
||||
// 消息头.
|
||||
struct MsgHead msg_head;
|
||||
// 终端注册时需填充注册信息.
|
||||
struct RegisterInfo register_info;
|
||||
// struct RegisterID register_id;
|
||||
// 平台随机生成鉴权码.
|
||||
uint8_t authentication_code[40];
|
||||
|
||||
//IMEI
|
||||
uint8_t IMEI[15];
|
||||
//软件版本号
|
||||
uint8_t softwareVersion[20];
|
||||
// 设置终端参数项.
|
||||
struct TerminalParameters terminal_parameters;
|
||||
// 查询终端参数ID列表.
|
||||
// std::vector<unsigned int> terminal_parameter_ids;
|
||||
// 位置上报时填充位置基本信息, 必须项.
|
||||
struct LocationBasicInformation location_info;
|
||||
// 位置上报时填充位置附加信息, 可选项.
|
||||
// LocationExtensions location_extension;
|
||||
// 临时位置跟踪控制信息.
|
||||
struct LocationTrackingControl location_tracking_control;
|
||||
|
||||
// 升级信息.
|
||||
struct UpgradeInfo upgrade_info;
|
||||
// 补传分包信息.
|
||||
struct FillPacket fill_packet;
|
||||
|
||||
//终端控制
|
||||
struct TerminalControl terminal_control;
|
||||
|
||||
// // 保留字段.
|
||||
// std::vector<unsigned char > retain;
|
||||
|
||||
// 用于解析消息.
|
||||
struct
|
||||
{
|
||||
unsigned char respone_result;
|
||||
unsigned short respone_msg_id;
|
||||
unsigned short respone_flow_num;
|
||||
// 解析出的消息头.
|
||||
struct MsgHead msg_head;
|
||||
// 解析出的注册信息.
|
||||
struct RegisterInfo register_info;
|
||||
// 解析出的鉴权码.
|
||||
// 平台随机生成鉴权码.
|
||||
unsigned char *authentication_code;
|
||||
// 解析出的设置终端参数项.
|
||||
struct TerminalParameters terminal_parameters;
|
||||
// 解析出的查询终端参数ID列表.
|
||||
// std::vector<unsigned int> terminal_parameter_ids;
|
||||
// 解析出的位置基本信息.
|
||||
struct LocationBasicInformation location_info;
|
||||
// 解析出的位置附加信息.
|
||||
// LocationExtensions location_extension;
|
||||
// 解析出的临时位置跟踪控制信息.
|
||||
struct LocationTrackingControl location_tracking_control;
|
||||
|
||||
// 解析出的升级信息.
|
||||
struct UpgradeInfo upgrade_info;
|
||||
// 解析出的补传分包信息.
|
||||
struct FillPacket fill_packet;
|
||||
|
||||
//终端控制
|
||||
struct TerminalControl terminal_control;
|
||||
|
||||
// 解析出的保留字段.
|
||||
// std::vector<unsigned char > retain;
|
||||
|
||||
} parse;
|
||||
};
|
||||
|
||||
|
||||
#endif // JT808_PROTOCOL_PARAMETER_H_
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
#include "protocol_parameter.h"
|
||||
#include "bcd.h"
|
||||
#include "util.h"
|
||||
|
||||
|
||||
#define PARA_SETTING_LIMIT 10 //终端打包器命令相应消息ID数量
|
||||
|
||||
// 所有终端数据打包命令.
|
||||
extern unsigned short kParameterSettingCMD[PARA_SETTING_LIMIT];
|
||||
|
||||
void jt808ParameterSettingParse(unsigned int id,unsigned char *buf,unsigned char buf_len, struct ProtocolParameter *para);
|
||||
void handle_HeartBeatInterval(unsigned char *buf,unsigned char buf_len,struct ProtocolParameter *para);
|
||||
void handle_MainServerAddress(unsigned char *buf,unsigned char buf_len,struct ProtocolParameter *para);
|
||||
void handle_ServerPort(unsigned char *buf,unsigned char buf_len,struct ProtocolParameter *para);
|
||||
void handle_DefaultTimeReportTimeInterval(unsigned char *buf,unsigned char buf_len,struct ProtocolParameter *para);
|
||||
void handle_CornerPointRetransmissionAngle(unsigned char *buf,unsigned char buf_len,struct ProtocolParameter *para);
|
||||
void handle_MaxSpeed(unsigned char *buf,unsigned char buf_len,struct ProtocolParameter *para);
|
||||
void handle_ProvinceID(unsigned char *buf,unsigned char buf_len,struct ProtocolParameter *para);
|
||||
void handle_CityID(unsigned char *buf,unsigned char buf_len,struct ProtocolParameter *para);
|
||||
void handle_CarPlateNum(unsigned char *buf,unsigned char buf_len,struct ProtocolParameter *para);
|
||||
void handle_CarPlateColor(unsigned char *buf,unsigned char buf_len,struct ProtocolParameter *para);
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
#ifndef JT808_TERMINAL_CONTROL_H_
|
||||
#define JT808_TERMINAL_CONTROL_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
//#include <fcntl.h>
|
||||
#include <stdint.h>
|
||||
#include "util.h"
|
||||
|
||||
// 0x8105终端控制命令字.
|
||||
union TerminalCtrlCmdByte
|
||||
{
|
||||
struct
|
||||
{
|
||||
unsigned char u8val_0 : 1; //
|
||||
unsigned char u8val_1 : 1; // 无线升级
|
||||
unsigned char u8val_2 : 1; // 控制终端连接指定服务器
|
||||
unsigned char u8val_3 : 1; // 终端关机
|
||||
unsigned char u8val_4 : 1; // 终端复位
|
||||
unsigned char u8val_5 : 1; // 终端恢复出厂设置
|
||||
unsigned char u8val_6 : 1; // 关闭数据通信
|
||||
unsigned char u8val_7 : 1; // 关闭所有无线通信
|
||||
} bit;
|
||||
unsigned char u8val;
|
||||
};
|
||||
|
||||
// 0x8105终端控制.
|
||||
struct TerminalControl
|
||||
{
|
||||
// TerminalCtrlCmdByte cmdByte; // 命令字
|
||||
unsigned char cmdByte; // 命令字 1:无线升级;2:控制终端连接指定服务器;3:终端关机;4:终端复位;5:终端恢复出厂设置;6:关闭数据通信;7:关闭所有无线通信
|
||||
const char *cmdParameter; // 命令参数
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,504 @@
|
|||
#ifndef JT808_TERMINAL_PARAMETER_H_
|
||||
#define JT808_TERMINAL_PARAMETER_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
//#include <fcntl.h>
|
||||
#include <stdint.h>
|
||||
#include "util.h"
|
||||
|
||||
// 终端参数设置项参数ID.
|
||||
enum TerminalParameterID
|
||||
{
|
||||
// DWORD, 终端心跳发送间隔(s).
|
||||
kTerminalHeartBeatInterval = 0x0001,
|
||||
|
||||
//STRING, 主服务器地址,IP 或域名
|
||||
kMainServerAddress = 0x0013,
|
||||
|
||||
//DWORD, 服务器 TCP 端口
|
||||
kServerPort = 0x0018,
|
||||
|
||||
// DWORD, 缺省时间汇报间隔
|
||||
kDefaultTimeReportTimeInterval = 0x0029,
|
||||
|
||||
// DWORD, 拐点补传角度, < 180°.
|
||||
kCornerPointRetransmissionAngle = 0x0030,
|
||||
|
||||
// DWORD, 最高速度, km/h.
|
||||
kMaxSpeed = 0x0055,
|
||||
|
||||
// WORD, 车辆所在的省域 ID
|
||||
kProvinceID = 0x0081,
|
||||
|
||||
// WORD, 车辆所在的市域 ID
|
||||
kCityID = 0x0082,
|
||||
|
||||
//STRING, 公安交通管理部门颁发的机动车号牌
|
||||
kCarPlateNum = 0x0083,
|
||||
|
||||
//车牌颜色,按照 JT/T415-2006 的 5.4.12
|
||||
kCarPlateColor = 0x0084,
|
||||
};
|
||||
|
||||
struct TerminalParameters
|
||||
{
|
||||
// DWORD, 终端心跳发送间隔(s).
|
||||
unsigned int HeartBeatInterval;
|
||||
|
||||
//STRING, 主服务器地址,IP 或域名
|
||||
unsigned char MainServerAddress[50];
|
||||
|
||||
//DWORD, 服务器 TCP 端口
|
||||
unsigned int ServerPort;
|
||||
|
||||
// DWORD, 缺省时间汇报间隔
|
||||
unsigned int DefaultTimeReportTimeInterval;
|
||||
|
||||
// DWORD, 拐点补传角度, < 180°.
|
||||
unsigned int CornerPointRetransmissionAngle;
|
||||
|
||||
// DWORD, 最高速度, km/h.
|
||||
unsigned int MaxSpeed;
|
||||
|
||||
// WORD, 车辆所在的省域 ID
|
||||
unsigned short ProvinceID;
|
||||
|
||||
// WORD, 车辆所在的市域 ID
|
||||
unsigned short CityID;
|
||||
|
||||
//STRING, 公安交通管理部门颁发的机动车号牌
|
||||
unsigned char CarPlateNum[12];
|
||||
|
||||
//车牌颜色,按照 JT/T415-2006 的 5.4.12
|
||||
unsigned char CarPlateColor;
|
||||
|
||||
// DWORD, 判断是否已经进行出厂化参数设置
|
||||
unsigned int initFactoryParameters;
|
||||
|
||||
//STRING, 版本号
|
||||
unsigned char version[12];
|
||||
|
||||
char PhoneNumber[20];
|
||||
char TerminalId[20];
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // JT808_TERMINAL_PARAMETER_H_
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//#ifndef JT808_TERMINAL_PARAMETER_H_
|
||||
//#define JT808_TERMINAL_PARAMETER_H_
|
||||
|
||||
//#include <stdio.h>
|
||||
//#include <stdbool.h>
|
||||
////#include <fcntl.h>
|
||||
//#include <stdint.h>
|
||||
//#include "util.h"
|
||||
|
||||
//// namespace libjt808 //原C++名称空间部分
|
||||
//// { //原C++名称空间部分
|
||||
|
||||
// // 终端参数设置项参数ID.
|
||||
// enum TerminalParameterID
|
||||
// {
|
||||
// // DWORD, 终端心跳发送间隔(s).
|
||||
// kTerminalHeartBeatInterval = 0x0001,
|
||||
//// // DWORD, TCP消息应答超时时间(s).
|
||||
//// kTCPResponseTimeout = 0x0002,
|
||||
//// // DWORD, TCP消息重传次数.
|
||||
//// kTCPMsgRetransmissionTimes = 0x0003,
|
||||
//// // DWORD, UDP消息应答超时时间(s).
|
||||
//// kUDPResponseTimeout = 0x0004,
|
||||
//// // DWORD, UDP消息重传次数
|
||||
//// kUDPMsgRetransmissionTimes = 0x0005,
|
||||
//// // DWORD, SMS消息应答超时时间(s).
|
||||
//// kSMSResponseTimeout = 0x0006,
|
||||
//// // DWORD, SMS消息重传次数.
|
||||
//// kSMSMsgRetransmissionTimes = 0x0007,
|
||||
//// // DWORD, 位置汇报策略, 0:定时汇报; 1:定距汇报; 2:定时和定距汇报.
|
||||
|
||||
//
|
||||
// kMainServerAddress = 0x0013,
|
||||
// //STRING, 主服务器地址,IP 或域名
|
||||
//
|
||||
// kServerPort = 0x0018,
|
||||
// //DWORD, 服务器 TCP 端口
|
||||
//
|
||||
//// kLocationReportWay = 0x0020,
|
||||
//// // DWORD, 位置汇报方案, 0:根据 ACC 状态; 1:根据登录状态和ACC
|
||||
//// // 状态, 先判断登录状态, 若登录再根据 ACC 状态.
|
||||
//// kLocationReportPlan = 0x0021,
|
||||
//// // DWORD, 驾驶员未登录汇报时间间隔.
|
||||
//// kDriverNotLoginReportTimeInterval = 0x0022,
|
||||
//// // DWORD, 休眠时汇报时间间隔
|
||||
//// kSleepingReportTimeInterval = 0x0027,
|
||||
//// // DWORD, 紧急报警时汇报时间间隔
|
||||
//// kAlarmingReportTimeInterval = 0x0028,
|
||||
//// // DWORD, 缺省时间汇报间隔
|
||||
// kDefaultTimeReportTimeInterval = 0x0029,
|
||||
// // DWORD, 缺省距离汇报间隔
|
||||
//// kDefaultReportDistanceInterval = 0x002C,
|
||||
//// // DWORD, 驾驶员未登录汇报距离间隔.
|
||||
//// kDriverNotLoginReportDistanceInterval = 0x002D,
|
||||
//// // DWORD, 休眠时汇报距离间隔
|
||||
//// kSleepingReportDistanceInterval = 0x002E,
|
||||
//// // DWORD, 紧急报警时汇报距离间隔
|
||||
//// kAlarmingReportDistanceInterval = 0x002F,
|
||||
//// // DWORD, 拐点补传角度, < 180°.
|
||||
// kCornerPointRetransmissionAngle = 0x0030,
|
||||
// // DWORD, 报警屏蔽字, 与位置信息汇报消息中的报警标志相对
|
||||
// // 应, 相应位为1则相应报警被屏蔽.
|
||||
//// kAlarmShieldWord = 0x0050,
|
||||
//// // DWORD, 报警发送文本SMS开关, 与位置信息汇报消息中的报警
|
||||
//// // 标志相对应, 相应位为1则相应报警时发送文本SMS.
|
||||
//// kAlarmSendSMSText = 0x0051,
|
||||
//// // DWORD, 报警拍摄开关, 与位置信息汇报消息中的报警标志相
|
||||
//// // 对应, 相应位为1则相应报警时摄像头拍摄.
|
||||
//// kAlarmShootSwitch = 0x0052,
|
||||
//// // DWORD, 报警拍摄存储标志, 与位置信息汇报消息中的报警标
|
||||
//// // 志相对应, 相应位为1则对相应报警时拍的照片进行
|
||||
//// // 存储, 否则实时上传.
|
||||
//// kAlarmShootSaveFlag = 0x0053,
|
||||
//// // DWORD, 关键标志, 与位置信息汇报消息中的报警标志相对应,
|
||||
//// // 相应位为1则对相应报警为关键报警.
|
||||
//// kAlarmKeyFlag = 0x0054,
|
||||
// // DWORD, 最高速度, km/h.
|
||||
// kMaxSpeed = 0x0055,
|
||||
//// // BYTE, GNSS定位模式, 定义如下:
|
||||
//// // bit0, 0: 禁用GPS定位, 1: 启用GPS定位;
|
||||
//// // bit1, 0: 禁用北斗定位, 1: 启用北斗定位;
|
||||
//// // bit2, 0: 禁用GLONASS定位, 1: 启用GLONASS定位;
|
||||
//// // bit3, 0: 禁用Galileo定位, 1: 启用Galileo定位.
|
||||
// kProvinceID = 0x0081,
|
||||
// // WORD, 车辆所在的省域 ID
|
||||
//
|
||||
// KCityID = 0x0082,
|
||||
// // WORD, 车辆所在的市域 ID
|
||||
//
|
||||
// KCarPlateNum = 0x0083,
|
||||
// //STRING, 公安交通管理部门颁发的机动车号牌
|
||||
//
|
||||
// KCarPlateColor = 0x0084,
|
||||
// //车牌颜色,按照 JT/T415-2006 的 5.4.12
|
||||
//
|
||||
// kGNSSPositionMode = 0x0090,
|
||||
// // BYTE, GNSS波特率, 定义如下:
|
||||
// // 0x00: 4800; 0x01: 9600: 0x02: 19200;
|
||||
// // 0x03: 38400; 0x04: 57600; 0x05: 115200.
|
||||
// kGNSSBaudeRate = 0x0091,
|
||||
// // BYTE, GNSS模块详细定位数据输出频率, 定义如下:
|
||||
// // 0x00: 500ms; 0x01: 1000ms(默认值);
|
||||
// // 0x02: 2000ms; 0x03: 3000ms; 0x04: 4000m.
|
||||
// kGNSSOutputFrequency = 0x0092,
|
||||
// // DWORD, GNSS模块详细定位数据采集频率(s), 默认为1.
|
||||
// kGNSSOutputCollectFrequency = 0x0093,
|
||||
// // BYTE, GNSS模块详细定位数据上传方式:
|
||||
// // 0x00, 本地存储, 不上传(默认值);
|
||||
// // 0x01, 按时间间隔上传;
|
||||
// // 0x02, 按距离间隔上传;
|
||||
// // 0x0B, 按累计时间上传, 达到传输时间后自动停止上传;
|
||||
// // 0x0C, 按累计距离上传, 达到距离后自动停止上传;
|
||||
// // 0x0D, 按累计条数上传, 达到上传条数后自动停止上传.
|
||||
// kGNSSOutputUploadWay = 0x0094,
|
||||
// // DWORD, GNSS模块详细定位数据上传设置:
|
||||
// // 上传方式为0x01时, 单位为秒;
|
||||
// // 上传方式为0x02时, 单位为米;
|
||||
// // 上传方式为0x0B时, 单位为秒;
|
||||
// // 上传方式为0x0C时, 单位为米;
|
||||
// // 上传方式为0x0D时, 单位为条.
|
||||
// kSetGNSSDataUpload = 0x0095,
|
||||
// // DWORD, CAN总线通道1采集时间间隔(ms), 0表示不采集.
|
||||
// kCANBus1CollectInterval = 0x0100,
|
||||
// // WORD, CAN总线通道1上传时间间隔(s), 0表示不上传.
|
||||
// kCANBus1UploadInterval = 0x0101,
|
||||
// // DWORD, CAN总线通道2采集时间间隔(ms), 0表示不采集.
|
||||
// kCANBus2CollectInterval = 0x0102,
|
||||
// // WORD, CAN总线通道2上传时间间隔(s), 0表示不上传.
|
||||
// kCANBus2UploadInterval = 0x0103,
|
||||
// // BYTE[8], CAN总线ID单独采集设置:
|
||||
// // bit63-bit32 表示此ID采集时间间隔(ms), 0表示不采集;
|
||||
// // bit31 表示CAN通道号, 0: CAN1, 1: CAN2;
|
||||
// // bit30 表示帧类型, 0: 标准帧, 1: 扩展帧;
|
||||
// // bit29 表示数据采集方式, 0: 原始数据, 1: 采集区间的计算值;
|
||||
// // bit28-bit0 表示CAN总线ID.
|
||||
// kSetCANBusSpecial = 0x0110,
|
||||
// };
|
||||
|
||||
// // GNSS模块数据输出波特率.
|
||||
// enum GNSSModelBaudeRate
|
||||
// {
|
||||
// kBDRT4800 = 0x0,
|
||||
// kBDRT9600,
|
||||
// kBDRT19200,
|
||||
// kBDRT38400,
|
||||
// kBDRT57600,
|
||||
// kBDRT115200,
|
||||
// };
|
||||
|
||||
/*
|
||||
// 终端参数存储定义: key: itemid, value: itemvalue.
|
||||
// using TerminalParameters = std::map<unsigned int , std::vector<unsigned char >>;//原C++相关定义
|
||||
|
||||
//
|
||||
// 终端参数转换.
|
||||
//
|
||||
// undefined type --> terminal parameter item.
|
||||
template <typename T>
|
||||
inline int SetTerminalParameter(unsigned int const &key, T const &value, TerminalParameters *items)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// terminal parameter item --> undefined type.
|
||||
template <typename T>
|
||||
inline int GetTerminalParameter(TerminalParameters const &items, unsigned int const &key, T *value)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// unsigned char --> terminal parameter item.
|
||||
template <>
|
||||
inline int SetTerminalParameter(unsigned int const &key, unsigned char const &value, TerminalParameters *items)
|
||||
{
|
||||
if (items == nullptr)
|
||||
return -1;
|
||||
auto it = items->find(key);
|
||||
if (it != items->end())
|
||||
{
|
||||
it->second.clear();
|
||||
it->second.push_back(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
items->insert(std::make_pair(key, std::vector<unsigned char >{value}));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// terminal parameter item --> unsigned char .
|
||||
template <>
|
||||
inline int GetTerminalParameter(TerminalParameters const &items, unsigned int const &key, unsigned char *value)
|
||||
{
|
||||
if (value == nullptr)
|
||||
return -1;
|
||||
auto const &it = items.find(key);
|
||||
if (it != items.end())
|
||||
{
|
||||
if (it->second.size() != 1)
|
||||
return -1;
|
||||
*value = it->second[0];
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// unsigned short --> terminal parameter item.
|
||||
template <>
|
||||
inline int SetTerminalParameter(unsigned int const &key, unsigned short const &value, TerminalParameters *items)
|
||||
{
|
||||
if (items == nullptr)
|
||||
return -1;
|
||||
U16ToU8Array cvt;
|
||||
cvt.u16val = EndianSwap16(value);
|
||||
auto it = items->find(key);
|
||||
if (it != items->end())
|
||||
{
|
||||
it->second.clear();
|
||||
it->second.assign(cvt.u8array, cvt.u8array + 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
items->insert(std::make_pair(key,
|
||||
std::vector<unsigned char >(cvt.u8array, cvt.u8array + 2)));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// terminal parameter item --> unsigned short .
|
||||
template <>
|
||||
inline int GetTerminalParameter(TerminalParameters const &items, unsigned int const &key, unsigned short *value)
|
||||
{
|
||||
if (value == nullptr)
|
||||
return -1;
|
||||
auto const &it = items.find(key);
|
||||
if (it != items.end())
|
||||
{
|
||||
if (it->second.size() != 2)
|
||||
return -1;
|
||||
*value = it->second[0] * 256 + it->second[1];
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// unsigned int --> terminal parameter item.
|
||||
template <>
|
||||
inline int SetTerminalParameter(unsigned int const &key, unsigned int const &value, TerminalParameters *items)
|
||||
{
|
||||
if (items == nullptr)
|
||||
return -1;
|
||||
U32ToU8Array cvt;
|
||||
cvt.u32val = EndianSwap32(value);
|
||||
auto it = items->find(key);
|
||||
if (it != items->end())
|
||||
{
|
||||
it->second.clear();
|
||||
it->second.assign(cvt.u8array, cvt.u8array + 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
items->insert(std::make_pair(key,
|
||||
std::vector<unsigned char >(cvt.u8array, cvt.u8array + 4)));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// terminal parameter item --> unsigned int .
|
||||
template <>
|
||||
inline int GetTerminalParameter(TerminalParameters const &items, unsigned int const &key, unsigned int *value)
|
||||
{
|
||||
if (value == nullptr)
|
||||
return -1;
|
||||
auto const &it = items.find(key);
|
||||
if (it != items.end())
|
||||
{
|
||||
if (it->second.size() != 4)
|
||||
return -1;
|
||||
*value = it->second[0] * 65536 * 256 +
|
||||
it->second[1] * 65536 +
|
||||
it->second[2] * 256 +
|
||||
it->second[3];
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// std::string --> terminal parameter item.
|
||||
template <>
|
||||
inline int SetTerminalParameter(unsigned int const &key, std::string const &value, TerminalParameters *items)
|
||||
{
|
||||
if (items == nullptr)
|
||||
return -1;
|
||||
auto it = items->find(key);
|
||||
if (it != items->end())
|
||||
{
|
||||
it->second.clear();
|
||||
it->second.assign(value.begin(), value.end());
|
||||
}
|
||||
else
|
||||
{
|
||||
items->insert(std::make_pair(key,
|
||||
std::vector<unsigned char >(value.begin(), value.end())));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// terminal parameter item --> std::string.
|
||||
template <>
|
||||
inline int GetTerminalParameter(TerminalParameters const &items, unsigned int const &key, std::string *value)
|
||||
{
|
||||
if (value == nullptr)
|
||||
return -1;
|
||||
auto const &it = items.find(key);
|
||||
if (it != items.end())
|
||||
{
|
||||
value->clear();
|
||||
value->assign(it->second.begin(), it->second.end());
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
//
|
||||
// 协议支持的终端参数项封装/解析.
|
||||
//
|
||||
|
||||
// 封装终端心跳发送间隔配置.
|
||||
// Args:
|
||||
// intv: 终端心跳时间间隔.
|
||||
// Returns:
|
||||
// 成功返回0, 失败返回-1.
|
||||
inline int PackagingTerminalParameterTerminalHeartBeatInterval(unsigned int const &intv, TerminalParameters *items)
|
||||
{
|
||||
return SetTerminalParameter(kTerminalHeartBeatInterval, intv, items);
|
||||
}
|
||||
|
||||
// 解析终端心跳发送间隔配置.
|
||||
// Args:
|
||||
// items: 终端参数项的map容器.
|
||||
// intv: 保存解析的终端心跳时间间隔.
|
||||
// Returns:
|
||||
// 成功返回0, 失败返回-1.
|
||||
inline int ParseTerminalParameterTerminalHeartBeatInterval(TerminalParameters const &items, unsigned int *intv)
|
||||
{
|
||||
return GetTerminalParameter(items, kTerminalHeartBeatInterval, intv);
|
||||
}
|
||||
*/
|
||||
|
||||
// } // namespace libjt808 //原C++名称空间部分
|
||||
|
||||
//#endif // JT808_TERMINAL_PARAMETER_H_
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
#ifndef JT808_TERMINAL_REGISTER_H_
|
||||
#define JT808_TERMINAL_REGISTER_H_
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
//#include <memory.h>
|
||||
#include <string.h>
|
||||
#include "protocol_parameter.h"
|
||||
|
||||
|
||||
/// @brief 设置注册省域ID
|
||||
/// @param provinceId
|
||||
void setRegisterProvinceId(unsigned short provinceId);
|
||||
|
||||
/// @brief 获取省域ID
|
||||
/// @return
|
||||
unsigned short getRegisterProvinceId(void);
|
||||
|
||||
/// @brief 设置市县域ID
|
||||
/// @param cityId
|
||||
void setRegisterCityId(unsigned short cityId);
|
||||
|
||||
/// @brief 获取市县域ID
|
||||
/// @return
|
||||
unsigned short getRegisterCityId(void);
|
||||
|
||||
// 制造商ID, 固定5个字节.
|
||||
void setRegister_manufacturer_id(const char *manufacturerId, unsigned int manufacturer_id_size);
|
||||
|
||||
const char *getRegister_manufacturer_id(void);
|
||||
|
||||
// 终端型号, 固定20个字节, 位数不足后补0x00.
|
||||
void setRegister_terminal_model(const char *terminalModel, unsigned int terminalModel_size);
|
||||
|
||||
/// @brief 获取终端型号
|
||||
/// @return
|
||||
const char *getRegister_terminal_model(void);
|
||||
|
||||
// 终端ID, 固定7个字节, 位数不足后补0x00.
|
||||
void setRegister_terminal_id(const char *terminal_id, unsigned int terminal_id_size);
|
||||
|
||||
/// @brief 获取终端型号
|
||||
/// @return
|
||||
const char *getRegister_terminal_id(void);
|
||||
|
||||
// 车牌颜色, 0表示未上牌.
|
||||
void setRegister_car_plate_color(unsigned char car_plate_color);
|
||||
|
||||
/// @brief 获取市县域ID
|
||||
/// @return
|
||||
unsigned char getRegister_car_plate_color(void);
|
||||
|
||||
// 车辆标识, 仅在上牌时使用.
|
||||
void setRegister_car_plate_num(const char *car_plate_num, unsigned int car_plate_num_size);
|
||||
|
||||
/// @brief 获取终端型号
|
||||
/// @return
|
||||
//const char *getRegister_car_plate_num(void);
|
||||
|
||||
void initRegisterInfo(struct ProtocolParameter *para);
|
||||
|
||||
#endif //JT808_TERMINAL_REGISTER_H_
|
||||
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
|
||||
#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>
|
||||
|
||||
// namespace libjt808
|
||||
// {
|
||||
|
||||
// 无符号64位整型转无符号字节数组.
|
||||
union U64ToU8Array
|
||||
{
|
||||
unsigned long u64val;
|
||||
unsigned char u8array[8];
|
||||
};
|
||||
|
||||
// 无符号32位整型转无符号字节数组.
|
||||
union U32ToU8Array
|
||||
{
|
||||
unsigned int u32val;
|
||||
unsigned char u8array[4];
|
||||
};
|
||||
|
||||
// 无符号16位整型转无符号字节数组.
|
||||
union U16ToU8Array
|
||||
{
|
||||
unsigned short u16val;
|
||||
unsigned char u8array[2];
|
||||
};
|
||||
|
||||
// 大小端互换.
|
||||
unsigned short EndianSwap16(unsigned short u16val);
|
||||
|
||||
// 大小端互换.
|
||||
unsigned int EndianSwap32(unsigned int u32val);
|
||||
|
||||
|
||||
// 转义函数.
|
||||
int Escape_C(unsigned char *in, unsigned int inlen, unsigned char *out, unsigned int *outlen);
|
||||
int ReverseEscape_C(unsigned char *in, unsigned int inlen, unsigned char *out, unsigned int *outlen);
|
||||
|
||||
// 异或校验.
|
||||
unsigned char BccCheckSum(const unsigned char *src, unsigned long len);
|
||||
|
||||
//处理字符串,返回子串在母串的第一个字符的位置
|
||||
int strStr(const char * haystack, const char * needle);
|
||||
|
||||
|
||||
#endif // JT808_UTIL_H_
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
CUSTOM_MAIN_DIR := custom/jt808
|
||||
|
||||
OC_FILES += $(CUSTOM_MAIN_DIR)/src/bcd.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/jt808_packager.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/set_terminal_parameter.c
|
||||
OC_FILES += $(CUSTOM_MAIN_DIR)/src/terminal_register.c
|
||||
OC_FILES += $(CUSTOM_MAIN_DIR)/src/util.c
|
||||
|
||||
INC += -I'$(CUSTOM_MAIN_DIR)/inc'
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
#include "bcd.h"
|
||||
#include "jt808_debug.h"
|
||||
|
||||
unsigned char HexToBcd(unsigned char src)
|
||||
{
|
||||
unsigned char temp;
|
||||
temp = ((src / 10) << 4) + (src % 10);
|
||||
return temp;
|
||||
}
|
||||
|
||||
unsigned char BcdToHex(unsigned char src)
|
||||
{
|
||||
unsigned char temp;
|
||||
temp = (src >> 4) * 10 + (src & 0x0f);
|
||||
return temp;
|
||||
}
|
||||
|
||||
unsigned char *jt808StringToBcdCompress(const unsigned char *src, unsigned char *dst, int srclen)
|
||||
{
|
||||
unsigned char *ptr = dst;
|
||||
unsigned char temp;
|
||||
if (srclen % 2 != 0)
|
||||
{
|
||||
*ptr++ = HexToBcd(*src++ - '0');
|
||||
}
|
||||
while (*src)
|
||||
{
|
||||
temp = *src++ - '0';
|
||||
temp *= 10;
|
||||
temp += *src++ - '0';
|
||||
*ptr++ = HexToBcd(temp);
|
||||
}
|
||||
*ptr = 0;
|
||||
return dst;
|
||||
}
|
||||
|
||||
unsigned char *jt808BcdToStringCompress(const unsigned char *src, unsigned char *dst, int srclen)
|
||||
{
|
||||
unsigned char *ptr = dst;
|
||||
unsigned char temp;
|
||||
int cnt = srclen;
|
||||
while (cnt--)
|
||||
{
|
||||
temp = BcdToHex(*src);
|
||||
*ptr++ = temp / 10 + '0';
|
||||
if (dst[0] == '0')
|
||||
{
|
||||
ptr = dst;
|
||||
}
|
||||
*ptr++ = temp % 10 + '0';
|
||||
++src;
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
|
||||
unsigned char *jt808BcdToStringCompressFillingZero(const unsigned char *src, unsigned char *dst, int srclen)
|
||||
{
|
||||
unsigned char *ptr = dst;
|
||||
unsigned char temp;
|
||||
int cnt = srclen;
|
||||
while (cnt--)
|
||||
{
|
||||
temp = BcdToHex(*src);
|
||||
*ptr++ = temp / 10 + '0';
|
||||
*ptr++ = temp % 10 + '0';
|
||||
++src;
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
|
@ -0,0 +1,497 @@
|
|||
#include "client_manager.h"
|
||||
#include "protocol_parameter.h"
|
||||
#include "set_terminal_parameter.h"
|
||||
#include "jt808_parser.h"
|
||||
#include "util.h"
|
||||
#include "bcd.h"
|
||||
#include "jt808_packager.h"
|
||||
#include "jt808_parser.h"
|
||||
#include "jt808_debug.h"
|
||||
|
||||
uint8_t Non_transliterated_receive[1024];
|
||||
struct ProtocolParameter parameter_;
|
||||
|
||||
void initSystemParameters(int i)
|
||||
{
|
||||
// Internal_ReadFlash(FLASH_ADDR, (uint8_t*)¶meter_.parse.terminal_parameters , sizeof(parameter_.parse.terminal_parameters));
|
||||
parameter_.parse.terminal_parameters.initFactoryParameters = i;
|
||||
|
||||
JT808_DEBUG("initFactoryParameters == %d \r\n", parameter_.parse.terminal_parameters.initFactoryParameters);
|
||||
|
||||
if (parameter_.parse.terminal_parameters.initFactoryParameters == 0)
|
||||
{
|
||||
FlashWrite();
|
||||
// Internal_ReadFlash(FLASH_ADDR, (uint8_t*)¶meter_.parse.terminal_parameters , sizeof(parameter_.parse.terminal_parameters));
|
||||
}
|
||||
JT808_DEBUG("-->---------------------------\r\n");
|
||||
JT808_DEBUG("--> \r\n");
|
||||
JT808_DEBUG("--> Version = %s \r\n", parameter_.parse.terminal_parameters.version);
|
||||
JT808_DEBUG("--> \r\n");
|
||||
JT808_DEBUG("-->---------------------------\r\n");
|
||||
JT808_DEBUG("HeartBeatInterval == %d \r\n", parameter_.parse.terminal_parameters.HeartBeatInterval);
|
||||
JT808_DEBUG("MainServerAddress == \"%s\" \r\n", parameter_.parse.terminal_parameters.MainServerAddress);
|
||||
JT808_DEBUG("ServerPort == %d \r\n", parameter_.parse.terminal_parameters.ServerPort);
|
||||
JT808_DEBUG("DefaultTimeReportTimeInterval == %d \r\n", parameter_.parse.terminal_parameters.DefaultTimeReportTimeInterval);
|
||||
JT808_DEBUG("CornerPointRetransmissionAngle == %d \r\n", parameter_.parse.terminal_parameters.CornerPointRetransmissionAngle);
|
||||
JT808_DEBUG("MaxSpeed == %d \r\n", parameter_.parse.terminal_parameters.MaxSpeed);
|
||||
JT808_DEBUG("ProvinceID == %d \r\n", parameter_.parse.terminal_parameters.ProvinceID);
|
||||
JT808_DEBUG("CityID == %d \r\n", parameter_.parse.terminal_parameters.CityID);
|
||||
JT808_DEBUG("CarPlateNum == %s \r\n", parameter_.parse.terminal_parameters.CarPlateNum);
|
||||
JT808_DEBUG("CarPlateColor == %02x \r\n", parameter_.parse.terminal_parameters.CarPlateColor);
|
||||
JT808_DEBUG("\r\n");
|
||||
JT808_DEBUG("initSystemParameters SUCCESS!!!!!!\r\n");
|
||||
JT808_DEBUG("\r\n");
|
||||
}
|
||||
|
||||
int FlashWrite()
|
||||
{
|
||||
parameter_.parse.terminal_parameters.HeartBeatInterval = 2;
|
||||
|
||||
memset(parameter_.parse.terminal_parameters.MainServerAddress, 0, sizeof(parameter_.parse.terminal_parameters.MainServerAddress));
|
||||
|
||||
// 研究院平台
|
||||
memcpy(parameter_.parse.terminal_parameters.MainServerAddress, "123.160.246.146", sizeof("123.160.246.146"));
|
||||
// memcpy(parameter_.parse.terminal_parameters.MainServerAddress,"http://jt808.gps.ciicp.com", sizeof("http://jt808.gps.ciicp.com"));
|
||||
|
||||
// //客户平台
|
||||
// memcpy(parameter_.parse.terminal_parameters.MainServerAddress,"123.60.47.210", sizeof("123.60.47.210"));
|
||||
|
||||
parameter_.parse.terminal_parameters.ServerPort = 7611;
|
||||
|
||||
parameter_.parse.terminal_parameters.DefaultTimeReportTimeInterval = 2;
|
||||
|
||||
parameter_.parse.terminal_parameters.CornerPointRetransmissionAngle = 10;
|
||||
|
||||
parameter_.parse.terminal_parameters.MaxSpeed = 60;
|
||||
|
||||
parameter_.parse.terminal_parameters.ProvinceID = 0x0029;
|
||||
|
||||
parameter_.parse.terminal_parameters.CityID = 0x0066;
|
||||
|
||||
parameter_.parse.terminal_parameters.CarPlateColor = 0x02;
|
||||
|
||||
parameter_.parse.terminal_parameters.initFactoryParameters = 1;
|
||||
|
||||
memset(parameter_.parse.terminal_parameters.version, 0, sizeof(parameter_.parse.terminal_parameters.version));
|
||||
memcpy(parameter_.parse.terminal_parameters.version, "v1.2", 5);
|
||||
|
||||
|
||||
memset(parameter_.parse.terminal_parameters.PhoneNumber, 0, 12);
|
||||
memset(parameter_.parse.terminal_parameters.CarPlateNum, 0, sizeof(parameter_.parse.terminal_parameters.CarPlateNum));
|
||||
memset(parameter_.parse.terminal_parameters.TerminalId, 0, 8);
|
||||
|
||||
memcpy(parameter_.parse.terminal_parameters.PhoneNumber, "00000000100211609999", 20);
|
||||
memcpy(parameter_.parse.terminal_parameters.TerminalId, "1609999", 8);
|
||||
memcpy(parameter_.parse.terminal_parameters.CarPlateNum, "A:123456", 9);
|
||||
|
||||
// FLASH_WriteByte(FLASH_ADDR , (uint8_t*)¶meter_.parse.terminal_parameters , sizeof(parameter_.parse.terminal_parameters));
|
||||
JT808_DEBUG("FLASH_Write SUCCESS!!!!!!\r\n");
|
||||
JT808_DEBUG("initFactoryParameters == %d \r\n", parameter_.parse.terminal_parameters.initFactoryParameters);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int IPFlashWrite()
|
||||
{
|
||||
memset(parameter_.parse.terminal_parameters.MainServerAddress, 0, sizeof(parameter_.parse.terminal_parameters.MainServerAddress));
|
||||
// memcpy(parameter_.parse.terminal_parameters.MainServerAddress,"121.5.140.126", sizeof("121.5.140.126"));
|
||||
memcpy(parameter_.parse.terminal_parameters.MainServerAddress, "123.60.47.210", sizeof("123.60.47.210"));
|
||||
|
||||
parameter_.parse.terminal_parameters.ServerPort = 7611;
|
||||
|
||||
parameter_.parse.terminal_parameters.DefaultTimeReportTimeInterval = 5;
|
||||
|
||||
// FLASH_WriteByte(FLASH_ADDR , (uint8_t*)¶meter_.parse.terminal_parameters , sizeof(parameter_.parse.terminal_parameters));
|
||||
JT808_DEBUG("IPFLASH_Write SUCCESS!!!!!!\r\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void setUUID(void)
|
||||
{
|
||||
// Internal_ReadFlash(FLASH_ADDR, (uint8_t *) ¶meter_.parse.terminal_parameters, sizeof(parameter_.parse.terminal_parameters));
|
||||
|
||||
setTerminalPhoneNumber(parameter_.parse.terminal_parameters.PhoneNumber, 20);
|
||||
setTerminalId(parameter_.parse.terminal_parameters.TerminalId, 8);
|
||||
|
||||
memset(parameter_.IMEI, 0, 15);
|
||||
memcpy(parameter_.IMEI, "100000000000000", 15);
|
||||
memset(parameter_.softwareVersion, 0, 20);
|
||||
memcpy(parameter_.softwareVersion, "10000000000000000000", 20);
|
||||
}
|
||||
|
||||
/// @brief 设置终端手机号
|
||||
/// @param phone
|
||||
void setTerminalPhoneNumber(const char *phone_num, unsigned int phoneSize)
|
||||
{
|
||||
memset(parameter_.msg_head.phone_num, 0, 13);
|
||||
memcpy(parameter_.msg_head.phone_num, phone_num, phoneSize);
|
||||
// parameter_.msg_head.phone_num = (unsigned char *)phone_num;
|
||||
JT808_DEBUG("parameter_.msg_head.phone_num = %s\r\n", parameter_.msg_head.phone_num);
|
||||
}
|
||||
|
||||
void setTerminalId(const char *TerminalId, unsigned int lenTerminalId)
|
||||
{
|
||||
// 终端ID
|
||||
// unsigned int lenTerminalId;
|
||||
// lenTerminalId = sizeof(TerminalId);
|
||||
// lenTerminalId =(lenTerminalId>20)?20:lenTerminalId;
|
||||
|
||||
memset(parameter_.register_info.terminal_id, 0, lenTerminalId);
|
||||
memcpy(parameter_.register_info.terminal_id, TerminalId, lenTerminalId);
|
||||
JT808_DEBUG("para->register_info.terminal_id = %s\r\n", parameter_.register_info.terminal_id);
|
||||
}
|
||||
|
||||
int packagingAndSendMessage(unsigned int msg_id)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void setStatusBit()
|
||||
{
|
||||
parameter_.location_info.status.bit.positioning = 1;
|
||||
}
|
||||
|
||||
void initLocationInfo(unsigned int v_alarm_value, unsigned int v_status_value)
|
||||
{
|
||||
|
||||
JT808_DEBUG("\n\r[InitLocationInfo] OK !\r\n");
|
||||
// 报警标志
|
||||
parameter_.location_info.alarm.value = v_alarm_value;
|
||||
JT808_DEBUG("para->alarm.value = %d\r\n", parameter_.location_info.alarm.value);
|
||||
// 状态
|
||||
parameter_.location_info.status.value = v_status_value;
|
||||
JT808_DEBUG("para->status.value = %d\r\n", parameter_.location_info.status.value);
|
||||
}
|
||||
|
||||
void updateLocation(double const v_latitude, double const v_longitude, float const v_altitude,
|
||||
float const v_speed, float const v_bearing, unsigned char *v_timestamp)
|
||||
{
|
||||
#ifdef __JT808_DEBUG
|
||||
JT808_DEBUG("\n\r[updateLocationInfo] OK !\r\n");
|
||||
#endif
|
||||
// if (speed >= 10) //默认车速大于等于10公里时为正常行驶状态
|
||||
// {
|
||||
// isCarMoving.store(true);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// isCarMoving.store(false);
|
||||
// }
|
||||
parameter_.location_info.latitude = v_latitude * 1e6;
|
||||
parameter_.location_info.longitude = v_longitude * 1e6;
|
||||
parameter_.location_info.altitude = v_altitude;
|
||||
parameter_.location_info.speed = v_speed * 10;
|
||||
parameter_.location_info.bearing = v_bearing;
|
||||
memcpy(parameter_.location_info.time, v_timestamp, 13);
|
||||
#ifdef __JT808_DEBUG
|
||||
JT808_DEBUG("para->latitude = %d\r\n", parameter_.location_info.latitude);
|
||||
JT808_DEBUG("para->longitude = %d\r\n", parameter_.location_info.longitude);
|
||||
JT808_DEBUG("para->altitude = %d\r\n", parameter_.location_info.altitude);
|
||||
JT808_DEBUG("para->speed = %d\r\n", parameter_.location_info.speed);
|
||||
JT808_DEBUG("para->bearing = %d\r\n", parameter_.location_info.bearing);
|
||||
JT808_DEBUG("para->time = %s\r\n", parameter_.location_info.time);
|
||||
#endif
|
||||
}
|
||||
|
||||
int packagingMessage(unsigned int msg_id)
|
||||
{
|
||||
|
||||
// 查找当前msgID是否存在于待打包消息ID数组中
|
||||
if (0 == findMsgIDFromTerminalPackagerCMD(msg_id))
|
||||
{
|
||||
JT808_DEBUG("[findMsgIDFromTerminalPackagerCMD] no msg_id \r\n");
|
||||
return -1;
|
||||
}
|
||||
#ifdef __JT808_DEBUG
|
||||
JT808_DEBUG("[findMsgIDFromTerminalPackagerCMD] OK !\r\n");
|
||||
#endif
|
||||
parameter_.msg_head.msg_id = msg_id; // 设置消息ID.
|
||||
if (jt808FramePackage(¶meter_) < 0)
|
||||
{
|
||||
JT808_DEBUG("[jt808FramePackage]: FAILED !!!\r\n");
|
||||
return -1;
|
||||
}
|
||||
++parameter_.msg_head.msg_flow_num; // 每正确生成一条命令, 消息流水号增加1.
|
||||
return 0;
|
||||
}
|
||||
|
||||
int findMsgIDFromTerminalPackagerCMD(unsigned int msg_id)
|
||||
{
|
||||
int result = 0;
|
||||
int i;
|
||||
for (i = 0; i < PACKAGER_NUM; ++i)
|
||||
{
|
||||
if (kTerminalPackagerCMD[i] == msg_id)
|
||||
{
|
||||
result = 1;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int findParameterIDFromArray(unsigned int para_id)
|
||||
{
|
||||
int result = 0;
|
||||
int i;
|
||||
for (i = 0; i < PARA_SETTING_LIMIT; ++i)
|
||||
{
|
||||
if (kParameterSettingCMD[i] == para_id)
|
||||
{
|
||||
result = 1;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int jt808TerminalRegister(int *isRegistered)
|
||||
{
|
||||
int i = 0;
|
||||
uint16_t msgRecvLength =0;
|
||||
while (i < 3)
|
||||
{
|
||||
packagingMessage(kTerminalRegister);
|
||||
#ifdef __JT808_DEBUG
|
||||
uint8_t j = 0;
|
||||
for (j = 0; j < RealBufferSendSize; j++)
|
||||
{
|
||||
JT808_DEBUG("%02x ", BufferSend[j]);
|
||||
}
|
||||
JT808_DEBUG("\r\n");
|
||||
#endif
|
||||
// UartSend_Non_transliterated(USART2,BufferSend,RealBufferSendSize);
|
||||
|
||||
// while(1)
|
||||
// {
|
||||
|
||||
// if(USART2_RX_STA&0X8000) //接收到数据
|
||||
// {
|
||||
// USART2_RX_STA = USART2_RX_STA&0x7FFF;//获取到实际字符数量
|
||||
|
||||
// msgRecvLength = UartRecv_Non_transliterated();
|
||||
|
||||
// if(msgRecvLength!=0)
|
||||
// {
|
||||
// USART2_RX_STA=0;
|
||||
// break;
|
||||
// }
|
||||
|
||||
// USART2_RX_STA=0;
|
||||
// }
|
||||
// }
|
||||
|
||||
parsingMessage(Non_transliterated_receive, msgRecvLength); // 校验
|
||||
|
||||
if ((parameter_.parse.respone_result == kRegisterSuccess) && (parameter_.parse.msg_head.msg_id == kTerminalRegisterResponse))
|
||||
{
|
||||
*isRegistered = 1;
|
||||
JT808_DEBUG("\r\n");
|
||||
JT808_DEBUG("TerminalRegister SUCCESS!!!!!!!!!!\r\n");
|
||||
JT808_DEBUG("\r\n");
|
||||
// USART2_RX_STA=0;
|
||||
break;
|
||||
}
|
||||
|
||||
JT808_DEBUG("\r\n");
|
||||
JT808_DEBUG("TerminalRegister FAILED!!!!!!\r\n");
|
||||
JT808_DEBUG("\r\n");
|
||||
i++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int jt808TerminalAuthentication(int *isAuthenticated)
|
||||
{
|
||||
int i = 0;
|
||||
uint16_t msgRecvLength =0;
|
||||
while (i < 3)
|
||||
{
|
||||
packagingMessage(kTerminalAuthentication);
|
||||
|
||||
// #ifdef __JT808_DEBUG
|
||||
// uint8_t j=0;
|
||||
// for(j=0; j<RealBufferSendSize; j++)
|
||||
// {
|
||||
// JT808_DEBUG("%02x ",BufferSend[j]);
|
||||
// }
|
||||
// JT808_DEBUG("\r\n");
|
||||
// #endif
|
||||
// Usart_SendStr_length(USART2, BufferSend, RealBufferSendSize);
|
||||
|
||||
// UartSend_Non_transliterated(USART2,BufferSend,RealBufferSendSize);
|
||||
// while(1)
|
||||
// {
|
||||
|
||||
// if(USART2_RX_STA&0X8000) //接收到数据
|
||||
// {
|
||||
// USART2_RX_STA = USART2_RX_STA&0x7FFF;//获取到实际字符数量
|
||||
|
||||
// msgRecvLength = UartRecv_Non_transliterated();
|
||||
|
||||
// if(msgRecvLength!=0)
|
||||
// {
|
||||
// USART2_RX_STA=0;
|
||||
// break;
|
||||
// }
|
||||
|
||||
// USART2_RX_STA=0;
|
||||
// }
|
||||
// }
|
||||
|
||||
parsingMessage(Non_transliterated_receive, msgRecvLength); // 校验
|
||||
if ((parameter_.parse.respone_result == kSuccess) && (parameter_.parse.respone_msg_id == kTerminalAuthentication))
|
||||
{
|
||||
*isAuthenticated = 1;
|
||||
JT808_DEBUG("\r\n");
|
||||
JT808_DEBUG("TerminalAuthentication SUCCESS!!!!!!!!\r\n");
|
||||
JT808_DEBUG("\r\n");
|
||||
// USART2_RX_STA=0;
|
||||
break;
|
||||
}
|
||||
|
||||
// USART2_RX_STA=0;
|
||||
i++;
|
||||
JT808_DEBUG("\r\n");
|
||||
JT808_DEBUG("TerminalAuthentication FAILED RETRY!!!!!!!!\r\n");
|
||||
JT808_DEBUG("\r\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int jt808LocationReport()
|
||||
{
|
||||
packagingMessage(kLocationReport);
|
||||
// UartSend_Non_transliterated(USART2,BufferSend,RealBufferSendSize);
|
||||
// JT808_DEBUG("latitude * 1e6 = %d\r\n", parameter_.location_info.latitude);
|
||||
// JT808_DEBUG("longitude * 1e6 = %d\r\n", parameter_.location_info.longitude);
|
||||
// JT808_DEBUG("altitude = %d\r\n", parameter_.location_info.altitude);
|
||||
// JT808_DEBUG("speed * 10 = %d\r\n", parameter_.location_info.speed);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int jt808TerminalHeartBeat()
|
||||
{
|
||||
packagingMessage(kTerminalHeartBeat);
|
||||
// UartSend_Non_transliterated(USART2,BufferSend,RealBufferSendSize);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int jt808TerminalUpgradeResultReport()
|
||||
{
|
||||
packagingMessage(kTerminalUpgradeResultReport);
|
||||
// UartSend_Non_transliterated(USART2,BufferSend,RealBufferSendSize);
|
||||
JT808_DEBUG("jt808TerminalLogOut report SUCCESS!!! \r\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int jt808TerminalLogOut()
|
||||
{
|
||||
packagingMessage(kTerminalLogOut);
|
||||
// UartSend_Non_transliterated(USART2,BufferSend,RealBufferSendSize);
|
||||
JT808_DEBUG("jt808TerminalLogOut report SUCCESS!!! \r\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int jt808TerminalGeneralResponse()
|
||||
{
|
||||
packagingMessage(kTerminalGeneralResponse);
|
||||
// UartSend_Non_transliterated(USART2,BufferSend,RealBufferSendSize);
|
||||
JT808_DEBUG("jt808TerminalGeneralResponse report SUCCESS!\r\n");
|
||||
JT808_delay_ms(1000);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void File_upload()
|
||||
{
|
||||
}
|
||||
|
||||
int parsingMessage(const unsigned char *in, unsigned int in_len)
|
||||
{
|
||||
// unsigned short msg_id;
|
||||
if (jt808FrameParse(in, in_len, ¶meter_) < 0)
|
||||
{
|
||||
JT808_DEBUG("jt808FrameParse ERROR\r\n");
|
||||
return -1;
|
||||
}
|
||||
#ifdef __JT808_DEBUG
|
||||
JT808_DEBUG("ok parsing\r\n");
|
||||
#endif
|
||||
|
||||
// msg_id = parameter_.parse.msg_head.msg_id;
|
||||
|
||||
#ifdef __JT808_DEBUG
|
||||
JT808_DEBUG("%s[%d]: [parameter_.parse.msg_head.msg_id] msg_id = 0x%02x \r\n", __FUNCTION__, __LINE__, msg_id);
|
||||
switch (msg_id)
|
||||
{
|
||||
// +平台通用应答.
|
||||
case kPlatformGeneralResponse:
|
||||
{
|
||||
JT808_DEBUG("%s[%d]: [ kPlatformGeneralResponse ] parse done \r\n", __FUNCTION__, __LINE__);
|
||||
}
|
||||
break;
|
||||
|
||||
// 补传分包请求.
|
||||
case kFillPacketRequest:
|
||||
{
|
||||
JT808_DEBUG("%s[%d]: [ kFillPacketRequest ] parse done \r\n", __FUNCTION__, __LINE__);
|
||||
}
|
||||
break;
|
||||
|
||||
// 终端注册应答..
|
||||
case kTerminalRegisterResponse:
|
||||
{
|
||||
JT808_DEBUG("%s[%d]: [ kTerminalRegisterResponse ] parse done \r\n", __FUNCTION__, __LINE__);
|
||||
}
|
||||
break;
|
||||
|
||||
// 设置终端参数..
|
||||
case kSetTerminalParameters:
|
||||
{
|
||||
JT808_DEBUG("%s[%d]: [ kSetTerminalParameters ] parse done \r\n", __FUNCTION__, __LINE__);
|
||||
}
|
||||
break;
|
||||
|
||||
// 查询终端参数..
|
||||
case kGetTerminalParameters:
|
||||
{
|
||||
JT808_DEBUG("%s[%d]: [ kGetTerminalParameters ] parse done \r\n", __FUNCTION__, __LINE__);
|
||||
}
|
||||
break;
|
||||
|
||||
// 查询指定终端参数..
|
||||
case kGetSpecificTerminalParameters:
|
||||
{
|
||||
JT808_DEBUG("%s[%d]: [ kGetSpecificTerminalParameters ] parse done \r\n", __FUNCTION__, __LINE__);
|
||||
}
|
||||
break;
|
||||
|
||||
// 终端控制
|
||||
case kTerminalControl:
|
||||
{
|
||||
JT808_DEBUG("%s[%d]: [ kTerminalControl ] parse done \r\n", __FUNCTION__, __LINE__);
|
||||
}
|
||||
break;
|
||||
|
||||
// 下发终端升级包.
|
||||
case kTerminalUpgrade:
|
||||
{
|
||||
JT808_DEBUG("%s[%d]: [ kTerminalUpgrade ] parse done\r\n", __FUNCTION__, __LINE__);
|
||||
}
|
||||
break;
|
||||
|
||||
// 位置信息查询..
|
||||
case kGetLocationInformation:
|
||||
{
|
||||
JT808_DEBUG("%s[%d]: [ kGetLocationInformation ] parse done\r\n", __FUNCTION__, __LINE__);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,133 @@
|
|||
#include "gbk_utf8.h"
|
||||
#include "jt808_debug.h"
|
||||
|
||||
/*
|
||||
namespace libjt808
|
||||
{
|
||||
#ifdef _WIN32
|
||||
|
||||
std::string GbkToUtf8(const char *src_str)
|
||||
{
|
||||
int len = MultiByteToWideChar(CP_ACP, 0, src_str, -1, NULL, 0);
|
||||
wchar_t *wstr = new wchar_t[len + 1];
|
||||
memset(wstr, 0, len + 1);
|
||||
MultiByteToWideChar(CP_ACP, 0, src_str, -1, wstr, len);
|
||||
len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
|
||||
char *str = new char[len + 1];
|
||||
memset(str, 0, len + 1);
|
||||
WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, len, NULL, NULL);
|
||||
std::string strTemp = str;
|
||||
if (wstr)
|
||||
delete[] wstr;
|
||||
if (str)
|
||||
delete[] str;
|
||||
return strTemp;
|
||||
}
|
||||
|
||||
std::string Utf8ToGbk(const char *src_str)
|
||||
{
|
||||
int len = MultiByteToWideChar(CP_UTF8, 0, src_str, -1, NULL, 0);
|
||||
wchar_t *wszGBK = new wchar_t[len + 1];
|
||||
memset(wszGBK, 0, len * 2 + 2);
|
||||
MultiByteToWideChar(CP_UTF8, 0, src_str, -1, wszGBK, len);
|
||||
len = WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, NULL, 0, NULL, NULL);
|
||||
char *szGBK = new char[len + 1];
|
||||
memset(szGBK, 0, len + 1);
|
||||
WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, szGBK, len, NULL, NULL);
|
||||
std::string strTemp(szGBK);
|
||||
if (wszGBK)
|
||||
delete[] wszGBK;
|
||||
if (szGBK)
|
||||
delete[] szGBK;
|
||||
return strTemp;
|
||||
}
|
||||
#else
|
||||
|
||||
int GbkToUtf8(char *str_str, size_t src_len, char *dst_str, size_t dst_len)
|
||||
{
|
||||
iconv_t cd;
|
||||
char **pin = &str_str;
|
||||
char **pout = &dst_str;
|
||||
|
||||
cd = iconv_open("utf-8", "gbk");
|
||||
if (cd == (iconv_t)-1)
|
||||
{
|
||||
JT808_DEBUG("GbkToUtf8 iconv_open error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(dst_str, 0, dst_len);
|
||||
if (iconv(cd, pin, &src_len, pout, &dst_len) != 0)
|
||||
{
|
||||
JT808_DEBUG("GbkToUtf8 iconv error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
iconv_close(cd);
|
||||
*pout = nullptr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Utf8ToGbk(char *src_str, size_t src_len, char *dst_str, size_t dst_len)
|
||||
{
|
||||
iconv_t cd;
|
||||
char **pin = &src_str;
|
||||
char **pout = &dst_str;
|
||||
|
||||
cd = iconv_open("gbk", "utf-8");
|
||||
if (cd == 0)
|
||||
{
|
||||
JT808_DEBUG("Utf8ToGbk iconv_open error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(dst_str, 0, dst_len);
|
||||
if (iconv(cd, pin, &src_len, pout, &dst_len) != 0)
|
||||
{
|
||||
JT808_DEBUG("Utf8ToGbk iconv error\n");
|
||||
return -1;
|
||||
}
|
||||
iconv_close(cd);
|
||||
*pout = nullptr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
std::string gbk_to_utf8_str(const std::vector<uint8_t> &gbk_src)
|
||||
{
|
||||
|
||||
//?GBK??????utf-8??
|
||||
size_t lenSRC = gbk_src.size();
|
||||
size_t lenDst = lenSRC * 2;
|
||||
char *dst_str = new char[lenDst];
|
||||
// Utf8ToGbk((char *)(txt8300_2013.data()), len, dst_str, 1024);
|
||||
if (GbkToUtf8((char *)(gbk_src.data()), lenSRC, dst_str, lenDst) != 0)
|
||||
return "";
|
||||
std::string str_GbkToUtf8(dst_str);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
delete[] dst_str;
|
||||
|
||||
return str_GbkToUtf8;
|
||||
}
|
||||
|
||||
std::string gbk_to_utf8_str(const std::string &str_gbk_src)
|
||||
{
|
||||
|
||||
//?GBK??????utf-8??
|
||||
size_t lenSRC = str_gbk_src.size();
|
||||
size_t lenDst = lenSRC * 2;
|
||||
char *dst_str = new char[lenDst];
|
||||
// Utf8ToGbk((char *)(txt8300_2013.data()), len, dst_str, 1024);
|
||||
if (GbkToUtf8((char *)(str_gbk_src.data()), lenSRC, dst_str, lenDst) != 0)
|
||||
return "";
|
||||
std::string str_GbkToUtf8(dst_str);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
delete[] dst_str;
|
||||
|
||||
return str_GbkToUtf8;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
|
@ -0,0 +1,519 @@
|
|||
#include "jt808_packager.h"
|
||||
#include "util.h"
|
||||
#include "terminal_parameter.h"
|
||||
#include "client_manager.h"
|
||||
#include "jt808_debug.h"
|
||||
|
||||
// 所有终端数据打包命令.
|
||||
unsigned short kTerminalPackagerCMD[PACKAGER_NUM] = {
|
||||
kTerminalGeneralResponse, // 终端通用应答.
|
||||
kTerminalHeartBeat, // 终端心跳.
|
||||
kTerminalRegister, // 终端注册.
|
||||
kTerminalLogOut, // 终端注销.
|
||||
kTerminalAuthentication, // 终端鉴权.
|
||||
kGetTerminalParametersResponse, // 查询终端参数应答.
|
||||
kTerminalUpgradeResultReport, // 终端升级结果通知.
|
||||
kLocationReport, // 位置信息汇报.
|
||||
kGetLocationInformationResponse // 位置信息查询应答.
|
||||
};
|
||||
|
||||
/// @brief 发送缓存
|
||||
unsigned char BufferSend[BUFFER_SIZE_SEND] = {0};
|
||||
|
||||
/// @brief 实际打包发送数据的长度
|
||||
unsigned int RealBufferSendSize = 0;
|
||||
// int RealBufferSendSize = 0;
|
||||
|
||||
void clearBufferSend()
|
||||
{
|
||||
memset(BufferSend, 0, BUFFER_SIZE_SEND);
|
||||
RealBufferSendSize = 0;
|
||||
}
|
||||
|
||||
void bufferSendPushByte(unsigned char byte)
|
||||
{
|
||||
BufferSend[RealBufferSendSize] = byte;
|
||||
++RealBufferSendSize;
|
||||
}
|
||||
|
||||
int bufferSendPushBytes(const unsigned char *bytes, unsigned int size)
|
||||
{
|
||||
unsigned int i;
|
||||
if (bytes == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < size; ++i)
|
||||
{
|
||||
bufferSendPushByte(*(bytes + i));
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int bufferSendChangeByte(unsigned char byte, unsigned int index)
|
||||
{
|
||||
if (index > RealBufferSendSize)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (index == RealBufferSendSize)
|
||||
{
|
||||
BufferSend[index] = byte;
|
||||
++RealBufferSendSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
BufferSend[index] = byte;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int copyU16ToU8ArrayToBufferSend(const unsigned char *u8array)
|
||||
{
|
||||
return bufferSendPushBytes(u8array, 2);
|
||||
}
|
||||
|
||||
int copyU32ToU8ArrayToBufferSend(const unsigned char *u8array)
|
||||
{
|
||||
return bufferSendPushBytes(u8array, 4);
|
||||
}
|
||||
|
||||
// 终端通用应答.
|
||||
int handle_kTerminalGeneralResponse(struct ProtocolParameter *para)
|
||||
{
|
||||
|
||||
int msg_len = 5;
|
||||
union U16ToU8Array u16converter;
|
||||
JT808_DEBUG("[%s] msg_id = 0x%04x \r\n", __FUNCTION__, kTerminalGeneralResponse);
|
||||
// 应答消息流水号.
|
||||
u16converter.u16val = EndianSwap16(para->parse.msg_head.msg_flow_num);
|
||||
copyU16ToU8ArrayToBufferSend(u16converter.u8array);
|
||||
JT808_DEBUG(" flow_num == 0x%04x \r\n", para->parse.msg_head.msg_flow_num);
|
||||
|
||||
// 应答消息ID.
|
||||
u16converter.u16val = EndianSwap16(para->parse.msg_head.msg_id);
|
||||
copyU16ToU8ArrayToBufferSend(u16converter.u8array);
|
||||
JT808_DEBUG(" msg_id == 0x%04x \r\n", para->parse.msg_head.msg_id);
|
||||
|
||||
// 应答结果.
|
||||
bufferSendPushByte(para->respone_result);
|
||||
JT808_DEBUG(" respone_result == 0x%02x \r\n", para->parse.respone_result);
|
||||
|
||||
return msg_len;
|
||||
}
|
||||
|
||||
// 终端心跳.
|
||||
int handle_kTerminalHeartBeat(struct ProtocolParameter *para)
|
||||
{
|
||||
#ifdef __JT808_DEBUG
|
||||
JT808_DEBUG("[%s] <no message body> msg_id = 0x%04x \r\n ", __FUNCTION__, kTerminalHeartBeat);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 终端注册.
|
||||
int handle_kTerminalRegister(struct ProtocolParameter *para)
|
||||
{
|
||||
int msg_len;
|
||||
union U16ToU8Array u16converter;
|
||||
|
||||
JT808_DEBUG("[%s] msg_id = 0x%04x \r\n", __FUNCTION__, kTerminalRegister);
|
||||
|
||||
initRegisterInfo(para); // 初始化注册参数
|
||||
|
||||
msg_len = 37;
|
||||
|
||||
// 省域ID.
|
||||
u16converter.u16val = EndianSwap16(para->register_info.province_id);
|
||||
copyU16ToU8ArrayToBufferSend(u16converter.u8array);
|
||||
|
||||
// 市县域ID.
|
||||
u16converter.u16val = EndianSwap16(para->register_info.city_id);
|
||||
copyU16ToU8ArrayToBufferSend(u16converter.u8array);
|
||||
|
||||
// 制造商ID.
|
||||
bufferSendPushBytes(para->register_info.manufacturer_id, sizeof(para->register_info.manufacturer_id));
|
||||
|
||||
// 终端型号.
|
||||
bufferSendPushBytes(para->register_info.terminal_model, sizeof(para->register_info.terminal_model));
|
||||
|
||||
// 终端ID.
|
||||
bufferSendPushBytes(para->register_info.terminal_id, sizeof(para->register_info.terminal_id));
|
||||
|
||||
// 车牌颜色.
|
||||
bufferSendPushByte(para->register_info.car_plate_color);
|
||||
|
||||
// 车牌标识,即车牌号
|
||||
if (para->register_info.car_plate_color != 0x00)
|
||||
{
|
||||
unsigned int len_car_num = strlen(para->register_info.car_plate_num);
|
||||
bufferSendPushBytes(para->register_info.car_plate_num, len_car_num);
|
||||
msg_len += len_car_num;
|
||||
}
|
||||
|
||||
return msg_len;
|
||||
}
|
||||
|
||||
// 终端注销.
|
||||
int handle_kTerminalLogOut(struct ProtocolParameter *para)
|
||||
{
|
||||
JT808_DEBUG("[%s] <no message body> msg_id = 0x%04x\r\n", __FUNCTION__, kTerminalLogOut);
|
||||
|
||||
// 空消息体.
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 终端鉴权.
|
||||
int handle_kTerminalAuthentication(struct ProtocolParameter *para)
|
||||
{
|
||||
int msg_len = strlen(para->parse.authentication_code);
|
||||
JT808_DEBUG("[%s] msg_id = 0x%04x \r\n", __FUNCTION__, kTerminalAuthentication);
|
||||
// 鉴权码.
|
||||
bufferSendPushBytes(para->parse.authentication_code, msg_len);
|
||||
|
||||
return msg_len;
|
||||
}
|
||||
|
||||
// 查询终端参数应答.
|
||||
int handle_kGetTerminalParametersResponse(struct ProtocolParameter *para)
|
||||
{
|
||||
JT808_DEBUG("[%s] msg_id = 0x%04x\n", __FUNCTION__, kGetTerminalParametersResponse);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 终端升级结果通知.
|
||||
int handle_kTerminalUpgradeResultReport(struct ProtocolParameter *para)
|
||||
{
|
||||
|
||||
int msg_len = 2;
|
||||
int result = 0;
|
||||
JT808_DEBUG("[%s] msg_id = 0x%04x\n", __FUNCTION__, kTerminalUpgradeResultReport);
|
||||
bufferSendPushByte(kTerminal); // 升级类型 终端
|
||||
msg_len += 1;
|
||||
|
||||
// 升级结果 0成功 1失败 2取消
|
||||
if (result == 0)
|
||||
{
|
||||
bufferSendPushByte(kTerminalUpgradeSuccess);
|
||||
}
|
||||
else if (result == 1)
|
||||
{
|
||||
bufferSendPushByte(kTerminalUpgradeFailed);
|
||||
}
|
||||
else
|
||||
{
|
||||
bufferSendPushByte(kTerminalUpgradeCancel);
|
||||
}
|
||||
msg_len += 1;
|
||||
|
||||
return msg_len;
|
||||
}
|
||||
|
||||
// 位置信息汇报.
|
||||
int handle_kLocationReport(struct ProtocolParameter *para)
|
||||
{
|
||||
unsigned char time_bcd[6] = {0};
|
||||
int msg_len = 28;
|
||||
union U32ToU8Array u32converter;
|
||||
union U16ToU8Array u16converter;
|
||||
|
||||
#ifdef JT808_DEBUG
|
||||
JT808_DEBUG("[%s] msg_id = 0x%04x\r\n", __FUNCTION__, kLocationReport);
|
||||
#endif
|
||||
|
||||
// 报警标志.
|
||||
u32converter.u32val = EndianSwap32(para->location_info.alarm.value);
|
||||
copyU32ToU8ArrayToBufferSend(u32converter.u8array);
|
||||
// 状态.
|
||||
u32converter.u32val = EndianSwap32(para->location_info.status.value);
|
||||
copyU32ToU8ArrayToBufferSend(u32converter.u8array);
|
||||
// 纬度.
|
||||
u32converter.u32val = EndianSwap32(para->location_info.latitude);
|
||||
copyU32ToU8ArrayToBufferSend(u32converter.u8array);
|
||||
// 经度.
|
||||
u32converter.u32val = EndianSwap32(para->location_info.longitude);
|
||||
copyU32ToU8ArrayToBufferSend(u32converter.u8array);
|
||||
// union U16ToU8Array u16converter;
|
||||
// 海拔高程.
|
||||
u16converter.u16val = EndianSwap16(para->location_info.altitude);
|
||||
copyU16ToU8ArrayToBufferSend(u16converter.u8array);
|
||||
// 速度.
|
||||
u16converter.u16val = EndianSwap16(para->location_info.speed);
|
||||
copyU16ToU8ArrayToBufferSend(u16converter.u8array);
|
||||
// 方向.
|
||||
u16converter.u16val = EndianSwap16(para->location_info.bearing);
|
||||
copyU16ToU8ArrayToBufferSend(u16converter.u8array);
|
||||
|
||||
jt808StringToBcdCompress(para->location_info.time, time_bcd, strlen(para->location_info.time));
|
||||
bufferSendPushBytes(time_bcd, 6);
|
||||
|
||||
bufferSendPushByte(kNetworkQuantity); // 附加信息ID 0x30
|
||||
bufferSendPushByte(1); // 附加信息长度
|
||||
bufferSendPushByte(0x53); // 附加信息,无线信号强度
|
||||
msg_len += 3;
|
||||
|
||||
bufferSendPushByte(kGnssSatellites); // 附加信息ID 0x31
|
||||
bufferSendPushByte(1); // 附加信息长度
|
||||
bufferSendPushByte(11); // 附加信息,卫星数量
|
||||
msg_len += 3;
|
||||
|
||||
bufferSendPushByte(kCustomInformationLength); // 附加信息ID 0xe0
|
||||
bufferSendPushByte(1); // 附加信息长度
|
||||
bufferSendPushByte(3); // 附加信息,后续数据长度
|
||||
msg_len += 3;
|
||||
|
||||
bufferSendPushByte(kPositioningStatus); // 附加信息ID 0xee
|
||||
bufferSendPushByte(1); // 附加信息长度
|
||||
bufferSendPushByte(2); // 附加信息,定位解状态
|
||||
msg_len += 3;
|
||||
|
||||
return msg_len;
|
||||
}
|
||||
|
||||
// 位置信息查询应答.
|
||||
int handle_kGetLocationInformationResponse(struct ProtocolParameter *para)
|
||||
{
|
||||
JT808_DEBUG("[%s] msg_id = 0x%04x\n", __FUNCTION__, kGetLocationInformationResponse);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int jt808FrameBodyPackage(struct ProtocolParameter *para)
|
||||
{
|
||||
unsigned short msg_id = para->msg_head.msg_id;
|
||||
int result = -1;
|
||||
#ifdef __JT808_DEBUG
|
||||
JT808_DEBUG("[jt808FrameBodyPackage] msg_id: 0x%04x\r\n", para->msg_head.msg_id);
|
||||
#endif
|
||||
|
||||
switch (msg_id)
|
||||
{
|
||||
// 终端通用应答.
|
||||
case kTerminalGeneralResponse:
|
||||
{
|
||||
result = handle_kTerminalGeneralResponse(para);
|
||||
}
|
||||
break;
|
||||
|
||||
// 终端心跳.
|
||||
case kTerminalHeartBeat:
|
||||
{
|
||||
result = handle_kTerminalHeartBeat(para);
|
||||
}
|
||||
break;
|
||||
|
||||
// 终端注册.
|
||||
case kTerminalRegister:
|
||||
{
|
||||
result = handle_kTerminalRegister(para);
|
||||
}
|
||||
break;
|
||||
|
||||
// 终端注销.
|
||||
case kTerminalLogOut:
|
||||
{
|
||||
result = handle_kTerminalLogOut(para);
|
||||
}
|
||||
break;
|
||||
|
||||
// 终端鉴权.
|
||||
case kTerminalAuthentication:
|
||||
{
|
||||
result = handle_kTerminalAuthentication(para);
|
||||
}
|
||||
break;
|
||||
|
||||
// 查询终端参数应答.
|
||||
case kGetTerminalParametersResponse:
|
||||
{
|
||||
result = handle_kGetTerminalParametersResponse(para);
|
||||
}
|
||||
break;
|
||||
|
||||
// 终端升级结果通知.
|
||||
case kTerminalUpgradeResultReport:
|
||||
{
|
||||
result = handle_kTerminalUpgradeResultReport(para);
|
||||
}
|
||||
break;
|
||||
|
||||
// 位置信息汇报
|
||||
case kLocationReport:
|
||||
{
|
||||
result = handle_kLocationReport(para);
|
||||
}
|
||||
break;
|
||||
|
||||
// 位置信息查询应答.
|
||||
case kGetLocationInformationResponse:
|
||||
{
|
||||
result = handle_kGetLocationInformationResponse(para);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// 消息内容长度修正.
|
||||
int jt808MsgBodyLengthFix(struct MsgHead *msg_head, unsigned int msgBody_len)
|
||||
{
|
||||
union U16ToU8Array u16converter;
|
||||
union MsgBodyAttribute msgbody_attr;
|
||||
if (RealBufferSendSize < 12)
|
||||
{
|
||||
JT808_DEBUG("%d \r\n", RealBufferSendSize);
|
||||
return -1;
|
||||
}
|
||||
|
||||
msgbody_attr = msg_head->msgbody_attr;
|
||||
msgbody_attr.bit.msglen = msgBody_len;
|
||||
// union U16ToU8Array u16converter;
|
||||
u16converter.u16val = EndianSwap16(msgbody_attr.u16val);
|
||||
BufferSend[3] = u16converter.u8array[0];
|
||||
BufferSend[4] = u16converter.u8array[1];
|
||||
|
||||
#ifdef __JT808_DEBUG
|
||||
JT808_DEBUG("[%s] OK !\r\n", __FUNCTION__);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
// JT808协议转义.
|
||||
int jt808MsgEscape()
|
||||
{
|
||||
unsigned int outBufferSize;
|
||||
unsigned char *outBuffer;
|
||||
BufferSend[0] = 0x00;
|
||||
BufferSend[RealBufferSendSize - 1] = 0x00;
|
||||
|
||||
outBufferSize = RealBufferSendSize * 2;
|
||||
outBuffer = (unsigned char *)malloc(outBufferSize);
|
||||
|
||||
if (Escape_C(BufferSend, RealBufferSendSize, outBuffer, &outBufferSize) < 0)
|
||||
{
|
||||
JT808_DEBUG("[%s] FAILED \r\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*(outBuffer + 0) = PROTOCOL_SIGN;
|
||||
*(outBuffer + (outBufferSize - 1)) = PROTOCOL_SIGN;
|
||||
|
||||
memcpy(BufferSend, outBuffer, outBufferSize);
|
||||
RealBufferSendSize = outBufferSize;
|
||||
|
||||
if (outBuffer != NULL)
|
||||
{
|
||||
free(outBuffer);
|
||||
outBuffer = NULL;
|
||||
}
|
||||
#ifdef __JT808_DEBUG
|
||||
JT808_DEBUG("[%s] OK !\r\n", __FUNCTION__);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
void jt808SetFrameFlagHeader()
|
||||
{
|
||||
// BufferSend[0] = PROTOCOL_SIGN; //设置头标识
|
||||
// ++RealBufferSendSize; //发送buf长度自加
|
||||
// bufferSendPushByte(PROTOCOL_SIGN);
|
||||
bufferSendChangeByte(PROTOCOL_SIGN, 0);
|
||||
}
|
||||
|
||||
int jt808FrameHeadPackage(struct MsgHead *msg_head)
|
||||
{
|
||||
union U16ToU8Array u16converter;
|
||||
unsigned char phone_num_bcd[6] = {0};
|
||||
// 1消息ID.
|
||||
u16converter.u16val = EndianSwap16(msg_head->msg_id);
|
||||
copyU16ToU8ArrayToBufferSend(u16converter.u8array);
|
||||
|
||||
// 2消息体属性.
|
||||
u16converter.u16val = EndianSwap16(msg_head->msgbody_attr.u16val);
|
||||
copyU16ToU8ArrayToBufferSend(u16converter.u8array);
|
||||
|
||||
// 3终端手机号(BCD码).
|
||||
// msg_head->phone_num = "17737702736"; //测试用2022.10.25
|
||||
// unsigned char phone_num_bcd[6] = {0};
|
||||
jt808StringToBcdCompress(msg_head->phone_num, phone_num_bcd, strlen(msg_head->phone_num));
|
||||
bufferSendPushBytes(phone_num_bcd, 6);
|
||||
|
||||
// 4消息流水号.
|
||||
u16converter.u16val = EndianSwap16(msg_head->msg_flow_num);
|
||||
bufferSendPushBytes(u16converter.u8array, 2);
|
||||
|
||||
// 5封包项.
|
||||
if ((msg_head->msgbody_attr.bit.packet == 1) &&
|
||||
(msg_head->total_packet > 1))
|
||||
{
|
||||
u16converter.u16val = EndianSwap16(msg_head->total_packet);
|
||||
|
||||
bufferSendPushBytes(u16converter.u8array, 2);
|
||||
|
||||
u16converter.u16val = EndianSwap16(msg_head->packet_seq);
|
||||
bufferSendPushBytes(u16converter.u8array, 2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int jt808FramePackage(struct ProtocolParameter *para)
|
||||
{
|
||||
int ret;
|
||||
unsigned char valueCheck;
|
||||
// 清空发送缓存,避免缓存中会有前一次的数据
|
||||
clearBufferSend();
|
||||
// 0、设置头标志位
|
||||
jt808SetFrameFlagHeader();
|
||||
|
||||
#ifdef __JT808_DEBUG
|
||||
JT808_DEBUG("[jt808SetFrameFlagHeader] OK !\r\n");
|
||||
#endif
|
||||
|
||||
// 1、生成消息头
|
||||
if (jt808FrameHeadPackage(&(para->msg_head)) < 0)
|
||||
{
|
||||
JT808_DEBUG("jt808FrameHeadPackage FAILED \r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef __JT808_DEBUG
|
||||
JT808_DEBUG("[jt808FrameHeadPackage] OK !\r\n");
|
||||
#endif
|
||||
|
||||
// 2、封装消息内容.
|
||||
ret = jt808FrameBodyPackage(para);
|
||||
|
||||
if (ret >= 0)
|
||||
{
|
||||
// 3、修正消息长度.
|
||||
if (jt808MsgBodyLengthFix(&(para->msg_head), ret) < 0)
|
||||
{
|
||||
JT808_DEBUG("jt808FrameHeadPackage FAILED \r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 4、获取校验码,并将其写入发送缓存.
|
||||
// valueCheck = BccCheckSum(BufferSend, RealBufferSendSize);
|
||||
valueCheck = BccCheckSum((BufferSend + 1), (RealBufferSendSize - 1)); // 参考接收解析
|
||||
bufferSendPushByte(valueCheck);
|
||||
|
||||
// 5、写入发送缓存结束标识位.
|
||||
bufferSendPushByte(PROTOCOL_SIGN);
|
||||
#ifdef __JT808_DEBUG
|
||||
JT808_DEBUG("[Write buffersend end PROTOCOL_SIGN] OK !\r\n");
|
||||
#endif
|
||||
// 6、处理转义.
|
||||
if (jt808MsgEscape() < 0)
|
||||
{
|
||||
JT808_DEBUG("[jt808MsgEscape] FAILED");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -0,0 +1,453 @@
|
|||
#include "jt808_parser.h"
|
||||
#include "set_terminal_parameter.h"
|
||||
#include "client_manager.h"
|
||||
#include "util.h"
|
||||
#include "bcd.h"
|
||||
#include "jt808_debug.h"
|
||||
|
||||
// 所有终端解析命令.
|
||||
unsigned short kTerminalParserCMD[PARSER_NUM] = {
|
||||
kPlatformGeneralResponse, // 平台通用应答
|
||||
kFillPacketRequest, // 补传分包请求.
|
||||
kTerminalRegisterResponse, // 终端注册应答.
|
||||
kSetTerminalParameters, // 设置终端参数.
|
||||
kGetTerminalParameters, // 查询终端参数.
|
||||
kGetSpecificTerminalParameters, // 查询指定终端参数.
|
||||
kTerminalControl, // 终端控制
|
||||
kTerminalUpgrade, // 下发终端升级包.
|
||||
kGetLocationInformation, // 位置信息查询.
|
||||
};
|
||||
|
||||
/// @brief 接收缓存
|
||||
unsigned char BufferReceive[BUFFER_SIZE_RECEIVE] = {0};
|
||||
|
||||
/// @brief 实际接收的数据长度
|
||||
unsigned int RealBufferReceiveSize = 0;
|
||||
|
||||
// 解析消息头.
|
||||
int jt808FrameHeadParse(const unsigned char *in, unsigned int in_len, struct MsgHead *msg_head)
|
||||
{
|
||||
if (msg_head == NULL || in_len < 15)
|
||||
{
|
||||
JT808_DEBUG("msg_head == NULL || in_len < 15");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 消息ID.
|
||||
msg_head->msg_id = (in[1] << 8) + in[2];
|
||||
|
||||
// 消息体属性.
|
||||
msg_head->msgbody_attr.u16val = (in[3] << 8) + in[4];
|
||||
|
||||
// 终端手机号.
|
||||
|
||||
memset(msg_head->phone_num, 0, 12);
|
||||
|
||||
if (jt808BcdToStringCompress((&(in[5])), msg_head->phone_num, 6) == NULL)
|
||||
{
|
||||
JT808_DEBUG("jt808BcdToStringCompress error \r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 消息流水号.
|
||||
msg_head->msg_flow_num = (in[11] << 8) + in[12];
|
||||
|
||||
// 出现封包.
|
||||
if ((msg_head->msgbody_attr.bit.packet == 1) &&
|
||||
((in_len - 15 - msg_head->msgbody_attr.bit.msglen) == 4))
|
||||
{
|
||||
msg_head->total_packet = (in[13] << 8) + in[14];
|
||||
msg_head->packet_seq = (in[15] << 8) + in[16];
|
||||
}
|
||||
else
|
||||
{
|
||||
msg_head->total_packet = 0;
|
||||
msg_head->packet_seq = 0;
|
||||
}
|
||||
|
||||
#ifdef __JT808_DEBUG
|
||||
JT808_DEBUG("[jt808FrameHeadParse] msg_head->msg_id = 0x%02x\r\n", msg_head->msg_id);
|
||||
JT808_DEBUG("[jt808FrameHeadParse] msg_head->msgbody_attr.u16val = 0x%02x\r\n", msg_head->msgbody_attr.u16val);
|
||||
JT808_DEBUG("[jt808FrameHeadParse] msg_head->phone_num = %s !!!\r\n", msg_head->phone_num);
|
||||
JT808_DEBUG("[jt808FrameHeadParse] msg_head->msg_flow_num = 0x%02x !!!\r\n", msg_head->msg_flow_num);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 平台通用应答
|
||||
int handle_kPlatformGeneralResponse(struct ProtocolParameter *para)
|
||||
{
|
||||
uint16_t pos;
|
||||
#ifdef __JT808_DEBUG
|
||||
JT808_DEBUG("[%s] msg_id = 0x%04x\r\n", __FUNCTION__, kPlatformGeneralResponse);
|
||||
#endif
|
||||
if (para == NULL)
|
||||
return -1;
|
||||
pos = MSGBODY_NOPACKET_POS;
|
||||
if (para->msg_head.msgbody_attr.bit.packet == 1)
|
||||
pos = MSGBODY_PACKET_POS;
|
||||
// 应答流水号.
|
||||
para->parse.respone_flow_num = (BufferReceive[pos] << 8) + BufferReceive[pos + 1];
|
||||
|
||||
// 应答消息ID.
|
||||
para->parse.respone_msg_id = (BufferReceive[pos + 2] << 8) + BufferReceive[pos + 3];
|
||||
|
||||
// 应答结果.
|
||||
para->parse.respone_result = BufferReceive[pos + 4];
|
||||
|
||||
#ifdef __JT808_DEBUG
|
||||
JT808_DEBUG("[%s] respone_flow_num = 0x%04x\r\n", __FUNCTION__, para->parse.respone_flow_num);
|
||||
JT808_DEBUG("[%s] respone_msg_id = 0x%04x\r\n", __FUNCTION__, para->parse.respone_msg_id);
|
||||
JT808_DEBUG("[%s] respone_result = 0x%04x\r\n", __FUNCTION__, para->parse.respone_result);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 补传分包请求.
|
||||
int handle_kFillPacketRequest(struct ProtocolParameter *para)
|
||||
{
|
||||
uint16_t pos;
|
||||
// unsigned short cnt;
|
||||
// unsigned char i;
|
||||
// unsigned short id;
|
||||
|
||||
JT808_DEBUG("[%s] msg_id = 0x%04x\r\n", __FUNCTION__, kFillPacketRequest);
|
||||
|
||||
if (para == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
pos = MSGBODY_NOPACKET_POS;
|
||||
if (para->parse.msg_head.msgbody_attr.bit.packet == 1)
|
||||
{
|
||||
pos = MSGBODY_PACKET_POS;
|
||||
}
|
||||
|
||||
para->fill_packet.first_packet_msg_flow_num = (BufferReceive[pos] << 8) + BufferReceive[pos + 1];
|
||||
pos += 2;
|
||||
|
||||
// cnt = BufferReceive[pos+2];
|
||||
++pos;
|
||||
|
||||
// if(para->msg_head.msgbody_attr.bit.msglen -3 != (cnt * 2))
|
||||
// {
|
||||
// return -1;
|
||||
// }
|
||||
//
|
||||
//// memset(para->fill_packet.packet_id, 0, sizeof(para->fill_packet.packet_id));
|
||||
// for(i=0;i<cnt;++i)
|
||||
// {
|
||||
// id = BufferReceive[pos + i * 2] + BufferReceive[pos + 1 + i * 2];
|
||||
// memncpy(para->fill_packet.packet_id[pos], id, 2);
|
||||
// pos += 2;
|
||||
// }
|
||||
|
||||
File_upload();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 终端注册应答..
|
||||
int handle_kTerminalRegisterResponse(struct ProtocolParameter *para)
|
||||
{
|
||||
unsigned short pos;
|
||||
unsigned short len_code;
|
||||
|
||||
JT808_DEBUG("[%s] msg_id = 0x%04x\r\n", __FUNCTION__, kTerminalRegisterResponse);
|
||||
|
||||
if (para == NULL)
|
||||
return -1;
|
||||
pos = MSGBODY_NOPACKET_POS;
|
||||
if (para->parse.msg_head.msgbody_attr.bit.packet == 1)
|
||||
pos = MSGBODY_PACKET_POS;
|
||||
// 应答流水号.
|
||||
para->parse.respone_flow_num = (BufferReceive[pos] << 8) + BufferReceive[pos + 1];
|
||||
JT808_DEBUG("[%s] respone_flow_num = 0x%04x\r\n", __FUNCTION__, para->parse.respone_flow_num);
|
||||
// 应答结果.
|
||||
para->parse.respone_result = BufferReceive[pos + 2];
|
||||
JT808_DEBUG("[%s] respone_result = 0x%02x\r\n", __FUNCTION__, para->parse.respone_result);
|
||||
// 应答结果为0(成功)时解析出附加的鉴权码.
|
||||
if (para->parse.respone_result == kRegisterSuccess)
|
||||
{
|
||||
len_code = para->parse.msg_head.msgbody_attr.bit.msglen - 3;
|
||||
para->parse.authentication_code = (unsigned char *)malloc((len_code + 1) * sizeof(unsigned char));
|
||||
memcpy(para->parse.authentication_code, &(BufferReceive[pos + 3]), len_code);
|
||||
|
||||
JT808_DEBUG("[%s] authentication_code = %s\r\n", __FUNCTION__, para->parse.authentication_code);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 设置终端参数..
|
||||
int handle_kSetTerminalParameters(struct ProtocolParameter *para)
|
||||
{
|
||||
uint16_t pos;
|
||||
unsigned short msg_len;
|
||||
unsigned int p_id;
|
||||
unsigned char cnt;
|
||||
union U32ToU8Array u32converter;
|
||||
int isFind = 0, i;
|
||||
unsigned len;
|
||||
|
||||
jt808TerminalGeneralResponse();
|
||||
|
||||
JT808_DEBUG("[%s] msg_id = 0x%04x\r\n", __FUNCTION__, kSetTerminalParameters);
|
||||
if (para == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
pos = MSGBODY_NOPACKET_POS;
|
||||
if (para->parse.msg_head.msgbody_attr.bit.packet == 1)
|
||||
{
|
||||
pos = MSGBODY_PACKET_POS;
|
||||
}
|
||||
msg_len = para->parse.msg_head.msgbody_attr.bit.msglen;
|
||||
if (msg_len < 1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
// 解析设置的参数总个数.
|
||||
cnt = BufferReceive[pos];
|
||||
pos++;
|
||||
|
||||
if (cnt <= 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < cnt; ++i)
|
||||
{
|
||||
// 查找参数项的参数ID
|
||||
memcpy(u32converter.u8array, (BufferReceive + pos), 4);
|
||||
p_id = EndianSwap32(u32converter.u32val);
|
||||
pos += 4;
|
||||
// 从已支持的参数项数组中查找是否有当前参数ID
|
||||
isFind = findParameterIDFromArray(p_id);
|
||||
len = BufferReceive[pos];
|
||||
pos++;
|
||||
if (isFind == 1)
|
||||
{
|
||||
jt808ParameterSettingParse(p_id, (BufferReceive + pos), len, para);
|
||||
}
|
||||
pos += len;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 查询终端参数..
|
||||
int handle_kGetTerminalParameters(struct ProtocolParameter *para)
|
||||
{
|
||||
JT808_DEBUG("[%s] msg_id = 0x%04x\r\n", __FUNCTION__, kGetTerminalParameters);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 查询指定终端参数..
|
||||
int handle_kGetSpecificTerminalParameters(struct ProtocolParameter *para)
|
||||
{
|
||||
JT808_DEBUG("[%s] msg_id = 0x%04x\r\n", __FUNCTION__, kGetSpecificTerminalParameters);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 终端控制
|
||||
int handle_kTerminalControl(struct ProtocolParameter *para)
|
||||
{
|
||||
JT808_DEBUG("[%s] msg_id = 0x%04x\r\n", __FUNCTION__, kTerminalControl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 下发终端升级包.
|
||||
int handle_kTerminalUpgrade(struct ProtocolParameter *para)
|
||||
{
|
||||
uint16_t pos;
|
||||
// uint16_t beg = pos;
|
||||
int i;
|
||||
JT808_DEBUG("[%s] msg_id = 0x%04x\r\n", __FUNCTION__, kTerminalUpgrade);
|
||||
jt808TerminalGeneralResponse();
|
||||
if (para == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
pos = MSGBODY_NOPACKET_POS;
|
||||
if (para->parse.msg_head.msgbody_attr.bit.packet == 1)
|
||||
{
|
||||
pos = MSGBODY_PACKET_POS;
|
||||
}
|
||||
|
||||
para->upgrade_info.upgrade_type = BufferReceive[pos++];
|
||||
|
||||
memset(para->upgrade_info.manufacturer_id, 0, sizeof(para->upgrade_info.manufacturer_id));
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
}
|
||||
|
||||
jt808TerminalUpgradeResultReport();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 位置信息查询..
|
||||
int handle_kGetLocationInformation(struct ProtocolParameter *para)
|
||||
{
|
||||
JT808_DEBUG("[%s] msg_id = 0x%04x\r\n", __FUNCTION__, kGetLocationInformation);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int jt808FrameBodyParse(struct ProtocolParameter *para)
|
||||
{
|
||||
unsigned short msg_id = para->parse.msg_head.msg_id;
|
||||
int result = -1;
|
||||
|
||||
#ifdef __JT808_DEBUG
|
||||
JT808_DEBUG("[%s] current msg_id: 0x%04x\r\n", __FUNCTION__, msg_id);
|
||||
#endif
|
||||
|
||||
switch (msg_id)
|
||||
{
|
||||
// +平台通用应答.
|
||||
case kPlatformGeneralResponse:
|
||||
{
|
||||
result = handle_kPlatformGeneralResponse(para);
|
||||
}
|
||||
break;
|
||||
|
||||
// 补传分包请求.
|
||||
case kFillPacketRequest:
|
||||
{
|
||||
result = handle_kFillPacketRequest(para);
|
||||
}
|
||||
break;
|
||||
|
||||
// 终端注册应答..
|
||||
case kTerminalRegisterResponse:
|
||||
{
|
||||
result = handle_kTerminalRegisterResponse(para);
|
||||
}
|
||||
break;
|
||||
|
||||
// 设置终端参数..
|
||||
case kSetTerminalParameters:
|
||||
{
|
||||
result = handle_kSetTerminalParameters(para);
|
||||
}
|
||||
break;
|
||||
|
||||
// 查询终端参数..
|
||||
case kGetTerminalParameters:
|
||||
{
|
||||
result = handle_kGetTerminalParameters(para);
|
||||
}
|
||||
break;
|
||||
|
||||
// 查询指定终端参数..
|
||||
case kGetSpecificTerminalParameters:
|
||||
{
|
||||
result = handle_kGetSpecificTerminalParameters(para);
|
||||
}
|
||||
break;
|
||||
|
||||
// 终端控制
|
||||
case kTerminalControl:
|
||||
{
|
||||
result = handle_kTerminalControl(para);
|
||||
}
|
||||
break;
|
||||
|
||||
// 下发终端升级包.
|
||||
case kTerminalUpgrade:
|
||||
{
|
||||
result = handle_kTerminalUpgrade(para);
|
||||
}
|
||||
break;
|
||||
|
||||
// 位置信息查询..
|
||||
case kGetLocationInformation:
|
||||
{
|
||||
result = handle_kGetLocationInformation(para);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int jt808FrameParse(const unsigned char *in, unsigned int in_len, struct ProtocolParameter *para)
|
||||
{
|
||||
int ret;
|
||||
unsigned int outBufferSize;
|
||||
unsigned char *outBuffer;
|
||||
|
||||
#ifdef __JT808_DEBUG
|
||||
JT808_DEBUG("%s[%d]: jt808FrameParse -->1 !!! \r\n", __FUNCTION__, __LINE__);
|
||||
#endif
|
||||
if (para == NULL)
|
||||
{
|
||||
JT808_DEBUG("para == NULL \r\n");
|
||||
return -1;
|
||||
}
|
||||
memcpy(BufferReceive, in, in_len);
|
||||
RealBufferReceiveSize = in_len;
|
||||
outBufferSize = RealBufferReceiveSize;
|
||||
outBuffer = (unsigned char *)malloc(outBufferSize * sizeof(unsigned char));
|
||||
memset(outBuffer, 0, outBufferSize);
|
||||
|
||||
#ifdef __JT808_DEBUG
|
||||
JT808_DEBUG("%s[%d]: outBufferSize = %d \r\n", __FUNCTION__, __LINE__, outBufferSize);
|
||||
#endif
|
||||
|
||||
// 逆转义.
|
||||
if (ReverseEscape_C(BufferReceive, RealBufferReceiveSize, outBuffer, &outBufferSize) < 0)
|
||||
{
|
||||
JT808_DEBUG("ReverseEscape_C ERROR\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
RealBufferReceiveSize = outBufferSize;
|
||||
|
||||
#ifdef __JT808_DEBUG
|
||||
JT808_DEBUG("%s[%d]: ReverseEscape_C. outBufferSize = %d !!!\r\n", __FUNCTION__, __LINE__, outBufferSize);
|
||||
#endif
|
||||
|
||||
// 异或校验检查.
|
||||
if (BccCheckSum(&(outBuffer[1]), (outBufferSize - 3)) != *(outBuffer + outBufferSize - 2))
|
||||
{
|
||||
JT808_DEBUG("BccCheckSum ERROR\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef __JT808_DEBUG
|
||||
JT808_DEBUG("%s[%d]: BccCheckSum. -->3 !!!\r\n", __FUNCTION__, __LINE__);
|
||||
#endif
|
||||
// 解析消息头.
|
||||
if (jt808FrameHeadParse(outBuffer, outBufferSize, &(para->parse.msg_head)) != 0)
|
||||
{
|
||||
JT808_DEBUG("jt808FrameHeadParse ERROR\r\n");
|
||||
return -1;
|
||||
}
|
||||
#ifdef __JT808_DEBUG
|
||||
JT808_DEBUG("%s[%d]: jt808FrameHeadParse. -->4 !!!\r\n", __FUNCTION__, __LINE__);
|
||||
#endif
|
||||
memcpy(para->msg_head.phone_num, para->parse.msg_head.phone_num, 11);
|
||||
|
||||
// 解析消息内容.
|
||||
ret = jt808FrameBodyParse(para);
|
||||
|
||||
// 释放缓存
|
||||
if (outBuffer != NULL)
|
||||
{
|
||||
free(outBuffer);
|
||||
outBuffer = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
#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__);
|
||||
// }
|
||||
|
|
@ -0,0 +1,304 @@
|
|||
#include "set_terminal_parameter.h"
|
||||
#include "terminal_parameter.h"
|
||||
#include "client_manager.h"
|
||||
#include "jt808_debug.h"
|
||||
|
||||
unsigned short kParameterSettingCMD[PARA_SETTING_LIMIT] = {
|
||||
kTerminalHeartBeatInterval, // DWORD, 终端心跳发送间隔(s).
|
||||
kMainServerAddress, // STRING, 主服务器地址,IP 或域名
|
||||
kServerPort, // DWORD, 服务器 TCP 端口
|
||||
kDefaultTimeReportTimeInterval, // DWORD, 缺省时间汇报间隔
|
||||
kCornerPointRetransmissionAngle, // DWORD, 拐点补传角度, < 180°.
|
||||
kMaxSpeed, // DWORD, 最高速度, km/h.
|
||||
kProvinceID, // WORD, 车辆所在的省域 ID
|
||||
kCityID, // WORD, 车辆所在的市域 ID
|
||||
kCarPlateNum, // STRING, 公安交通管理部门颁发的机动车号牌
|
||||
kCarPlateColor, // 车牌颜色,按照 JT/T415-2006 的 5.4.12
|
||||
};
|
||||
|
||||
void jt808ParameterSettingParse(unsigned int id, unsigned char *buf, unsigned char buf_len, struct ProtocolParameter *para)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case kTerminalHeartBeatInterval:
|
||||
{
|
||||
handle_HeartBeatInterval(buf, buf_len, para);
|
||||
}
|
||||
break;
|
||||
|
||||
case kMainServerAddress:
|
||||
{
|
||||
handle_MainServerAddress(buf, buf_len, para);
|
||||
}
|
||||
break;
|
||||
|
||||
case kServerPort:
|
||||
{
|
||||
handle_ServerPort(buf, buf_len, para);
|
||||
}
|
||||
break;
|
||||
|
||||
case kDefaultTimeReportTimeInterval:
|
||||
{
|
||||
handle_DefaultTimeReportTimeInterval(buf, buf_len, para);
|
||||
}
|
||||
break;
|
||||
|
||||
case kCornerPointRetransmissionAngle:
|
||||
{
|
||||
handle_CornerPointRetransmissionAngle(buf, buf_len, para);
|
||||
}
|
||||
break;
|
||||
|
||||
case kMaxSpeed:
|
||||
{
|
||||
handle_MaxSpeed(buf, buf_len, para);
|
||||
}
|
||||
break;
|
||||
|
||||
case kProvinceID:
|
||||
{
|
||||
handle_ProvinceID(buf, buf_len, para);
|
||||
}
|
||||
break;
|
||||
|
||||
case kCityID:
|
||||
{
|
||||
handle_CityID(buf, buf_len, para);
|
||||
}
|
||||
break;
|
||||
|
||||
case kCarPlateNum:
|
||||
{
|
||||
handle_CarPlateNum(buf, buf_len, para);
|
||||
}
|
||||
break;
|
||||
|
||||
case kCarPlateColor:
|
||||
{
|
||||
handle_CarPlateColor(buf, buf_len, para);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void handle_HeartBeatInterval(unsigned char *buf, unsigned char buf_len, struct ProtocolParameter *para)
|
||||
{
|
||||
union U32ToU8Array u32converter; // 注意大小端转换
|
||||
unsigned char *p = NULL;
|
||||
unsigned int heartBeatInterval;
|
||||
if ((buf == NULL) || (buf_len == 0))
|
||||
return;
|
||||
|
||||
p = (unsigned char *)malloc(sizeof(unsigned char) * buf_len);
|
||||
memcpy(p, buf, buf_len);
|
||||
|
||||
memcpy(u32converter.u8array, p, buf_len);
|
||||
heartBeatInterval = EndianSwap32(u32converter.u32val);
|
||||
|
||||
para->parse.terminal_parameters.HeartBeatInterval = 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));
|
||||
|
||||
free(p);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void handle_MainServerAddress(unsigned char *buf, unsigned char buf_len, struct ProtocolParameter *para)
|
||||
{
|
||||
unsigned char *p = NULL;
|
||||
if ((buf == NULL) || (buf_len == 0))
|
||||
return;
|
||||
|
||||
p = (unsigned char *)malloc(sizeof(unsigned char) * (buf_len + 1));
|
||||
memcpy(p, buf, buf_len);
|
||||
|
||||
// 字符串注意GBK转码
|
||||
memset(para->parse.terminal_parameters.MainServerAddress, 0, sizeof(para->parse.terminal_parameters.MainServerAddress));
|
||||
memcpy(para->parse.terminal_parameters.MainServerAddress, p, buf_len);
|
||||
// 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);
|
||||
free(p);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void handle_ServerPort(unsigned char *buf, unsigned char buf_len, struct ProtocolParameter *para)
|
||||
{
|
||||
union U32ToU8Array u32converter; // 注意大小端转换
|
||||
unsigned char *p = NULL;
|
||||
unsigned int serverPort;
|
||||
|
||||
if ((buf == NULL) || (buf_len == 0))
|
||||
return;
|
||||
|
||||
p = (unsigned char *)malloc(sizeof(unsigned char) * buf_len);
|
||||
memcpy(p, buf, buf_len);
|
||||
|
||||
memcpy(u32converter.u8array, p, buf_len);
|
||||
serverPort = EndianSwap32(u32converter.u32val);
|
||||
|
||||
para->parse.terminal_parameters.ServerPort = serverPort;
|
||||
// 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);
|
||||
free(p);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void handle_DefaultTimeReportTimeInterval(unsigned char *buf, unsigned char buf_len, struct ProtocolParameter *para)
|
||||
{
|
||||
union U32ToU8Array u32converter; // 注意大小端转换
|
||||
unsigned char *p = NULL;
|
||||
unsigned int DefaultTimeReportTimeInterval;
|
||||
if ((buf == NULL) || (buf_len == 0))
|
||||
return;
|
||||
|
||||
p = (unsigned char *)malloc(sizeof(unsigned char) * buf_len);
|
||||
memcpy(p, buf, buf_len);
|
||||
|
||||
memcpy(u32converter.u8array, p, buf_len);
|
||||
DefaultTimeReportTimeInterval = EndianSwap32(u32converter.u32val);
|
||||
if (DefaultTimeReportTimeInterval >= 30)
|
||||
{
|
||||
DefaultTimeReportTimeInterval = 30;
|
||||
}
|
||||
if (DefaultTimeReportTimeInterval <= 2)
|
||||
{
|
||||
DefaultTimeReportTimeInterval = 2;
|
||||
}
|
||||
para->parse.terminal_parameters.DefaultTimeReportTimeInterval = DefaultTimeReportTimeInterval;
|
||||
// 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);
|
||||
free(p);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void handle_CornerPointRetransmissionAngle(unsigned char *buf, unsigned char buf_len, struct ProtocolParameter *para)
|
||||
{
|
||||
union U32ToU8Array u32converter; // 注意大小端转换
|
||||
unsigned char *p = NULL;
|
||||
unsigned int CornerPointRetransmissionAngle;
|
||||
if ((buf == NULL) || (buf_len == 0))
|
||||
return;
|
||||
|
||||
p = (unsigned char *)malloc(sizeof(unsigned char) * buf_len);
|
||||
memcpy(p, buf, buf_len);
|
||||
|
||||
memcpy(u32converter.u8array, p, buf_len);
|
||||
CornerPointRetransmissionAngle = EndianSwap32(u32converter.u32val);
|
||||
|
||||
para->parse.terminal_parameters.CornerPointRetransmissionAngle = CornerPointRetransmissionAngle;
|
||||
// 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);
|
||||
free(p);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void handle_MaxSpeed(unsigned char *buf, unsigned char buf_len, struct ProtocolParameter *para)
|
||||
{
|
||||
union U32ToU8Array u32converter; // 注意大小端转换
|
||||
unsigned char *p = NULL;
|
||||
unsigned int MaxSpeed;
|
||||
if ((buf == NULL) || (buf_len == 0))
|
||||
return;
|
||||
|
||||
p = (unsigned char *)malloc(sizeof(unsigned char) * buf_len);
|
||||
memcpy(p, buf, buf_len);
|
||||
|
||||
memcpy(u32converter.u8array, p, buf_len);
|
||||
MaxSpeed = EndianSwap32(u32converter.u32val);
|
||||
|
||||
para->parse.terminal_parameters.MaxSpeed = MaxSpeed;
|
||||
// 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);
|
||||
free(p);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void handle_ProvinceID(unsigned char *buf, unsigned char buf_len, struct ProtocolParameter *para)
|
||||
{
|
||||
union U16ToU8Array u16converter; // 注意大小端转换
|
||||
unsigned char *p = NULL;
|
||||
unsigned short ProvinceID;
|
||||
if ((buf == NULL) || (buf_len == 0))
|
||||
return;
|
||||
|
||||
p = (unsigned char *)malloc(sizeof(unsigned char) * buf_len);
|
||||
memcpy(p, buf, buf_len);
|
||||
|
||||
memcpy(u16converter.u8array, p, buf_len);
|
||||
ProvinceID = EndianSwap16(u16converter.u16val);
|
||||
|
||||
para->parse.terminal_parameters.ProvinceID = ProvinceID;
|
||||
// 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);
|
||||
free(p);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void handle_CityID(unsigned char *buf, unsigned char buf_len, struct ProtocolParameter *para)
|
||||
{
|
||||
union U16ToU8Array u16converter; // 注意大小端转换
|
||||
unsigned char *p = NULL;
|
||||
unsigned short CityID;
|
||||
if ((buf == NULL) || (buf_len == 0))
|
||||
return;
|
||||
|
||||
p = (unsigned char *)malloc(sizeof(unsigned char) * buf_len);
|
||||
memcpy(p, buf, buf_len);
|
||||
|
||||
memcpy(u16converter.u8array, p, buf_len);
|
||||
CityID = EndianSwap16(u16converter.u16val);
|
||||
|
||||
para->parse.terminal_parameters.CityID = CityID;
|
||||
// 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);
|
||||
free(p);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void handle_CarPlateNum(unsigned char *buf, unsigned char buf_len, struct ProtocolParameter *para)
|
||||
{
|
||||
// 字符串注意GBK转码
|
||||
unsigned char *p = NULL;
|
||||
if ((buf == NULL) || (buf_len == 0))
|
||||
return;
|
||||
|
||||
p = (unsigned char *)malloc(sizeof(unsigned char) * buf_len + 1);
|
||||
memcpy(p, buf, buf_len);
|
||||
|
||||
memset(para->parse.terminal_parameters.CarPlateNum, 0, sizeof(para->parse.terminal_parameters.CarPlateNum));
|
||||
memcpy(para->parse.terminal_parameters.CarPlateNum, p, buf_len);
|
||||
// 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);
|
||||
free(p);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void handle_CarPlateColor(unsigned char *buf, unsigned char buf_len, struct ProtocolParameter *para)
|
||||
{
|
||||
unsigned char *p = NULL;
|
||||
// unsigned char write_buf[FLASH_BUFFER_SIZE] = {0};
|
||||
if ((buf == NULL) || (buf_len == 0))
|
||||
return;
|
||||
p = (unsigned char *)malloc(sizeof(unsigned char) * buf_len + 1);
|
||||
memcpy(p, buf, buf_len);
|
||||
|
||||
para->parse.terminal_parameters.CarPlateColor = *p;
|
||||
// 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);
|
||||
free(p);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
#include "terminal_register.h"
|
||||
#include "string.h"
|
||||
#include "jt808_debug.h"
|
||||
|
||||
struct RegisterInfo registerInfo_;
|
||||
|
||||
void initRegisterInfo(struct ProtocolParameter *para)
|
||||
{
|
||||
int lenManufacturer, lenTModel;//, lenTerminalId;
|
||||
JT808_DEBUG("\r\n[ initRegisterInfo ] OK !\r\n");
|
||||
// 省域ID
|
||||
para->register_info.province_id = para->parse.terminal_parameters.ProvinceID;
|
||||
JT808_DEBUG("para->register_info.province_id = %d\r\n", para->register_info.province_id);
|
||||
|
||||
// 市域ID
|
||||
para->register_info.city_id = para->parse.terminal_parameters.CityID;
|
||||
JT808_DEBUG("para->register_info.city_id = %04d\r\n", para->register_info.city_id);
|
||||
|
||||
// 制造商ID
|
||||
lenManufacturer = sizeof("XINDA");
|
||||
lenManufacturer = (lenManufacturer > 5) ? 5 : lenManufacturer;
|
||||
|
||||
memset(para->register_info.manufacturer_id, 0, lenManufacturer);
|
||||
memcpy(para->register_info.manufacturer_id, "XINDA", lenManufacturer);
|
||||
JT808_DEBUG("para->register_info.manufacturer_id = %s\r\n", para->register_info.manufacturer_id);
|
||||
|
||||
// 终端型号
|
||||
lenTModel = sizeof("ZXIAT-CZ01");
|
||||
lenTModel = (lenTModel > 20) ? 20 : lenTModel;
|
||||
|
||||
memset(para->register_info.terminal_model, 0, lenTModel);
|
||||
memcpy(para->register_info.terminal_model, "ZXIAT-CZ01", lenTModel);
|
||||
JT808_DEBUG("para->register_info.terminal_model = %s\r\n", para->register_info.terminal_model);
|
||||
|
||||
// //终端ID
|
||||
// lenTerminalId = sizeof("1000000");
|
||||
// lenTerminalId=(lenTerminalId>20)?20:lenTerminalId;
|
||||
|
||||
// memset(para->register_info.terminal_id, 0, lenTerminalId);
|
||||
// memcpy(para->register_info.terminal_id, "1000000", lenTerminalId);
|
||||
// JT808_DEBUG("para->register_info.terminal_id = %s\r\n", para->register_info.terminal_id);
|
||||
|
||||
// 车牌颜色
|
||||
para->register_info.car_plate_color = para->parse.terminal_parameters.CarPlateColor;
|
||||
JT808_DEBUG("para->register_info.car_plate_color = 0x%02x\r\n", para->register_info.car_plate_color);
|
||||
|
||||
// 车牌号
|
||||
if (para->register_info.car_plate_color != 0x00)
|
||||
{
|
||||
memcpy(para->register_info.car_plate_num, para->parse.terminal_parameters.CarPlateNum, 12);
|
||||
JT808_DEBUG("para->register_info.car_plate_num = %s\r\n", para->register_info.car_plate_num);
|
||||
}
|
||||
JT808_DEBUG("\r\n");
|
||||
JT808_DEBUG("注册信息更新完成\r\n");
|
||||
JT808_DEBUG("\r\n");
|
||||
}
|
||||
|
|
@ -0,0 +1,162 @@
|
|||
#include "util.h"
|
||||
#include "protocol_parameter.h"
|
||||
#include "client_manager.h"
|
||||
#include "jt808_debug.h"
|
||||
|
||||
union U16ToU8Array u16converter;
|
||||
union U32ToU8Array u32converter;
|
||||
|
||||
// 双字节大小段互换
|
||||
unsigned short EndianSwap16(unsigned short u16val)
|
||||
{
|
||||
return (((u16val & 0x00FF) << 8) +
|
||||
((u16val & 0xFF00) >> 8));
|
||||
}
|
||||
|
||||
// 四字节大小端互换.
|
||||
unsigned int EndianSwap32(unsigned int u32val)
|
||||
{
|
||||
return (((u32val & 0x000000FF) << 24) +
|
||||
((u32val & 0x0000FF00) << 8) +
|
||||
((u32val & 0x00FF0000) >> 8) +
|
||||
((u32val & 0xFF000000) >> 24));
|
||||
}
|
||||
|
||||
// 转义函数. outlen应大于inlen 建议outlen >= 2*inlen;
|
||||
int Escape_C(unsigned char *in, unsigned int inlen, unsigned char *out, unsigned int *outlen)
|
||||
{
|
||||
unsigned int i;
|
||||
int offset_num;
|
||||
if ((out == NULL) || ((*outlen) < 2 * inlen))
|
||||
{
|
||||
JT808_DEBUG("[%s] FAILED \r\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(out, 0, *outlen);
|
||||
|
||||
offset_num = 0;
|
||||
for (i = 0; i < inlen; ++i)
|
||||
{
|
||||
if (in[i] == PROTOCOL_SIGN)
|
||||
{
|
||||
out[i + offset_num] = PROTOCOL_ESCAPE;
|
||||
out[i + 1 + offset_num] = PROTOCOL_ESCAPE_SIGN;
|
||||
offset_num++;
|
||||
}
|
||||
else if (in[i] == PROTOCOL_ESCAPE)
|
||||
{
|
||||
out[i + offset_num] = PROTOCOL_ESCAPE;
|
||||
out[i + 1 + offset_num] = PROTOCOL_ESCAPE_ESCAPE;
|
||||
offset_num++;
|
||||
}
|
||||
else
|
||||
{
|
||||
out[i + offset_num] = in[i];
|
||||
}
|
||||
}
|
||||
*outlen = inlen + offset_num;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 逆转义函数. outlen >= (inlen/2)
|
||||
int ReverseEscape_C(unsigned char *in, unsigned int inlen, unsigned char *out, unsigned int *outlen)
|
||||
{
|
||||
// if ((out == NULL) || (inlen == 0))
|
||||
// return -1;
|
||||
// memset(out, 0, *outlen);
|
||||
unsigned int i;
|
||||
int offset_num;
|
||||
#ifdef __JT808_DEBUG
|
||||
JT808_DEBUG("[ReverseEscape_C]:");
|
||||
#endif
|
||||
|
||||
offset_num = 0;
|
||||
for (i = 0; i < inlen; ++i)
|
||||
{
|
||||
if ((in[i] == PROTOCOL_ESCAPE) && (in[i + 1] == PROTOCOL_ESCAPE_SIGN))
|
||||
{
|
||||
out[i - offset_num] = PROTOCOL_SIGN;
|
||||
++i;
|
||||
offset_num++;
|
||||
}
|
||||
else if ((in[i] == PROTOCOL_ESCAPE) && (in[i + 1] == PROTOCOL_ESCAPE_ESCAPE))
|
||||
{
|
||||
out[i - offset_num] = PROTOCOL_ESCAPE;
|
||||
++i;
|
||||
offset_num++;
|
||||
}
|
||||
else
|
||||
{
|
||||
out[i - offset_num] = in[i];
|
||||
#ifdef __JT808_DEBUG
|
||||
JT808_DEBUG("%02x ", out[i - offset_num]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#ifdef __JT808_DEBUG
|
||||
JT808_DEBUG("\r\n");
|
||||
#endif
|
||||
|
||||
*outlen = inlen - offset_num;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 异或校验.
|
||||
unsigned char BccCheckSum(const unsigned char *src, unsigned long len)
|
||||
{
|
||||
unsigned char checksum = 0;
|
||||
unsigned long i;
|
||||
for (i = 0; i < len; ++i)
|
||||
{
|
||||
checksum = checksum ^ src[i];
|
||||
}
|
||||
#ifdef __JT808_DEBUG
|
||||
JT808_DEBUG("[BccCheckSum] OK !\r\n");
|
||||
#endif
|
||||
return checksum;
|
||||
}
|
||||
// 处理字符串,返回子串在母串的第一个字符的位置
|
||||
int strStr(const char *haystack, const char *needle)
|
||||
{
|
||||
int len1 = strlen(haystack);
|
||||
int len2 = strlen(needle);
|
||||
int i = 0, j = 0, k = 0;
|
||||
bool jieguo = true;
|
||||
if (len1 < len2)
|
||||
{
|
||||
jieguo = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i <= len1 - len2; i++)
|
||||
{
|
||||
for (j = i, k = 0; j < i + len2; j++, k++)
|
||||
{
|
||||
if (haystack[j] != needle[k])
|
||||
{
|
||||
jieguo = false;
|
||||
break;
|
||||
}
|
||||
if (haystack[j] == needle[k])
|
||||
{
|
||||
jieguo = true;
|
||||
}
|
||||
}
|
||||
if (jieguo == true)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (jieguo == false)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue