shaneajg | 063d0e0 | 2020-08-03 11:57:41 -0400 | [diff] [blame] | 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 | |
Alexei Frolov | d3e5cb7 | 2021-01-08 13:08:45 -0800 | [diff] [blame] | 15 | #include "pw_hdlc/decoder.h" |
shaneajg | 063d0e0 | 2020-08-03 11:57:41 -0400 | [diff] [blame] | 16 | |
| 17 | #include <array> |
| 18 | #include <cstddef> |
| 19 | |
| 20 | #include "gtest/gtest.h" |
| 21 | #include "pw_bytes/array.h" |
Alexei Frolov | d3e5cb7 | 2021-01-08 13:08:45 -0800 | [diff] [blame] | 22 | #include "pw_hdlc_private/protocol.h" |
shaneajg | 063d0e0 | 2020-08-03 11:57:41 -0400 | [diff] [blame] | 23 | |
Alexei Frolov | d3e5cb7 | 2021-01-08 13:08:45 -0800 | [diff] [blame] | 24 | namespace pw::hdlc { |
shaneajg | 063d0e0 | 2020-08-03 11:57:41 -0400 | [diff] [blame] | 25 | namespace { |
| 26 | |
Wyatt Hepler | cdb0f4e | 2020-09-14 08:49:17 -0700 | [diff] [blame] | 27 | using std::byte; |
shaneajg | 063d0e0 | 2020-08-03 11:57:41 -0400 | [diff] [blame] | 28 | |
Wyatt Hepler | cdb0f4e | 2020-09-14 08:49:17 -0700 | [diff] [blame] | 29 | TEST(Frame, Fields) { |
| 30 | static constexpr auto kFrameData = bytes::String("1234\xa3\xe0\xe3\x9b"); |
| 31 | constexpr Frame frame(kFrameData); |
| 32 | |
| 33 | static_assert(frame.address() == unsigned{'1'}); |
| 34 | static_assert(frame.control() == byte{'2'}); |
| 35 | |
| 36 | static_assert(frame.data().size() == 2u); |
| 37 | static_assert(frame.data()[0] == byte{'3'}); |
| 38 | static_assert(frame.data()[1] == byte{'4'}); |
shaneajg | 063d0e0 | 2020-08-03 11:57:41 -0400 | [diff] [blame] | 39 | } |
| 40 | |
Wyatt Hepler | cdb0f4e | 2020-09-14 08:49:17 -0700 | [diff] [blame] | 41 | TEST(Decoder, Clear) { |
| 42 | DecoderBuffer<8> decoder; |
shaneajg | 063d0e0 | 2020-08-03 11:57:41 -0400 | [diff] [blame] | 43 | |
Wyatt Hepler | cdb0f4e | 2020-09-14 08:49:17 -0700 | [diff] [blame] | 44 | // Process a partial packet |
| 45 | decoder.Process(bytes::String("~1234abcd"), |
| 46 | [](const Result<Frame>&) { FAIL(); }); |
| 47 | |
Alexei Frolov | 5039a81 | 2021-01-20 15:14:06 -0800 | [diff] [blame] | 48 | decoder.Clear(); |
Wyatt Hepler | d78f7c6 | 2020-09-28 14:27:32 -0700 | [diff] [blame] | 49 | Status status = Status::Unknown(); |
Wyatt Hepler | cdb0f4e | 2020-09-14 08:49:17 -0700 | [diff] [blame] | 50 | |
| 51 | decoder.Process( |
| 52 | bytes::String("~1234\xa3\xe0\xe3\x9b~"), |
| 53 | [&status](const Result<Frame>& result) { status = result.status(); }); |
| 54 | |
Wyatt Hepler | 1b3da3a | 2021-01-07 13:26:57 -0800 | [diff] [blame] | 55 | EXPECT_EQ(OkStatus(), status); |
shaneajg | 063d0e0 | 2020-08-03 11:57:41 -0400 | [diff] [blame] | 56 | } |
| 57 | |
Wyatt Hepler | cdb0f4e | 2020-09-14 08:49:17 -0700 | [diff] [blame] | 58 | TEST(Decoder, ExactFit) { |
| 59 | DecoderBuffer<8> decoder; |
shaneajg | 063d0e0 | 2020-08-03 11:57:41 -0400 | [diff] [blame] | 60 | |
Wyatt Hepler | cdb0f4e | 2020-09-14 08:49:17 -0700 | [diff] [blame] | 61 | for (byte b : bytes::String("~1234\xa3\xe0\xe3\x9b")) { |
Wyatt Hepler | d78f7c6 | 2020-09-28 14:27:32 -0700 | [diff] [blame] | 62 | EXPECT_EQ(Status::Unavailable(), decoder.Process(b).status()); |
shaneajg | 063d0e0 | 2020-08-03 11:57:41 -0400 | [diff] [blame] | 63 | } |
Wyatt Hepler | cdb0f4e | 2020-09-14 08:49:17 -0700 | [diff] [blame] | 64 | auto result = decoder.Process(kFlag); |
Wyatt Hepler | 1b3da3a | 2021-01-07 13:26:57 -0800 | [diff] [blame] | 65 | ASSERT_EQ(OkStatus(), result.status()); |
Wyatt Hepler | cdb0f4e | 2020-09-14 08:49:17 -0700 | [diff] [blame] | 66 | ASSERT_EQ(result.value().data().size(), 2u); |
| 67 | ASSERT_EQ(result.value().data()[0], byte{'3'}); |
| 68 | ASSERT_EQ(result.value().data()[1], byte{'4'}); |
shaneajg | 063d0e0 | 2020-08-03 11:57:41 -0400 | [diff] [blame] | 69 | } |
| 70 | |
Wyatt Hepler | cdb0f4e | 2020-09-14 08:49:17 -0700 | [diff] [blame] | 71 | TEST(Decoder, MinimumSizedBuffer) { |
| 72 | DecoderBuffer<6> decoder; |
shaneajg | 063d0e0 | 2020-08-03 11:57:41 -0400 | [diff] [blame] | 73 | |
Wyatt Hepler | cdb0f4e | 2020-09-14 08:49:17 -0700 | [diff] [blame] | 74 | for (byte b : bytes::String("~12\xcd\x44\x53\x4f")) { |
Wyatt Hepler | d78f7c6 | 2020-09-28 14:27:32 -0700 | [diff] [blame] | 75 | EXPECT_EQ(Status::Unavailable(), decoder.Process(b).status()); |
shaneajg | 063d0e0 | 2020-08-03 11:57:41 -0400 | [diff] [blame] | 76 | } |
Wyatt Hepler | cdb0f4e | 2020-09-14 08:49:17 -0700 | [diff] [blame] | 77 | |
| 78 | auto result = decoder.Process(kFlag); |
Wyatt Hepler | 1b3da3a | 2021-01-07 13:26:57 -0800 | [diff] [blame] | 79 | ASSERT_EQ(OkStatus(), result.status()); |
Wyatt Hepler | cdb0f4e | 2020-09-14 08:49:17 -0700 | [diff] [blame] | 80 | EXPECT_EQ(result.value().data().size(), 0u); |
shaneajg | 063d0e0 | 2020-08-03 11:57:41 -0400 | [diff] [blame] | 81 | } |
| 82 | |
Wyatt Hepler | cdb0f4e | 2020-09-14 08:49:17 -0700 | [diff] [blame] | 83 | TEST(Decoder, TooLargeForBuffer_ReportsResourceExhausted) { |
| 84 | DecoderBuffer<8> decoder; |
shaneajg | 063d0e0 | 2020-08-03 11:57:41 -0400 | [diff] [blame] | 85 | |
Alexei Frolov | 5039a81 | 2021-01-20 15:14:06 -0800 | [diff] [blame] | 86 | for (byte b : bytes::String("~12345\x1c\x3a\xf5\xcb")) { |
Wyatt Hepler | d78f7c6 | 2020-09-28 14:27:32 -0700 | [diff] [blame] | 87 | EXPECT_EQ(Status::Unavailable(), decoder.Process(b).status()); |
shaneajg | 063d0e0 | 2020-08-03 11:57:41 -0400 | [diff] [blame] | 88 | } |
Wyatt Hepler | d78f7c6 | 2020-09-28 14:27:32 -0700 | [diff] [blame] | 89 | EXPECT_EQ(Status::ResourceExhausted(), decoder.Process(kFlag).status()); |
Wyatt Hepler | cdb0f4e | 2020-09-14 08:49:17 -0700 | [diff] [blame] | 90 | |
Alexei Frolov | 5039a81 | 2021-01-20 15:14:06 -0800 | [diff] [blame] | 91 | for (byte b : bytes::String("~12345678901234567890\xf2\x19\x63\x90")) { |
Wyatt Hepler | d78f7c6 | 2020-09-28 14:27:32 -0700 | [diff] [blame] | 92 | EXPECT_EQ(Status::Unavailable(), decoder.Process(b).status()); |
Wyatt Hepler | cdb0f4e | 2020-09-14 08:49:17 -0700 | [diff] [blame] | 93 | } |
Wyatt Hepler | d78f7c6 | 2020-09-28 14:27:32 -0700 | [diff] [blame] | 94 | EXPECT_EQ(Status::ResourceExhausted(), decoder.Process(kFlag).status()); |
shaneajg | 063d0e0 | 2020-08-03 11:57:41 -0400 | [diff] [blame] | 95 | } |
| 96 | |
Wyatt Hepler | cdb0f4e | 2020-09-14 08:49:17 -0700 | [diff] [blame] | 97 | TEST(Decoder, TooLargeForBuffer_StaysWithinBufferBoundaries) { |
| 98 | std::array<byte, 16> buffer = bytes::Initialized<16>('?'); |
shaneajg | 063d0e0 | 2020-08-03 11:57:41 -0400 | [diff] [blame] | 99 | |
Wyatt Hepler | cdb0f4e | 2020-09-14 08:49:17 -0700 | [diff] [blame] | 100 | Decoder decoder(std::span(buffer.data(), 8)); |
| 101 | |
Alexei Frolov | 5039a81 | 2021-01-20 15:14:06 -0800 | [diff] [blame] | 102 | for (byte b : bytes::String("~12345678901234567890\xf2\x19\x63\x90")) { |
Wyatt Hepler | d78f7c6 | 2020-09-28 14:27:32 -0700 | [diff] [blame] | 103 | EXPECT_EQ(Status::Unavailable(), decoder.Process(b).status()); |
shaneajg | 063d0e0 | 2020-08-03 11:57:41 -0400 | [diff] [blame] | 104 | } |
Wyatt Hepler | cdb0f4e | 2020-09-14 08:49:17 -0700 | [diff] [blame] | 105 | |
| 106 | for (size_t i = 8; i < buffer.size(); ++i) { |
| 107 | ASSERT_EQ(byte{'?'}, buffer[i]); |
| 108 | } |
| 109 | |
Wyatt Hepler | d78f7c6 | 2020-09-28 14:27:32 -0700 | [diff] [blame] | 110 | EXPECT_EQ(Status::ResourceExhausted(), decoder.Process(kFlag).status()); |
shaneajg | 063d0e0 | 2020-08-03 11:57:41 -0400 | [diff] [blame] | 111 | } |
| 112 | |
Wyatt Hepler | cdb0f4e | 2020-09-14 08:49:17 -0700 | [diff] [blame] | 113 | TEST(Decoder, TooLargeForBuffer_DecodesNextFrame) { |
| 114 | DecoderBuffer<8> decoder; |
shaneajg | 063d0e0 | 2020-08-03 11:57:41 -0400 | [diff] [blame] | 115 | |
Alexei Frolov | 5039a81 | 2021-01-20 15:14:06 -0800 | [diff] [blame] | 116 | for (byte b : bytes::String("~12345678901234567890\xf2\x19\x63\x90")) { |
Wyatt Hepler | d78f7c6 | 2020-09-28 14:27:32 -0700 | [diff] [blame] | 117 | EXPECT_EQ(Status::Unavailable(), decoder.Process(b).status()); |
shaneajg | 063d0e0 | 2020-08-03 11:57:41 -0400 | [diff] [blame] | 118 | } |
Wyatt Hepler | d78f7c6 | 2020-09-28 14:27:32 -0700 | [diff] [blame] | 119 | EXPECT_EQ(Status::ResourceExhausted(), decoder.Process(kFlag).status()); |
shaneajg | 063d0e0 | 2020-08-03 11:57:41 -0400 | [diff] [blame] | 120 | |
Wyatt Hepler | cdb0f4e | 2020-09-14 08:49:17 -0700 | [diff] [blame] | 121 | for (byte b : bytes::String("1234\xa3\xe0\xe3\x9b")) { |
Wyatt Hepler | d78f7c6 | 2020-09-28 14:27:32 -0700 | [diff] [blame] | 122 | EXPECT_EQ(Status::Unavailable(), decoder.Process(b).status()); |
shaneajg | 063d0e0 | 2020-08-03 11:57:41 -0400 | [diff] [blame] | 123 | } |
Wyatt Hepler | 1b3da3a | 2021-01-07 13:26:57 -0800 | [diff] [blame] | 124 | EXPECT_EQ(OkStatus(), decoder.Process(kFlag).status()); |
shaneajg | 063d0e0 | 2020-08-03 11:57:41 -0400 | [diff] [blame] | 125 | } |
| 126 | |
| 127 | } // namespace |
Alexei Frolov | d3e5cb7 | 2021-01-08 13:08:45 -0800 | [diff] [blame] | 128 | } // namespace pw::hdlc |