/** * @brief Crea il CRC della frame e lo appende * @param in frame * @retval L'esito : * @arg 0 Fallito * @arg 1 Successo */ CAL_Option_Type frameCRCCreate(uint8_t* data, uint32_t length) { if (crcCheckState() != 1) { return CAL_NO; } uint32_t* data32 = (uint32_t*) data; uint32_t data32Length = (length - CRC_LENGTH) / 4; uint32_t crcValue = crcCalculate(data32, data32Length); data32[data32Length] = crcValue; return CAL_YES; }
/** * @brief Controlla il CRC della frame e lo appende * @param in frame * @retval L'esito : * @arg 0 Fallito * @arg 1 Successo */ CAL_Option_Type frameCRCCheck(uint8_t* data, uint32_t length) { if (crcCheckState() != 1) { return CAL_NO; } uint32_t* data32 = (uint32_t*) data; uint32_t data32Length = (length - CRC_LENGTH) / 4; uint32_t crcValue = crcCalculate(data32, data32Length); uint32_t crcValueToCheck = data32[data32Length]; if (crcValue == crcValueToCheck) return CAL_YES; else return CAL_NO; }
/** @brief Receive message from the server @param size - return size of data @param decrypt - if TRUE, then decrypt received data by session key @param control - return control character @return data (you MUST free memory after use) */ byte *tcpReceiveMessage(int Handle, uint32 *size, byte *control, uint32 TimeoutMsec) { StreamMethod Method = smRecvSend; byte *data; int ret = 0; byte cc = 0; byte LengthField[MAXLENGTHFIELDSIZE]; byte LengthFieldSize; uint32 AlignedSize; byte AttempsCount = 1; byte MaxAttempsCount = 5; lblWaitAgain: *size = 0; *control = 0; data = NULL; sleepms(100); ret = recvByte(Handle, Method, &cc, 0/*Timeout*/); //printf"recvByte: %d. byte %d\n", ret, cc); if (ret > 0) { *control = cc; switch (cc) { case pccSTX: *size = ReceiveLengthField(Handle, Method, LengthField, &LengthFieldSize, TimeoutMsec); // получаем размер данных if (*size != 0xFFFFFFFF) { AlignedSize = GetAlignedSize(*size); data = malloc(AlignedSize); // allocate data ret = recvBuffer(Handle, Method, data, AlignedSize, TimeoutMsec); #ifdef TCP_DEBUG // PrintHEX(data, *size); #endif //printf"comRecvBufLarge: %d\n", ret); if (ret > 0) { // ok, we have a data - calc CRC uint32 CRCBufferSize = LengthFieldSize + AlignedSize + 1; // datasize + data + ETX byte *CRCBuffer = malloc(CRCBufferSize); memcpy(CRCBuffer, LengthField, LengthFieldSize); // copy length field to checkbuffer memcpy(CRCBuffer+LengthFieldSize, data, AlignedSize); // copy data from checkbuffer CRCBuffer[CRCBufferSize - 1] = pccETX; // last character = ETX uint64 CalculatedCRC = crcCalculate(CRCBuffer, CRCBufferSize); free(CRCBuffer); CRCBuffer = NULL; ret = recvByte(Handle, Method, &cc, TimeoutMsec); // receive ETX character //printf"comRecv: %d. byte %d\n", ret, cc); if (ret > 0 && cc == pccETX) { byte crcfield[crcGetFieldSize(CRCBufferSize)]; ret = recvBuffer(Handle, Method, crcfield, sizeof(crcfield), TimeoutMsec); // get size uint64 ReceivedCRC = crcExtract(crcfield, sizeof(crcfield)); //printf"comRecvBuf: %d\n", ret); if (ret > 0) { if (ReceivedCRC == CalculatedCRC) // check the data ret = sendByte(Handle, Method, pccACK); // good!!! else { if (AttempsCount <= MaxAttempsCount) { AttempsCount++; ret = sendByte(Handle, Method, pccNAK); // and go to wait this packet again goto lblWaitAgain; } else { free(data); data = NULL; } } } else { free(data); data = NULL; } } else { free(data); data = NULL; } } else { free(data); data = NULL; } } break; case pccEOT: // query close connection data = NULL; break; case pccBEL: sendByte(Handle, Method, pccBEL); goto lblWaitAgain; default: data = NULL; break; } } else { *control = 0; data = NULL; } /*if (data) cphDecrypt(data, data, PCSessionKey, AlignedSize, ToServer); // decipher received data*/ return data; }