Search code examples
ccrcmodbuscrc16

Crash when validating the CRC of a dynamic byte array | c


For an embedded system I am writing code in c to validate a received byte array based on the provided CRC. The system is active in an RTU Modbus.

In my unit test I have the following (correct) byte array:

unsigned char frame[7] = { 0x01, 0x04, 0x02, 0x03, 0xFF, 0x80, 0xF9 }

The last two bytes are the provided CRC code that I want to validate.

My approach is to split the received array into two arrays. The first array being n-2 in length and the second array being 2 in length. Afterwards, create my own CRC code based on the first array, and finally I want to validating if the second array and my own CRC code are the same.

This is the code I have right now:

bool validateCrc16ModbusFrame(unsigned char frame[])
{
   // A valid response frame consists of at least 6 bytes.
   size_t size = sizeof frame;  
   if (size < 6) {
       return false;
   }

   // Split the frame into the 'bytes to check' and the 'provided CRC.'
   int newSize = size - 2;
   unsigned char* bytesToCheck = (unsigned char*)_malloca(newSize + 1); // Not sure about this line.
   char providedCrc[2];
   memcpy(bytesToCheck, frame, newSize * sizeof(int));
   memcpy(providedCrc, &frame[newSize], 2 * sizeof(int));

   // Calculate the CRC with the bytes to check.
   uint16_t calculatedCrc = calculateCrc16Modbus(bytesToCheck, newSize); // This function calculates the correct CRC code.
   _freea(bytesToCheck); // Not sure about this line.

   // The CRC is provided as two uint8_t bytes. Convered the two uint8_t to one uint16_t.
   uint8_t firstByteProvidedCrc = providedCrc[0];
   uint8_t secondByteProvidedCrc = providedCrc[1];
   uint16_t uint16ProvidedCrc = ((uint16_t)firstByteProvidedCrc << 8) | secondByteProvidedCrc;

   // Compare the provided CRC and the calculated CRC.
   bool result = uint16ProvidedCrc == calculatedCrc;
   return result;
}

But when I run the test code it crashes with the message '!! This test has probaly CRASHED !!' When I debug the test code I get an exception with the message 'TestProjectName.exe has triggered a breakpoint.' I think the problem arises from creating and/or freeing the memory for the dynamic byte array.

Anyone know what I'm doing wrong?

Thanks in advance.

Kind regards, Frenk


Solution

  • The problem is the memcpy calls are multiplying newsize by sizeof(int), when only newsize+1 characters are allocated. They should probably be:

       memcpy(bytesToCheck, frame, newSize);       /* no sizeof(int) */
       memcpy(providedCrc, &frame[newSize], 2);    /* no sizeof(int) */
    

    Also you don't need to copy or split the array. You can calculate the CRC on the original array including the appended CRC, and the resulting CRC will be zero if the CRC is not post complemented, or some non-zero constant value if the CRC is post complemented.