| // Copyright 2023 The Pigweed Authors |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| // use this file except in compliance with the License. You may obtain a copy of |
| // the License at |
| // |
| // https://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| // License for the specific language governing permissions and limitations under |
| // the License. |
| |
| #include "pw_bluetooth_sapphire/internal/host/sm/packet.h" |
| |
| #include "pw_bluetooth_sapphire/internal/host/common/byte_buffer.h" |
| #include "pw_unit_test/framework.h" |
| |
| namespace bt::sm { |
| namespace { |
| |
| TEST(PacketTest, ParseValidPacket) { |
| StaticByteBuffer kValidPacket(kPairingFailed, ErrorCode::kEncryptionKeySize); |
| ByteBufferPtr valid_packet_ptr = |
| std::make_unique<DynamicByteBuffer>(kValidPacket); |
| fit::result<ErrorCode, ValidPacketReader> maybe_reader = |
| ValidPacketReader::ParseSdu(valid_packet_ptr); |
| ASSERT_TRUE(maybe_reader.is_ok()); |
| ValidPacketReader reader = maybe_reader.value(); |
| ASSERT_EQ(reader.code(), kPairingFailed); |
| ErrorCode payload = reader.payload<ErrorCode>(); |
| ASSERT_EQ(payload, ErrorCode::kEncryptionKeySize); |
| } |
| |
| TEST(PacketTest, EmptyPacketGivesError) { |
| ByteBufferPtr empty_packet_ptr = std::make_unique<DynamicByteBuffer>(); |
| fit::result<ErrorCode, ValidPacketReader> maybe_reader = |
| ValidPacketReader::ParseSdu(empty_packet_ptr); |
| ASSERT_TRUE(maybe_reader.is_error()); |
| ErrorCode ecode = maybe_reader.error_value(); |
| ASSERT_EQ(ecode, ErrorCode::kInvalidParameters); |
| } |
| |
| TEST(PacketTest, UnknownSMPCodeGivesError) { |
| StaticByteBuffer kUnknownCodePacket( |
| 0xFF, // Not a valid SMP packet header code. |
| ErrorCode::kEncryptionKeySize); |
| ByteBufferPtr unknown_code_packet_ptr = |
| std::make_unique<DynamicByteBuffer>(kUnknownCodePacket); |
| fit::result<ErrorCode, ValidPacketReader> maybe_reader = |
| ValidPacketReader::ParseSdu(unknown_code_packet_ptr); |
| ASSERT_TRUE(maybe_reader.is_error()); |
| ErrorCode ecode = maybe_reader.error_value(); |
| ASSERT_EQ(ecode, ErrorCode::kCommandNotSupported); |
| } |
| |
| // This tests a case where the `size_t` packet size was stored into a `uint8_t`. |
| // If the packet size modulo 2^8 was 0, the length would overflow the `uint8_t` |
| // and the packet would be incorrectly recognized as having 0 length, leading to |
| // the wrong error being returned (and logged). |
| TEST(PacketTest, Mod256Equals0LengthPacketGivesCorrectError) { |
| constexpr size_t k2ToThe8Size = 256; |
| Code kInvalidSmpCode = 0xFF; |
| StaticByteBuffer<k2ToThe8Size> unfortunately_sized_packet; |
| PacketWriter(kInvalidSmpCode, &unfortunately_sized_packet); |
| ByteBufferPtr p = |
| std::make_unique<DynamicByteBuffer>(unfortunately_sized_packet); |
| fit::result<ErrorCode, ValidPacketReader> maybe_reader = |
| ValidPacketReader::ParseSdu(p); |
| ASSERT_TRUE(maybe_reader.is_error()); |
| ErrorCode ecode = maybe_reader.error_value(); |
| ASSERT_EQ(ecode, ErrorCode::kCommandNotSupported); |
| } |
| |
| TEST(PacketTest, PayloadSizeDoesNotMatchHeaderGivesError) { |
| // The PairingFailed code is expected to have a one byte error code as |
| // payload, not three bytes. |
| StaticByteBuffer kMalformedPacket(kPairingFailed, 0x01, 0x01, 0x01); |
| ByteBufferPtr malformed_packet_ptr = |
| std::make_unique<DynamicByteBuffer>(kMalformedPacket); |
| fit::result<ErrorCode, ValidPacketReader> maybe_reader = |
| ValidPacketReader::ParseSdu(malformed_packet_ptr); |
| ASSERT_TRUE(maybe_reader.is_error()); |
| ErrorCode ecode = maybe_reader.error_value(); |
| ASSERT_EQ(ecode, ErrorCode::kInvalidParameters); |
| } |
| |
| } // namespace |
| } // namespace bt::sm |