blob: 2a5e203a7e84c168589123c539f754658a0b1d95 [file] [log] [blame]
// 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/hci/advertising_handle_map.h"
#include "pw_bluetooth_sapphire/internal/host/hci-spec/constants.h"
#include "pw_bluetooth_sapphire/internal/host/hci-spec/protocol.h"
#include "pw_unit_test/framework.h"
namespace bt::hci {
namespace {
TEST(AdvertisingHandleMapTest, Bidirectional) {
AdvertisingHandleMap handle_map;
DeviceAddress address_a = DeviceAddress(DeviceAddress::Type::kLEPublic, {0});
std::optional<hci_spec::AdvertisingHandle> handle_a =
handle_map.MapHandle(address_a);
EXPECT_LE(handle_a.value(), hci_spec::kMaxAdvertisingHandle);
EXPECT_TRUE(handle_a);
DeviceAddress address_b = DeviceAddress(DeviceAddress::Type::kLEPublic, {1});
std::optional<hci_spec::AdvertisingHandle> handle_b =
handle_map.MapHandle(address_b);
EXPECT_TRUE(handle_b);
EXPECT_LE(handle_b.value(), hci_spec::kMaxAdvertisingHandle);
EXPECT_EQ(address_a, handle_map.GetAddress(handle_a.value()));
EXPECT_EQ(address_b, handle_map.GetAddress(handle_b.value()));
}
TEST(AdvertisingHandleMapTest, GetHandleDoesntCreateMapping) {
AdvertisingHandleMap handle_map;
EXPECT_EQ(0u, handle_map.Size());
EXPECT_TRUE(handle_map.Empty());
DeviceAddress address = DeviceAddress(DeviceAddress::Type::kLEPublic, {0});
std::optional<hci_spec::AdvertisingHandle> handle =
handle_map.GetHandle(address);
EXPECT_EQ(0u, handle_map.Size());
EXPECT_TRUE(handle_map.Empty());
EXPECT_FALSE(handle);
handle = handle_map.MapHandle(address);
EXPECT_EQ(1u, handle_map.Size());
EXPECT_FALSE(handle_map.Empty());
EXPECT_TRUE(handle);
EXPECT_EQ(0u, handle.value());
handle = handle_map.GetHandle(address);
EXPECT_EQ(1u, handle_map.Size());
EXPECT_FALSE(handle_map.Empty());
EXPECT_TRUE(handle);
}
TEST(AdvertisingHandleMapTest, MapHandleAlreadyExists) {
AdvertisingHandleMap handle_map;
DeviceAddress address = DeviceAddress(DeviceAddress::Type::kLEPublic, {0});
std::optional<hci_spec::AdvertisingHandle> expected =
handle_map.MapHandle(address);
EXPECT_LE(expected.value(), hci_spec::kMaxAdvertisingHandle);
ASSERT_TRUE(expected);
std::optional<hci_spec::AdvertisingHandle> actual =
handle_map.MapHandle(address);
EXPECT_LE(actual.value(), hci_spec::kMaxAdvertisingHandle);
ASSERT_TRUE(actual);
EXPECT_EQ(expected, actual);
}
TEST(AdvertisingHandleMapTest, MapHandleMoreThanSupported) {
AdvertisingHandleMap handle_map;
for (uint8_t i = 0; i < handle_map.capacity(); i++) {
DeviceAddress address = DeviceAddress(DeviceAddress::Type::kLEPublic, {i});
std::optional<hci_spec::AdvertisingHandle> handle =
handle_map.MapHandle(address);
EXPECT_LE(handle.value(), hci_spec::kMaxAdvertisingHandle);
EXPECT_TRUE(handle) << "Couldn't add device address " << i;
EXPECT_EQ(i + 1u, handle_map.Size());
}
DeviceAddress address =
DeviceAddress(DeviceAddress::Type::kLEPublic, {handle_map.capacity()});
std::optional<hci_spec::AdvertisingHandle> handle =
handle_map.MapHandle(address);
EXPECT_FALSE(handle);
EXPECT_EQ(handle_map.capacity(), handle_map.Size());
}
TEST(AdvertisingHandleMapTest, MapHandleSupportHandleReallocation) {
AdvertisingHandleMap handle_map;
for (uint8_t i = 0; i < handle_map.capacity(); i++) {
DeviceAddress address = DeviceAddress(DeviceAddress::Type::kLEPublic, {i});
std::optional<hci_spec::AdvertisingHandle> handle =
handle_map.MapHandle(address);
EXPECT_LE(handle.value(), hci_spec::kMaxAdvertisingHandle);
EXPECT_TRUE(handle) << "Couldn't add device address " << i;
EXPECT_EQ(i + 1u, handle_map.Size());
}
hci_spec::AdvertisingHandle old_handle = 0;
std::optional<DeviceAddress> old_address = handle_map.GetAddress(old_handle);
ASSERT_TRUE(old_address);
handle_map.RemoveHandle(old_handle);
DeviceAddress address =
DeviceAddress(DeviceAddress::Type::kLEPublic, {handle_map.capacity()});
std::optional<hci_spec::AdvertisingHandle> new_handle =
handle_map.MapHandle(address);
EXPECT_LE(new_handle.value(), hci_spec::kMaxAdvertisingHandle);
ASSERT_TRUE(new_handle);
ASSERT_EQ(old_handle, new_handle.value());
std::optional<DeviceAddress> new_address =
handle_map.GetAddress(new_handle.value());
ASSERT_TRUE(new_address);
ASSERT_NE(old_address, new_address);
}
TEST(AdvertisingHandleMapTest, GetAddressNonExistent) {
AdvertisingHandleMap handle_map;
std::optional<DeviceAddress> address = handle_map.GetAddress(0);
EXPECT_FALSE(address);
}
TEST(AdvertisingHandleMapTest, RemoveHandle) {
AdvertisingHandleMap handle_map;
EXPECT_TRUE(handle_map.Empty());
DeviceAddress address = DeviceAddress(DeviceAddress::Type::kLEPublic, {0});
std::optional<hci_spec::AdvertisingHandle> handle =
handle_map.MapHandle(address);
EXPECT_LE(handle.value(), hci_spec::kMaxAdvertisingHandle);
EXPECT_EQ(1u, handle_map.Size());
EXPECT_FALSE(handle_map.Empty());
handle_map.RemoveHandle(handle.value());
EXPECT_EQ(0u, handle_map.Size());
EXPECT_TRUE(handle_map.Empty());
}
TEST(AdvertisingHandleMapTest, RemoveAddress) {
AdvertisingHandleMap handle_map;
EXPECT_TRUE(handle_map.Empty());
DeviceAddress address = DeviceAddress(DeviceAddress::Type::kLEPublic, {0});
handle_map.MapHandle(address);
EXPECT_EQ(1u, handle_map.Size());
EXPECT_FALSE(handle_map.Empty());
handle_map.RemoveAddress(address);
EXPECT_EQ(0u, handle_map.Size());
EXPECT_TRUE(handle_map.Empty());
}
TEST(AdvertisingHandleMapTest, RemoveHandleNonExistent) {
AdvertisingHandleMap handle_map;
DeviceAddress address = DeviceAddress(DeviceAddress::Type::kLEPublic, {0});
std::optional<hci_spec::AdvertisingHandle> handle =
handle_map.MapHandle(address);
ASSERT_TRUE(handle);
size_t size = handle_map.Size();
handle_map.RemoveHandle(handle.value() + 1);
EXPECT_EQ(size, handle_map.Size());
handle = handle_map.MapHandle(address);
EXPECT_TRUE(handle);
}
TEST(AdvertisingHandleMapTest, RemoveAddressNonExistent) {
AdvertisingHandleMap handle_map;
DeviceAddress address = DeviceAddress(DeviceAddress::Type::kLEPublic, {0});
std::optional<hci_spec::AdvertisingHandle> handle =
handle_map.MapHandle(address);
ASSERT_TRUE(handle);
size_t size = handle_map.Size();
DeviceAddress nonexistent_address =
DeviceAddress(DeviceAddress::Type::kLEPublic, {1});
handle_map.RemoveAddress(nonexistent_address);
EXPECT_EQ(size, handle_map.Size());
handle = handle_map.MapHandle(address);
EXPECT_TRUE(handle);
}
TEST(AdvertisingHandleMapTest, Clear) {
AdvertisingHandleMap handle_map;
std::optional<hci_spec::AdvertisingHandle> handle =
handle_map.MapHandle(DeviceAddress(DeviceAddress::Type::kLEPublic, {0}));
EXPECT_LE(handle.value(), hci_spec::kMaxAdvertisingHandle);
EXPECT_TRUE(handle);
EXPECT_EQ(1u, handle_map.Size());
handle_map.Clear();
EXPECT_EQ(0u, handle_map.Size());
std::optional<DeviceAddress> address = handle_map.GetAddress(handle.value());
EXPECT_FALSE(address);
}
} // namespace
} // namespace bt::hci