Fixed TransportCRC compatibility with CRC-16-CCITT

This commit is contained in:
Pavel Kirienko
2014-02-26 09:45:06 +04:00
parent a6ab9c416f
commit 887ee64d54
3 changed files with 39 additions and 26 deletions
@@ -4,6 +4,7 @@
#pragma once #pragma once
#include <cassert>
#include <stdint.h> #include <stdint.h>
namespace uavcan namespace uavcan
@@ -11,8 +12,16 @@ namespace uavcan
/** /**
* CRC-16-CCITT * CRC-16-CCITT
* Initial value: 0x0000 * Initial value: 0xFFFF
* Coefficient: 0x1021 * Poly: 0x1021
* Reverse: no
* Output xor: 0
*
* import crcmod
* crc = crcmod.predefined.Crc('crc-ccitt-false')
* crc.update('123456789')
* crc.hexdigest()
* '29B1'
*/ */
class TransportCRC class TransportCRC
{ {
@@ -23,17 +32,26 @@ public:
enum { NumBytes = 2 }; enum { NumBytes = 2 };
TransportCRC() TransportCRC()
: value_(0x0000) : value_(0xFFFF)
{ } { }
TransportCRC(const uint8_t* bytes, unsigned int len) TransportCRC(const uint8_t* bytes, unsigned int len)
: value_(0x0000) : value_(0xFFFF)
{ {
add(bytes, len); add(bytes, len);
} }
uint16_t add(uint8_t byte); void add(uint8_t byte)
uint16_t add(const uint8_t* bytes, unsigned int len); {
value_ = ((value_ << 8) ^ Table[((value_ >> 8) ^ byte) & 0xFF]) & 0xFFFF;
}
void add(const uint8_t* bytes, unsigned int len)
{
assert(bytes);
while (len--)
add(*bytes++);
}
uint16_t get() const { return value_; } uint16_t get() const { return value_; }
}; };
-14
View File
@@ -45,18 +45,4 @@ const uint16_t TransportCRC::Table[256] =
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
}; };
uint16_t TransportCRC::add(uint8_t byte)
{
value_ = (value_ << 8) ^ Table[((value_ >> 8) ^ byte) & 0xFF];
return value_;
}
uint16_t TransportCRC::add(const uint8_t* bytes, unsigned int len)
{
assert(bytes);
while (len--)
add(*bytes++);
return value_;
}
} }
+15 -6
View File
@@ -2,25 +2,34 @@
* Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com> * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
*/ */
#include <algorithm>
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <uavcan/internal/transport/crc.hpp> #include <uavcan/internal/transport/crc.hpp>
/*
import crcmod
crc = crcmod.predefined.Crc('crc-ccitt-false')
crc.update('123')
crc.hexdigest()
'5BCE'
crc.update('456789')
crc.hexdigest()
'29B1'
*/
TEST(TransportCRC, Correctness) TEST(TransportCRC, Correctness)
{ {
uavcan::TransportCRC crc; uavcan::TransportCRC crc;
ASSERT_EQ(0x0000, crc.get()); ASSERT_EQ(0xFFFF, crc.get());
crc.add('1'); crc.add('1');
crc.add('2'); crc.add('2');
crc.add('3'); crc.add('3');
ASSERT_EQ(38738, crc.get()); ASSERT_EQ(0x5BCE, crc.get());
crc.add(reinterpret_cast<const uint8_t*>("Foobar"), 6); crc.add(reinterpret_cast<const uint8_t*>("456789"), 6);
ASSERT_EQ(53881, crc.get()); ASSERT_EQ(0x29B1, crc.get());
// Initializing constructor // Initializing constructor
ASSERT_EQ(crc.get(), uavcan::TransportCRC(reinterpret_cast<const uint8_t*>("123Foobar"), 9).get()); ASSERT_EQ(crc.get(), uavcan::TransportCRC(reinterpret_cast<const uint8_t*>("123456789"), 9).get());
} }