• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 
15 #include "pw_hdlc/decoder.h"
16 
17 #include <array>
18 #include <cstddef>
19 
20 #include "gtest/gtest.h"
21 #include "pw_bytes/array.h"
22 #include "pw_hdlc/internal/protocol.h"
23 
24 namespace pw::hdlc {
25 namespace {
26 
27 using std::byte;
28 
TEST(Frame,Fields)29 TEST(Frame, Fields) {
30   static constexpr auto kFrameData =
31       bytes::String("\x05\xab\x42\x24\xf9\x54\xfb\x3d");
32   auto result = Frame::Parse(kFrameData);
33   ASSERT_TRUE(result.ok());
34   Frame& frame = result.value();
35 
36   EXPECT_EQ(frame.address(), 2u);
37   EXPECT_EQ(frame.control(), byte{0xab});
38 
39   EXPECT_EQ(frame.data().size(), 2u);
40   EXPECT_EQ(frame.data()[0], byte{0x42});
41   EXPECT_EQ(frame.data()[1], byte{0x24});
42 }
43 
TEST(Frame,MultibyteAddress)44 TEST(Frame, MultibyteAddress) {
45   static constexpr auto kFrameData =
46       bytes::String("\x2c\xd9\x33\x01\x02\xaf\xc8\x77\x48");
47   auto result = Frame::Parse(kFrameData);
48   ASSERT_TRUE(result.ok());
49   Frame& frame = result.value();
50 
51   EXPECT_EQ(frame.address(), 0b11011000010110u);
52   EXPECT_EQ(frame.control(), byte{0x33});
53 
54   EXPECT_EQ(frame.data().size(), 2u);
55   EXPECT_EQ(frame.data()[0], byte{0x01});
56   EXPECT_EQ(frame.data()[1], byte{0x02});
57 }
58 
TEST(Frame,MultibyteAddressTooLong)59 TEST(Frame, MultibyteAddressTooLong) {
60   // 11-byte encoded address.
61   constexpr auto kLongAddress =
62       bytes::String("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01");
63   static constexpr auto kFrameData = bytes::Concat(
64       kLongAddress, bytes::String("\x33\x01\x02\xaf\xc8\x77\x48"));
65   auto result = Frame::Parse(kFrameData);
66   EXPECT_EQ(result.status(), Status::DataLoss());
67 }
68 
TEST(Decoder,Clear)69 TEST(Decoder, Clear) {
70   DecoderBuffer<8> decoder;
71 
72   // Process a partial packet
73   decoder.Process(bytes::String("~1234abcd"),
74                   [](const Result<Frame>&) { FAIL(); });
75 
76   decoder.Clear();
77   Status status = Status::Unknown();
78 
79   decoder.Process(
80       bytes::String("~1234\xa3\xe0\xe3\x9b~"),
81       [&status](const Result<Frame>& result) { status = result.status(); });
82 
83   EXPECT_EQ(OkStatus(), status);
84 }
85 
TEST(Decoder,ExactFit)86 TEST(Decoder, ExactFit) {
87   DecoderBuffer<8> decoder;
88 
89   for (byte b : bytes::String("~1234\xa3\xe0\xe3\x9b")) {
90     EXPECT_EQ(Status::Unavailable(), decoder.Process(b).status());
91   }
92   auto result = decoder.Process(kFlag);
93   ASSERT_EQ(OkStatus(), result.status());
94   ASSERT_EQ(result.value().data().size(), 2u);
95   ASSERT_EQ(result.value().data()[0], byte{'3'});
96   ASSERT_EQ(result.value().data()[1], byte{'4'});
97 }
98 
TEST(Decoder,MinimumSizedBuffer)99 TEST(Decoder, MinimumSizedBuffer) {
100   DecoderBuffer<6> decoder;
101 
102   for (byte b : bytes::String("~12\xcd\x44\x53\x4f")) {
103     EXPECT_EQ(Status::Unavailable(), decoder.Process(b).status());
104   }
105 
106   auto result = decoder.Process(kFlag);
107   ASSERT_EQ(OkStatus(), result.status());
108   EXPECT_EQ(result.value().data().size(), 0u);
109 }
110 
TEST(Decoder,TooLargeForBuffer_ReportsResourceExhausted)111 TEST(Decoder, TooLargeForBuffer_ReportsResourceExhausted) {
112   DecoderBuffer<8> decoder;
113 
114   for (byte b : bytes::String("~12345\x1c\x3a\xf5\xcb")) {
115     EXPECT_EQ(Status::Unavailable(), decoder.Process(b).status());
116   }
117   EXPECT_EQ(Status::ResourceExhausted(), decoder.Process(kFlag).status());
118 
119   for (byte b : bytes::String("~12345678901234567890\xf2\x19\x63\x90")) {
120     EXPECT_EQ(Status::Unavailable(), decoder.Process(b).status());
121   }
122   EXPECT_EQ(Status::ResourceExhausted(), decoder.Process(kFlag).status());
123 }
124 
TEST(Decoder,TooLargeForBuffer_StaysWithinBufferBoundaries)125 TEST(Decoder, TooLargeForBuffer_StaysWithinBufferBoundaries) {
126   std::array<byte, 16> buffer = bytes::Initialized<16>('?');
127 
128   Decoder decoder(std::span(buffer.data(), 8));
129 
130   for (byte b : bytes::String("~12345678901234567890\xf2\x19\x63\x90")) {
131     EXPECT_EQ(Status::Unavailable(), decoder.Process(b).status());
132   }
133 
134   for (size_t i = 8; i < buffer.size(); ++i) {
135     ASSERT_EQ(byte{'?'}, buffer[i]);
136   }
137 
138   EXPECT_EQ(Status::ResourceExhausted(), decoder.Process(kFlag).status());
139 }
140 
TEST(Decoder,TooLargeForBuffer_DecodesNextFrame)141 TEST(Decoder, TooLargeForBuffer_DecodesNextFrame) {
142   DecoderBuffer<8> decoder;
143 
144   for (byte b : bytes::String("~12345678901234567890\xf2\x19\x63\x90")) {
145     EXPECT_EQ(Status::Unavailable(), decoder.Process(b).status());
146   }
147   EXPECT_EQ(Status::ResourceExhausted(), decoder.Process(kFlag).status());
148 
149   for (byte b : bytes::String("1234\xa3\xe0\xe3\x9b")) {
150     EXPECT_EQ(Status::Unavailable(), decoder.Process(b).status());
151   }
152   EXPECT_EQ(OkStatus(), decoder.Process(kFlag).status());
153 }
154 
155 }  // namespace
156 }  // namespace pw::hdlc
157