N32G451CCL7芯片JT808通信应用代码

JT808通信底层驱动,代码中加入了一些自定义通信,移植时可根据项目需求,适配应用代码即可。同样,前面是头文件代码,后面是应用代码,仅做记录,方便以后移植应用,代码已实测。

#ifndef __JT808_H_

#define __JT808_H_

#include "main.h" //

#define JT808_RX_LEN   1024

#define JT808_TX_LEN   1024

//JT808 header message  id

#define LOGIN_ID        0X0100    //login ID

#define LOGOUT_ID       0X0003    //logout ID

#define HEARTBEAT_ID    0X0002    //heartbeat ID

#define AUTH_ID         0X0102    //authentication ID

#define TRANSPARENT_ID  0X0900    //transparent ID

#define POSITION_ID     0X0200    //position ID.

#define CALL_NAME_ID    0X0201    //position ID.

#define BLIND_ID        0X0704    //off line position data ID.

#define NTP_ID          0X0E00    //NTP:network timing protocol 网络校时协议

#define NTP_F_ID        0X0F00    //NTP:network timing protocol 网络校时协议

#define T_ACK_ID        0X0001    //terminal divice ack ID.

#define T_INQUIRE_ACK   0X0104    //terminal inquire ack ID.

#define TEXT_ACK_ID     0X0300    //text ack.

#define FILE_ACK_ID     0X0F05    //file ack

#define T_ATTR_ACK_ID   0X0107    //terminal divice attribute chech ack.

#define DEFAULT_ID      0XFFFF    //default ID

//jt808 message body sub_id

#define JT808_GERSOR_ID        0xB0    // 0xB0 three-axis sensor data ID

enum JT808Status

{

    JT808_START_MODE = 1,          

    JT808_LOGIN,

    JT808_LOGOUT,

    JT808_AUTH,

    JT808_HEART_BEAT,

    JT808_POSITON,

    JT808_T_ATTR,

    JT808_WAIT_AGPS,

    JT808_WORK_MODE,      //    

    JT808_NTP,            //NTP:network timing protocol 网络校时协议

    JT808_POWER_OFF,      //Turn off EC800 power

    JT808_SHUT_DOWN,      //shutdown system,the power is still on

    JT808_MODULE_INIT,    //JT808 module initialization

    JT808_DEFAULT,

    JT808_REV  

};

enum ALARM__NUM

{

    ALARM_TRUE = 1,

    ALARM_H_TH,      //hight temperature

    ALARM_L_TH,      //

    ALARM_H_HU,      //hight humidity

    ALARM_L_HU,      //

    ALARM_HAVE_EX_POWER,

    ALARM_HAVE_NO_POWER,

    ALARM_CHARGE,

    ALARM_NO_CHARGE,

    ALARM_VIBRATE,

    ALARM_ROLLOVER,

    ALARM_KEY1,

    ALARM_KEY2,

    ALARM_LIGHT_F_ON,

    ALARM_LIGHT_F_OFF,

    ALARM_LIGHT_B_ON,

    ALARM_LIGHT_B_OFF,

    ALARM_LOCK_ON,

    ALARM_LOCK_OFF,

    ALARM_FIRST_LOCATION,

    ALARM_OBD_INSERT,

    ALARM_OBD_EX_LP, //OBD外电低压报警。

    ALARM_OBD_VIN_CODE,//vin码更新报警。

    ALARM_OBD_EX_POWER,//obd外电变化报警。

    ALARM_REV  

};

//__packed  

struct __JT808_                  //jt808 structure data

{

    u16 provinceId;         //省ID

    u16 prefectureId;       //市ID

    u8   status;                  //running status.

    u8   alarmNum;

    u8   alarmFlag;

    u8    extendAlarmFlag;    

    u8    repeatTimesLimit;        //data retransmission times.

    u32   ackTimeoutLimit;         //ack time out.

    u32   heartCountDown;         //心跳倒计时

    u32   positionCountDown;      //位置上报倒计时

    u8    heartbeatAckFlag;             //heartbeat ack .

    u8    heartbeatReadyFlag;

    u8    haveDataFlag;

    u32   heartBeatTime;           //jt808 heartbeat time.

    u32   heartBeatTimeLimit;      //heartbeat time limit.  

    u32   positionReportTime;

    u32   positionReportTimeLimit;

    u8    positionAckFlag;             //position report ack.

    u8    attr0107Ok;

    u8    positionReadyFlag;       //

    u8    rxBuf[JT808_RX_LEN];     //rx buf.

    u8    txBuf[JT808_TX_LEN];     //tx buf.

    u8    callNameFlag;

    // u8    blindBuf[10];          //  

    // u32   blindDataLen;       //

    // u16   blindDataNum;       //

    // u32   blindDataCurrentAdd; //

    // u8    blindAck;

    u16   rxLen;                   //rx buf length.

    u16   txLen;                   //tx buf length.

    u8    ackFlag;                 //ACK flag.

    u8    ackSendFlag;

    u8    ackErrorFlag;            //ACK error flag.

    u8    rxOkFlag;                //rx buf ready flag.

    u8    loginFlag;               //login.

    u8    logoutFlag;              //logout.

    // char  authCode[AUTH_CODE_LEN]; //authentication code.

    u8  authFlag;                //authentication flag.

    u8  ntpFlag;                 //NTP:network timing protocol 网络校时协议

    u16 ackId;                   //ACK ID.

    u16 ackWater;                  //ack water number.

    u8  ackResult;               //Ack result.

    u16 rxBodyId;               //Rx message body id.

    u16 rxBodyLen;               //Rx message body length.

    u8* rxBodyP;                 //Rx message body pointer.

    u8  subPackage;              //Transparent message body subpackage.

    u16 txSubId;                 // Message bode sub_ID.

    u32 timeOut;

    u8  rxDebug;

    u8  txDebug;

    u8  atDebug;     //JT808 at command debug mode.

    u8  debug;

};

__packed struct __MsgHeader_      //message header struct

{

    u16 id;          //message header ID

    u16 attr;        //message header attribute

    char tel[6];     //tel number

    u16 water;       //water number

    u16 totalNum;    //package total number

    u16 subPkgNum;   //subpackage number        

};

__packed struct __FILE_      //File struct

{

    u32 id;           //file ID

    u8 type;          //0:图像;1:音频;2视频;

    u8 format;        //0:JPG;1:TIF;2:MP3;3:WAV;4:WMV;5:AMR;6:BMP(单色);7:BMP(16灰),8:BMP

    u8 compressType;  //compressed files type 0:未压缩;1:RLE区分压缩(长度字节最高位置1表示后续N个非重复字节,n最大127);

    u8 storageNum;    //sequence number

    u16 totalNum;     //package total number

    u16 currentNum;   //current package number

    u16 packageLen;   //package length

    u8 data[128];       //file package data.

    u32 timeOut;

    u8 fileRxFlag;

};

struct __TEXT_

{

    u8 type;

    u8 buf[128];

    u16 len;

};

__packed  struct __LoginBody_     //login message body struct

{

    u16 provinceId;             //province ID

    u16 prefectureId;           //prefecture/city ID

    char manuId[5];             //manufacturer ID

    char tMode[20];             //terminal mode

    char tId[7];                //terminal ID

  char color;                 //plate number color

    u8  carNum[15];             //car number    

};

__packed  struct __HeartbeatBody_ //Heartbeat message body struct

{

    char   soc;                //battery soc

    u16    externVol;          //external power

    char   gsm;

    u16    temperature;        //

    u16    humidity;           //

    char   chargeFlag;         //battery charge flag

    u8 powerSupply; //0:battery supply 1:ertern power -1:invalid

    u8 mode;        //work mode.

    u8 batteryVol;             //battery voltage.

    u8 buf[4];                 //reserve

    u8 thID;

    u8 thLen;

    s16 tem1;

    s16 hum1;

    s16 tem2;

    s16 hum2;

    s16 tem3;

    s16 hum3;

    u8 gsId;   //三轴、六轴ID

    u16 gsLen;


 

};

__packed  struct __AuthBody_      //authentication message body struct

{

    char code[11];              //

};

__packed  struct __Terminal_Ack_Body_      //terminal universal ack.

{

    u16 waterNumber;  

    u16 id;              //

  u8    result;          //0:成功/确认;1:失败;2:消息有误;3:不支持;4:终端收到指令后延时执行。

};

    __packed  struct __32BIT_

    {

        u32 Bit24 :1;            //byte3

        u32 Bit25 :1;            //

        u32 Bit26 :1;            //

        u32 Bit27 :1;            //

        u32 Bit28 :1;            //

        u32 Bit29 :1;            //

        u32 Bit30 :1;            //

        u32 Bit31 :1;            //

        u32 Bit16 :1;            // byte2

        u32 Bit17 :1;            //

        u32 Bit18 :1;            //

        u32 Bit19 :1;            //

        u32 Bit20 :1;            //

        u32 Bit21 :1;            //

        u32 Bit22 :1;            //

        u32 Bit23 :1;            //

   

        u32 Bit08 :1;            //byte1

        u32 Bit09 :1;            //

        u32 Bit10 :1;            //

        u32 Bit11 :1;            //

        u32 Bit12 :1;            //

        u32 Bit13 :1;            //

        u32 Bit14 :1;            //

        u32 Bit15 :1;            //

        u32 Bit00 :1;            //byte0

        u32 Bit01 :1;            //

        u32 Bit02 :1;            //

        u32 Bit03 :1;            //

        u32 Bit04 :1;            //

        u32 Bit05 :1;            //

        u32 Bit06 :1;            //

        u32 Bit07 :1;            //

    };

__packed  struct __POSITION_Body_      //authentication message body struct

{

    __packed  struct __ALAMR_

    {

        u32 Bit24 :1;            //byte3

        u32 Bit25 :1;            //

        u32 Bit26 :1;            //

        u32 Bit27 :1;            //

        u32 Bit28 :1;            //

        u32 Bit29 :1;            //

        u32 Bit30 :1;            //

        u32 Bit31 :1;            //

        u32 Bit16 :1;            // byte2

        u32 Bit17 :1;            //

        u32 Bit18 :1;            //

        u32 Bit19 :1;            //

        u32 Bit20 :1;            //

        u32 Bit21 :1;            //

        u32 Bit22 :1;            //

        u32 Bit23 :1;            //

   

        u32 Bit08 :1;            //byte1

        u32 Bit09 :1;            //

        u32 Bit10 :1;            //

        u32 Bit11 :1;            //

        u32 Bit12 :1;            //

        u32 Bit13 :1;            //

        u32 Bit14 :1;            //

        u32 Bit15 :1;            //

        u32 Bit00 :1;            //byte0

        u32 Bit01 :1;            //

        u32 Bit02 :1;            //

        u32 Bit03 :1;            //

        u32 Bit04 :1;            //

        u32 Bit05 :1;            //

        u32 Bit06 :1;            //

        u32 Bit07 :1;            //

    }alarm;

    __packed  struct __STATUS_

    {

        u32 Bit24 :1;            //byte3

        u32 Bit25 :1;            //

        u32 Bit26 :1;            //

        u32 Bit27 :1;            //

        u32 Bit28 :1;            //

        u32 Bit29 :1;            //

        u32 Bit30 :1;            //

        u32 Bit31 :1;            //

        u32 Bit16 :1;            // byte2

        u32 Bit17 :1;            //

        u32 Bit18 :1;            //

        u32 Bit19 :1;            //

        u32 Bit20 :1;            //

        u32 Bit21 :1;            //

        u32 Bit22 :1;            //

        u32 Bit23 :1;            //

   

        u32 Bit08 :1;            //byte1

        u32 Bit09 :1;            //

        u32 Bit10 :1;            //

        u32 Bit11 :1;            //

        u32 Bit12 :1;            //

        u32 Bit13 :1;            //

        u32 Bit14 :1;            //

        u32 Bit15 :1;            //

        u32 Bit00 :1;            //byte0

        u32 Bit01 :1;            //

        u32 Bit02 :1;            //

        u32 Bit03 :1;            //

        u32 Bit04 :1;            //

        u32 Bit05 :1;            //

        u32 Bit06 :1;            //

        u32 Bit07 :1;            //

    }status;

    u32 latitude;

    u32 longitude;

    u16 high;

    u16 speed;

    u16 direction;

    u8 year;

    u8 month;

    u8 day;

    u8 hour;

    u8 minute;

    u8 second;

};

extern struct __JT808_ jt808;          //JT808 struct

// extern struct __FILE_           file;         //File package structure

// extern struct __AuthBody_       authBody;     //authentication message body.

extern struct __MsgHeader_      rxHeader;        //message header rx data.

extern struct __MsgHeader_      txHeader;        //message header tx data.

void jt808ParaInit(void);  //JT808 parameter initialization

void jt808Deal(void);      //jt808

#endif // __JT808_H_

#include "jt808.h"

struct __JT808_          jt808;           //JT808 structure
struct __MsgHeader_      rxHeader;        //message header rx data.
struct __MsgHeader_      txHeader;        //message header tx data.
// struct __LoginBody_      loginBody;       //login message body.
// struct __AuthBody_       authBody;        //authentication message body.
// struct __HeartbeatBody_  heartbeatBoy;    //Heartbeat message body.
// struct __POSITION_Body_  positionBody;    //position body
struct __32BIT_          positionAlarm;      //位置数据包32bit报警信息
struct __32BIT_          positionStatus;     //位置数据包32bit状态信息
// struct __FILE_           file;            //File package structure
struct __32BIT_          extendAlarmBits; //extend alarm bits.
struct __Terminal_Ack_Body_      tAckBody;//terminal universal ack.
struct __TEXT_ text;                      //jt808 text struct.
struct __32BIT_          obdStatusBits;
// u32   blindDataLen = 0;            //
// u16   blindDataNum = 0;            //
u8 ascaiiToInt(char tempChar) //字符串转整数
{
    u8 temp = 0;
    if (0x30<=tempChar && tempChar<=0x39)
    {
        temp = tempChar - 0x30;
    }
    else if (0x41<=tempChar && tempChar<=0x46)
    {
        temp = tempChar - 0x41+10;
    }
    else
    {
        temp = 0;
    }
    return temp;
}
void jt808Send(u8* buf,u16 len)
{
    u16 tempLen = 0;
    jt808.ackFlag = NOT_OK;  //
    // if(ec800.status != EC800_TRANSMIT_MODE) //去掉此处判断,如果EC800异常,发送数据,返回错误状态。
    // {
    //     debugLog("连接服务器异常,无法发送数据,请检查设备。\n");
    //     return;
    // }
      sprintf(ec800.txBuf,"AT+QISEND=%d,%d\r\n",JT808_CONNECT_ID,len); //直吐数据传输模式
    // sendAtCmd(ec800.txBuf);
    tempLen = strlen(ec800.txBuf);
    ec800Send((u8*)ec800.txBuf,tempLen);
      delay_ms(10); //delay1Ms(10);
    debugLog("上传平台数据:Id:0X%04X,本地流水号:%d,长度:%d.\n",txHeader.id,txHeader.water-1,len);
    ec800Send(buf,len);                    
    
    if(txHeader.id == 0x0001) //通用应答。
    {    
        debugLog("JT808 TX sub Id:0X%04X,子流水号:%d.\n",tAckBody.id,tAckBody.waterNumber);
    }
    if(jt808.txDebug)  //jt808 rxBuf
    {
        u16 i=0;        
        debugLog("上传平台原始数据:");
        for(i=0;i<jt808.txLen;i++)
        {
            printf("0x%0.2x,",jt808.txBuf[i]);
        }
        printf("\n");        
    }    
}
void mergeChar(char *psr,u16 *plen)  //merge:合并  merge char:合并转义字符
{
    char  buf[1024]={0};
  char *beginP=psr;            //存储起始指针
  memcpy(buf,psr,*plen);       //缓存数据
  memset(psr,0,*plen);         //清零原始数组
  *(psr++)=0x7e;               //头0x7e
  for(u16 i=1;i<*plen;++i)     //从数组buf[1]开始,跳过buf[0] = 0x7e,结尾buf[*plen - 1] = 0x7e,也会放回数组。
  {
        if(buf[i]==0x7d)
        {
            if(buf[i+1]==0x01) *(psr++)=0x7d;        //0x7d 0x01合并成0x7d
            else if(buf[i+1]==0x02) *(psr++)=0x7e;   //0x7d 0x02合并成0x7e
             i++; 
        }    
    else
    {
        *(psr++)=buf[i];
    }                
  }
    *plen=psr-beginP; //计算出转换后的数组长度。
}
void addChar(char *psr,u16 *plen)    //add:添加  add char:添加转义字符,同时修改长度为转义后的实际长度。
{
    u8  buf[1024]={0};
    u16 i;
    char *beginP=psr;         //save begin pointer
    memcpy(buf,psr,*plen);  //buffer the raw data
    memset(psr,0,*plen);    //clear the raw data
    *(psr++)=0x7E;
    for(i=1;i<(*plen-1);++i)
    {
        if(buf[i]==0x7e)
        {
            *(psr++)=0x7d;
            *(psr++)=0x02;
        }
        else if(buf[i]==0x7d)
        {
            *(psr++)=0x7d;
            *(psr++)=0x01;
        }
        else
        {
            *(psr++)=buf[i];
        }
    }
    *(psr++)=buf[i]; //psr[*plen-1],即0x7E.
    *plen=psr-beginP;    
}
void jt808ParaInit(void) //JT808 parameter initialization
{    
    // sprintf(jt808.authCode,"12345678900"); //This code just for testing.  authentication code    
    // sprintf(authBody.code,"12345678900"); //This code just for testing.  authentication code    
    //memcpy(authBody.code,jt808.authCode,11); 

    txHeader.water = 1;                   //water number    
    jt808.positionAckFlag = NOT_OK;    
    jt808.status = JT808_START_MODE;      //jt808 run status
    // jt808.status = JT808_WORK_MODE;  //This code just for test.     
    txHeader.id    = DEFAULT_ID;          //JT808 message ID,DEFAULT_ID:There was nothing to do.        
    // jt808.loginFlag = FALSE;
      jt808.timeOut = Timer.ms;   //超时控制变量

    jt808.debug = FALSE;
    // jt808.debug = TRUE;      // 

    jt808.rxDebug = FALSE;
    // jt808.rxDebug = TRUE;    // 

    jt808.txDebug = FALSE;
    // jt808.txDebug = TRUE;    // 

    jt808.atDebug = FALSE;
    // jt808.atDebug = TRUE;    

    addSecondsRTC(&positionRepotRtc,rtc,Parm.wkMode[Parm.currentMode].positionReportTimeLimit);    //计算下次位置上报时间
    addSecondsRTC(&heartbeatRtc,rtc,Parm.wkMode[Parm.currentMode].heartBeatTimeLimit);              //计算下次心跳时间
}
void jt808Parser(void)   //JT808 rx data parse.
{    
    if(jt808.rxOkFlag == NOT_OK) return; //
    jt808.rxOkFlag = NOT_OK;             //jt808接收数据包完成标志清除

    jt808.rxBodyP = NULL;        //接收到的消息体指针。
      u8  subpackageFlag = 0;      //分包信息    
    char *buf = (char*)jt808.rxBuf;
    u16  len = jt808.rxLen;        
    mergeChar(buf,&len);  //调用转义合并字符后len会修改为合并后数组的实际长度    
    char sum = 0; //check sum
    for(u16 i = 1;i<len-1;i++) //将数组中校验和本身buf[len-2]也计算在内,如果校验和正确,sum ==0.
    {
        sum ^=buf[i];
    }
    // if(sum != 0) return;    //校验和不对,则直接返回.    
    // usartSendBuf(USART3,jt808.rxBuf,jt808.rxLen); //发送整包数据到log串口    
                    
    if(jt808.rxDebug)  //jt808 rxBuf
    {
        u16 i=0;        
        debugLog("JT808 rx data:");
        for(i=0;i<jt808.rxLen;i++)
        {
            printf("0x%0.2x,",jt808.rxBuf[i]);
        }
        printf("\n");        
    }        
    rxHeader.id      = (buf[1] << 8) | buf[2];  //jt808 rx header ID.
    rxHeader.attr    = (buf[3] << 8) | buf[4];    
    if(rxHeader.id == 0x8F05)
    {
        jt808.rxBodyLen    = rxHeader.attr;           //接收消息体长度 :bit10--bit0
    }
    else 
    {
        jt808.rxBodyLen    = rxHeader.attr & 0x03FF;           //接收消息体长度 :bit10--bit0
    }    
    subpackageFlag   = (u8)((rxHeader.attr >> 13) & 0x01); //判断是否有分包 bit13 = 1:有   bit13 = 0 :无
    if (subpackageFlag == 1) //有分包
    {
        if (jt808.rxBodyLen != (len - 19))  //有分包情况,消息体长度=接收长度len-1字节(0x7e包头)-16字节(消息头)-1字节(校验)-1字节(0x7e包尾)   共19个字节
        {
            return;
        }    
        rxHeader.totalNum = (buf[12]<<8)+buf[13];
        rxHeader.subPkgNum   = (buf[14]<<8)+buf[15];
        jt808.rxBodyP     = (u8*)&buf[17]; //消息体首地址赋值
    } 
    else //不分包
    {
        if (jt808.rxBodyLen != (len - 15)) //消息体长度=接收长度len-1字节(0x7e包头)-12字节(消息头)-1字节(校验)-1字节(0x7e包尾)   共15个字节
        {
            return;
        }
        jt808.rxBodyP = (u8*)&buf[13];
    }    
    u16 temp = (buf[11] << 8) | buf[12];
    // if(rxHeader.water == temp&&rxHeader.id == 0x8F04)return;   //
    // if(rxHeader.water == temp)return;   //
    rxHeader.water = temp;
    debugLog("平台下发数据:Id: 0X%04X,平台流水号:%d,长度:%d.\n",rxHeader.id,rxHeader.water,jt808.rxLen);  //This code just for testing        
    ec800.relinkTimes = 0;   //reset times clear.
    switch(rxHeader.id )
    {
        case 0x8001: //通用应答
        {            
            if(jt808.rxBodyLen < 5) break;//5为消息体最小长度限制            
            jt808.ackWater =     ((*jt808.rxBodyP)<<8) +*(jt808.rxBodyP+1); 
            jt808.ackId = ((*(jt808.rxBodyP+2))<<8) +*(jt808.rxBodyP+3); 
            jt808.ackResult = *(jt808.rxBodyP+4);//            
            debugLog("通用应答子Id:0x%04x,本地流水号:%d.\n",jt808.ackId,jt808.ackWater);  //This code just for testing            
            switch(jt808.ackId)
            {
                case 0x0102://authentication ack
                {            
                    jt808.ackFlag  = OK;  //        
                    jt808.authFlag = OK; //authentication flag ok.        
                    // if(jt808.debug)debugLog("JT808 authentication ack ok.\n");  //This code just for testing        
                    break;
                }
                case 0x0003://注销应答
                {
                    break;
                }
                case 0x0002://心跳 bodyP[4]应答结果,//0:成功/确认;1:失败;2:消息有误;3:不支持;4:报警处理确认;
                {
                    jt808.ackFlag = OK;  //        
                    jt808.heartbeatAckFlag = OK;            
                    // if(jt808.debug) debugLog("JT808 heartbeat ack ok.\r\n"); //This code just for test.Edit by kevin.        
                    break;
                }
                case 0x0107://终端属性查询.
                {
                    jt808.ackFlag = OK;  //        
                    break;
                }    
                case 0x0200://位置应答
                {
                    jt808.ackFlag = OK;  //            
                    jt808.positionAckFlag = TRUE;    
                    // u32 tempDelayTime = 10;
                    // if(Parm.currentMode == WORK_MODE_0)  //0模式省电控制。
                    // { 
                    //     if (Sleep.workTime>tempDelayTime && Gps.locationMode != FALSE)
                    //     {
                    //         Sleep.workTime = tempDelayTime;   //发送完成位置数据包,XX秒后进入休眠。
                    //         debugLog("GPS定位成功,位置上报完成,系统%d秒后进入低功耗模式。\r\n",tempDelayTime);            
                    //     }        
                    //     ec800.lowPowerFlag = TRUE;                                                
                    //   debugLog("成功上报位置,设置4G进入低功耗,系统准备进入休眠。\n");                
                    // }
                    break;
                }                
                case 0x0201://位置信息查询应答的应答
                {
                    break;
                }
                case 0x0704://盲区应答
                {
                    break;    
                }
                case 0x0900://透传应答
                {
          jt808.ackFlag = OK;  //            
                    break;    
                }
                case 0x0FB1:
                {
                    break;
                }
                case 0x0FB2:
                {
                    break;
                }        
                default:break;
            }
            break;
        }
        case 0x8003://服务器重传分包请求
      {
            //u8 rc = jt_server_retran_pack_request(pbody, body_len);
            break;
      }        
        case 0x8100: //login ack.
        {
            char authCode[11];
            jt808.ackWater =     ((*jt808.rxBodyP)<<8) +*(jt808.rxBodyP+1); 
            jt808.ackResult = *(jt808.rxBodyP+2);//0:成功 1:车辆已被注册;2:数据库中无该车辆;3:终端已被注册;4:数据库中无该终端 
            if(jt808.ackResult == 0)
            {
            jt808.ackFlag = OK;  //
            memcpy(authCode,jt808.rxBodyP+3,11);    //copy the authentication code
            jt808.loginFlag = OK;
            u8 * parmP = (u8 *)(&Parm);  //获取参数结构体地址。
            w25qxxRead(parmP,PARAMETER_ADDR,sizeof(Parm)); //read back the flash parameter.
            Parm.jt808LoginFlag = TRUE;
            memcpy(Parm.authCode,authCode,11);    
            w25qxxWrite(parmP,PARAMETER_ADDR,sizeof(Parm));  //Write system parameters to FLASH.
            if(jt808.debug)  //jt808 rxBuf
            {
                u16 i=0;
                debugLog("The authentication code:\n");
                for(i=0;i<11;i++)
                {
                    printf("0x%0.2x,",Parm.authCode[i]);
                }
                printf("\n");                
            }    
            jt808.ackFlag = OK;  //            
            // if(jt808.debug)debugLog("JT808 login ok.\n");  //This code just for testing    
            }
          break;
        }
        // case 0x8102: //authentication ack
        // {                
        //     break;
        // }         
        // case 0x8103://设置终端参数
        // {

        //     jt808.ackResult = 0;
        //     tAckBody.waterNumber = rxHeader.water;
        //     tAckBody.id = rxHeader.id;
        //     tAckBody.result = 0x00;
        //     jt808.ackSendFlag = TRUE;
        //     txHeader.id = T_ACK_ID;        //终端通用应答                
        //     break;
        // }        
        case 0x8104://查询终端参数
        {            
            // jt808.ackSendFlag = TRUE;
            // txHeader.id = T_INQUIRE_ACK;      //Terminal inquire ack.

            jt808.ackResult = 0;
            tAckBody.waterNumber = rxHeader.water;
            tAckBody.id = rxHeader.id;
            tAckBody.result = 0x00;
            jt808.ackSendFlag = TRUE;
            txHeader.id = T_INQUIRE_ACK;        //终端属性查询应答
            break;
        }        
        case 0x8105://终端控制
        {            
            u16 len = 0;
            u8 command = jt808.rxBodyP[len++];
            switch(command)
            {
                case 0x01:
                {
                    break;
                }
                case 0x02:
                {                    
                    break;
                }
                case 0x03: //终端关机
                {
                    if(jt808.debug)debugLog("Shut down the divice?????????????????????????????????????????????????????????????????????????.\n");                    
                    break;
                }
                case 0x04: //终端复位
                {
                    Device.reset = TRUE;    
                    debugLog("收到平台重启指令,系统准备重启.\n");                    
                    break;
                }
                case 0x05:
                {
                    if(jt808.debug)debugLog("Factory data reset ?????????????????????????????????????????????????????????????????????????.\n");        
                    break;
                }
                case 0x06:
                {                    
                    break;
                }
                case 0x07:
                {                    
                    break;
                }
                case 0x08:
                {                    
                    break;
                }
                case 0x09:
                {                    
                    break;
                }
                case 0x64:
                {                    
                    break;
                }
                case 0x65:
                {                    
                    break;
                }
                case 0x66:
                {                    
                    break;
                }
                case 0x67:
                {                    
                    break;
                }
                default:break;
            }
            jt808.ackResult = 0;
            tAckBody.waterNumber = rxHeader.water;
            tAckBody.id = rxHeader.id;
            tAckBody.result = 0x00;
            jt808.ackSendFlag = TRUE;
            txHeader.id = T_ACK_ID;        //终端通用应答
            break;
        }        

        // case 0x8106://查询指定终端参数
        // {
        //     break;
        // }    

        case 0x8107://查询终端属性
        {
            jt808.ackResult = 0;
            tAckBody.waterNumber = rxHeader.water;
            tAckBody.id = rxHeader.id;
            tAckBody.result = 0x00;
            jt808.ackSendFlag = TRUE;
            txHeader.id = T_ATTR_ACK_ID;        //终端属性查询应答

            jt808.ackFlag  = OK;  //    

            break;
        }

        // case 0x8108://下发终端升级指令
        // {
        //     break;
        // }    

        case 0x8201://位置信息查询
        {
            jt808.callNameFlag = TRUE;
            jt808.alarmFlag = TRUE;

            jt808.ackResult = 0;  //回复平台通用应答。
            tAckBody.waterNumber = rxHeader.water;
            tAckBody.id = rxHeader.id;
            tAckBody.result = 0x00;
            jt808.ackSendFlag = TRUE;
            txHeader.id = T_ACK_ID;    
            break;
        }        
        // case 0x8202://临时位置跟踪控制
        // {            

        //     break;
        // }
        case 0x8300: //文本下发
        {
            // char textBuf[128];
            if(jt808.rxBodyLen<=128)
            {
                text.type = *jt808.rxBodyP;    
                text.len = jt808.rxBodyLen-1;    
                memcpy(text.buf,jt808.rxBodyP+1,text.len);    //copy the data to buf        
                // zrdCommand.rxOkFlag = OK;        //
                // zrdCommand.rxLen = text.len;                
                // memcpy(zrdCommand.rxBuf,text.buf,text.len);    //copy the data to buf
                // if(jt808.atDebug)  //如果是AT debug模式,则在LOG口输出平台AT指令。
                // {
                //     debugLog("JT808 at: %s\n",text.buf);
                // }
                zrdAtCmdParser((char*)text.buf,text.len);
            }            
            // jt808.ackSendFlag = TRUE;
            // txHeader.id = TEXT_ACK_ID;      //
            jt808.ackResult = 0;
            tAckBody.waterNumber = rxHeader.water;
            tAckBody.id = rxHeader.id;
            tAckBody.result = 0x00;
            jt808.ackSendFlag = TRUE;
            txHeader.id = T_ACK_ID;     
            break;
        }        
        case 0x8301://事件设置
        {
            break;
        }
        case 0x8E00://终端校时应答
        {                
            rtc.setDate = 1; //设置RTC 日期
            rtc.setTime = 1; //设置RTC 时间            
            rtcSetData.Year    = (*(jt808.rxBodyP+2+0)>>4)*10+(*(jt808.rxBodyP+2+0)&0x0f);
            rtcSetData.Month   = (*(jt808.rxBodyP+2+1)>>4)*10+(*(jt808.rxBodyP+2+1)&0x0f);
            rtcSetData.Date    = (*(jt808.rxBodyP+2+2)>>4)*10+(*(jt808.rxBodyP+2+2)&0x0f);            
            rtcSetTime.Hours   = (*(jt808.rxBodyP+2+3)>>4)*10+(*(jt808.rxBodyP+2+3)&0x0f);                
            rtcSetTime.Minutes = (*(jt808.rxBodyP+2+4)>>4)*10+(*(jt808.rxBodyP+2+4)&0x0f);
            rtcSetTime.Seconds = (*(jt808.rxBodyP+2+5)>>4)*10+(*(jt808.rxBodyP+2+5)&0x0f);
            debugLog("RTC网络校时:%02d/%02d/%02d,%02d:%02d:%02d.\n",rtcSetData.Year,rtcSetData.Month,rtcSetData.Date,rtcSetTime.Hours,rtcSetTime.Minutes,rtcSetTime.Seconds);                
            rtcDeal();  //RTC处理
            getRtc(); //获取RTC时间
            jt808.ntpFlag = TRUE;  //网络校时OK标志。
            jt808.ackFlag = OK;  //
            break;
        }
        case 0x8E01://平台校时
        {
            rtc.setDate = 1; //设置RTC 日期
            rtc.setTime = 1; //设置RTC 时间            
            rtcSetData.Year    = (*(jt808.rxBodyP+2+0)>>4)*10+(*(jt808.rxBodyP+2+0)&0x0f);
            rtcSetData.Month   = (*(jt808.rxBodyP+2+1)>>4)*10+(*(jt808.rxBodyP+2+1)&0x0f);
            rtcSetData.Date    = (*(jt808.rxBodyP+2+2)>>4)*10+(*(jt808.rxBodyP+2+2)&0x0f);            
            rtcSetTime.Hours   = (*(jt808.rxBodyP+2+3)>>4)*10+(*(jt808.rxBodyP+2+3)&0x0f);                
            rtcSetTime.Minutes = (*(jt808.rxBodyP+2+4)>>4)*10+(*(jt808.rxBodyP+2+4)&0x0f);
            rtcSetTime.Seconds = (*(jt808.rxBodyP+2+5)>>4)*10+(*(jt808.rxBodyP+2+5)&0x0f);
            debugLog("RTC网络校时:%02d/%02d/%02d,%02d:%02d:%02d.\n",rtcSetData.Year,rtcSetData.Month,rtcSetData.Date,rtcSetTime.Hours,rtcSetTime.Minutes,rtcSetTime.Seconds);                
            rtcDeal();  //RTC处理
            getRtc(); //获取RTC时间
            jt808.ackResult = 0;                    //通用应答数据设置
            tAckBody.waterNumber = rxHeader.water;
            tAckBody.id = rxHeader.id;
            tAckBody.result = 0x00;
            jt808.ackSendFlag = TRUE;
            txHeader.id = T_ACK_ID;                     
            break;
        }
        case 0x8F00://平台对时命令
        {            
            rtc.setDate = 1; //设置RTC 日期
            rtc.setTime = 1; //设置RTC 时间            
            rtcSetData.Year    = (*(jt808.rxBodyP+1)>>4)*10+(*(jt808.rxBodyP+1)&0x0f);
            rtcSetData.Month   = (*(jt808.rxBodyP+2)>>4)*10+(*(jt808.rxBodyP+2)&0x0f);
            rtcSetData.Date    = (*(jt808.rxBodyP+3)>>4)*10+(*(jt808.rxBodyP+3)&0x0f);            
            rtcSetTime.Hours   = (*(jt808.rxBodyP+4)>>4)*10+(*(jt808.rxBodyP+4)&0x0f);                
            rtcSetTime.Minutes = (*(jt808.rxBodyP+5)>>4)*10+(*(jt808.rxBodyP+5)&0x0f);
            rtcSetTime.Seconds = (*(jt808.rxBodyP+6)>>4)*10+(*(jt808.rxBodyP+6)&0x0f);
            debugLog("RTC网络校时:%02d/%02d/%02d,%02d:%02d:%02d.\n",rtcSetData.Year,rtcSetData.Month,rtcSetData.Date,rtcSetTime.Hours,rtcSetTime.Minutes,rtcSetTime.Seconds);                
            rtcDeal();  //RTC处理
            getRtc();     //获取RTC时间    
            jt808.ntpFlag = TRUE;  //网络校时OK标志。
            jt808.ackFlag = OK;                     
            break;
        }
        // case 0x8F04://image display set
        // {
        //     u32 fileId = 0;
        //     u16 tempLen = 0;        
        //     jt808.rxBodyId = jt808.rxBodyP[tempLen++];        
        //     jt808.rxBodyLen = jt808.rxBodyP[tempLen++];        
        //     fileId |= jt808.rxBodyP[tempLen++]<<24;
        //     fileId |= jt808.rxBodyP[tempLen++]<<16;
        //     fileId |= jt808.rxBodyP[tempLen++]<<8;
        //     fileId |= jt808.rxBodyP[tempLen++];
        //     for(u8 i = 0;i<7;i++)
        //     {
        //         if(Parm.image.fileId[i] == fileId)
        //         {                    
        //             epd.currentImage = i;    
        //             epd.lastImage = i+1;    
        //             break;                
        //         }
        //     }
        //     if(jt808.debug)
        //     {
        //         debugLog("Parm.image.fileId[0] = %08X.\n",Parm.image.fileId[0]);            //This code just for testing.    
        //         debugLog("Parm.image.fileId[1] = %08X.\n",Parm.image.fileId[1]);            //This code just for testing.    
        //         debugLog("Parm.image.fileId[2] = %08X.\n",Parm.image.fileId[2]);            //This code just for testing.    
        //         debugLog("Parm.image.fileId[3] = %08X.\n",Parm.image.fileId[3]);            //This code just for testing.    
        //         debugLog("Parm.image.fileId[4] = %08X.\n",Parm.image.fileId[4]);            //This code just for testing.    
        //         debugLog("Parm.image.fileId[5] = %08X.\n",Parm.image.fileId[5]);            //This code just for testing.    
        //         debugLog("Parm.image.fileId[6] = %08X.\n",Parm.image.fileId[6]);            //This code just for testing.    
        //         debugLog("fileId = %08X.\n",fileId);            //This code just for testing.    
        //     }    
        //     u8 * parmP = (u8 *)(&Parm);  //获取参数结构体地址。
        //     w25qxxRead(parmP,PARAMETER_ADDR,sizeof(Parm)); //w25qxxRead(u8* pBuffer,u32 ReadAddr,u16 NumByteToRead)                         
        //     Parm.image.currentNum = epd.currentImage;            
        //     w25qxxWrite(parmP,PARAMETER_ADDR,sizeof(Parm));  //Write system parameters to FLASH.        
        //     jt808.ackResult = 0;
        //     tAckBody.waterNumber = rxHeader.water;
        //     tAckBody.id = rxHeader.id;
        //     tAckBody.result = 0x00;
          //   jt808.ackSendFlag = TRUE;
        //     txHeader.id = T_ACK_ID;     
        //     break;
        // }    
        // case 0x8F05://image file data
        // {
        //     u16 tempLen = 0;
        //     static u16 preNumber = 0;
        //     file.id = 0;
        //     file.id |= jt808.rxBodyP[tempLen++]<<24;
        //     file.id |= jt808.rxBodyP[tempLen++]<<16;
        //     file.id |= jt808.rxBodyP[tempLen++]<<8;
        //     file.id |= jt808.rxBodyP[tempLen++];
        //     file.type = jt808.rxBodyP[tempLen++];
        //     file.format = jt808.rxBodyP[tempLen++];
        //     file.compressType = jt808.rxBodyP[tempLen++];
        //     file.storageNum = jt808.rxBodyP[tempLen++];
        //     file.totalNum = 0;
        //     file.totalNum |= jt808.rxBodyP[tempLen++]<<8;
        //     file.totalNum |= jt808.rxBodyP[tempLen++];
        //     file.currentNum = 0;
        //     file.currentNum |= jt808.rxBodyP[tempLen++]<<8;
        //     file.currentNum |= jt808.rxBodyP[tempLen++];
        //     file.packageLen = 0;
        //     file.packageLen |= jt808.rxBodyP[tempLen++]<<8;
        //     file.packageLen |= jt808.rxBodyP[tempLen++];
        //   file.fileRxFlag = TRUE;
        //     file.timeOut = 0;
        //     memcpy(file.data,&jt808.rxBodyP[tempLen],file.packageLen);    //copy the data to buf
        //     if(jt808.debug) debugLog("File data file.totalNum = %d,file.currentNum = %d.\n",file.totalNum,file.currentNum);    
        //     if(file.type == 0) //image file
        //     {
        //         if(file.currentNum == 1) //The first package of data processing
        //         {
        //             w25qxx.len=0;          //flash buf data length.
        //             w25qxx.packageNum = 0; //flash buf data package number.
        //             preNumber = file.currentNum;
        //             rleDecode(file.data,file.packageLen,file.storageNum);//将数据解压并存储到FLASH芯片。
        //         }                    
        //         if((file.currentNum < file.totalNum) &&(preNumber+1 == file.currentNum))
        //         // else if(file.currentNum < file.totalNum)
        //         {
        //             preNumber = file.currentNum;
        //             rleDecode(file.data,file.packageLen,file.storageNum);//将数据解压并存储到FLASH芯片。                    
        //         }    
        //     else if(file.currentNum == file.totalNum) //最后一包数据处理
        //         {
        //             rleDecode(file.data,file.packageLen,file.storageNum);//将数据解压并存储到FLASH芯片。
        //             debugLog("The complete file data was received.\n");                
        //             u8 * parmP = (u8 *)(&Parm);  //获取参数结构体地址。
        //             u8 temp = 0;
        //             w25qxxRead(parmP,PARAMETER_ADDR,sizeof(Parm)); //w25qxxRead(u8* pBuffer,u32 ReadAddr,u16 NumByteToRead)             
        //             Parm.image.fileId[file.storageNum] = file.id;  //存储图片名称.
        //             //Parm.image.imageFlag |= 1<<imageNum;  //
        //             for(int i = 0;i<IMAGE_MAX_NUM;i++)
        //             {
        //                 if(Parm.image.fileId[i] != 0xFFFFFFFF) 
        //                 {
        //                     temp++;
        //                 }
        //             }
        //             Parm.image.totalNum = temp; //计算图片总数量。
        //             Parm.image.currentNum = file.storageNum;
        //             epd.currentImage = Parm.image.currentNum;
        //             epd.lastImage =     epd.currentImage+1;
        //             w25qxxWrite(parmP,PARAMETER_ADDR,sizeof(Parm));  //Write system parameters to FLASH.
        //             debugLog("Parm.image.fileId[0] = %08X.\n",Parm.image.fileId[0]);            //This code just for testing.    
        //             debugLog("Parm.image.fileId[1] = %08X.\n",Parm.image.fileId[1]);            //This code just for testing.    
        //             debugLog("Parm.image.fileId[2] = %08X.\n",Parm.image.fileId[2]);            //This code just for testing.    
        //             debugLog("Parm.image.fileId[3] = %08X.\n",Parm.image.fileId[3]);            //This code just for testing.    
        //             debugLog("Parm.image.fileId[4] = %08X.\n",Parm.image.fileId[4]);            //This code just for testing.    
        //             debugLog("Parm.image.fileId[5] = %08X.\n",Parm.image.fileId[5]);            //This code just for testing.    
        //             debugLog("Parm.image.fileId[6] = %08X.\n",Parm.image.fileId[6]);            //This code just for testing.    
        //             debugLog("Parm.image.totalNum = %08X.\n",Parm.image.totalNum);              //
        //             debugLog("Parm.image.currentNum = %08X.\n",Parm.image.currentNum);      //                    
        //             file.fileRxFlag = FALSE;  //图片接收完成,清除接收标志。    
        //             debugLog("The lash w25qxx.packageNum = %d, length = %d.\n",w25qxx.packageNum,w25qxx.len);
        //             preNumber = 0;
        //         }    
        //         if(file.currentNum > file.totalNum) 
        //         {
        //             debugLog("The image package is wrong.\n");
        //             file.fileRxFlag = FALSE;  //图片接收完成,清除接收标志。    
        //             preNumber = 0;
        //         }                    
        //     }
        //     jt808.ackResult = 0;
        //     txHeader.id = FILE_ACK_ID;
        //     jt808.ackSendFlag = TRUE;     
        //     break;
        // }    
        // case 0x8FB0://安全认证下行消息
        // {   
        //     break;
        // }        
        // case 0x8FB3://终端配置参数下发
        // {
        //     break;
        // }                    
        default:
        {
            // jt808.ackResult = 0;
            // tAckBody.waterNumber = rxHeader.water;
            // tAckBody.id = rxHeader.id;
            // tAckBody.result = 0x00;
            // jt808.ackSendFlag = TRUE;
            // txHeader.id = T_ACK_ID;        //终端通用应答
             break;    
        }    
    }
}
void packageJt808TxBuf(char* txBuf,u16 * pLen) //By message ID ,package the jt808.txBuf data.
{
    u16 len = 0;    
    u16 tempLen = 0;  //用于计算消息体长度。
    if (Power.lowPowerFlag == TRUE) return;//低压禁止,防止流水号变更。    
    txBuf[len++] = 0x7e;   //header
    txBuf[len++] = txHeader.id>>8;  //message header ID
    txBuf[len++] = txHeader.id;
    txHeader.attr = 0;  //Package the message body , assign the value of txHeader.attr into the txBuf[3]and txBuf[4].    
    txBuf[len++] = txHeader.attr>>8; //message body attribute:subpackage、encryption、length of message body.
    txBuf[len++] = txHeader.attr;
    if (Parm.imeiFlag==0)
    {
        for(int i = 0;i<6;i++) //12 cell phone number,BCD[6]:6 byte BCD code,The twelfth digit must be 0.
        {
            txBuf[len+i] = (ec800.imei[3+2*i]<<4)+(ec800.imei[3+2*i+1]&0x0f);        //Skip ec800.emei[0]、ec800.imei[1]、ec800.imei[2]                
        }
        txBuf[len] &= 0x0f; //The telphone twelfth digit must be 0。
        len = len+6;
    }
    else
    {
        txBuf[len++] = (Parm.imei[0]&0x0f);        //
        for(int i = 0;i<5;i++) //12 cell phone number,BCD[6]:6 byte BCD code,The twelfth digit must be 0.
        {
            txBuf[len+i] = (Parm.imei[1+2*i]<<4)+(Parm.imei[1+2*i+1]&0x0f);        //Skip Parm.emei[0]        
        }    
        len = len+5;
    }    
    txBuf[len++] = txHeader.water>>8; //water number  high 8 bit
    txBuf[len++] = txHeader.water;    //流水号低8位   至此 消息头结束,如果分包则增加一个 <封装项> 内容
    txHeader.water++;    
    switch(txHeader.id) //package message body.
    {
        case LOGIN_ID:       //login ID 0x0100.    
        {
            tempLen = len;  //用于计算消息体长度。    
            jt808.provinceId = 913;  //广东
              txBuf[len++] = jt808.provinceId>>8;   //省
              txBuf[len++] = jt808.provinceId;
            jt808.prefectureId = 94;
              txBuf[len++] = jt808.prefectureId>>8;   //市
              txBuf[len++] = jt808.prefectureId;            
            for(int i = 0;i<5;i++)  //manufacturer ID
            {                
                txBuf[len++] = Device.id[i]; 
            }                        
            for(int i = 0;i<20;i++) //terminal mode
            {
                txBuf[len++] = i+0x41;  
            }
            for(int i = 0;i<7;i++) //terminal ID
            {
                txBuf[len++] = i+0x30;  
            }
            txBuf[len++] = 0x01;  //car color.            
            for(int i = 0;i<15;i++) //
            {
                txBuf[len++] = Parm.carNum[i]; //car number
            }        
            if (Parm.imeiFlag == 0)
            {
                for (u16 i = 0; i < 15; i++)  //IMEI 新疆项目
                {
                    txBuf[len++] = ec800.imei[i];
                }
            }
            else  //自主设置模式
            {
                u16 imeiLen = strlen( Parm.imei);
                if (imeiLen<=20)
                {
                    for (u16 i = 0; i < 15; i++)  //IMEI 新疆项目
                    {
                        txBuf[len++] = Parm.imei[i];
                    }
                }                
            }
            for (u8 i = 0; i < 10; i++) //20位ICCID转10位BCD码
            {
                txBuf[len++] = (ascaiiToInt(ec800.iccid[2*i])<<4)+ascaiiToInt(ec800.iccid[2*i+1]);
                // txBuf[len++] = 0;
            }
            txHeader.attr = len - tempLen;     //get the length of  message body.
            txBuf[3] = txHeader.attr>>8; //message body attribute:subpackage、encryption、length of message body.
            txBuf[4] = txHeader.attr;    
            break;        
        }
        case LOGOUT_ID:      //logout ID 0X0003.
        {
            txHeader.attr = 0; //logout: The message body is empty,so the length of message body is 0;
            txBuf[3] = txHeader.attr>>8; //message body attribute:subpackage、encryption、length of message body.
            txBuf[4] = txHeader.attr;
            break;
        }
        case AUTH_ID:        //authentication ID 0X0102.
        {
            tempLen = len;  //用于计算消息体长度。    
          for( int i = 0;i<11;i++)
          {
                txBuf[len++] = Parm.authCode[i];
            }
            txHeader.attr = len - tempLen;     //get the length of  message body.
            txBuf[3] = txHeader.attr>>8; //message body attribute:subpackage、encryption、length of message body.
            txBuf[4] = txHeader.attr;    
          break;
        }
        case NTP_ID: //NTP:network timing protocol 网络校时协议
        case NTP_F_ID:
        {
            txHeader.attr = 0;           //logout: The message body is empty,so the length of message body is 0;
              txBuf[3] = txHeader.attr>>8; //message body attribute:subpackage、encryption、length of message body.
            txBuf[4] = txHeader.attr;
            break;
        }        
        case HEARTBEAT_ID:   //heartbeat ID 0X0002.
        {
            tempLen = len;
            txBuf[len++] = Power.soc; //电池可用电量百分比            
            txBuf[len++] = Power.externVol>>8; //power 0.1V
            txBuf[len++] = Power.externVol;
            txBuf[len++] = ec800.csqH;         //CSQ    
            txBuf[len++] = 0>>8;  //  heartbeatBoy.temperature = 0;
            txBuf[len++] = 0;    
            txBuf[len++] = 0>>8; //  heartbeatBoy.humidity = 0;
            txBuf[len++] = 0;
            txBuf[len++] = Power.chargeFlag;            
            txBuf[len++] = Power.powerSupply; //0:battery supply 1:ertern power -1:invalid
            if (Parm.currentMode == WORK_MODE_0)
            {
                txBuf[len++] = 3;
            }
            else
            {
                txBuf[len++] = Parm.currentMode;
            }            
            txBuf[len++] = Power.voltage;  //
            txBuf[len++] = Sleep.wakeupSourceReport; //唤醒源
            txBuf[len++] = 0xAA;  //reserve data.
            txBuf[len++] = Device.resetRs;  //reserve data.
            txBuf[len++] = 0xAA;  //reserve data.
            txBuf[len++] = 0x01;  //
            txBuf[len++] = 12;   //
            u16 tempValue = adc0.tem*10;
            txBuf[len++] = tempValue>>8;  //cpu temperature 0.1摄氏度.
            txBuf[len++] = tempValue;
            txBuf[len++] = 0>>8;
            txBuf[len++] = 0;
            // heartbeatBoy.tem2 = aht20.tem;         //interior temperature and humidity.
            txBuf[len++] = 0;  
            txBuf[len++] = 0;
              // heartbeatBoy.hum2 = aht20.hum;
            txBuf[len++] = 0;
            txBuf[len++] = 0;
            // heartbeatBoy.tem3 = 0;                //extern temperature and humidity.
            txBuf[len++] = 0>>8;  
            txBuf[len++] = 0;
              // heartbeatBoy.hum3 = 0;
            txBuf[len++] = 0>>8;
            txBuf[len++] = 0;    
            // 附加消息 0XE6 三轴数据.
            txBuf[len++] = 0XE6; //id  //终端ID信息.
            txBuf[len++] = 12; //length of message data.
            txBuf[len++] = rtc.year; //
            txBuf[len++] = rtc.month; //
            txBuf[len++] = rtc.date; //
            txBuf[len++] = rtc.hours; //
            txBuf[len++] = rtc.minutes; //
            txBuf[len++] = rtc.seconds; //
            txBuf[len++] = da215.maxX>>8;
            txBuf[len++] = da215.maxX;
            txBuf[len++] = da215.maxY>>8;
            txBuf[len++] = da215.maxY;
            txBuf[len++] = da215.maxZ>>8;
            txBuf[len++] = da215.maxZ;
            txHeader.attr = len - tempLen;     //get the length of  message body.
            txBuf[3] = txHeader.attr>>8; //message body attribute:subpackage、encryption、length of message body.
            txBuf[4] = txHeader.attr;        
          break;            
        }
        case POSITION_ID:   //position report ID 0X0200.
        case CALL_NAME_ID:   //
        {
            tempLen = len;
            // txHeader.attr = sizeof(positionBody); //get the length of  message body.若考虑分包则增加操作
            // txBuf[3] = txHeader.attr>>8; //message body attribute:subpackage、encryption、length of message body.
            // txBuf[4] = txHeader.attr;

              //alarm bit
            positionAlarm.Bit00 = 0;
            positionAlarm.Bit01 = 0;
            positionAlarm.Bit02 = 0;
            positionAlarm.Bit03 = 0;
            positionAlarm.Bit04 = 0;
            positionAlarm.Bit05 = 0;
            positionAlarm.Bit06 = 0;
            if (obd.exLowPowerAlarm == TRUE) //obd外电低电压报警.
            {
                positionAlarm.Bit07 = TRUE;
            }
            else
            {
                positionAlarm.Bit07 = FALSE;
            }
              if (Power.powerDownFlag == TRUE) //battery power down.
            {
                positionAlarm.Bit08 = TRUE;
            }
            else
            {
                positionAlarm.Bit08 = FALSE;
            }
            positionAlarm.Bit09 = 0;
            positionAlarm.Bit10 = 0;
            positionAlarm.Bit11 = 0;
            positionAlarm.Bit12 = 0;
            positionAlarm.Bit13 = 0;
            positionAlarm.Bit14 = 0;
            if (da215.vibrateAlarmFlag == TRUE) //vibrate alarm. 
            {
                positionAlarm.Bit15 = TRUE;
            }
            else
            {
                positionAlarm.Bit15 = FALSE;
            }
              if(light.lightBackFlag == LIGHT)
            {
                positionAlarm.Bit16 = 1;
            }
            else
            {
                positionAlarm.Bit16 = 0;
            }            
            positionAlarm.Bit17 = 0;
              positionAlarm.Bit18 = 0;
            positionAlarm.Bit19 = 0;
            positionAlarm.Bit20 = 0;
            positionAlarm.Bit21 = 0;
            positionAlarm.Bit22 = 0;
            positionAlarm.Bit23 = 0;
            positionAlarm.Bit24 = 0;
            positionAlarm.Bit25 = 0;
            positionAlarm.Bit26 = 0;
            positionAlarm.Bit27 = 0;
              positionAlarm.Bit28 = 0;
            positionAlarm.Bit29 = 0;
            if(da215.rolloverFlag == TRUE)
            {
                positionAlarm.Bit30 = TRUE;   // 侧翻报警
                da215.rolloverFlag = FALSE;
            }
            else
            {
                positionAlarm.Bit30 = FALSE;   //
            }            
            positionAlarm.Bit31 = 0;
            u8 * tempPointer = (u8*) (&positionAlarm);                                                      //测试:默认soc = 100 0x64 This code just for testing.
            txBuf[len++] = *(tempPointer); //
            txBuf[len++] = *(tempPointer+1);
            txBuf[len++] = *(tempPointer+2);
            txBuf[len++] = *(tempPointer+3);
             //status bit             
            if(da215.vibrateFlag == TRUE) //0:ACC 关;1:ACC 开
            {
                positionStatus.Bit00 = 1; //0:ACC 关;1:ACC 开
            }
            else
            {
                positionStatus.Bit00 = 0; //0:ACC 关;1:ACC 开
            }
            // positionStatus.Bit01 = 0; //0:未定位;1:定位
            // positionStatus.Bit02 = 0; //0:北纬;1:南纬
            // positionStatus.Bit03 = 0; //0:东经;1:西经
            if(Gps.locationMode == 0) //未定位
            {
                positionStatus.Bit01 = 0;
            }
            else
            {
                positionStatus.Bit01 = 1; //定位
            }
            if(Gps.ns == 'N')  // N S 
            {
                positionStatus.Bit02 = 0;
            }
            else
            {
                positionStatus.Bit02 = 1;
            }
            if(Gps.ew == 'E')  //E W
            {
                positionStatus.Bit03 = 0;
            }
            else
            {
                positionStatus.Bit03 = 1;
            } 
            positionStatus.Bit04 = 0; //
            positionStatus.Bit05 = 0; //
            positionStatus.Bit06 = 0; //
            positionStatus.Bit07 = 0; //
              positionStatus.Bit08 = 0; //
            positionStatus.Bit09 = 0; //
            positionStatus.Bit10 = 0; //
            positionStatus.Bit11 = 0; //其他产品主电源掉电报警。
            positionStatus.Bit12 = 0; //
            positionStatus.Bit13 = 0; //
            positionStatus.Bit14 = 0; //
            positionStatus.Bit15 = 0; //      
            positionStatus.Bit16 = 0; //
            positionStatus.Bit17 = 0; //
             positionStatus.Bit18 = 0; //
            positionStatus.Bit19 = 0; //
            positionStatus.Bit20 = 0; //
            positionStatus.Bit21 = 0; //
            positionStatus.Bit22 = 0; //
            if(Power.chargeFlag == TRUE && Power.externPowerFlag == TRUE) //battery charge status.
            {                
                positionStatus.Bit23 = 1; //
            }
            else
            {                
                positionStatus.Bit23 = 0; //
            }            
            // positionStatus.Bit23 = 0; //
              // if(lock.status == OPEN)
            // {
            //     positionStatus.Bit24 = 0; //
            // }
            // else
            // {
            //     positionStatus.Bit24 = 1; //
            // }            
            positionStatus.Bit25 = 0; //
            positionStatus.Bit26 = 0; //
            positionStatus.Bit27 = 0; //
              positionStatus.Bit28 = 0; //
            positionStatus.Bit29 = 0; //
            positionStatus.Bit30 = 0; //
            positionStatus.Bit31 = 0; //        
            tempPointer = (u8*) (&positionStatus);   //位置数据包,32BIT状态信息。
            txBuf[len++] = *(tempPointer); //
            txBuf[len++] = *(tempPointer+1);
            txBuf[len++] = *(tempPointer+2);
            txBuf[len++] = *(tempPointer+3);            
            // positionBody.latitude = Gps.mapLatitude; //纬度
            txBuf[len++] = Gps.mapLatitude>>24; //
            txBuf[len++] = Gps.mapLatitude>>16;
            txBuf[len++] = Gps.mapLatitude>>8;
            txBuf[len++] = Gps.mapLatitude;
            // positionBody.longitude = Gps.mapLongitude; //经度
            txBuf[len++] = Gps.mapLongitude>>24; //
            txBuf[len++] = Gps.mapLongitude>>16;
            txBuf[len++] = Gps.mapLongitude>>8;
            txBuf[len++] = Gps.mapLongitude;
            u16 msl = Gps.msl; //高度
            txBuf[len++] = msl>>8;
            txBuf[len++] = msl;
            u16 speed = Gps.gnrmcSpeed; //速度
            txBuf[len++] = speed>>8;
            txBuf[len++] = speed;
            u16 direction = Gps.gnrmcOrientation; //方向
            txBuf[len++] = direction>>8;
            txBuf[len++] = direction;
            u8 year = ((rtc.year/10)<<4)+(rtc.year%10); //转换成BCD码
            txBuf[len++] = year;
            u8 month = ((rtc.month/10)<<4)+(rtc.month%10);
            txBuf[len++] = month;
            u8 day = ((rtc.date/10)<<4)+(rtc.date%10);
            txBuf[len++] = day;
            u8 hour = ((rtc.hours/10)<<4)+(rtc.hours%10);
            txBuf[len++] = hour;
            u8 minute = ((rtc.minutes/10)<<4)+(rtc.minutes%10);
            txBuf[len++] = minute;
            u8 second = ((rtc.seconds/10)<<4)+(rtc.seconds%10);
            txBuf[len++] = second;
            txHeader.attr = len - tempLen;     //get the length of  message body.
            txBuf[3] = txHeader.attr>>8;       //message body attribute:subpackage、encryption、length of message body.
            txBuf[4] = txHeader.attr;        

            // 附加消息 0X21
            txBuf[len++] = 0x21;  //机体温湿度
              txBuf[len++] = 8;
            u16 tempValue = adc0.tem*10;
            txBuf[len++] = tempValue>>8;  //cpu temperature 0.1摄氏度.
            txBuf[len++] = tempValue;
              // heartbeatBoy.hum1 = 0;
            txBuf[len++] = 0>>8;
            txBuf[len++] = 0;
            // heartbeatBoy.tem2 = aht20.tem;         //interior temperature and humidity.
            txBuf[len++] = 0>>8;  
            txBuf[len++] = 0;
              // heartbeatBoy.hum2 = aht20.hum;
            txBuf[len++] = 0>>8;
            txBuf[len++] = 0;        

            txBuf[len++] = 0x22;  //附加消息 0X22 外部温湿度
              txBuf[len++] = 4;
            // heartbeatBoy.tem3 = 0;                //extern temperature and humidity.
            txBuf[len++] = 0>>8;  
            txBuf[len++] = 0;
              // heartbeatBoy.hum3 = 0;
            txBuf[len++] = 0>>8;
            txBuf[len++] = 0;

            //附加消息 0X30
            txBuf[len++] = 0x30;  //csq
              txBuf[len++] = 0x01;
              txBuf[len++] = ec800.csqH & 0xff;

            //附加消息 0X31
            txBuf[len++] = 0x31;  //GNSS卫星颗数
              txBuf[len++] = 0x01;
              txBuf[len++] = Gps.satelliteNum;

            //附加消息 0X54:WIFI定位 0X5D:基站定位            
            if(Gps.locationMode == 0)
            {
                if(wifiNum>0)
                {
                    txBuf[len++] = 0X54; //id  WIFI 
                     txBuf[len++] = wifiNum*7+1; //长度
                    txBuf[len++] = wifiNum;     //WIFI数目
                    for(u8 i = 0;i<wifiNum;i++)
                    {
                        txBuf[len++] = wifi[i].buf[0];
                        txBuf[len++] = wifi[i].buf[1];
                        txBuf[len++] = wifi[i].buf[2];
                        txBuf[len++] = wifi[i].buf[3];
                        txBuf[len++] = wifi[i].buf[4];
                        txBuf[len++] = wifi[i].buf[5];
                        txBuf[len++] = wifi[i].rssi;
                    }                
                }    
                if(bs.state == TRUE) //base station data
                {
                    txBuf[len++] = 0X5D;             //base station data 
                     txBuf[len++] = 1+10+10*bsNbNum;  //附加信息长度 基站数目+本小区数据长度+邻居小区数据长度
                    txBuf[len++] = 0x01+bsNbNum;     //小区基站个数+bsNbNum(邻居小区基站数目)
                    txBuf[len++]=(bs.mcc >> 8) &0xff;//本小区基站数据
                    txBuf[len++]= bs.mcc & 0xff;    
                    txBuf[len++]=bs.mnc & 0xff;                    
                    txBuf[len++] = (bs.lac >> 8) & 0xff;
                    txBuf[len++] =  bs.lac &0xff;                    
                    txBuf[len++] = (bs.cellId >> 24) & 0xff;
                    txBuf[len++] = (bs.cellId >> 16) & 0xff;
                    txBuf[len++] = (bs.cellId >> 8) & 0xff;
                    txBuf[len++] =  bs.cellId &0xff;
                    txBuf[len++] = bs.rxlev;
                    for (u8 i = 0; i < bsNbNum; i++) //邻居小区基站信息
                    {
                        txBuf[len++]=(bsNb[i].mcc >> 8) &0xff;
                        txBuf[len++]= bsNb[i].mcc & 0xff;    
                        txBuf[len++]=bsNb[i].mnc & 0xff;                        
                        txBuf[len++] = (bsNb[i].lac >> 8) & 0xff;
                        txBuf[len++] =  bsNb[i].lac &0xff;                        
                        txBuf[len++] = (bsNb[i].cellId >> 24) & 0xff;
                        txBuf[len++] = (bsNb[i].cellId >> 16) & 0xff;
                        txBuf[len++] = (bsNb[i].cellId >> 8) & 0xff;
                        txBuf[len++] =  bsNb[i].cellId &0xff;
                        txBuf[len++] = bsNb[i].rxlev;
                    }                
                }            
            }
            wifiNum = 0;        //清零WIFI热点数目,以防下次传输历史数据.
            bsNbNum = 0;        //清零邻居小区基站数目
            bs.state = FALSE;

            //附加消息 0X56
            txBuf[len++] = 0X56; //id  //电池电量扩展
            txBuf[len++] = 0X02; //长度    
            txBuf[len++] = Power.soc; //
            txBuf[len++] = Power.voltage; //    
      
            //VIN码上报
            txBuf[len++] = 0XAB; //id  
            txBuf[len++] = 18+5; //长度     OBD状态(5)+vin码(18)结构体
            txBuf[len++] = 0x01;  //行车数据项ID 0X01:OBD状态标志位,4字节
            txBuf[len++] = 4;     //数据项长度
              obdStatusBits.Bit00 = 0;
            obdStatusBits.Bit01 = 0;
            if (obd.readFlag == TRUE)   
            {
                obdStatusBits.Bit02 = 1;  //读取
            }
            else
            {
                obdStatusBits.Bit02 = 0; //缓存
            }        
            obd.readFlag = FALSE;    
            obdStatusBits.Bit03 = 0;
            obdStatusBits.Bit04 = 0;
            obdStatusBits.Bit05 = 0;
            obdStatusBits.Bit06 = 0;
            obdStatusBits.Bit07 = 0;
            obdStatusBits.Bit08 = 0;
            obdStatusBits.Bit09 = 0;
            obdStatusBits.Bit10 = 0;
            obdStatusBits.Bit11 = 0;
            obdStatusBits.Bit12 = 0;
            obdStatusBits.Bit13 = 0;
            obdStatusBits.Bit14 = 0;
            obdStatusBits.Bit15 = 0;
            obdStatusBits.Bit16 = 0;
            obdStatusBits.Bit17 = 0;
            obdStatusBits.Bit18 = 0;
            obdStatusBits.Bit19 = 0;
            obdStatusBits.Bit20 = 0;
            obdStatusBits.Bit21 = 0;
            obdStatusBits.Bit22 = 0;
            obdStatusBits.Bit23 = 0;
            obdStatusBits.Bit24 = 0;
            obdStatusBits.Bit25 = 0;
            obdStatusBits.Bit26 = 0;
            obdStatusBits.Bit27 = 0;
            obdStatusBits.Bit28 = 0;
            obdStatusBits.Bit29 = 0;
            obdStatusBits.Bit30 = 0;
            obdStatusBits.Bit31 = 0;
            tempPointer = (u8*) (&obdStatusBits);   
            txBuf[len++] = *(tempPointer); //
            txBuf[len++] = *(tempPointer+1);
            txBuf[len++] = *(tempPointer+2);
            txBuf[len++] = *(tempPointer+3);
            txBuf[len++] = 0xF7; //行车数据项ID 0XF7:汽车VIN码 17字节
            txBuf[len++] = 17;   //数据项长度
            for (u8 i = 0; i < 17; i++)  //17字节VIN码
            {
                txBuf[len++] = obd.vinCodeBuf[i];
                // txBuf[len++] = 0x41+i;
            } 

            //附加消息 0XAD
            txBuf[len++] = 0XAD; //id  //外电电压扩展
            txBuf[len++] = 0X02; //长度    
            txBuf[len++] = Power.externVol>>8; //
            txBuf[len++] = Power.externVol; //    

            //运动时长     
            txBuf[len++] = 0XE1; //id  运动时长
            txBuf[len++] = 0X04; //附加数据长度
            if (da215.motionSeconds>Parm.wkMode[Parm.currentMode].positionReportTimeLimit-15)  //舍弃小于15秒的静止时间。
            {            
                da215.motionSeconds = Parm.wkMode[Parm.currentMode].positionReportTimeLimit;                
            }
            txBuf[len++] = da215.motionSeconds>>24; //
            txBuf[len++] = da215.motionSeconds>>16;
            txBuf[len++] = da215.motionSeconds>>8;
            txBuf[len++] = da215.motionSeconds;

            // txBuf[len++] = 0XE2; //id  静止时长
            // txBuf[len++] = 0X04; //附加数据长度
            // txBuf[len++] = da215.motionlessSeconds>>24; // Parm.wkMode[Parm.currentMode].positionReportTimeLimit
            // txBuf[len++] = da215.motionlessSeconds>>16;
            // txBuf[len++] = da215.motionlessSeconds>>8;
            // txBuf[len++] = da215.motionlessSeconds;
            txBuf[len++] = 0XE2; //id  静止时长
            txBuf[len++] = 0X04; //附加数据长度
            if (da215.motionSeconds+da215.motionlessSeconds>Parm.wkMode[Parm.currentMode].positionReportTimeLimit-10)
            {
                txBuf[len++] = (Parm.wkMode[Parm.currentMode].positionReportTimeLimit-da215.motionSeconds)>>24; // Parm.wkMode[Parm.currentMode].positionReportTimeLimit
                txBuf[len++] = (Parm.wkMode[Parm.currentMode].positionReportTimeLimit-da215.motionSeconds)>>16;
                txBuf[len++] = (Parm.wkMode[Parm.currentMode].positionReportTimeLimit-da215.motionSeconds)>>8;
                txBuf[len++] = (Parm.wkMode[Parm.currentMode].positionReportTimeLimit-da215.motionSeconds);
            }
            else
            {
                txBuf[len++] = da215.motionlessSeconds>>24; //
                txBuf[len++] = da215.motionlessSeconds>>16;
                txBuf[len++] = da215.motionlessSeconds>>8;
                txBuf[len++] = da215.motionlessSeconds;
            }            

            txBuf[len++] = 0XE3; //
            txBuf[len++] = 0X01; //附加数据长度
              // txBuf[len++] = da215.vibrateReportFlag;    //上报震动状态。
            if (da215.motionSeconds == 0)
            {
                txBuf[len++] = 0;    //上报震动状态。
            }
            else
            {
                txBuf[len++] = 1;    //上报震动状态。
            }        
            da215.motionSeconds = 0;      //运动秒数
            da215.motionlessSeconds = 0;  //静止秒数        

            //附加消息 0XE5
            txBuf[len++] = 0XE5; //id  //电池及工作模式附加消息
            txBuf[len++] = 0X02; //id
            if (Power.externPowerFlag == TRUE) //外电判断
            {
                txBuf[len++] = 0X01; //外电供电
            }
            else
            {
                txBuf[len++] = 0X00; //电池供电
            }
            if (Parm.currentMode == WORK_MODE_0)  //工作模式上报
            {
                txBuf[len++] = 3;
            }
            else
            {
                txBuf[len++] = Parm.currentMode;
            }        

            // 附加消息 0XE6 三轴数据.
            txBuf[len++] = 0XE6; //id  //终端ID信息.
            txBuf[len++] = 12; //length of message data.
            txBuf[len++] = rtc.year; //
            txBuf[len++] = rtc.month; //
            txBuf[len++] = rtc.date; //
            txBuf[len++] = rtc.hours; //
            txBuf[len++] = rtc.minutes; //
            txBuf[len++] = rtc.seconds; //
            txBuf[len++] = da215.maxX>>8;
            txBuf[len++] = da215.maxX;
            txBuf[len++] = da215.maxY>>8;
            txBuf[len++] = da215.maxY;
            txBuf[len++] = da215.maxZ>>8;
            txBuf[len++] = da215.maxZ;

              //附加消息 0XE6 终端ID信息.
            // txBuf[len++] = 0XE6; //id  //终端ID信息.
            // txBuf[len++] = 20; //length of message data.
            // for(u16 i = 0;i<20;i++)
            // {
            //     txBuf[len++] = ec800.iccid[i];
            // }

            //附加消息 0XE8 报警类型.
            txBuf[len++] = 0XE8; //id  //终端ID信息.
            txBuf[len++] = 1; //length of message data.            
            txBuf[len++] = jt808.alarmNum;
            jt808.alarmNum = 0;            

            // if (jt808.extendAlarmFlag == TRUE) //扩展报警信息
            // {
            jt808.extendAlarmFlag = FALSE; //扩展报警信息
            txBuf[len++] = 0XAE; //id
            txBuf[len++] = 0X04; //id
            //extend alarm bits 
            if (obd.insertFlag == TRUE) 
            {
                extendAlarmBits.Bit00 = 0;
            }
            else
            {
                extendAlarmBits.Bit00 = 1;
            }            
            extendAlarmBits.Bit01 = 0;
            extendAlarmBits.Bit02 = 0;
            extendAlarmBits.Bit03 = 0;
            extendAlarmBits.Bit04 = 0;
            extendAlarmBits.Bit05 = 0;
            extendAlarmBits.Bit06 = 0;
            extendAlarmBits.Bit07 = 0;
            extendAlarmBits.Bit08 = 0;
            if(light.lightFrontFlag == LIGHT)
            {
                // extendAlarmBits.Bit09 = 1;
            }
            else
            {
                extendAlarmBits.Bit09 = 0;
            }                
            extendAlarmBits.Bit10 = 0;
            extendAlarmBits.Bit11 = 0;
            extendAlarmBits.Bit12 = 0;
            extendAlarmBits.Bit13 = 0;
            extendAlarmBits.Bit14 = 0;
            extendAlarmBits.Bit15 = 0;
            extendAlarmBits.Bit16 = 0;
            extendAlarmBits.Bit17 = 0;
            extendAlarmBits.Bit18 = 0;
            extendAlarmBits.Bit19 = 0;
            extendAlarmBits.Bit20 = 0;
            extendAlarmBits.Bit21 = 0;
            extendAlarmBits.Bit22 = 0;
            extendAlarmBits.Bit23 = 0;
            extendAlarmBits.Bit24 = 0;
            extendAlarmBits.Bit25 = 0;
            extendAlarmBits.Bit26 = 0;
            extendAlarmBits.Bit27 = 0;
            extendAlarmBits.Bit28 = 0;
            extendAlarmBits.Bit29 = 0;
            extendAlarmBits.Bit30 = 0;
            extendAlarmBits.Bit31 = 0;
            tempPointer = (u8*) (&extendAlarmBits);   
            txBuf[len++] = *(tempPointer); //
            txBuf[len++] = *(tempPointer+1);
            txBuf[len++] = *(tempPointer+2);
            txBuf[len++] = *(tempPointer+3);
                // txHeader.attr = sizeof(positionBody)+6; //附加消息体不算在主消息体长度里面。
                // txBuf[3] = txHeader.attr>>8; //message body attribute:subpackage、encryption、length of message body.
                // txBuf[4] = txHeader.attr;
            // }                    
          break;            
        }
        case TRANSPARENT_ID: //transparent ID 0X0900.
        {
            switch(jt808.txSubId) //By message bode sub_ID ,package the jt808.txBuf
            {
                case JT808_GERSOR_ID:  //0xB0 three-axis sensor data ID 
                {
                    txHeader.attr = 1+2+6+da215.sampleNumber*6; //get the length of  message body.
              txBuf[3] = txHeader.attr>>8; //message body attribute:subpackage、encryption、length of message body.
            txBuf[4] = txHeader.attr;
                  txBuf[len++] = 0xB0;  //three-axis sensor data ID 
                    u16 tempLen = 6+da215.sampleNumber*6;
                    txBuf[len++] = tempLen>>8; //message body attribute:subpackage、encryption、length of message body.
            txBuf[len++] = tempLen;
                  txBuf[len++] = rtc.year;       //year
                  txBuf[len++] = rtc.month;      //month
                  txBuf[len++] = rtc.date;       //day
                  txBuf[len++] = rtc.hours;      //hours
                  txBuf[len++] = rtc.minutes;    //minutes
                  txBuf[len++] = rtc.seconds;    //seconds        
          for(int i  = 0;i<da215.sampleNumber*6;i++)    
          {
                        txBuf[len++] = da215.data[i];  //package the three-axis sensor data
                    }                        
                    break;
                }                    
                case 1:    break;
                default:break;
            }            
          break;    
        }
        case T_INQUIRE_ACK:  //authentication ID 0X0104.
        {            
            u16 temp = 0;        
            tempLen = len;    
            txHeader.attr = 9;  //get the length of  message body.若考虑分包则增加操作
          txBuf[3] = txHeader.attr>>8;       //message body attribute:subpackage、encryption、length of message body.
        txBuf[4] = txHeader.attr;
          txBuf[len++] = rxHeader.water>>8;        //应该流水号
            txBuf[len++] = rxHeader.water;
            txBuf[len++] = 0x01;    //Parameter number.
            temp = 0x0001;        //终端心跳发送间隔
            txBuf[len++] = temp>>8;        //参数ID
            txBuf[len++] = temp;
            temp = 0x0004;            //参数长度
            txBuf[len++] = temp;
            u32 paramter = Parm.wkMode[Parm.currentMode].heartBeatTimeLimit;
            txBuf[len++] = paramter>>24;    
            txBuf[len++] = paramter>>16;    
            txBuf[len++] = paramter>>8;        //参数
            txBuf[len++] = paramter;
            txHeader.attr = len - tempLen;     //get the length of  message body.
            txBuf[3] = txHeader.attr>>8; //message body attribute:subpackage、encryption、length of message body.
            txBuf[4] = txHeader.attr;        
          break;
        }
        case T_ACK_ID:       //terminal universal ack ID 0X0001.
        {
            txHeader.attr = sizeof(tAckBody); //get the length of  message body.若考虑分包则增加操作
            txBuf[3] = txHeader.attr>>8;     //message body attribute:subpackage、encryption、length of message body.
            txBuf[4] = txHeader.attr;
            txBuf[len++] = tAckBody.waterNumber>>8; //
            txBuf[len++] = tAckBody.waterNumber;
            txBuf[len++] = tAckBody.id>>8; //
            txBuf[len++] = tAckBody.id;
            txBuf[len++] = tAckBody.result;            
          break;            
        }            
        // case FILE_ACK_ID:     //File ack.    
        // {
        //     txHeader.attr = 7;     //get the length of  message body.
        //     txBuf[3] = txHeader.attr>>8; //message body attribute:subpackage、encryption、length of message body.
        //     txBuf[4] = txHeader.attr;
        //     txBuf[len++] =    file.id>>24;
        //     txBuf[len++] =    file.id>>16;
        //     txBuf[len++] =    file.id>>8;
        //     txBuf[len++] =    file.id;
        //     txBuf[len++] =    file.currentNum>>8;
        //     txBuf[len++] =    file.currentNum;
        //     txBuf[len++] = jt808.ackResult; //
        //     break;
        // }    
        case TEXT_ACK_ID:     //Text ack ID:0X300.    
        {
            txHeader.attr = text.len+sizeof(text.type)+sizeof(text.len);     //get the length of  message body.
            txBuf[3] = txHeader.attr>>8; //message body attribute:subpackage、encryption、length of message body.
            txBuf[4] = txHeader.attr;
            txBuf[len++] = text.type; //
            txBuf[len++] = text.len>>8;
            txBuf[len++] = text.len;
            for(u16 i = 0;i<jt808.rxBodyLen-1;i++)
            {
                txBuf[len++] = text.buf[i];
            }
            break;
        }    
        case T_ATTR_ACK_ID:     //终端属性查询应答 ID:0X0107.    
        {
            tempLen = len;
            char tempBuf[10];
            txHeader.attr = 0;     //get the length of  message body.
            txBuf[3] = txHeader.attr>>8; //message body attribute:subpackage、encryption、length of message body.
            txBuf[4] = txHeader.attr;
            txBuf[len++] = 0x00; //终端类型
            txBuf[len++] = 0x00;
            txBuf[len++] = 0x36; //制造商ID 5字节.
            txBuf[len++] = 0x36; //
            txBuf[len++] = 0x36; //
            txBuf[len++] = 0x36; //
            txBuf[len++] = 0x36; //
            for (u16 i = 0; i < 20; i++) //终端型号20字节,放入自主设置的IMEI号码
            {
                txBuf[len++] = Parm.imei[i];
            }
            for (u16 i = 0; i < 7; i++)  //gps ic
            {
                txBuf[len++] = Gps.name[i];
            }
            for(int i = 0;i<10;i++) //ICCID
            {
                txBuf[len++] = (ec800.iccid[2*i]<<4)+(ec800.iccid[2*i+1]&0x0f);        //
            }
            txBuf[len++] = strlen(Parm.versionH); //终端硬件版本号长度
            for (u16 i = 0; i < strlen(Parm.versionH); i++)
            {
                txBuf[len++] = Parm.versionH[i];
            }
            txBuf[len++] = strlen(Device.versionS); //终端固件版本号长度
            for (u16 i = 0; i < strlen(Device.versionS); i++)
            {
                txBuf[len++] = Device.versionS[i];
            }
            txBuf[len++] = 0x00; //GNSS属性
            txBuf[len++] = 0x00; //通信模块属性
            for (u16 i = 0; i < 15; i++)  //IMEI,原始号码。
            {
                txBuf[len++] = ec800.imei[i];
            }
            sprintf(tempBuf,":%d",Parm.serverIp[0].port);
            txBuf[len++] = strlen(Parm.serverIp[0].addr)+strlen(tempBuf);            //位置服务器IP列表长度。            
            for (u16 i = 0; i < strlen(Parm.serverIp[0].addr); i++)  //
            {
                txBuf[len++] = Parm.serverIp[0].addr[i];
            }
            for (u16 i = 0; i < strlen(tempBuf); i++)  //
            {
                txBuf[len++] = tempBuf[i];
            }
              sprintf(tempBuf,":%d",Parm.updateServerIp[0].port);
            txBuf[len++] = strlen(Parm.updateServerIp[0].addr)+strlen(tempBuf);            //升级服务器IP列表长度。
            for (u16 i = 0; i < strlen(Parm.updateServerIp[0].addr); i++)  //
            {
                txBuf[len++] = Parm.updateServerIp[0].addr[i];
            }
            for (u16 i = 0; i < strlen(tempBuf); i++)  //
            {
                txBuf[len++] = tempBuf[i];
            }
            txBuf[len++] = strlen(da215.name)+2;            //震动传感器型号长度。
            for (u16 i = 0; i < strlen(da215.name); i++)  //
            {
                txBuf[len++] = da215.name[i];
            }
            if (da215.id == 0x13)
            {
                txBuf[len++] = '1';
                txBuf[len++] = '3';
            }
            else
            {
                txBuf[len++] = 'F';
                txBuf[len++] = 'F';
            }            
            txBuf[len++] = strlen(Parm.apn[0].name);            //APN长度。
            for (u16 i = 0; i < strlen(Parm.apn[0].name); i++)  //
            {
                txBuf[len++] = Parm.apn[0].name[i];
            }
            txBuf[len++] = ec800.csqH & 0xff;    //CSQ            
            txBuf[len++] = Power.externVol>>8; //外电电压 0.1V
            txBuf[len++] = Power.externVol;
            txBuf[len++] = Power.soc; //电池可用电量百分比    
            txBuf[len++] = Parm.wkMode[Parm.currentMode].heartBeatTimeLimit>>8; //心跳时间,单位秒
            txBuf[len++] = Parm.wkMode[Parm.currentMode].heartBeatTimeLimit;
            txBuf[len++] = Parm.wkMode[Parm.currentMode].positionReportTimeLimit>>24; //定位时间,单位秒
            txBuf[len++] = Parm.wkMode[Parm.currentMode].positionReportTimeLimit>>16; //
            txBuf[len++] = Parm.wkMode[Parm.currentMode].positionReportTimeLimit>>8; //
            txBuf[len++] = Parm.wkMode[Parm.currentMode].positionReportTimeLimit;
            // Gps.mapLatitude = Gps.mapLatitude; //
            txBuf[len++] = Gps.mapLatitude>>24; //纬度
            txBuf[len++] = Gps.mapLatitude>>16;
            txBuf[len++] = Gps.mapLatitude>>8;
            txBuf[len++] = Gps.mapLatitude;
            // Gps.mapLongitude = Gps.mapLongitude; //经度
            txBuf[len++] = Gps.mapLongitude>>24; //经度
            txBuf[len++] = Gps.mapLongitude>>16;
            txBuf[len++] = Gps.mapLongitude>>8;
            txBuf[len++] = Gps.mapLongitude;
            txBuf[len++] = 0>>8;    //时区
            txBuf[len++] = 0;
            txBuf[len++] = 0; //报警号码列表长度,没有或不传时给0,下一段无字节
            txBuf[len++] = 0; //开关 
            txBuf[len++] = 0; //状态
            if (Parm.currentMode == WORK_MODE_0)
            {
                txBuf[len++] = 3;
            }
            else
            {
                txBuf[len++] = Parm.currentMode;
            }            
            txBuf[len++] = 0;                        //油电状态
            txBuf[len++] = Parm.da215.shreshold>>8;  //震动阈值
            txBuf[len++] = Parm.da215.shreshold;
            txBuf[len++] = 0>>8;   //低压阈值
            txBuf[len++] = 0;
            txBuf[len++] = 0;      //弯道阈值
            txBuf[len++] = 0>>8;   //超速报警阈值
            txBuf[len++] = 0;
            txBuf[len++] = 0>>24;  //设备存储区剩余空间
            txBuf[len++] = 0>>16;
            txBuf[len++] = 0>>8;
            txBuf[len++] = 0;
            txBuf[len++] = Device.resetRs;     //开机原因.
            txBuf[len++] = 0>>8;  //电池使用次数.
            txBuf[len++] = 0;            
            txBuf[len++] = strlen(Device.mcu);            //MCU型号长度.
            for (u16 i = 0; i < strlen(Device.mcu); i++)  //
            {
                txBuf[len++] = Device.mcu[i];
            }
            txBuf[len++] = strlen(ec800.mtRevison);            //4G模块版本号长度。
            for (u16 i = 0; i < strlen(ec800.mtRevison); i++)  //
            {
                txBuf[len++] = ec800.mtRevison[i];
            }
            txBuf[len++] = Parm.inflectionPointFlag; //拐点上报开关
            txBuf[len++] = Parm.wkMode[Parm.currentMode].resetTime>>24;  //重启时长单位:秒
            txBuf[len++] = Parm.wkMode[Parm.currentMode].resetTime>>16;
            txBuf[len++] = Parm.wkMode[Parm.currentMode].resetTime>>8;
            txBuf[len++] = Parm.wkMode[Parm.currentMode].resetTime;
            txBuf[len++] = Parm.wkMode[Parm.currentMode].sleepTime>>24;  //休眠时长 单位:秒
            txBuf[len++] = Parm.wkMode[Parm.currentMode].sleepTime>>16;
            txBuf[len++] = Parm.wkMode[Parm.currentMode].sleepTime>>8;
            txBuf[len++] = Parm.wkMode[Parm.currentMode].sleepTime;
            txBuf[len++] = Parm.wkMode[Parm.currentMode].workTime>>8; //唤醒后工作时长 单位:秒
            txBuf[len++] = Parm.wkMode[Parm.currentMode].workTime;    
            txHeader.attr = len - tempLen;     //get the length of  message body.
            txBuf[3] = txHeader.attr>>8; //message body attribute:subpackage、encryption、length of message body.
            txBuf[4] = txHeader.attr;
            break;
        }                            
        // case DEFAULT_ID:     //Reserved ID,nothing to do.    
        // {
        //     break;
        // }          
        default: break;        
    }    
    txBuf[len++] = 0;      //CRC SET TO 0
    txBuf[len++] = 0x7e ;  //包尾    
    txBuf[len-2] = 0;      //CRC SET TO 0
    for(int i = 1;i<len-2;i++)    //Skip data 0x7e crc 0x7e.
    {
        txBuf[len-2] ^= txBuf[i] ;  //crc校验        
    }
    addChar(txBuf,&len);   //添加转义字符,顺便修改len长度.
    *pLen = len;           //
}
void savePositionData(void)
{    
}
void jt808PackageSendOrSave(void)              //jt808 package send to server or store to local.    
{
    static u8 step = 0;
    static u32 timeout = 0;       //jt808 ack timeout
    static u16 repeatTimes = 0;   //jt808 data retransmission times 
    // if(txHeader.id != DEFAULT_ID && ec800.wifiScanFlag == FALSE) //
    if((txHeader.id != DEFAULT_ID)&&(ec800.status == EC800_TRANSMIT_MODE)) //
    {
        switch(step)
        {
            case 0:
            {                
                packageJt808TxBuf((char*)jt808.txBuf,&jt808.txLen);     //By message ID ,package the jt808.txBuf
                jt808.ackFlag = NOT_OK;  //clear jt808.ackFlag
                timeout = Timer.ms; //update timeout.
                repeatTimes = 0;         //clear jt808 data retransmission times 
                if (jt808.ackSendFlag == TRUE)
                {
                    jt808.ackSendFlag = FALSE;
                    step = 2;                    
                }
                else
                {                    
                    step = 1;
                }
                break;
            }            
            case 1:
            {            
                if(jt808.ackFlag == OK)       //If jt808.ackFlag == OK, complete data transmission
                {
                    txHeader.id = DEFAULT_ID;
                    timeout = Timer.ms; //update timeout.
                    repeatTimes = 0;         //clear jt808 data retransmission times                 
                    step = 0;
                    break;            //                        
                }        
                if( repeatTimes == 0 )   //The first direct transmission.
                {
                    repeatTimes ++;    
                    timeout = Timer.ms;  
                    jt808Send(jt808.txBuf,jt808.txLen);  //    
                    debugLog("发送数据到平台,第%d次.\n",repeatTimes);                                                      
                    break;
                }
                else if(repeatTimes > 0 && repeatTimes<jt808.repeatTimesLimit )
                {
                    if(Timer.ms - timeout>jt808.ackTimeoutLimit) //应答超时重发  
                    {
                        timeout = Timer.ms;             //updata timeout.
                        repeatTimes++;
                        jt808Send(jt808.txBuf,jt808.txLen);  //    
                        debugLog("发送数据到平台,第%d次.\n",repeatTimes);              
                        break;
                    }
                }
                else //If exceed the repeat times ,end data transmission
                {
                    if(Timer.ms - timeout>jt808.ackTimeoutLimit) //应答超时重发  
                    {
                        txHeader.id = DEFAULT_ID; //There was nothing to do.
                        timeout = Timer.ms; //update timeout.
                        repeatTimes = 0;         //clear jt808 data retransmission times                             
                        step = 0;
                        // if(jt808.debug) 
                        {
                            ec800.relink = TRUE;            //发送超时,重启4G模块。                    
                            debugLog("平台数据发送超时,重新启动4G模块。.\n");  //This code just for testing
                        }                            
                        break;                        
                    }                        
                }                    
                break;                                
            }        
            case 2:  //终端应答信号发送。
            {                        
                jt808Send(jt808.txBuf,jt808.txLen);  //    file.totalNum        
                txHeader.id = DEFAULT_ID;
                jt808.ackFlag = OK;
                step = 0;                    
                break;                    
            }
            default:break;            
        }        
    }    
}
void jt808Deal(void)                           //JT808 data deal.
{    
    // static u32 timeOut = 0;
    static u32 agpsTime = 0;
    // if (Timer.ms<2000) return;    
    // if(jt808.status != JT808_WORK_MODE)
    // {
    //     if (Timer.ms-jt808.timeOut>50000)//超过50秒,超时。
    //     {
    //         jt808.timeOut = Timer.ms;    
    //         jt808.status = JT808_WORK_MODE;//            
    //         debugLog("开机50秒,一直无法连接服务器,jt808跳过鉴权,0107等,进入正常工作模式。\r\n");    
    //     }        
    // }            
    jt808Parser();             //JT808 data parse.
    jt808PackageSendOrSave();  //JT808 package send to server or store to local flash.    
    // if(ec800.status == EC800_TRANSMIT_MODE) 
    {        
        switch(jt808.status)       //JT808 control logic  
        {
            case JT808_START_MODE:   //JT808 start.
            {
                // if(jt808.loginFlag == FALSE) //如果没有注册,则注册。
                {
                    if(ec800.status == EC800_TRANSMIT_MODE) //等待EC800进入正常工作模式 
                    {
                        txHeader.id = LOGIN_ID;     //进入注册操作
                        jt808.status = JT808_LOGIN; //进入注册步骤,等待注册成功。        
                        jt808.loginFlag = FALSE;                                 
                    }                     
                }
                // else if(jt808.loginFlag == TRUE)//如果注册过的,则直接进行鉴权
                // {
                //     if(ec800.status == EC800_TRANSMIT_MODE) //等待EC800进入正常工作模式
                //     {
                //         txHeader.id = AUTH_ID;     //进入鉴权操作
                //         jt808.status = JT808_AUTH; //进入鉴权步骤,等待成功。   
                //     }
                // }                    
                break;    
            }
            case JT808_LOGIN:        //login. 
            {
                if(jt808.loginFlag == OK) //注册成功
                {
                    txHeader.id    = AUTH_ID; //进入鉴权操作
                    jt808.authFlag = NOT_OK;
                    jt808.status   = JT808_AUTH; //进入鉴权步骤,等待成功。   
                }                
                break;
            }
            case JT808_LOGOUT:       //logout.
            {
                break;
            }            
            case JT808_AUTH:         //authentication.
            {
                if(jt808.authFlag == OK) //鉴权成功进入正常工作模式
                {
                    if (strstr((const char *)Device.id,"T19")!=NULL)//新疆T19H才需要网络对时。
                    {
                        txHeader.id = NTP_ID;      //发送网络校时    
                        jt808.ntpFlag = NOT_OK;                            
                    }
                    else if (strstr((const char *)Device.id,"S50B")!=NULL)//
                    {
                        txHeader.id = NTP_F_ID;      //发送网络校时    
                        jt808.ntpFlag = NOT_OK;                            
                    }
                    else if (strstr((const char *)Device.id,"WK301")!=NULL)//
                    {
                        txHeader.id = NTP_F_ID;      //发送网络校时    
                        jt808.ntpFlag = NOT_OK;                            
                    }
                    else if (strstr((const char *)Device.id,"T18")!=NULL)//
                    {
                        txHeader.id = NTP_F_ID;      //发送网络校时    
                        jt808.ntpFlag = NOT_OK;                            
                    }
                    else
                    {                    
                        jt808.ntpFlag = TRUE;  //跳过网络对时。    
                    }        
                    jt808.status = JT808_NTP;  //                                            
                }                                        
                break;    
            }    
            case JT808_NTP:
            {
                if(jt808.ntpFlag == TRUE) //网络校时成功,发送心跳包
                {
                    txHeader.id = HEARTBEAT_ID;      //发一包心跳
                    jt808.heartBeatTime = 0;         //JT808 心跳包时间控制变量
                    jt808.heartbeatAckFlag = NOT_OK;
                    addSecondsRTC(&heartbeatRtc,rtc,Parm.wkMode[Parm.currentMode].heartBeatTimeLimit);    //计算下次心跳时间
                    jt808.status = JT808_HEART_BEAT;  //
                    jt808.heartCountDown = Parm.wkMode[Parm.currentMode].heartBeatTimeLimit;        //心跳倒计时    
                    debugLog("下次心跳:日期:%d,RTC%d:%d:%d.\n",heartbeatRtc.date,heartbeatRtc.hours,heartbeatRtc.minutes,heartbeatRtc.seconds);            
                }
                break;
            }
            case JT808_HEART_BEAT://等待心跳包发送完成。
            {
                if(jt808.heartbeatAckFlag == OK) //第一次心跳发送完成,紧接着发送一包0107信息。
                {
                    jt808.status = JT808_T_ATTR;//开始工作发送一包定位,然后发送0107信息。
                    txHeader.id  = T_ATTR_ACK_ID;      //
                    jt808.ackSendFlag = TRUE;        
                    agpsTime = Timer.ms;                                    
                    jt808.attr0107Ok = TRUE;            //0107数据包上传OK.    
                }                    
                break;
            }        
            case JT808_T_ATTR://第一次心跳发送完成,紧接着发送0107产品信息。
            {
                if (Device.firstPowerUpFlag == TRUE) //首次上电
                {                        
                    if (Timer.ms-agpsTime > 15000||Gps.agpsOk == TRUE)//等待AGPS时间最大25秒。
                    {
                        agpsTime = Timer.ms;
                        jt808.alarmFlag = TRUE;  //发送一包位置信息。
                        jt808.status = JT808_WORK_MODE; //开始工作发送一次心跳包后,紧接着发送一包定位,然后进入正常工作模式。    
                        Device.firstPowerUpFlag = FALSE;
                        addSecondsRTC(&agpsRtc,rtc,AGPS_TIME);  //下次AGPS时间           
                        addSecondsRTC(&resetRtc,rtc,Parm.wkMode[Parm.currentMode].resetTime);  //下次重启RTC时间
                        debugLog("下次重启日期:%d  RTC:%d:%d:%d\r\n",resetRtc.date,resetRtc.hours,resetRtc.minutes,resetRtc.seconds);        
                        debugLog("下次AGPS日期:%d  RTC:%d:%d:%d\r\n",agpsRtc.date,agpsRtc.hours,agpsRtc.minutes,agpsRtc.seconds);                                
                    }        
                    else if(Timer.ms-agpsTime > 1000)
                    {
                        if(jt808.attr0107Ok == TRUE)  //0107数据包上传1秒后,开始AGPS.
                        {
                            jt808.attr0107Ok = FALSE;            //
                            Gps.status = GPS_START;         //AGPS
                        }                    
                    }        
                }
                else  //不是首次上电,则直接跳过AGPS
                {
                    jt808.alarmFlag = TRUE;  //发送一包位置信息。
                    jt808.status = JT808_WORK_MODE; //开始进入正常工作模式。
                }                
                break;  //
            }            
            case JT808_WORK_MODE:    //work mode. 
            {
                // static u32 tempjt808SendTime = 0;
                if(positionRepotReadyRtc.hours == rtc.hours && positionRepotReadyRtc.minutes == rtc.minutes && positionRepotReadyRtc.seconds == rtc.seconds)
                // if((subRtc(positionRepotReadyRtc,rtc)<=0)||(subRtc(positionRepotReadyRtc,rtc)>Parm.wkMode[Parm.currentMode].positionReportTimeLimit-Parm.gpsAdvanceTime))//
                {
                    jt808.positionReadyFlag = TRUE;
                    positionRepotReadyRtc.seconds = positionRepotReadyRtc.seconds-1; //防止重复进入该处。
                }
                if(jt808.positionReadyFlag == TRUE) //需要准备位置信息,WIFI扫描。
                {
                    static u8 step = 0;
                    static u32 pTempTime = 0;
                    if(da215.vibrateFlag == TRUE) //震动模式下,准备采集位置信息。
                    {
                        switch (step)
                        {
                            case STEP0:   //打开GPS
                            {
                                Gps.openPowerFlag = TRUE; 
                                // Gps.workTime = Timer.ms; 
                                pTempTime = Timer.ms;
                                // GPS_POWER(GPS_POWER_ON);
                                debugLog("定时位置上报,准备打开GPS电源。\n");
                                step = STEP1;
                                break;
                            }
                            case STEP1:
                            {

                                // if(Timer.ms-pTempTime>3000)  //Parm.gpsAdvanceTime
                                if(Timer.ms-pTempTime>Parm.gpsAdvanceTime*1000-6000)
                                {
                                    pTempTime = Timer.ms;
                                    ec800.wifiScanStep = 0;
                                    step = STEP2;
                                }
                                break;                                
                            }
                            case STEP2:
                            {                                
                                // if(Gps.locationMode == FALSE&&file.fileRxFlag == FALSE&&jt808.alarmFlag == FALSE)//报警无定位状态下,立即搜WIFI和基站。
                                if(Gps.locationMode == FALSE&&jt808.alarmFlag == FALSE)//报警无定位状态下,立即搜WIFI和基站。
                                {
                                    if(scanWifi() == OK)    //WIFI and base station scan.
                                    {
                                        step = STEP3;
                                        debugLog("定时位置上报,位置准备完成。\n");        
                                        debugLog("位置上报:%d:%d:%d.\n",positionRepotRtc.hours,positionRepotRtc.minutes,positionRepotRtc.seconds);                        
                                    }
                                }
                                else
                                {
                                    step = STEP3;                    
                                }
                                break;
                            }    
                            case STEP3:
                            {
                                jt808.positionReadyFlag = FALSE;
                                step = STEP0;
                                break;
                            }                    
                            default: break;
                        }                        
                    }                    
                }    
                // if(Timer.ms -  tempjt808SendTime <200) return;
                // {
                //     tempjt808SendTime = Timer.ms;
                // }

                // if((heartbeatRtc.hours == rtc.hours && heartbeatRtc.minutes == rtc.minutes && heartbeatRtc.seconds == rtc.seconds)
                //  ||(jt808.heartBeatTime>jt808.heartBeatTimeLimit+3000))//heartbeat package 
                // subRtc(struct __RTC__ rtc1,struct __RTC__ rtc2) //return seconds = rtc1-rtc2;
                // s32 tempHeart = 0-jt808.heartBeatTimeLimit/1000;//心跳时间负值
                // if((subRtc(heartbeatRtc,rtc)==0)||(subRtc(heartbeatRtc,rtc)>jt808.heartBeatTimeLimit/1000)||(subRtc(heartbeatRtc,rtc)<tempHeart))//当前RTC时间大约等于心跳RTC时间则发送心跳包。
                if((subRtc(heartbeatRtc,rtc)<=0)||(subRtc(heartbeatRtc,rtc)>Parm.wkMode[Parm.currentMode].heartBeatTimeLimit))//当前RTC时间大约等于心跳RTC时间则发送心跳包。
                // if((subRtc(heartbeatRtc,rtc)==0)||(subRtc(heartbeatRtc,rtc)>jt808.heartBeatTimeLimit/1000))//
                {
                    if(jt808.heartBeatTime >3000) //避免1秒内重复设置
                    {
                        jt808.heartBeatTime = 0;                
                        addSecondsRTC(&heartbeatRtc,rtc,Parm.wkMode[Parm.currentMode].heartBeatTimeLimit);    //计算下次心跳时间                                    
                        jt808.heartBeatTime = 0; //clear the heartBeatTime value jt808.heartBeatTime = jt808.heartBeatTimeLimit*3;
                        txHeader.id = HEARTBEAT_ID;
                        jt808.heartCountDown = Parm.wkMode[Parm.currentMode].heartBeatTimeLimit;        //心跳倒计时    
                        debugLog("心跳时间到,下次心跳:日期:%d,RTC%d:%d:%d.\n",heartbeatRtc.date,heartbeatRtc.hours,heartbeatRtc.minutes,heartbeatRtc.seconds);            
                    }                                
                }    
                // s32 tempReport = 0-Parm.wkMode[Parm.currentMode].positionReportTimeLimit;//心跳时间负值    
                if(jt808.alarmFlag != 0) //有报警信息,立即上报一包报警数据(位置信息与报警)。
                {
                    static u8 step = STEP0;
                    static u32 tempTime = 0;
                    switch (step)
                    {
                        case STEP0:   //打开GPS
                        {
                            Gps.openPowerFlag = TRUE;      
                            debugLog("报警位置上报,准备打开GPS电源。\n");                        
                            debugLog("报警号:%d---",jt808.alarmFlag);
                            // Gps.workTime = Timer.ms;
                            tempTime = Timer.ms;
                            // GPS_POWER(GPS_POWER_ON);        
                            switch (jt808.alarmFlag)
                            {
                                case ALARM_TRUE:
                                {
                                    printf("常规报警.\n");
                                    break;
                                }
                                case ALARM_H_TH:
                                {
                                    printf("高温报警.\n");
                                    break;
                                }
                                case ALARM_L_TH:
                                {
                                    printf("低温报警.\n");
                                    break;
                                }
                                case ALARM_H_HU:
                                {
                                    printf("高湿报警.\n");
                                    break;
                                }
                                case ALARM_L_HU:
                                {
                                    printf("低湿报警.\n");
                                    break;
                                }
                                case ALARM_HAVE_EX_POWER:
                                {
                                    printf("外电报警.\n");
                                    break;
                                }
                                case ALARM_HAVE_NO_POWER:
                                {
                                    printf("无外电报警.\n");
                                    break;
                                }
                                case ALARM_CHARGE:
                                {
                                    printf("充电报警.\n");
                                    break;
                                }                                    
                                case ALARM_NO_CHARGE:
                                {
                                    printf("无充电报警.\n");
                                    break;
                                }                                    
                                case ALARM_VIBRATE:
                                {
                                    printf("震动报警.\n");                                    
                                    break;
                                }                                    
                                case ALARM_ROLLOVER:
                                {
                                    printf("侧翻报警.\n");                                
                                    break;
                                }                                    
                                case ALARM_KEY1:
                                {
                                    printf("按键1报警.\n");                                
                                    break;
                                }                                    
                                case ALARM_KEY2:
                                {
                                    printf("按键2报警.\n");                                
                                    break;
                                }                                    
                                case ALARM_LIGHT_F_ON:
                                {
                                    printf("前光感有光报警.\n");                                
                                    break;
                                }                                    
                                case ALARM_LIGHT_F_OFF:
                                {
                                    printf("前光感无光报警.\n");                                
                                    break;
                                }                                    
                                case ALARM_LIGHT_B_ON:
                                {
                                    printf("后光感有光报警.\n");                                
                                    break;
                                }                                    
                                case ALARM_LIGHT_B_OFF:
                                {
                                    printf("后光感无光报警.\n");                                
                                    break;
                                }                                    
                                case ALARM_LOCK_ON:
                                {
                                    printf("开锁报警.\n");                            
                                    break;
                                }                                    
                                case ALARM_LOCK_OFF:
                                {
                                    printf("上锁报警.\n");
                                    break;
                                }        
                                case ALARM_FIRST_LOCATION:
                                {
                                    printf("首次定位,位置补报报警.\n");
                                    break;
                                }                                                
                                default:break;
                            }                                
                            step = STEP1;
                            break;
                        }
                        case STEP1:
                        {
                            // if(Timer.ms-tempTime>Parm.gpsAdvanceTime*1000) //报警状态,等待GPS时间。
                            if(Timer.ms-tempTime>6*1000) //
                            {
                                tempTime = Timer.ms;
                                ec800.wifiScanStep = 0;
                                step = STEP2;
                            }
                            break;                                
                        }
                        case STEP2:                        
                        {
                            if(Gps.locationMode == FALSE)//报警无定位状态下,立即搜WIFI和基站。
                            {
                                if(scanWifi() == OK)    //WIFI and base station scan.
                                {
                                    step = STEP3;
                                    tempTime = Timer.ms;                                    
                                }
                            }
                            else
                            {
                                step = STEP3;
                            }
                            break;
                        }
                        case STEP3:
                        {
                            if(Timer.ms-tempTime<500) break;
                            if(jt808.callNameFlag == TRUE)
                            {
                                step = STEP5;                                
                            }
                            else
                            {
                                step = STEP4;
                            }
                            
                            tempTime = Timer.ms;
                            break;
                        }
                        case STEP4:
                        {                            
                            jt808.alarmNum =     jt808.alarmFlag; //上报报警号。
                            jt808.alarmFlag = 0;            
                            jt808.positionReportTime = 0; //clear value
                            addSecondsRTC(&positionRepotRtc,rtc,Parm.wkMode[Parm.currentMode].positionReportTimeLimit);    //计算下次位置上报时间                            
                            addSecondsRTC(&positionRepotReadyRtc,rtc,Parm.wkMode[Parm.currentMode].positionReportTimeLimit-Parm.gpsAdvanceTime);    //提前xx秒准备数据。                            
                            jt808.positionCountDown = Parm.wkMode[Parm.currentMode].positionReportTimeLimit; //位置上报倒计时
                            debugLog("报警位置上报,下次上报:%d:%d:%d.\n",positionRepotRtc.hours,positionRepotRtc.minutes,positionRepotRtc.seconds);
                            debugLog("下次位置准备时间:%d:%d:%d.\n",positionRepotReadyRtc.hours,positionRepotReadyRtc.minutes,positionRepotReadyRtc.seconds);
                            txHeader.id = POSITION_ID;
                            step = STEP0;
                            break;
                        }
                        case STEP5:
                        {
                            jt808.alarmNum =     jt808.alarmFlag; //上报报警号。
                            jt808.alarmFlag = 0;        
                            txHeader.id = POSITION_ID;
                            jt808.ackSendFlag = TRUE;
                            jt808.callNameFlag = FALSE;
                            step = STEP0;
                            break;
                        }
                        default: break;
                    }                    
                }
                // else if((positionRepotRtc.hours == rtc.hours && positionRepotRtc.minutes == rtc.minutes && positionRepotRtc.seconds == rtc.seconds)
                //       ||(jt808.positionReportTime>jt808.positionReportTimeLimit+3000))//
                // else if((subRtc(positionRepotRtc,rtc)==0)||(subRtc(positionRepotRtc,rtc)>Parm.wkMode[Parm.currentMode].positionReportTimeLimit)||(subRtc(positionRepotRtc,rtc)<tempReport))//
                else if((subRtc(positionRepotRtc,rtc)<=0)||(subRtc(positionRepotRtc,rtc)>Parm.wkMode[Parm.currentMode].positionReportTimeLimit))//
                {
                    if (jt808.positionReportTime >3000) //避免1秒内重复设置
                    {
                        jt808.positionReportTime = 0; //clear value                            
                        addSecondsRTC(&positionRepotRtc,rtc,Parm.wkMode[Parm.currentMode].positionReportTimeLimit);    //计算下次位置上报时间
                        addSecondsRTC(&positionRepotReadyRtc,rtc,Parm.wkMode[Parm.currentMode].positionReportTimeLimit-Parm.gpsAdvanceTime);    //提前xx秒准备数据。
                        jt808.positionCountDown = Parm.wkMode[Parm.currentMode].positionReportTimeLimit; //位置上报倒计时
                        debugLog("定时位置上报时间到,下次定时位置:%d:%d:%d.\n",positionRepotRtc.hours,positionRepotRtc.minutes,positionRepotRtc.seconds);
                        debugLog("下次定时位置准备时间:%d:%d:%d.\n",positionRepotReadyRtc.hours,positionRepotReadyRtc.minutes,positionRepotReadyRtc.seconds);
                        if(da215.vibrateFlag == TRUE)
                        {
                            txHeader.id = POSITION_ID;                                    
                        }                     
                    }                    
                }    
                // if(da215.reportFlag == 1)   //震动数据上报
                // {
                //     if (da215.bufReady == OK)
                //     {                        
                //         if (txHeader.id != DEFAULT_ID && ec800.wifiScanFlag == FALSE)
                //         {
                //             da215.bufReady = FALSE;
                //             txHeader.id   = TRANSPARENT_ID;  //通过发送震动数据到平台
                //       jt808.txSubId = JT808_GERSOR_ID;
                //         }                        
                //     }                    
                // }                    
                break;
            }
            default: break;        
        }    
    }        
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kevinpan2011

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值