summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Manton <cmanton@google.com>2022-04-14 02:55:26 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2022-04-14 02:55:26 +0000
commit551a92df97795724f602fd86b95acf55b608715e (patch)
tree9e2ee15bd71ba355a23531edeb4597fd20894959
parenta4a643848d989f9b910d221bb442aae51ac7a206 (diff)
parent1a3760522f88756cd8826a8f337d6f8d55804d5a (diff)
Check cache before sending acceptlist commands am: 938563452c am: 1a3760522f
Original change: https://android-review.googlesource.com/c/platform/packages/modules/Bluetooth/+/2058468 Change-Id: I0c9dcb7b29b29c79d42b676b64237c893d496588 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--system/gd/hci/Android.bp1
-rw-r--r--system/gd/hci/acl_manager/le_impl.h14
-rw-r--r--system/gd/hci/acl_manager/le_impl_test.cc233
3 files changed, 248 insertions, 0 deletions
diff --git a/system/gd/hci/Android.bp b/system/gd/hci/Android.bp
index d25a589b55..742d0c8aa6 100644
--- a/system/gd/hci/Android.bp
+++ b/system/gd/hci/Android.bp
@@ -33,6 +33,7 @@ filegroup {
filegroup {
name: "BluetoothHciUnitTestSources",
srcs: [
+ "acl_manager/le_impl_test.cc",
"acl_builder_test.cc",
"address_unittest.cc",
"address_with_type_test.cc",
diff --git a/system/gd/hci/acl_manager/le_impl.h b/system/gd/hci/acl_manager/le_impl.h
index 7abb5d81a1..4dc3693e91 100644
--- a/system/gd/hci/acl_manager/le_impl.h
+++ b/system/gd/hci/acl_manager/le_impl.h
@@ -40,6 +40,8 @@
using bluetooth::crypto_toolbox::Octet16;
+#define PRIVATE_ADDRESS_WITH_TYPE(addr) addr.ToString().substr(12U).c_str()
+
namespace bluetooth {
namespace hci {
namespace acl_manager {
@@ -529,6 +531,12 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback {
return;
}
+ if (connect_list.find(address_with_type) != connect_list.end()) {
+ LOG_WARN(
+ "Device already exists in acceptlist and cannot be added:%s", PRIVATE_ADDRESS_WITH_TYPE(address_with_type));
+ return;
+ }
+
connect_list.insert(address_with_type);
register_with_address_manager();
le_address_manager_->AddDeviceToConnectList(
@@ -536,6 +544,10 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback {
}
void remove_device_from_connect_list(AddressWithType address_with_type) {
+ if (connect_list.find(address_with_type) == connect_list.end()) {
+ LOG_WARN("Device not in acceptlist and cannot be removed:%s", PRIVATE_ADDRESS_WITH_TYPE(address_with_type));
+ return;
+ }
connect_list.erase(address_with_type);
direct_connections_.erase(address_with_type);
register_with_address_manager();
@@ -937,6 +949,8 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback {
std::map<AddressWithType, os::Alarm> create_connection_timeout_alarms_;
};
+#undef PRIVATE_ADDRESS_WITH_TYPE
+
} // namespace acl_manager
} // namespace hci
} // namespace bluetooth
diff --git a/system/gd/hci/acl_manager/le_impl_test.cc b/system/gd/hci/acl_manager/le_impl_test.cc
new file mode 100644
index 0000000000..1f3c17ffb4
--- /dev/null
+++ b/system/gd/hci/acl_manager/le_impl_test.cc
@@ -0,0 +1,233 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://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 "hci/acl_manager/le_impl.h"
+
+#include <gtest/gtest.h>
+
+#include <chrono>
+
+#include "common/bidi_queue.h"
+#include "common/callback.h"
+#include "hci/acl_manager.h"
+#include "hci/address_with_type.h"
+#include "hci/controller.h"
+#include "hci/hci_packets.h"
+#include "os/handler.h"
+#include "os/log.h"
+#include "packet/raw_builder.h"
+
+using namespace std::chrono_literals;
+
+using ::bluetooth::common::BidiQueue;
+using ::bluetooth::common::Callback;
+using ::bluetooth::os::Handler;
+using ::bluetooth::os::Thread;
+
+namespace bluetooth {
+namespace hci {
+namespace acl_manager {
+
+class TestController : public Controller {
+ public:
+ uint16_t GetNumAclPacketBuffers() const {
+ return max_acl_packet_credits_;
+ }
+
+ uint16_t GetAclPacketLength() const {
+ return hci_mtu_;
+ }
+
+ LeBufferSize GetLeBufferSize() const {
+ LeBufferSize le_buffer_size;
+ le_buffer_size.le_data_packet_length_ = le_hci_mtu_;
+ le_buffer_size.total_num_le_packets_ = le_max_acl_packet_credits_;
+ return le_buffer_size;
+ }
+
+ void RegisterCompletedAclPacketsCallback(CompletedAclPacketsCallback cb) {
+ acl_credits_callback_ = cb;
+ }
+
+ void SendCompletedAclPacketsCallback(uint16_t handle, uint16_t credits) {
+ acl_credits_callback_.Invoke(handle, credits);
+ }
+
+ void UnregisterCompletedAclPacketsCallback() {
+ acl_credits_callback_ = {};
+ }
+
+ const uint16_t max_acl_packet_credits_ = 10;
+ const uint16_t hci_mtu_ = 1024;
+ const uint16_t le_max_acl_packet_credits_ = 15;
+ const uint16_t le_hci_mtu_ = 27;
+
+ private:
+ CompletedAclPacketsCallback acl_credits_callback_;
+};
+
+class TestHciLayer : public HciLayer {
+ template <typename T>
+ class CommandInterfaceImpl : public CommandInterface<T> {
+ public:
+ explicit CommandInterfaceImpl(HciLayer& hci) : hci_(hci) {}
+ ~CommandInterfaceImpl() = default;
+
+ void EnqueueCommand(
+ std::unique_ptr<T> command, common::ContextualOnceCallback<void(CommandCompleteView)> on_complete) override {
+ hci_.EnqueueCommand(move(command), std::move(on_complete));
+ }
+
+ void EnqueueCommand(
+ std::unique_ptr<T> command, common::ContextualOnceCallback<void(CommandStatusView)> on_status) override {
+ hci_.EnqueueCommand(move(command), std::move(on_status));
+ }
+ HciLayer& hci_;
+ };
+
+ public:
+ LeAclConnectionInterface* GetLeAclConnectionInterface(
+ common::ContextualCallback<void(LeMetaEventView)> event_handler,
+ common::ContextualCallback<void(uint16_t, ErrorCode)> on_disconnect,
+ common::ContextualCallback<
+ void(hci::ErrorCode hci_status, uint16_t, uint8_t version, uint16_t manufacturer_name, uint16_t sub_version)>
+ on_read_remote_version) override {
+ disconnect_handlers_.push_back(on_disconnect);
+ read_remote_version_handlers_.push_back(on_read_remote_version);
+ return &le_acl_connection_manager_interface_2_;
+ }
+
+ void PutLeAclConnectionInterface() override {}
+
+ CommandInterfaceImpl<AclCommandBuilder> le_acl_connection_manager_interface_2_{*this};
+};
+
+class LeImplTest : public ::testing::Test {
+ public:
+ void SetUp() override {
+ thread_ = new Thread("thread", Thread::Priority::NORMAL);
+ handler_ = new Handler(thread_);
+ controller_ = new TestController();
+ hci_layer_ = new TestHciLayer();
+
+ round_robin_scheduler_ = new RoundRobinScheduler(handler_, controller_, hci_queue_.GetUpEnd());
+ hci_queue_.GetDownEnd()->RegisterDequeue(
+ handler_, common::Bind(&LeImplTest::HciDownEndDequeue, common::Unretained(this)));
+ le_impl_ = new le_impl(hci_layer_, controller_, handler_, round_robin_scheduler_, true);
+ }
+
+ void TearDown() override {
+ sync_handler();
+ delete le_impl_;
+
+ hci_queue_.GetDownEnd()->UnregisterDequeue();
+
+ delete hci_layer_;
+ delete round_robin_scheduler_;
+ delete controller_;
+
+ handler_->Clear();
+ delete handler_;
+ delete thread_;
+ }
+
+ void sync_handler() {
+ std::promise<void> promise;
+ auto future = promise.get_future();
+ handler_->BindOnceOn(&promise, &std::promise<void>::set_value).Invoke();
+ auto status = future.wait_for(10ms);
+ ASSERT_EQ(status, std::future_status::ready);
+ }
+
+ void HciDownEndDequeue() {
+ auto packet = hci_queue_.GetDownEnd()->TryDequeue();
+ // Convert from a Builder to a View
+ auto bytes = std::make_shared<std::vector<uint8_t>>();
+ bluetooth::packet::BitInserter i(*bytes);
+ bytes->reserve(packet->size());
+ packet->Serialize(i);
+ auto packet_view = bluetooth::packet::PacketView<bluetooth::packet::kLittleEndian>(bytes);
+ AclView acl_packet_view = AclView::Create(packet_view);
+ ASSERT_TRUE(acl_packet_view.IsValid());
+ PacketView<true> count_view = acl_packet_view.GetPayload();
+ sent_acl_packets_.push(acl_packet_view);
+
+ packet_count_--;
+ if (packet_count_ == 0) {
+ packet_promise_->set_value();
+ packet_promise_ = nullptr;
+ }
+ }
+
+ uint16_t packet_count_;
+ std::unique_ptr<std::promise<void>> packet_promise_;
+ std::unique_ptr<std::future<void>> packet_future_;
+ std::queue<AclView> sent_acl_packets_;
+
+ BidiQueue<AclView, AclBuilder> hci_queue_{3};
+
+ Thread* thread_;
+ Handler* handler_;
+ HciLayer* hci_layer_{nullptr};
+ TestController* controller_;
+ RoundRobinScheduler* round_robin_scheduler_{nullptr};
+
+ struct le_impl* le_impl_;
+};
+
+TEST_F(LeImplTest, nop) {}
+
+TEST_F(LeImplTest, add_device_to_connect_list) {
+ le_impl_->add_device_to_connect_list({{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}, AddressType::PUBLIC_DEVICE_ADDRESS});
+ ASSERT_EQ(1UL, le_impl_->connect_list.size());
+
+ le_impl_->add_device_to_connect_list({{0x11, 0x12, 0x13, 0x14, 0x15, 0x16}, AddressType::PUBLIC_DEVICE_ADDRESS});
+ ASSERT_EQ(2UL, le_impl_->connect_list.size());
+
+ le_impl_->add_device_to_connect_list({{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}, AddressType::PUBLIC_DEVICE_ADDRESS});
+ ASSERT_EQ(2UL, le_impl_->connect_list.size());
+
+ le_impl_->add_device_to_connect_list({{0x11, 0x12, 0x13, 0x14, 0x15, 0x16}, AddressType::PUBLIC_DEVICE_ADDRESS});
+ ASSERT_EQ(2UL, le_impl_->connect_list.size());
+}
+
+TEST_F(LeImplTest, remove_device_from_connect_list) {
+ le_impl_->add_device_to_connect_list({{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}, AddressType::PUBLIC_DEVICE_ADDRESS});
+ le_impl_->add_device_to_connect_list({{0x11, 0x12, 0x13, 0x14, 0x15, 0x16}, AddressType::PUBLIC_DEVICE_ADDRESS});
+ le_impl_->add_device_to_connect_list({{0x21, 0x22, 0x23, 0x24, 0x25, 0x26}, AddressType::PUBLIC_DEVICE_ADDRESS});
+ le_impl_->add_device_to_connect_list({{0x31, 0x32, 0x33, 0x34, 0x35, 0x36}, AddressType::PUBLIC_DEVICE_ADDRESS});
+ ASSERT_EQ(4UL, le_impl_->connect_list.size());
+
+ le_impl_->remove_device_from_connect_list({{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}, AddressType::PUBLIC_DEVICE_ADDRESS});
+ ASSERT_EQ(3UL, le_impl_->connect_list.size());
+
+ le_impl_->remove_device_from_connect_list({{0x11, 0x12, 0x13, 0x14, 0x15, 0x16}, AddressType::PUBLIC_DEVICE_ADDRESS});
+ ASSERT_EQ(2UL, le_impl_->connect_list.size());
+
+ le_impl_->remove_device_from_connect_list({{0x11, 0x12, 0x13, 0x14, 0x15, 0x16}, AddressType::PUBLIC_DEVICE_ADDRESS});
+ ASSERT_EQ(2UL, le_impl_->connect_list.size());
+
+ le_impl_->remove_device_from_connect_list({Address::kEmpty, AddressType::PUBLIC_DEVICE_ADDRESS});
+ ASSERT_EQ(2UL, le_impl_->connect_list.size());
+
+ le_impl_->remove_device_from_connect_list({{0x21, 0x22, 0x23, 0x24, 0x25, 0x26}, AddressType::PUBLIC_DEVICE_ADDRESS});
+ le_impl_->remove_device_from_connect_list({{0x31, 0x32, 0x33, 0x34, 0x35, 0x36}, AddressType::PUBLIC_DEVICE_ADDRESS});
+ ASSERT_EQ(0UL, le_impl_->connect_list.size());
+}
+
+} // namespace acl_manager
+} // namespace hci
+} // namespace bluetooth