From 057574b2ecc6b5c39a2a30ed909504b9bdfbac91 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Wed, 26 Feb 2014 19:01:12 +0400 Subject: [PATCH] DataTypeSignature --- .../include/uavcan/internal/data_type.hpp | 25 ++++++++++ libuavcan/src/data_type.cpp | 37 ++++++++++++++ libuavcan/test/data_type.cpp | 48 +++++++++++++++++++ 3 files changed, 110 insertions(+) create mode 100644 libuavcan/src/data_type.cpp diff --git a/libuavcan/include/uavcan/internal/data_type.hpp b/libuavcan/include/uavcan/internal/data_type.hpp index 650ef7ad46..e820cc0cad 100644 --- a/libuavcan/include/uavcan/internal/data_type.hpp +++ b/libuavcan/include/uavcan/internal/data_type.hpp @@ -7,6 +7,7 @@ #include #include #include +#include namespace uavcan { @@ -60,6 +61,30 @@ public: }; +class DataTypeSignature +{ + uint64_t value_; + + void mixin64(uint64_t x); + + DataTypeSignature() : value_(0) { } + +public: + static DataTypeSignature zero() { return DataTypeSignature(); } + + explicit DataTypeSignature(uint64_t value) : value_(value) { } + + void extend(DataTypeSignature dts); + + TransferCRC toTransferCRC() const; + + uint64_t get() const { return value_; } + + bool operator==(DataTypeSignature rhs) const { return value_ == rhs.value_; } + bool operator!=(DataTypeSignature rhs) const { return !operator==(rhs); } +}; + + struct DataTypeHash { enum { NumBytes = 16 }; diff --git a/libuavcan/src/data_type.cpp b/libuavcan/src/data_type.cpp new file mode 100644 index 0000000000..654846e145 --- /dev/null +++ b/libuavcan/src/data_type.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2014 Pavel Kirienko + */ + +#include +#include +#include + +namespace uavcan +{ +/* + * DataTypeSignature + */ +void DataTypeSignature::mixin64(uint64_t x) +{ + DataTypeSignatureCRC crc = DataTypeSignatureCRC::extend(value_); + for (int i = 0; i < 64; i += 8) // LSB first + crc.add((x >> i) & 0xFF); + value_ = crc.get(); +} + +void DataTypeSignature::extend(DataTypeSignature dts) +{ + const uint64_t y = value_; + mixin64(dts.get()); + mixin64(y); +} + +TransferCRC DataTypeSignature::toTransferCRC() const +{ + TransferCRC tcrc; + for (int i = 0; i < 64; i += 8) // LSB first + tcrc.add((value_ >> i) & 0xFF); + return tcrc; +} + +} diff --git a/libuavcan/test/data_type.cpp b/libuavcan/test/data_type.cpp index a2ca68dfb7..5bb38c97e7 100644 --- a/libuavcan/test/data_type.cpp +++ b/libuavcan/test/data_type.cpp @@ -35,3 +35,51 @@ TEST(DataTypeSignatureCRC, Extension) ASSERT_EQ(0x62EC59E3F1A4F00A, crc2.get()); } + + +TEST(DataTypeSignature, Correctness) +{ + using uavcan::DataTypeSignature; + using uavcan::DataTypeSignatureCRC; + + DataTypeSignature signature = DataTypeSignature::zero(); + ASSERT_EQ(0, signature.get()); + + /* + * First extension + */ + signature.extend(DataTypeSignature(0x123456789abcdef0)); + + DataTypeSignatureCRC crc; + crc.add(0xF0); + crc.add(0xDE); + crc.add(0xBC); + crc.add(0x9A); + crc.add(0x78); + crc.add(0x56); + crc.add(0x34); + crc.add(0x12); + for (int i = 0; i < 8; i++) + crc.add(0); + + ASSERT_EQ(crc.get(), signature.get()); + + const uint64_t old_signature = signature.get(); + + /* + * Second extension + */ + signature.extend(DataTypeSignature(0xfedcba9876543210)); + crc.add(0x10); + crc.add(0x32); + crc.add(0x54); + crc.add(0x76); + crc.add(0x98); + crc.add(0xba); + crc.add(0xdc); + crc.add(0xfe); + for (int i = 0; i < 64; i += 8) + crc.add((old_signature >> i) & 0xFF); + + ASSERT_EQ(crc.get(), signature.get()); +}