blob: d6735d4564d7ac4646c65ad6ad43c0c3f344b328 [file]
// Copyright 2025 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/hci_util.h"
#include <cstdint>
#include "pw_status/status.h"
#include "pw_unit_test/framework.h" // IWYU pragma: keep
namespace pw::bluetooth {
namespace {
TEST(HciUtilTest, GetHciHeaderSize_Command) {
pw::Result<size_t> result = GetHciHeaderSize(emboss::H4PacketType::COMMAND);
EXPECT_TRUE(result.ok());
EXPECT_EQ(result.value(), static_cast<size_t>(3));
}
TEST(HciUtilTest, GetHciHeaderSize_Acl) {
pw::Result<size_t> result = GetHciHeaderSize(emboss::H4PacketType::ACL_DATA);
EXPECT_TRUE(result.ok());
EXPECT_EQ(result.value(), static_cast<size_t>(4));
}
TEST(HciUtilTest, GetHciHeaderSize_Sync) {
pw::Result<size_t> result = GetHciHeaderSize(emboss::H4PacketType::SYNC_DATA);
EXPECT_TRUE(result.ok());
EXPECT_EQ(result.value(), static_cast<size_t>(3));
}
TEST(HciUtilTest, GetHciHeaderSize_Event) {
pw::Result<size_t> result = GetHciHeaderSize(emboss::H4PacketType::EVENT);
EXPECT_TRUE(result.ok());
EXPECT_EQ(result.value(), static_cast<size_t>(2));
}
TEST(HciUtilTest, GetHciHeaderSize_Iso) {
pw::Result<size_t> result = GetHciHeaderSize(emboss::H4PacketType::ISO_DATA);
EXPECT_TRUE(result.ok());
EXPECT_EQ(result.value(), static_cast<size_t>(4));
}
TEST(HciUtilTest, GetHciHeaderSize_Unknown) {
pw::Result<size_t> result = GetHciHeaderSize(emboss::H4PacketType::UNKNOWN);
EXPECT_FALSE(result.ok());
EXPECT_EQ(result.status(), Status::InvalidArgument());
}
TEST(HciUtilTest, GetHciHeaderSize_Invalid) {
pw::Result<size_t> result =
GetHciHeaderSize(static_cast<emboss::H4PacketType>(22));
EXPECT_FALSE(result.ok());
EXPECT_EQ(result.status(), Status::InvalidArgument());
}
TEST(HciUtilTest, GetHciPayloadSize_Command) {
std::array<uint8_t, 3> data = {0x03, 0x02, 0x10};
pw::Result<size_t> result =
GetHciPayloadSize(emboss::H4PacketType::COMMAND, data);
EXPECT_TRUE(result.ok());
EXPECT_EQ(result.value(), static_cast<size_t>(0x10));
}
TEST(HciUtilTest, GetHciPayloadSize_Command_OutOfRange) {
std::array<uint8_t, 2> data = {0x03, 0x02};
pw::Result<size_t> result =
GetHciPayloadSize(emboss::H4PacketType::COMMAND, data);
EXPECT_FALSE(result.ok());
EXPECT_EQ(result.status(), Status::OutOfRange());
}
TEST(HciUtilTest, GetHciPayloadSize_Acl) {
std::array<uint8_t, 4> data = {0x0c, 0x00, 0x34, 0x12};
pw::Result<size_t> result =
GetHciPayloadSize(emboss::H4PacketType::ACL_DATA, data);
EXPECT_TRUE(result.ok());
EXPECT_EQ(result.value(), static_cast<size_t>(0x1234));
}
TEST(HciUtilTest, GetHciPayloadSize_AclWithHci_OutOfRange) {
std::array<uint8_t, 3> data = {0x0c, 0x00, 0x34};
pw::Result<size_t> result =
GetHciPayloadSize(emboss::H4PacketType::ACL_DATA, data);
EXPECT_FALSE(result.ok());
EXPECT_EQ(result.status(), Status::OutOfRange());
}
TEST(HciUtilTest, GetHciPayloadSize_Sync) {
std::array<uint8_t, 3> data = {0x02, 0x00, 0x06};
pw::Result<size_t> result =
GetHciPayloadSize(emboss::H4PacketType::SYNC_DATA, data);
EXPECT_TRUE(result.ok());
EXPECT_EQ(result.value(), static_cast<size_t>(0x06));
}
TEST(HciUtilTest, GetHciPayloadSize_Sync_OutOfRange) {
std::array<uint8_t, 2> data = {0x02, 0x00};
pw::Result<size_t> result =
GetHciPayloadSize(emboss::H4PacketType::SYNC_DATA, data);
EXPECT_FALSE(result.ok());
EXPECT_EQ(result.status(), Status::OutOfRange());
}
TEST(HciUtilTest, GetHciPayloadSize_Event) {
std::array<uint8_t, 2> data = {0x0e, 0x04};
pw::Result<size_t> result =
GetHciPayloadSize(emboss::H4PacketType::EVENT, data);
EXPECT_TRUE(result.ok());
EXPECT_EQ(result.value(), static_cast<size_t>(0x04));
}
TEST(HciUtilTest, GetHciPayloadSize_Event_OutOfRange) {
std::array<uint8_t, 1> data = {0x0e};
pw::Result<size_t> result =
GetHciPayloadSize(emboss::H4PacketType::EVENT, data);
EXPECT_FALSE(result.ok());
EXPECT_EQ(result.status(), Status::OutOfRange());
}
TEST(HciUtilTest, GetHciPayloadSize_Iso) {
std::array<uint8_t, 4> data = {0x02, 0x00, 0x12, 0xAB};
pw::Result<size_t> result =
GetHciPayloadSize(emboss::H4PacketType::ISO_DATA, data);
EXPECT_TRUE(result.ok());
// The size is 14 bits, extract it via bitmask
EXPECT_EQ(result.value(), static_cast<size_t>(0xAB12 & 0x3FFF));
}
TEST(HciUtilTest, GetHciPayloadSize_Iso_OutOfRange) {
std::array<uint8_t, 3> data = {0x02, 0x00, 0x06};
pw::Result<size_t> result =
GetHciPayloadSize(emboss::H4PacketType::ISO_DATA, data);
EXPECT_FALSE(result.ok());
EXPECT_EQ(result.status(), Status::OutOfRange());
}
TEST(HciUtilTest, GetHciPayloadSize_Invalid) {
std::array<uint8_t, 3> data = {0x03, 0x02, 0x10};
pw::Result<size_t> result =
GetHciPayloadSize(static_cast<emboss::H4PacketType>(22), data);
EXPECT_FALSE(result.ok());
EXPECT_EQ(result.status(), Status::InvalidArgument());
}
} // namespace
} // namespace pw::bluetooth