I'm trying to get going radio communication between a device and my server. Data from the device looks like this:
fa-00-01-09-16-aa-00-14-10-01-01-00-01-16-ff-ff-ff-ff-ff-ff-cb-14
where last two bytes are CRC. Now I need to send reply to my device and calculate its CRC as well. Device's data sheet doesn't say much and it only provides C function to calculate it, but I have a hard time understanding what should I feed to this function
unsigned int CRC_Check(unsigned char *ucCRC_Buf, unsigned char ucBufLength)
{
unsigned int uiX, uiY, uiCRC;
unsigned char ucStart = 0;
uiCRC = 0xFFFF; //set all 1
if (ucBufLength <= 0 || ucStart > ucBufLength)
{
uiCRC = 0;
}
else
{
ucBufLength += ucStart;
for (uiX = (unsigned int)ucStart; uiX < ucBufLength; uiX++)
{
uiCRC = (unsigned int)(uiCRC ^ ucCRC_Buf[uiX]);
for (uiY = 0; uiY <= 7; uiY++)
{
if((uiCRC & 1) != 0)
uiCRC = (unsigned int)((uiCRC >> 1)^0xA001);
else
uiCRC = (unsigned int)(uiCRC >> 1);
}
}
}
return uiCRC;
}
Data sheet also says "CRC check is conducted on the data packet excluding the start code & check code" that means first byte (0xFA) and last two bytes (the CRC).
Now I'm trying to understand what it expects as unsigned char *ucCRC_Buf
and unsigned char ucBufLength
. From my main I'm trying to do:
unsigned int crc = CRC_Check("00010916aa0014100101000116ffffffffffff",38);
printf("%d\n", crc);
Which is same string as in the beginning (without the first and last two bytes) and I'm expecting CB14 (hex). But it gives different number (54016 (dec) which is D300 (hex)).
Any idea what I'm doing wrong?
A CRC is pretty simple; you take a polynomial represented as bits and the data, and divide the polynomial into the data (or you represent the data as a polynomial and do the same thing). The remainder, which is between 0 and the polynomial is the CRC.
A cyclic redundancy check (CRC) is an error-detecting code commonly used in digital networks and storage devices to detect accidental changes to digital data. Blocks of data entering these systems get a short check value attached, based on the remainder of a polynomial division of their contents.
CRC Error Checking - No Errors Upon reception, an entire received codeword R(x) = "message + crc" can be checked simply by dividing R(x)/P(x) using the same generating polynomial. If the remainder after division equals zero, then no error was found.
Probably you have to pass the bytes themselves, not their hex-representation.
Change
unsigned int crc=CRC_Check("00010916aa0014100101000116ffffffffffff",38);
to
unsigned int crc=CRC_Check("\x00\x01\x09\x16\xaa\x00\x14\x10\x01\x01\x00\x01\x16\xff\xff\xff\xff\xff\xff", 19);
Note that there are only 19 bytes. (Thanks @alk)
The data server is sending is assumed in Hexadecimal
format.
You are passing a string to function which is giving you wrong results.
Correct way to verify is:
unsigned char data[] = {0x00,0x01,0x09,0x16,0xaa,0x00,0x14,0x10,0x01,0x01,0x00,0x01,0x16,0xff,0xff,0xff,0xff,0xff,0xff}
unsigned int CRC = CRC_Check(&data[0],19);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With