TMC32_QJB/App/communication.c

576 lines
12 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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