1*61c4878aSAndroid Build Coastguard Worker // Copyright 2020 The Pigweed Authors
2*61c4878aSAndroid Build Coastguard Worker //
3*61c4878aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4*61c4878aSAndroid Build Coastguard Worker // use this file except in compliance with the License. You may obtain a copy of
5*61c4878aSAndroid Build Coastguard Worker // the License at
6*61c4878aSAndroid Build Coastguard Worker //
7*61c4878aSAndroid Build Coastguard Worker // https://www.apache.org/licenses/LICENSE-2.0
8*61c4878aSAndroid Build Coastguard Worker //
9*61c4878aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*61c4878aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11*61c4878aSAndroid Build Coastguard Worker // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12*61c4878aSAndroid Build Coastguard Worker // License for the specific language governing permissions and limitations under
13*61c4878aSAndroid Build Coastguard Worker // the License.
14*61c4878aSAndroid Build Coastguard Worker
15*61c4878aSAndroid Build Coastguard Worker #include "pw_checksum/crc16_ccitt.h"
16*61c4878aSAndroid Build Coastguard Worker
17*61c4878aSAndroid Build Coastguard Worker #include <string_view>
18*61c4878aSAndroid Build Coastguard Worker
19*61c4878aSAndroid Build Coastguard Worker #include "pw_unit_test/framework.h"
20*61c4878aSAndroid Build Coastguard Worker
21*61c4878aSAndroid Build Coastguard Worker namespace pw::checksum {
22*61c4878aSAndroid Build Coastguard Worker namespace {
23*61c4878aSAndroid Build Coastguard Worker
24*61c4878aSAndroid Build Coastguard Worker // The expected CRC16 values were calculated using
25*61c4878aSAndroid Build Coastguard Worker //
26*61c4878aSAndroid Build Coastguard Worker // http://www.sunshine2k.de/coding/javascript/crc/crc_js.html
27*61c4878aSAndroid Build Coastguard Worker //
28*61c4878aSAndroid Build Coastguard Worker // with polynomial 0x1021, initial value 0xFFFF.
29*61c4878aSAndroid Build Coastguard Worker constexpr uint8_t kBytes[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
30*61c4878aSAndroid Build Coastguard Worker constexpr uint16_t kBufferCrc = 0x3B0A;
31*61c4878aSAndroid Build Coastguard Worker
32*61c4878aSAndroid Build Coastguard Worker constexpr std::string_view kString =
33*61c4878aSAndroid Build Coastguard Worker "In the beginning the Universe was created. This has made a lot of "
34*61c4878aSAndroid Build Coastguard Worker "people very angry and been widely regarded as a bad move.";
35*61c4878aSAndroid Build Coastguard Worker constexpr uint16_t kStringCrc = 0xC184;
36*61c4878aSAndroid Build Coastguard Worker
TEST(Crc16,Empty)37*61c4878aSAndroid Build Coastguard Worker TEST(Crc16, Empty) {
38*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Crc16Ccitt::Calculate(span<std::byte>()),
39*61c4878aSAndroid Build Coastguard Worker Crc16Ccitt::kInitialValue);
40*61c4878aSAndroid Build Coastguard Worker }
41*61c4878aSAndroid Build Coastguard Worker
TEST(Crc16,ByteByByte)42*61c4878aSAndroid Build Coastguard Worker TEST(Crc16, ByteByByte) {
43*61c4878aSAndroid Build Coastguard Worker uint16_t crc = Crc16Ccitt::kInitialValue;
44*61c4878aSAndroid Build Coastguard Worker for (size_t i = 0; i < sizeof(kBytes); i++) {
45*61c4878aSAndroid Build Coastguard Worker crc = Crc16Ccitt::Calculate(std::byte{kBytes[i]}, crc);
46*61c4878aSAndroid Build Coastguard Worker }
47*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(crc, kBufferCrc);
48*61c4878aSAndroid Build Coastguard Worker }
49*61c4878aSAndroid Build Coastguard Worker
TEST(Crc16,Buffer)50*61c4878aSAndroid Build Coastguard Worker TEST(Crc16, Buffer) {
51*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Crc16Ccitt::Calculate(as_bytes(span(kBytes))), kBufferCrc);
52*61c4878aSAndroid Build Coastguard Worker }
53*61c4878aSAndroid Build Coastguard Worker
TEST(Crc16,String)54*61c4878aSAndroid Build Coastguard Worker TEST(Crc16, String) {
55*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Crc16Ccitt::Calculate(as_bytes(span(kString))), kStringCrc);
56*61c4878aSAndroid Build Coastguard Worker }
57*61c4878aSAndroid Build Coastguard Worker
TEST(Crc16Class,Buffer)58*61c4878aSAndroid Build Coastguard Worker TEST(Crc16Class, Buffer) {
59*61c4878aSAndroid Build Coastguard Worker Crc16Ccitt crc16;
60*61c4878aSAndroid Build Coastguard Worker crc16.Update(as_bytes(span(kBytes)));
61*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(crc16.value(), kBufferCrc);
62*61c4878aSAndroid Build Coastguard Worker }
63*61c4878aSAndroid Build Coastguard Worker
TEST(Crc16Class,String)64*61c4878aSAndroid Build Coastguard Worker TEST(Crc16Class, String) {
65*61c4878aSAndroid Build Coastguard Worker Crc16Ccitt crc16;
66*61c4878aSAndroid Build Coastguard Worker crc16.Update(as_bytes(span(kString)));
67*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(crc16.value(), kStringCrc);
68*61c4878aSAndroid Build Coastguard Worker }
69*61c4878aSAndroid Build Coastguard Worker
70*61c4878aSAndroid Build Coastguard Worker extern "C" uint16_t CallChecksumCrc16Ccitt(const void* data, size_t size_bytes);
71*61c4878aSAndroid Build Coastguard Worker
TEST(Crc16FromC,Buffer)72*61c4878aSAndroid Build Coastguard Worker TEST(Crc16FromC, Buffer) {
73*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(CallChecksumCrc16Ccitt(kBytes, sizeof(kBytes)), kBufferCrc);
74*61c4878aSAndroid Build Coastguard Worker }
75*61c4878aSAndroid Build Coastguard Worker
TEST(Crc16FromC,String)76*61c4878aSAndroid Build Coastguard Worker TEST(Crc16FromC, String) {
77*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(CallChecksumCrc16Ccitt(kString.data(), kString.size()), kStringCrc);
78*61c4878aSAndroid Build Coastguard Worker }
79*61c4878aSAndroid Build Coastguard Worker
80*61c4878aSAndroid Build Coastguard Worker } // namespace
81*61c4878aSAndroid Build Coastguard Worker } // namespace pw::checksum
82