Separate integrity checks code from readFrames() function

This commit is contained in:
Alex Spataru 2021-09-23 20:19:34 -05:00
parent 2e54c6d73f
commit 5af8ffd748
2 changed files with 118 additions and 93 deletions

View File

@ -543,102 +543,20 @@ void Manager::readFrames()
cursor = cursor.mid(fIndex + finish.length(), -1);
bytes += fIndex + finish.length();
// Check CRC-8
if (cursor.startsWith("crc8:"))
{
// Enable the CRC flag
m_enableCrc = true;
// Check if we have enough data in the buffer
if (cursor.length() >= 6)
{
// Increment the number of bytes to remove from master buffer
bytes += 6;
// Get 8-bit checksum
quint8 crc = cursor.at(5);
// Compare checksums
if (crc8(frame.data(), frame.length()) == crc)
emit frameReceived(frame);
}
// Not enough data, check next time...
else
{
bytes = prevBytes;
break;
}
}
// Check CRC-16
else if (cursor.startsWith("crc16:"))
{
// Enable the CRC flag
m_enableCrc = true;
// Check if we have enough data in the buffer
if (cursor.length() >= 8)
{
// Increment the number of bytes to remove from master buffer
bytes += 8;
// Get 16-bit checksum
quint8 a = cursor.at(6);
quint8 b = cursor.at(7);
quint16 crc = (a << 8) | (b & 0xff);
// Compare checksums
if (crc16(frame.data(), frame.length()) == crc)
emit frameReceived(frame);
}
// Not enough data, check next time...
else
{
bytes = prevBytes;
break;
}
}
// Check CRC-32
else if (cursor.startsWith("crc32:"))
{
// Enable the CRC flag
m_enableCrc = true;
// Check if we have enough data in the buffer
if (cursor.length() >= 10)
{
// Increment the number of bytes to remove from master buffer
bytes += 10;
// Get 32-bit checksum
quint8 a = cursor.at(6);
quint8 b = cursor.at(7);
quint8 c = cursor.at(8);
quint8 d = cursor.at(9);
quint32 crc = (a << 24) | (b << 16) | (c << 8) | (d & 0xff);
// Compare checksums
if (crc32(frame.data(), frame.length()) == crc)
emit frameReceived(frame);
}
// Not enough data, check next time...
else
{
bytes = prevBytes;
break;
}
}
// Buffer does not contain CRC code
else if (!m_enableCrc)
// Checksum verification & emit RX frame
auto result = integrityChecks(frame, cursor, &bytes);
if (result == ValidationStatus::FrameOk)
emit frameReceived(frame);
// Checksum data incomplete, try next time...
else if (result == ValidationStatus::ChecksumIncomplete)
{
bytes = prevBytes;
break;
}
// Frame read successfully, save the number of bytes to chop.
// This is used to manage incomplete frames with checksums
// This is used to manage frames with incomplete checksums
prevBytes = bytes;
}
@ -724,3 +642,99 @@ void Manager::setDevice(QIODevice *device)
LOG_TRACE() << "Device pointer set to" << m_device;
}
/**
* Checks if the @c cursor has a checksum corresponding to the given @a frame.
* If so, the function shall calculate the appropiate checksum to for the @a frame and
* compare it with the sent checksum to ensure data integrity.
*
* @param frame data in which we shall perform integrity checks
* @param cursor master buffer, should start with checksum type header
* @param bytes pointer to the number of bytes that we need to chop from the master buffer
* @return
*/
Manager::ValidationStatus Manager::integrityChecks(const QByteArray &frame,
const QByteArray &cursor, int *bytes)
{
// Check CRC-8
if (cursor.startsWith("crc8:"))
{
// Enable the CRC flag
m_enableCrc = true;
// Check if we have enough data in the buffer
if (cursor.length() >= 6)
{
// Increment the number of bytes to remove from master buffer
*bytes += 6;
// Get 8-bit checksum
quint8 crc = cursor.at(5);
// Compare checksums
if (crc8(frame.data(), frame.length()) == crc)
return ValidationStatus::FrameOk;
else
return ValidationStatus::ChecksumError;
}
}
// Check CRC-16
else if (cursor.startsWith("crc16:"))
{
// Enable the CRC flag
m_enableCrc = true;
// Check if we have enough data in the buffer
if (cursor.length() >= 8)
{
// Increment the number of bytes to remove from master buffer
*bytes += 8;
// Get 16-bit checksum
quint8 a = cursor.at(6);
quint8 b = cursor.at(7);
quint16 crc = (a << 8) | (b & 0xff);
// Compare checksums
if (crc16(frame.data(), frame.length()) == crc)
return ValidationStatus::FrameOk;
else
return ValidationStatus::ChecksumError;
}
}
// Check CRC-32
else if (cursor.startsWith("crc32:"))
{
// Enable the CRC flag
m_enableCrc = true;
// Check if we have enough data in the buffer
if (cursor.length() >= 10)
{
// Increment the number of bytes to remove from master buffer
*bytes += 10;
// Get 32-bit checksum
quint8 a = cursor.at(6);
quint8 b = cursor.at(7);
quint8 c = cursor.at(8);
quint8 d = cursor.at(9);
quint32 crc = (a << 24) | (b << 16) | (c << 8) | (d & 0xff);
// Compare checksums
if (crc32(frame.data(), frame.length()) == crc)
return ValidationStatus::FrameOk;
else
return ValidationStatus::ChecksumError;
}
}
// Buffer does not contain CRC code
else if (!m_enableCrc)
return ValidationStatus::FrameOk;
// Checksum data incomplete
return ValidationStatus::ChecksumIncomplete;
}

View File

@ -97,6 +97,14 @@ public:
};
Q_ENUM(DataSource)
enum class ValidationStatus
{
FrameOk,
ChecksumError,
ChecksumIncomplete
};
Q_ENUM(ValidationStatus)
static Manager *getInstance();
bool readOnly();
@ -144,6 +152,9 @@ private:
Manager();
~Manager();
ValidationStatus integrityChecks(const QByteArray &frame,
const QByteArray &masterBuffer, int *bytesToChop);
private:
QTimer m_watchdog;
bool m_enableCrc;