// 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(kValidPacket); fit::result 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(); ASSERT_EQ(payload, ErrorCode::kEncryptionKeySize); } TEST(PacketTest, EmptyPacketGivesError) { ByteBufferPtr empty_packet_ptr = std::make_unique(); fit::result 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(kUnknownCodePacket); fit::result 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 unfortunately_sized_packet; PacketWriter(kInvalidSmpCode, &unfortunately_sized_packet); ByteBufferPtr p = std::make_unique(unfortunately_sized_packet); fit::result 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(kMalformedPacket); fit::result 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