576 lines
12 KiB
C
576 lines
12 KiB
C
/**
|
||
******************************************************************************
|
||
* @file communication.c
|
||
* @author TMC Scan Team
|
||
* @version V1.0.0
|
||
* @date 09/06/2019
|
||
* @brief
|
||
******************************************************************************
|
||
*
|
||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
||
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
|
||
* TIME. AS A RESULT, TMC SHALL NOT BE HELD LIABLE FOR ANY
|
||
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
|
||
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
|
||
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
||
*
|
||
* <h2><center>© COPYRIGHT 2016 TMC</center></h2>
|
||
******************************************************************************
|
||
**/
|
||
|
||
#include "global.h"
|
||
|
||
uint8_t gReceiveBuf[MAX_RECEIVE_DATA_LEN]; //USB接收数据BUF,局限性最大支持256字节
|
||
uint16_t gReceiveLen = 0; //接收数据长度
|
||
uint8_t gOutputBuf[MAX_SEND_DATA_LEN]; //发送数据BUF,局限性最大支持2070字节
|
||
uint16_t gOutputLen = 0; //发送数据长度
|
||
uint8_t gPackType = PACK_TYPEA;
|
||
uint8_t gReceiveKey = 0;
|
||
extern uint32_t gFunTrace;
|
||
|
||
uint8_t RN[30]={0};//random number
|
||
uint8_t HEXDIGIT[16]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
|
||
uint8_t BinToCode16(uint8_t *bin,uint8_t *c16,uint8_t len);
|
||
|
||
#define PACKMAX 250
|
||
#define MAXCRYPTWORD ((PACKMAX-6)/4)
|
||
|
||
uint8_t PackData[PACKMAX];
|
||
uint8_t lenPack = 0;
|
||
uint8_t packStatus = PACK_RECEIVE_START;
|
||
|
||
/**
|
||
* @function ClearOutputLen
|
||
* @brief clear output len to zero
|
||
* @return 无
|
||
*/
|
||
void ClearOutputLen()
|
||
{
|
||
gOutputLen = 0;
|
||
}
|
||
|
||
/**
|
||
* @function SetOutputData
|
||
* @brief set output data into output buffer
|
||
* @param[in] pSrcData 输出数据的源地址
|
||
* @param[in] uLen 输出数据的长度
|
||
* @return 无
|
||
*/
|
||
void SetOutputData(uint8_t *pSrcData, uint16_t uLen)
|
||
{
|
||
if((gOutputLen + uLen) > MAX_SEND_DATA_LEN)
|
||
{
|
||
while(1)
|
||
{
|
||
if((gOutputLen + uLen) <= MAX_SEND_DATA_LEN)break;
|
||
}
|
||
}
|
||
|
||
memcpy(gOutputBuf + gOutputLen, (const uint8_t *)pSrcData, uLen);
|
||
gOutputLen += uLen;
|
||
}
|
||
|
||
|
||
/**
|
||
* @brief CryptCmd
|
||
* @retval None
|
||
*/
|
||
uint8_t CryptCmd(uint8_t *cmd,uint8_t len, uint8_t *C)
|
||
{
|
||
uint8_t T[PACKMAX], *p, lent=0,mlen;
|
||
unsigned short P[PACKMAX/2];
|
||
|
||
if(len>MAXCRYPTWORD)len = MAXCRYPTWORD;
|
||
for (int i = 0; i < len; i++)
|
||
{
|
||
C[i] = cmd[i];
|
||
}
|
||
|
||
for (int i = 0; i < len; i++)
|
||
{
|
||
P[i] = C[i] * (i + 3) + RN[i%10] * (i + 2);
|
||
}
|
||
p = (uint8_t *)&P[0];
|
||
|
||
BinToCode16(p, T, len*2);
|
||
|
||
mlen = 0;
|
||
for (int i = 0; i < len*2; i++)
|
||
{
|
||
C[mlen++] = T[i * 2];
|
||
C[mlen++] = T[i * 2 + 1];
|
||
}
|
||
C[mlen] = 0;
|
||
return mlen;
|
||
}
|
||
|
||
/**
|
||
* @brief PackOutputData
|
||
* @retval None
|
||
*/
|
||
void PackOutputData(uint8_t type)
|
||
{
|
||
|
||
uint8_t pack[PACKMAX],i,lenm,C[PACKMAX];
|
||
pack[0] = 0x5B;
|
||
pack[1] = type;
|
||
pack[2] = 0;
|
||
if(type==PACK_TYPEA)
|
||
{
|
||
pack[3] = gOutputLen;
|
||
for(i=0;i<gOutputLen;i++)
|
||
{
|
||
pack[i+4] = gOutputBuf[i];
|
||
}
|
||
pack[gOutputLen+4] = BccCheck(&pack[1], gOutputLen + 3);
|
||
pack[gOutputLen+5] = 0x5D;
|
||
lenm = gOutputLen+6;
|
||
} else if(type==PACK_TYPEB)
|
||
{
|
||
return;
|
||
} else if(type==PACK_TYPEC)
|
||
{
|
||
lenm = CryptCmd(gOutputBuf,gOutputLen,C);
|
||
pack[3] = lenm;
|
||
for(i=0;i<lenm;i++)
|
||
{
|
||
pack[i+4] = C[i];
|
||
}
|
||
pack[lenm+4] = BccCheck(&pack[1], lenm + 3);
|
||
pack[lenm+5] = 0x5D;
|
||
lenm = lenm+6;
|
||
|
||
}
|
||
else return;
|
||
|
||
memcpy(gOutputBuf,pack,lenm);
|
||
gOutputLen = lenm;
|
||
|
||
}
|
||
|
||
/**
|
||
* @function ReportData
|
||
* @brief 根据不同的通信接口,完成不同的输出
|
||
* @return 无
|
||
*/
|
||
void ReportData(int barType)
|
||
{
|
||
// PackOutputData(gPackType);
|
||
AppUSBSendData(gOutputBuf, gOutputLen);
|
||
ClearOutputLen();
|
||
SetSysPackType();
|
||
}
|
||
|
||
/**
|
||
* @function HIDPOSDataSend
|
||
* @brief HIDPOS模式下数据上传格式
|
||
* @param[in] pSrc 指针指向源数据
|
||
* @param[in] uLen 数据长度
|
||
* @return 无
|
||
*/
|
||
void HIDPOSDataSend(uint8_t *pSrc, uint16_t uLen)
|
||
{
|
||
uint16_t dataoffset = 0;
|
||
uint8_t buffer[HIDPOS_BUFLEN];
|
||
int i;
|
||
|
||
//如果现在的数据超过56个字节,分包发
|
||
while(uLen > NOTAILLEN)
|
||
{
|
||
buffer[0] = HIDPOS_SEND_DATA_HEAD;
|
||
buffer[1] = HIDPOS_SEND_DATA_MAX_LEN;
|
||
Memcpy(&buffer[2], &pSrc[dataoffset], NOTAILLEN);
|
||
|
||
for(i = 58; i < HIDPOS_BUFLEN - 1; i++)
|
||
{
|
||
buffer[i] = 0x00;
|
||
}
|
||
|
||
buffer[HIDPOS_BUFLEN - 1] = HIDPOS_RECEIVE_DATA_TAIL_CONTINUE;
|
||
AppUSBSendData(buffer, HIDPOS_BUFLEN);
|
||
dataoffset += NOTAILLEN;
|
||
uLen -= NOTAILLEN;
|
||
}
|
||
|
||
//处理不足一包的数据
|
||
buffer[0] = HIDPOS_SEND_DATA_HEAD;
|
||
buffer[1] = uLen;
|
||
Memcpy(&buffer[2], &pSrc[dataoffset], uLen);
|
||
|
||
for(i = (uLen + 2); i < HIDPOS_BUFLEN; i++)
|
||
{
|
||
buffer[i] = 0;
|
||
}
|
||
|
||
AppUSBSendData(buffer, HIDPOS_BUFLEN);
|
||
}
|
||
|
||
/**
|
||
* @function CheckRecieveData
|
||
* @brief 检查USB接收数据的合法性
|
||
* @param[in] pSrc 源数据
|
||
* @param[in] len 源数据长度
|
||
* @return RECIEVE_OVERMAXLEN 数据长度越界,最大接收MAX_RECEIVE_DATA_LEN字节数
|
||
* HIDPOS_RECIEVE_REPORTID_ERROR 上报ID错误
|
||
* HIDPOS_RECIEVE_DATALEN_ERROR 数据长度错误
|
||
* HIDPOS_RECIEVE_PACKAGEEND_ERROR 数据包尾有误
|
||
*/
|
||
uint8_t CheckRecieveData(HIDPOSReciveData *pOnePackegedata, uint32_t len)
|
||
{
|
||
//根据自定义HIDPOS协议,检查数据合法性
|
||
if(pOnePackegedata->reportID != HIDPOS_RECEIVE_DATA_HEAD) //包头
|
||
{
|
||
return HIDPOS_RECIEVE_REPORTID_ERROR;
|
||
}
|
||
|
||
if(pOnePackegedata->endPackage == HIDPOS_RECEIVE_DATA_TAIL_CONTINUE) //当前数据包后续还有数据
|
||
{
|
||
if(pOnePackegedata->dataLen != HIDPOS_RECEIBE_DATA_MAX_LEN) //满包数据长度必须是60
|
||
{
|
||
return HIDPOS_RECIEVE_DATALEN_ERROR;
|
||
}
|
||
else
|
||
{
|
||
return HIDPOS_RECIEVE_CONTINUE;
|
||
}
|
||
}
|
||
else if(pOnePackegedata->endPackage == HIDPOS_RECEIVE_DATA_TAIL_FINISH) //最后一包数据
|
||
{
|
||
if(pOnePackegedata->dataLen > HIDPOS_RECEIBE_DATA_MAX_LEN) //数据长度不大于60
|
||
{
|
||
return HIDPOS_RECIEVE_DATALEN_ERROR;
|
||
}
|
||
else
|
||
{
|
||
return RECIEVE_FINISH;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
return HIDPOS_RECIEVE_PACKAGEEND_ERROR;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @function VSPRecieveData
|
||
* @brief USB接口VSP接收数据
|
||
* @return
|
||
*/
|
||
uint8_t VSPRecieveData(void)
|
||
{
|
||
uint32_t len = 0;
|
||
//接收下发数据
|
||
len = usbVspRecvChars(gReceiveBuf, MAX_RECEIVE_DATA_LEN);
|
||
|
||
if(len > 0)
|
||
{
|
||
gReceiveLen = len;
|
||
return RECIEVE_FINISH;
|
||
}
|
||
|
||
return RECEIVE_FAIL;
|
||
}
|
||
|
||
/**
|
||
* @function HIDPOSRecieveData
|
||
* @brief HIDPOS接收数据,并返回接收的状态或者数据的合法性
|
||
* @return USB_RECIEVE_RIGHT 正确收到数据
|
||
* HIDPOS_RECIEVE_REPORTID_ERROR 上报ID错误
|
||
* HIDPOS_RECIEVE_DATALEN_ERROR 数据长度错误
|
||
* HIDPOS_RECIEVE_PACKAGEEND_ERROR 数据包尾有误
|
||
*/
|
||
uint8_t HIDPOSRecieveData(void)
|
||
{
|
||
uint8_t status;
|
||
uint8_t buffer[HIDPOS_BUFLEN]; //根据自定义HIDPOS数据协议,数据包固定长度为HIDPOS_BUFLEN
|
||
uint32_t len = 0;
|
||
HIDPOSReciveData *pReceivedata = (HIDPOSReciveData *)buffer;
|
||
//接收下发数据
|
||
len = usbHidPosRecvChars(buffer, HIDPOS_BUFLEN);
|
||
|
||
if(len > 0)
|
||
{
|
||
//step1:判断数据协议的合法性
|
||
status = CheckRecieveData(pReceivedata, len);
|
||
|
||
if((status != RECIEVE_FINISH) && (status != HIDPOS_RECIEVE_CONTINUE))
|
||
{
|
||
return status;
|
||
}
|
||
|
||
if((gReceiveLen + pReceivedata->dataLen) > MAX_RECEIVE_AVAILABLE_DATA_LEN) //超过设置的最大接收长度
|
||
{
|
||
gReceiveLen = 0;
|
||
return RECIEVE_OVERMAXLEN;
|
||
}
|
||
|
||
memcpy(gReceiveBuf + gReceiveLen, pReceivedata->dataBlock, pReceivedata->dataLen);
|
||
gReceiveLen += pReceivedata->dataLen;
|
||
return status;
|
||
}
|
||
|
||
return RECEIVE_FAIL;
|
||
}
|
||
|
||
/**
|
||
* @brief Code16ToBin
|
||
* @retval
|
||
*/
|
||
uint8_t Code16ToBin(uint8_t *c16,uint8_t len)
|
||
{
|
||
uint8_t i,c;
|
||
for( i=0;i<len;i++)
|
||
{
|
||
c = c16[i*2];
|
||
if(c>='0' && c<='9')c -='0';
|
||
else if(c>='A' &&c<='F') c -=('A'-10);
|
||
else if(c>='a' &&c<='f') c -=('a'-10);
|
||
else return 0;
|
||
c16[i] = (c<<4);
|
||
c = c16[i*2+1];
|
||
if(c>='0' && c<='9')c -='0';
|
||
else if(c>='A' &&c<='F') c -=('A'-10);
|
||
else if(c>='a' &&c<='f') c -=('a'-10);
|
||
else return 0;
|
||
c16[i]+= c;
|
||
}
|
||
return 1;
|
||
}
|
||
|
||
/**
|
||
* @brief BinToCode16
|
||
* @retval
|
||
*/
|
||
uint8_t BinToCode16(uint8_t *bin,uint8_t *c16,uint8_t len)
|
||
{
|
||
uint8_t i,c;
|
||
for(i=0;i<len;i++)
|
||
{
|
||
c = (bin[i]>>4)&0x0f;
|
||
c16[i*2] = HEXDIGIT[c];
|
||
c = bin[i]&0x0f;
|
||
c16[i*2+1] = HEXDIGIT[c];
|
||
|
||
}
|
||
c16[len*2] = 0;
|
||
}
|
||
|
||
/**
|
||
* @brief DecodeACommand
|
||
* @retval
|
||
*/
|
||
uint8_t DecodeACommand(void)
|
||
{
|
||
uint8_t i;
|
||
|
||
lenPack = (PackData[2]<<8)|PackData[3];
|
||
|
||
if(lenPack>246)
|
||
{
|
||
lenPack = 0;
|
||
return 0;
|
||
}
|
||
for(i=0;i<lenPack;i++)
|
||
{
|
||
PackData[i] = PackData[i+4];
|
||
}
|
||
PackData[lenPack] = 0;
|
||
return 1;
|
||
}
|
||
|
||
/**
|
||
* @brief DecodeBCommand
|
||
* @retval
|
||
*/
|
||
uint8_t DecodeBCommand(void)
|
||
{
|
||
uint8_t i,*p,S[10],T[20];
|
||
uint16_t *p16;
|
||
|
||
p = &PackData[4];
|
||
for(i=0;i<10;i++)
|
||
{
|
||
S[i] = p[i*3];
|
||
T[i*2] = p[i*3+1];
|
||
T[i*2+1] = p[i*3+2];
|
||
}
|
||
lenPack = 0;
|
||
if(!Code16ToBin(S,5))return 0;
|
||
if(!Code16ToBin(T,10))return 0;
|
||
for(i=0;i<5;i++)RN[i] = S[i];
|
||
for(i=10;i<20;i++)RN[i] = RN[i-10];
|
||
for(i=20;i<30;i++)RN[i] = RN[i-20];
|
||
|
||
for(i=0;i<5;i++)
|
||
{
|
||
p16 = (uint16_t *)&T[i*2];
|
||
PackData[i] = (*p16 - RN[i%10]*(i+2))/(i+3);
|
||
}
|
||
PackData[5] = 0;
|
||
lenPack = 5;
|
||
gReceiveKey = 1;
|
||
|
||
return 1;
|
||
}
|
||
|
||
/**
|
||
* @brief DecodeCCommand
|
||
* @retval
|
||
*/
|
||
uint8_t DecodeCCommand(void)
|
||
{
|
||
uint8_t i,*p,T[PACKMAX],rlen;
|
||
uint16_t *p16;
|
||
|
||
lenPack = 0;
|
||
rlen = (PackData[2]<<8)|PackData[3];
|
||
if(rlen>PACKMAX-6)return 0;
|
||
p = &PackData[4];
|
||
for(i=0;i<rlen;i++)
|
||
{
|
||
T[i] = p[i];
|
||
}
|
||
|
||
rlen = rlen/4;
|
||
|
||
if(!Code16ToBin(T,rlen*2))return 0;
|
||
|
||
for(i=0;i<rlen;i++)
|
||
{
|
||
p16 = (uint16_t *)&T[i*2];
|
||
PackData[i] = (*p16 - RN[i%10]*(i+2))/(i+3);
|
||
}
|
||
PackData[rlen] = 0;
|
||
lenPack = rlen;
|
||
|
||
return 1;
|
||
}
|
||
|
||
uint8_t GetPackData()
|
||
{
|
||
uint8_t *p = gReceiveBuf;
|
||
uint16_t len = gReceiveLen;
|
||
gReceiveLen = 0;
|
||
|
||
if(packStatus==PACK_RECEIVE_START)
|
||
{
|
||
while(*p!=UART_PROTOCOL_STX_VALUE&&len>0)
|
||
{
|
||
p++;
|
||
len--;
|
||
}
|
||
if(len==0)return 0;
|
||
packStatus = PACK_RECEIVE_DATA;
|
||
lenPack = 0;
|
||
}
|
||
if(packStatus==PACK_RECEIVE_DATA){
|
||
while(*p!=UART_PROTOCOL_ETX_VALUE&&len>0)
|
||
{
|
||
if(*p==UART_PROTOCOL_STX_VALUE)
|
||
{
|
||
lenPack = 0;
|
||
}
|
||
PackData[lenPack++] = *p++;
|
||
len--;
|
||
}
|
||
if(len==0)return 1;
|
||
PackData[lenPack++] = *p++;
|
||
}
|
||
packStatus = PACK_RECEIVE_START;
|
||
return 2;
|
||
}
|
||
|
||
/**
|
||
* @function RecieveData
|
||
* @brief 不同通讯接口接收数据
|
||
* @param[in] pRecievedata 存储接收的数据
|
||
* @return
|
||
*/
|
||
uint8_t RecieveData(BarData *pRecievedata)
|
||
{
|
||
uint8_t status;
|
||
|
||
gFunTrace = 34;
|
||
status = VSPRecieveData();
|
||
|
||
if((status == RECIEVE_FINISH) && (gReceiveLen>0))
|
||
{
|
||
|
||
status = GetPackData();
|
||
if(status==0)
|
||
{
|
||
gReceiveLen = 0;
|
||
gOutputLen = 0;
|
||
SetPackType(PACK_TYPEA);
|
||
SetOutputData((uint8_t *)"ILLEGALCMD", 10);
|
||
ReportData(Communication_Id);
|
||
return FALSE;
|
||
}
|
||
if(status==1)return FALSE;
|
||
|
||
pRecievedata->packType = PackData[1];
|
||
if(PackData[0]==UART_PROTOCOL_STX_VALUE)
|
||
{
|
||
uint16_t len;
|
||
len = (PackData[2]<<8)|PackData[3];
|
||
|
||
if(BccCheck(&PackData[1],len+3)==PackData[len+4])
|
||
{
|
||
if(PackData[1]==PACK_TYPEA)
|
||
{
|
||
DecodeACommand();
|
||
} else
|
||
if(PackData[1]==PACK_TYPEB)
|
||
{
|
||
DecodeBCommand();
|
||
}
|
||
else if(PackData[1]==PACK_TYPEC)
|
||
{
|
||
if(gReceiveKey==0)
|
||
{
|
||
SetPackType(PACK_TYPEA);
|
||
SetOutputData((uint8_t *)"NOKEY", 5);
|
||
ReportData(Communication_Id);
|
||
gReceiveLen = 0;
|
||
gOutputLen = 0;
|
||
return FALSE;
|
||
}
|
||
DecodeCCommand();
|
||
}
|
||
} else
|
||
{
|
||
SetPackType(PACK_TYPEA);
|
||
SetOutputData((uint8_t *)"ILLEGALCMD", 10);
|
||
ReportData(Communication_Id);
|
||
gReceiveLen = 0;
|
||
gOutputLen = 0;
|
||
return FALSE;
|
||
}
|
||
}
|
||
|
||
if(lenPack==0)
|
||
{
|
||
SetPackType(PACK_TYPEA);
|
||
SetOutputData((uint8_t *)"ILLEGALCMD", 10);
|
||
ReportData(Communication_Id);
|
||
gOutputLen = 0;
|
||
return FALSE;
|
||
}
|
||
|
||
//将通信命令信息放在BarData结构体中,目的是为了和扫码命令分发共用指令分发函数
|
||
|
||
pRecievedata->bardata = PackData;
|
||
pRecievedata->bartype = Communication_Id; //与扫码ID做一个区别,可以在指令分发函数中作为是通信命令还是扫码命令判别依据
|
||
pRecievedata->datalen = lenPack;
|
||
pRecievedata->barinfo = NULL;
|
||
|
||
|
||
//清接收长度&发送长度
|
||
gReceiveLen = 0;
|
||
gOutputLen = 0;
|
||
return TRUE;
|
||
}
|
||
|
||
return FALSE;
|
||
}
|