From: Chris Manton Date: Thu, 27 Aug 2020 01:00:33 +0000 (-0700) Subject: First entry acl shim layer X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=edf3cf93d5;p=android-x86%2Fsystem-bt.git First entry acl shim layer Test: atest bluetooth_test_gd Bug: 166280067 Tag: #refactor Change-Id: I720045436cd0405b2b9ea1c0e657f8128dffa3a1 --- diff --git a/main/shim/Android.bp b/main/shim/Android.bp index 1f3e0bad5..3742b675d 100644 --- a/main/shim/Android.bp +++ b/main/shim/Android.bp @@ -1,6 +1,8 @@ filegroup { name: "LibBluetoothShimSources", srcs: [ + "acl.cc", + "acl_api.cc", "btif_dm.cc", "btm.cc", "btm_api.cc", diff --git a/main/shim/acl.cc b/main/shim/acl.cc new file mode 100644 index 000000000..046f71a47 --- /dev/null +++ b/main/shim/acl.cc @@ -0,0 +1,349 @@ +/* + * Copyright 2020 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 +#include +#include +#include + +#include "gd/hci/acl_manager.h" +#include "gd/hci/acl_manager/acl_connection.h" +#include "gd/hci/acl_manager/classic_acl_connection.h" +#include "gd/hci/acl_manager/connection_management_callbacks.h" +#include "gd/hci/acl_manager/le_acl_connection.h" +#include "gd/hci/acl_manager/le_connection_management_callbacks.h" + +#include "gd/os/handler.h" +#include "gd/os/queue.h" +#include "main/shim/acl.h" +#include "main/shim/entry.h" +#include "main/shim/helpers.h" +#include "stack/include/acl_hci_link_interface.h" +#include "stack/include/ble_acl_interface.h" +#include "stack/include/btm_status.h" +#include "stack/include/sec_hci_link_interface.h" + +using namespace bluetooth; + +using HciHandle = uint16_t; +constexpr HciHandle kInvalidHciHandle = 0xffff; + +class ShimAclConnection { + public: + ShimAclConnection(os::Handler* handler, + hci::acl_manager::AclConnection::QueueUpEnd* queue_up_end) + : handler_(handler), queue_up_end_(queue_up_end) {} + + virtual ~ShimAclConnection() { + ASSERT(queue_.empty()); + UnregisterEnqueue(); + } + + void EnqueuePacket(std::unique_ptr packet) { + queue_.push(std::move(packet)); + RegisterEnqueue(); + } + + std::unique_ptr handle_enqueue() { + auto packet = std::move(queue_.front()); + queue_.pop(); + if (queue_.empty()) { + UnregisterEnqueue(); + } + return packet; + } + + protected: + os::Handler* handler_; + + private: + hci::acl_manager::AclConnection::QueueUpEnd* queue_up_end_; + std::queue> queue_; + bool is_enqueue_registered_{false}; + + void RegisterEnqueue() { + if (is_enqueue_registered_) return; + is_enqueue_registered_ = true; + queue_up_end_->RegisterEnqueue( + handler_, common::Bind(&ShimAclConnection::handle_enqueue, + common::Unretained(this))); + } + + void UnregisterEnqueue() { + if (!is_enqueue_registered_) return; + is_enqueue_registered_ = false; + queue_up_end_->UnregisterEnqueue(); + } + + virtual void RegisterCallbacks() = 0; +}; + +class ClassicShimAclConnection + : public ShimAclConnection, + public hci::acl_manager::ConnectionManagementCallbacks { + public: + ClassicShimAclConnection( + os::Handler* handler, + std::unique_ptr connection) + : ShimAclConnection(handler, connection->GetAclQueueEnd()), + connection_(std::move(connection)) {} + + void RegisterCallbacks() override { + connection_->RegisterCallbacks(this, handler_); + } + + void OnConnectionPacketTypeChanged(uint16_t packet_type) override { + LOG_INFO("%s UNIMPLEMENTED", __func__); + } + void OnAuthenticationComplete() override { + LOG_INFO("%s UNIMPLEMENTED", __func__); + } + void OnEncryptionChange(hci::EncryptionEnabled enabled) override { + LOG_INFO("%s UNIMPLEMENTED", __func__); + } + void OnChangeConnectionLinkKeyComplete() override { + LOG_INFO("%s UNIMPLEMENTED", __func__); + } + void OnReadClockOffsetComplete(uint16_t clock_offset) override { + LOG_INFO("%s UNIMPLEMENTED", __func__); + } + void OnModeChange(hci::Mode current_mode, uint16_t interval) override { + LOG_INFO("%s UNIMPLEMENTED", __func__); + } + void OnQosSetupComplete(hci::ServiceType service_type, uint32_t token_rate, + uint32_t peak_bandwidth, uint32_t latency, + uint32_t delay_variation) override { + LOG_INFO("%s UNIMPLEMENTED", __func__); + } + void OnFlowSpecificationComplete(hci::FlowDirection flow_direction, + hci::ServiceType service_type, + uint32_t token_rate, + uint32_t token_bucket_size, + uint32_t peak_bandwidth, + uint32_t access_latency) override { + LOG_INFO("%s UNIMPLEMENTED", __func__); + } + void OnFlushOccurred() override { LOG_INFO("%s UNIMPLEMENTED", __func__); } + void OnRoleDiscoveryComplete(hci::Role current_role) override { + LOG_INFO("%s UNIMPLEMENTED", __func__); + } + void OnReadLinkPolicySettingsComplete( + uint16_t link_policy_settings) override { + LOG_INFO("%s UNIMPLEMENTED", __func__); + } + void OnReadAutomaticFlushTimeoutComplete(uint16_t flush_timeout) override { + LOG_INFO("%s UNIMPLEMENTED", __func__); + } + void OnReadTransmitPowerLevelComplete(uint8_t transmit_power_level) override { + LOG_INFO("%s UNIMPLEMENTED", __func__); + } + void OnReadLinkSupervisionTimeoutComplete( + uint16_t link_supervision_timeout) override { + LOG_INFO("%s UNIMPLEMENTED", __func__); + } + void OnReadFailedContactCounterComplete( + uint16_t failed_contact_counter) override { + LOG_INFO("%s UNIMPLEMENTED", __func__); + } + void OnReadLinkQualityComplete(uint8_t link_quality) override { + LOG_INFO("%s UNIMPLEMENTED", __func__); + } + void OnReadAfhChannelMapComplete( + hci::AfhMode afh_mode, std::array afh_channel_map) override { + LOG_INFO("%s UNIMPLEMENTED", __func__); + } + void OnReadRssiComplete(uint8_t rssi) override { + LOG_INFO("%s UNIMPLEMENTED", __func__); + } + void OnReadClockComplete(uint32_t clock, uint16_t accuracy) override { + LOG_INFO("%s UNIMPLEMENTED", __func__); + } + void OnMasterLinkKeyComplete(hci::KeyFlag key_flag) override { + LOG_INFO("%s UNIMPLEMENTED", __func__); + } + void OnRoleChange(hci::Role new_role) override { + LOG_INFO("%s UNIMPLEMENTED", __func__); + } + + void OnDisconnection(hci::ErrorCode reason) override { + btm_sec_disconnected(connection_->GetHandle(), + static_cast(reason)); + } + + private: + std::unique_ptr connection_; +}; + +class LeShimAclConnection + : public ShimAclConnection, + public hci::acl_manager::LeConnectionManagementCallbacks { + public: + LeShimAclConnection( + os::Handler* handler, + std::unique_ptr connection) + : ShimAclConnection(handler, connection->GetAclQueueEnd()), + connection_(std::move(connection)) {} + + void RegisterCallbacks() override { + connection_->RegisterCallbacks(this, handler_); + } + + void OnConnectionUpdate(uint16_t connection_interval, + uint16_t connection_latency, + uint16_t supervision_timeout) { + LOG_INFO("%s UNIMPLEMENTED", __func__); + } + void OnDataLengthChange(uint16_t tx_octets, uint16_t tx_time, + uint16_t rx_octets, uint16_t rx_time) { + LOG_INFO("%s UNIMPLEMENTED", __func__); + } + void OnDisconnection(hci::ErrorCode reason) { + LOG_INFO("%s UNIMPLEMENTED", __func__); + } + + private: + std::unique_ptr connection_; +}; + +struct bluetooth::shim::legacy::Acl::impl { + std::map> + handle_to_classic_connection_map_; + std::map> + handle_to_le_connection_map_; + + bool IsClassicAcl(HciHandle handle) { + return handle_to_classic_connection_map_.find(handle) != + handle_to_classic_connection_map_.end(); + } + + void EnqueueClassicPacket( + HciHandle handle, std::unique_ptr packet) { + handle_to_classic_connection_map_[handle]->EnqueuePacket(std::move(packet)); + } + + bool IsLeAcl(HciHandle handle) { + return handle_to_le_connection_map_.find(handle) != + handle_to_le_connection_map_.end(); + } + + void EnqueueLePacket(HciHandle handle, + std::unique_ptr packet) { + handle_to_le_connection_map_[handle]->EnqueuePacket(std::move(packet)); + } +}; + +bluetooth::shim::legacy::Acl::Acl(os::Handler* handler) : handler_(handler) { + pimpl_ = std::make_unique(); + GetAclManager()->RegisterCallbacks(this, handler_); + GetAclManager()->RegisterLeCallbacks(this, handler_); +} + +bluetooth::shim::legacy::Acl::~Acl() {} + +void bluetooth::shim::legacy::Acl::WriteData( + HciHandle handle, std::unique_ptr packet) { + if (pimpl_->IsClassicAcl(handle)) { + pimpl_->EnqueueClassicPacket(handle, std::move(packet)); + } else if (pimpl_->IsLeAcl(handle)) { + pimpl_->EnqueueLePacket(handle, std::move(packet)); + } else { + LOG_ERROR("%s Unable to find destination to write data\n", __func__); + } +} + +void bluetooth::shim::legacy::Acl::CreateClassicConnection( + const bluetooth::hci::Address& address) { + LOG_DEBUG("%s Initiate the creation of a classic connection %s", __func__, + address.ToString().c_str()); + GetAclManager()->CreateConnection(address); +} + +void bluetooth::shim::legacy::Acl::CreateLeConnection( + const bluetooth::hci::AddressWithType& address_with_type) { + LOG_DEBUG("%s Initiate the creation of a le connection %s", __func__, + address_with_type.ToString().c_str()); + GetAclManager()->CreateLeConnection(address_with_type); +} + +void bluetooth::shim::legacy::Acl::OnConnectSuccess( + std::unique_ptr connection) { + ASSERT(connection != nullptr); + auto handle = connection->GetHandle(); + const RawAddress bd_addr = ToRawAddress(connection->GetAddress()); + + pimpl_->handle_to_classic_connection_map_.emplace( + handle, std::make_unique( + handler_, std::move(connection))); + pimpl_->handle_to_classic_connection_map_[handle]->RegisterCallbacks(); + + LOG_DEBUG("%s Classic ACL created successfully peer:%s", __func__, + bd_addr.ToString().c_str()); + btm_acl_connected(bd_addr, handle, HCI_SUCCESS, false); +} + +void bluetooth::shim::legacy::Acl::OnConnectFail(hci::Address address, + hci::ErrorCode reason) { + const RawAddress bd_addr = ToRawAddress(address); + LOG_WARN("%s Unable to create classic ACL peer:%s", __func__, + address.ToString().c_str()); + btm_acl_connected(bd_addr, kInvalidHciHandle, ToLegacyHciErrorCode(reason), + false); +} + +void bluetooth::shim::legacy::Acl::OnLeConnectSuccess( + hci::AddressWithType address_with_type, + std::unique_ptr connection) { + ASSERT(connection != nullptr); + auto handle = connection->GetHandle(); + + pimpl_->handle_to_le_connection_map_.emplace( + handle, + std::make_unique(handler_, std::move(connection))); + pimpl_->handle_to_le_connection_map_[handle]->RegisterCallbacks(); + + LOG_DEBUG("%s Le ACL created successfully peer:%s", __func__, + address_with_type.ToString().c_str()); + + tBLE_BD_ADDR legacy_address_with_type = + ToLegacyAddressWithType(address_with_type); + + uint8_t role = 0; /* TODO Master */ + bool match = false; /* TODO Was address resolved with known record ? */ + + uint16_t conn_interval{0}; /* TODO */ + uint16_t conn_latency{0}; /* TODO */ + uint16_t conn_timeout{0}; /* TODO */ + + RawAddress local_rpa = legacy_address_with_type.bda; /* TODO enhanced */ + RawAddress peer_rpa = legacy_address_with_type.bda; /* TODO enhanced */ + uint8_t peer_addr_type = 0; /* TODO public */ + + acl_ble_enhanced_connection_complete( + legacy_address_with_type, handle, role, match, conn_interval, + conn_latency, conn_timeout, local_rpa, peer_rpa, peer_addr_type); +} + +void bluetooth::shim::legacy::Acl::OnLeConnectFail( + hci::AddressWithType address_with_type, hci::ErrorCode reason) { + tBLE_BD_ADDR legacy_address_with_type = + ToLegacyAddressWithType(address_with_type); + + uint16_t handle{0}; /* TODO Unneeded */ + bool enhanced{true}; /* TODO logging metrics only */ + uint8_t status = ToLegacyHciErrorCode(reason); + + acl_ble_connection_fail(legacy_address_with_type, handle, enhanced, status); +} diff --git a/main/shim/acl.h b/main/shim/acl.h new file mode 100644 index 000000000..8276b251f --- /dev/null +++ b/main/shim/acl.h @@ -0,0 +1,64 @@ +/* + * Copyright 2020 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. + */ + +#pragma once + +#include + +#include "gd/hci/acl_manager/connection_callbacks.h" +#include "gd/hci/acl_manager/le_connection_callbacks.h" +#include "gd/hci/address.h" +#include "gd/hci/address_with_type.h" +#include "gd/os/handler.h" +#include "gd/packet/raw_builder.h" + +namespace bluetooth { +namespace shim { +namespace legacy { + +class Acl : public hci::acl_manager::ConnectionCallbacks, + public hci::acl_manager::LeConnectionCallbacks { + public: + explicit Acl(os::Handler* handler); + ~Acl(); + + void CreateClassicConnection(const bluetooth::hci::Address& address); + void CreateLeConnection( + const bluetooth::hci::AddressWithType& address_with_type); + + void OnLeConnectSuccess( + hci::AddressWithType, + std::unique_ptr) override; + void OnLeConnectFail(hci::AddressWithType, hci::ErrorCode reason) override; + + void OnConnectSuccess( + std::unique_ptr) override; + void OnConnectFail(hci::Address, hci::ErrorCode reason) override; + + void WriteData(uint16_t hci_handle, + std::unique_ptr packet); + void OnRead(); // TODO + + private: + os::Handler* handler_; + struct impl; + std::unique_ptr pimpl_; + DISALLOW_COPY_AND_ASSIGN(Acl); +}; + +} // namespace legacy +} // namespace shim +} // namespace bluetooth diff --git a/main/shim/acl_api.cc b/main/shim/acl_api.cc new file mode 100644 index 000000000..cdb8e3f2a --- /dev/null +++ b/main/shim/acl_api.cc @@ -0,0 +1,41 @@ +/* + * Copyright 2020 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 +#include + +#include "main/shim/acl_api.h" +#include "main/shim/helpers.h" +#include "main/shim/stack.h" +#include "types/raw_address.h" + +void bluetooth::shim::ACL_CreateClassicConnection( + const RawAddress& raw_address) { + auto address = ToGdAddress(raw_address); + Stack::GetInstance()->GetAcl()->CreateClassicConnection(address); +} + +void bluetooth::shim::ACL_CreateLeConnection(const RawAddress& raw_address) { + auto address_with_type = ToAddressWithType(raw_address, BLE_ADDR_PUBLIC); + Stack::GetInstance()->GetAcl()->CreateLeConnection(address_with_type); +} + +void bluetooth::shim::ACL_WriteData(uint16_t handle, const uint8_t* data, + size_t len) { + std::unique_ptr packet = + MakeUniquePacket(data, len); + Stack::GetInstance()->GetAcl()->WriteData(handle, std::move(packet)); +} diff --git a/main/shim/acl_api.h b/main/shim/acl_api.h new file mode 100644 index 000000000..ac6f44f23 --- /dev/null +++ b/main/shim/acl_api.h @@ -0,0 +1,29 @@ +/* + * Copyright 2020 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. + */ + +#pragma once + +#include "types/raw_address.h" + +namespace bluetooth { +namespace shim { + +void ACL_CreateClassicConnection(const RawAddress& raw_address); +void ACL_CreateLeConnection(const RawAddress& raw_address); +void ACL_WriteData(uint16_t handle, const uint8_t* data, size_t len); + +} // namespace shim +} // namespace bluetooth diff --git a/main/shim/l2c_api.cc b/main/shim/l2c_api.cc index 7fbabde65..7b96714ea 100644 --- a/main/shim/l2c_api.cc +++ b/main/shim/l2c_api.cc @@ -20,7 +20,6 @@ #include "gd/l2cap/le/l2cap_le_module.h" #include "gd/os/log.h" #include "gd/os/queue.h" -#include "gd/packet/raw_builder.h" #include "main/shim/btm.h" #include "main/shim/entry.h" #include "main/shim/helpers.h" diff --git a/main/shim/stack.cc b/main/shim/stack.cc index 9d5e36253..a3fbff558 100644 --- a/main/shim/stack.cc +++ b/main/shim/stack.cc @@ -105,6 +105,9 @@ void Stack::StartEverything() { btm_ = new Btm(stack_handler_, stack_manager_.GetInstance()); } + if (common::InitFlags::GdAclEnabled()) { + acl_ = new legacy::Acl(stack_handler_); + } is_running_ = true; if (!common::InitFlags::GdCoreEnabled()) { bluetooth::shim::hci_on_reset_complete(); @@ -132,6 +135,9 @@ void Stack::Stop() { ASSERT_LOG(is_running_, "%s Gd stack not running", __func__); is_running_ = false; + delete acl_; + acl_ = nullptr; + delete btm_; btm_ = nullptr; @@ -160,6 +166,12 @@ StackManager* Stack::GetStackManager() { return &stack_manager_; } +legacy::Acl* Stack::GetAcl() { + std::lock_guard lock(mutex_); + ASSERT(is_running_); + return acl_; +} + Btm* Stack::GetBtm() { std::lock_guard lock(mutex_); ASSERT(is_running_); diff --git a/main/shim/stack.h b/main/shim/stack.h index 04f396984..d83df8329 100644 --- a/main/shim/stack.h +++ b/main/shim/stack.h @@ -18,6 +18,7 @@ #include +#include "main/shim/acl.h" #include "main/shim/btm.h" #include "gd/module.h" @@ -47,6 +48,7 @@ class Stack { bool IsRunning(); StackManager* GetStackManager(); + legacy::Acl* GetAcl(); Btm* GetBtm(); os::Handler* GetHandler(); @@ -58,6 +60,7 @@ class Stack { bool is_running_ = false; os::Thread* stack_thread_ = nullptr; os::Handler* stack_handler_ = nullptr; + legacy::Acl* acl_ = nullptr; Btm* btm_ = nullptr; void Start(ModuleList* modules); diff --git a/stack/acl/btm_acl.cc b/stack/acl/btm_acl.cc index 746e1e755..65f53ec20 100644 --- a/stack/acl/btm_acl.cc +++ b/stack/acl/btm_acl.cc @@ -42,6 +42,7 @@ #include "device/include/controller.h" #include "device/include/interop.h" #include "include/l2cap_hci_link_interface.h" +#include "main/shim/acl_api.h" #include "main/shim/btm_api.h" #include "main/shim/shim.h" #include "osi/include/log.h" @@ -2791,6 +2792,10 @@ constexpr uint16_t kDefaultPacketTypes = void acl_create_classic_connection(const RawAddress& bd_addr, bool there_are_high_priority_channels, bool is_bonding) { + if (bluetooth::shim::is_gd_acl_enabled()) { + bluetooth::shim::ACL_CreateClassicConnection(bd_addr); + } + const bool controller_supports_role_switch = controller_get_interface()->supports_role_switch(); const bool acl_allows_role_switch = acl_is_role_switch_allowed();