summaryrefslogtreecommitdiffstats
path: root/src/ipmiblob/crc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ipmiblob/crc.cpp')
-rw-r--r--src/ipmiblob/crc.cpp44
1 files changed, 44 insertions, 0 deletions
diff --git a/src/ipmiblob/crc.cpp b/src/ipmiblob/crc.cpp
new file mode 100644
index 0000000..d6f59ef
--- /dev/null
+++ b/src/ipmiblob/crc.cpp
@@ -0,0 +1,44 @@
+#include "crc.hpp"
+
+namespace host_tool
+{
+
+/*
+ * This implementation tracks the specification given at
+ * http://srecord.sourceforge.net/crc16-ccitt.html
+ * Code copied from internal portable sources.
+ */
+std::uint16_t generateCrc(const std::vector<std::uint8_t>& data)
+{
+ const std::uint16_t kPoly = 0x1021;
+ const std::uint16_t kLeftBit = 0x8000;
+ const int kExtraRounds = 2;
+ const std::uint8_t* bytes = data.data();
+ std::uint16_t crc = 0xFFFF;
+ std::size_t i;
+ std::size_t j;
+ std::size_t size = data.size();
+
+ for (i = 0; i < size + kExtraRounds; ++i)
+ {
+ for (j = 0; j < 8; ++j)
+ {
+ bool xor_flag = (crc & kLeftBit) ? 1 : 0;
+ crc <<= 1;
+ // If this isn't an extra round and the current byte's j'th bit from
+ // the left is set, increment the CRC.
+ if (i < size && (bytes[i] & (1 << (7 - j))))
+ {
+ crc++;
+ }
+ if (xor_flag)
+ {
+ crc ^= kPoly;
+ }
+ }
+ }
+
+ return crc;
+}
+
+} // namespace host_tool
OpenPOWER on IntegriCloud