/** ****************************************************************************** * @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. * *

© COPYRIGHT 2016 TMC

****************************************************************************** **/ #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 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='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>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;iPACKMAX-6)return 0; p = &PackData[4]; for(i=0;i0) { 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; }