diff --git a/docs/formats.html b/docs/formats.html index cac1788..3eb76b2 100644 --- a/docs/formats.html +++ b/docs/formats.html @@ -589,6 +589,11 @@ In input, the next byte or bytes must match the checksum. href="http://www.ietf.org/rfc/rfc1950.txt">RFC 1950.
%<hexsum8>
One byte. The sum of all hex digits. (Other characters are ignored.)
+
%<lrc>
+
One byte. The Longitudinal Redundancy Check according to Wikipedia.
+
%<hexlrc>
+
One byte. The LRC for the hex digits. (Other characters are ignored.)
diff --git a/src/ChecksumConverter.cc b/src/ChecksumConverter.cc index df0a2c9..c1396bb 100755 --- a/src/ChecksumConverter.cc +++ b/src/ChecksumConverter.cc @@ -522,6 +522,57 @@ static uint32_t brksCryo(const uint8_t* data, size_t len, uint32_t sum) return xsum; } +// Longitudinal Redundancy Check +static uint32_t lrc(const uint8_t* data, size_t len, uint32_t sum) +{ + while (len--) { + sum = (sum + (*data++)) & 0xFF; + } + + sum = ((sum ^ 0xFF) + 1) & 0xFF; + + return sum; +} + +// Longitudinal Redundancy Check using ASCII representation of numbers, 2-by-2 +static uint32_t hexlrc(const uint8_t* data, size_t len, uint32_t sum) +{ + uint32_t d; + uint32_t final_digit = 0; + + while (len--) + { + d = toupper(*data++); + + // Convert all hex digits, ignore all other bytes + if (isxdigit(d)) + { + // Convert digits from ASCII to number + if (isdigit(d)) { + d -= '0'; + } + else { + d -= 'A' - 0x0A; + } + + // For the most significant bits, shift 4 bits + if (len % 2) { + final_digit = d << 4; + // Least significant bits are summed to previous converted digit + } else { + d += final_digit; + final_digit = 0; + // Apply lrc rule + sum = (sum + d) & 0xFF; + } + } + } + + // Apply lrc rule + sum = ((sum ^ 0xFF) + 1) & 0xFF; + + return sum; +} struct checksum { @@ -565,7 +616,9 @@ static checksum checksumMap[] = {"hexsum8", hexsum, 0x00, 0x00, 1}, // 0x2D {"cpi", CPI, 0x00, 0x00, 1}, // 0x7E {"leybold", leybold, 0x00, 0x00, 1}, // 0x22 - {"brksCryo",brksCryo, 0x00, 0x00, 1} // 0x4A + {"brksCryo",brksCryo, 0x00, 0x00, 1}, // 0x4A + {"lrc", lrc, 0x00, 0x00, 1}, // 0x23 + {"hexlrc", hexlrc, 0x00, 0x00, 1} // 0xA7 }; static uint32_t mask[5] = {0, 0xFF, 0xFFFF, 0xFFFFFF, 0xFFFFFFFF}; diff --git a/streamApp/checksums.proto b/streamApp/checksums.proto index e0dea78..5624437 100644 --- a/streamApp/checksums.proto +++ b/streamApp/checksums.proto @@ -54,4 +54,6 @@ write { out "%s hexsum8 %0.12"; out "%s cpi %0.12"; out "%s leybold %0.12"; + out "%s lrc %0.12"; + out "%s hexlrc %0.12"; }