添加第三方jt808协议库 zsxfly20241013

This commit is contained in:
zsx 2024-10-18 00:41:54 +08:00
parent e3baeaa47f
commit 3093935b23
26 changed files with 3816 additions and 2 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/.vscode/
out/

View File

@ -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

View File

@ -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");
}

29
custom/jt808/inc/bcd.h Normal file
View File

@ -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_

View File

@ -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_

View File

@ -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_

View File

@ -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

View File

@ -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);

View File

@ -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_

View File

@ -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);

View File

@ -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_

View File

@ -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);

View File

@ -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

View File

@ -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_

View File

@ -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_

54
custom/jt808/inc/util.h Normal file
View File

@ -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_

14
custom/jt808/jt808.mk Normal file
View File

@ -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'

70
custom/jt808/src/bcd.c Normal file
View File

@ -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;
}

View File

@ -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*)&parameter_.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*)&parameter_.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*)&parameter_.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*)&parameter_.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 *) &parameter_.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(&parameter_) < 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, &parameter_) < 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;
}

133
custom/jt808/src/gbk_utf8.c Normal file
View File

@ -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;
}
}
*/

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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__);
// }

View File

@ -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 *) &para->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 *) &para->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 *) &para->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 *) &para->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 *) &para->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 *) &para->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 *) &para->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 *) &para->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 *) &para->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 *) &para->parse.terminal_parameters , sizeof(para->parse.terminal_parameters));
JT808_DEBUG("handle_CarPlateColor ==== 0x%02x \r\n", para->parse.terminal_parameters.CarPlateColor);
free(p);
return;
}

View File

@ -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");
}

162
custom/jt808/src/util.c Normal file
View File

@ -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;
}
}