From 55052961969c43ebe643741916ba5db73d629692 Mon Sep 17 00:00:00 2001 From: Hansong Zhang Date: Mon, 11 Jan 2021 17:30:34 -0800 Subject: [PATCH] Shim hack: Add SCO disconnect callback Test: cert/run Tag: #gd-refactor Bug: 141555841 Change-Id: I3f2ba43702542db6e07b1f6f61b9687ef178310c --- gd/hci/acl_manager.cc | 4 ++ gd/hci/acl_manager.h | 131 ++++++++++++++++++++------------------ gd/hci/acl_manager/classic_impl.h | 11 ++++ main/shim/l2c_api.cc | 7 ++ 4 files changed, 91 insertions(+), 62 deletions(-) diff --git a/gd/hci/acl_manager.cc b/gd/hci/acl_manager.cc index 92840202e..6ca22c9d0 100644 --- a/gd/hci/acl_manager.cc +++ b/gd/hci/acl_manager.cc @@ -245,6 +245,10 @@ uint16_t AclManager::HACK_GetLeHandle(Address address) { return pimpl_->le_impl_->HACK_get_handle(address); } +void AclManager::HACK_SetScoDisconnectCallback(std::function callback) { + pimpl_->classic_impl_->HACK_SetScoDisconnectCallback(callback); +} + void AclManager::ListDependencies(ModuleList* list) { list->add(); list->add(); diff --git a/gd/hci/acl_manager.h b/gd/hci/acl_manager.h index 1dd339939..229762794 100644 --- a/gd/hci/acl_manager.h +++ b/gd/hci/acl_manager.h @@ -16,6 +16,7 @@ #pragma once +#include #include #include "common/bidi_queue.h" @@ -37,95 +38,101 @@ class SecurityModule; } namespace shim { class Btm; +void L2CA_UseLegacySecurityModule(); } namespace hci { class AclManager : public Module { friend class bluetooth::shim::Btm; - public: - AclManager(); - // NOTE: It is necessary to forward declare a default destructor that overrides the base class one, because - // "struct impl" is forwarded declared in .cc and compiler needs a concrete definition of "struct impl" when - // compiling AclManager's destructor. Hence we need to forward declare the destructor for AclManager to delay - // compiling AclManager's destructor until it starts linking the .cc file. - ~AclManager(); + friend void bluetooth::shim::L2CA_UseLegacySecurityModule(); - // Should register only once when user module starts. - // Generates OnConnectSuccess when an incoming connection is established. - virtual void RegisterCallbacks(acl_manager::ConnectionCallbacks* callbacks, os::Handler* handler); +public: + AclManager(); + // NOTE: It is necessary to forward declare a default destructor that overrides the base class one, because + // "struct impl" is forwarded declared in .cc and compiler needs a concrete definition of "struct impl" when + // compiling AclManager's destructor. Hence we need to forward declare the destructor for AclManager to delay + // compiling AclManager's destructor until it starts linking the .cc file. + ~AclManager(); - // Should register only once when user module starts. - virtual void RegisterLeCallbacks(acl_manager::LeConnectionCallbacks* callbacks, os::Handler* handler); + // Should register only once when user module starts. + // Generates OnConnectSuccess when an incoming connection is established. + virtual void RegisterCallbacks(acl_manager::ConnectionCallbacks* callbacks, os::Handler* handler); - // Generates OnConnectSuccess if connected, or OnConnectFail otherwise - virtual void CreateConnection(Address address); + // Should register only once when user module starts. + virtual void RegisterLeCallbacks(acl_manager::LeConnectionCallbacks* callbacks, os::Handler* handler); - // Generates OnLeConnectSuccess if connected, or OnLeConnectFail otherwise - virtual void CreateLeConnection(AddressWithType address_with_type); + // Generates OnConnectSuccess if connected, or OnConnectFail otherwise + virtual void CreateConnection(Address address); - // Ask the controller for specific data parameters - virtual void SetLeSuggestedDefaultDataParameters(uint16_t octets, uint16_t time); + // Generates OnLeConnectSuccess if connected, or OnLeConnectFail otherwise + virtual void CreateLeConnection(AddressWithType address_with_type); - virtual void SetPrivacyPolicyForInitiatorAddress( - LeAddressManager::AddressPolicy address_policy, - AddressWithType fixed_address, - crypto_toolbox::Octet16 rotation_irk, - std::chrono::milliseconds minimum_rotation_time, - std::chrono::milliseconds maximum_rotation_time); + // Ask the controller for specific data parameters + virtual void SetLeSuggestedDefaultDataParameters(uint16_t octets, uint16_t time); - // TODO(jpawlowski): remove once we have config file abstraction in cert tests - virtual void SetPrivacyPolicyForInitiatorAddressForTest( - LeAddressManager::AddressPolicy address_policy, - AddressWithType fixed_address, - crypto_toolbox::Octet16 rotation_irk, - std::chrono::milliseconds minimum_rotation_time, - std::chrono::milliseconds maximum_rotation_time); + virtual void SetPrivacyPolicyForInitiatorAddress( + LeAddressManager::AddressPolicy address_policy, + AddressWithType fixed_address, + crypto_toolbox::Octet16 rotation_irk, + std::chrono::milliseconds minimum_rotation_time, + std::chrono::milliseconds maximum_rotation_time); - // Generates OnConnectFail with error code "terminated by local host 0x16" if cancelled, or OnConnectSuccess if not - // successfully cancelled and already connected - virtual void CancelConnect(Address address); + // TODO(jpawlowski): remove once we have config file abstraction in cert tests + virtual void SetPrivacyPolicyForInitiatorAddressForTest( + LeAddressManager::AddressPolicy address_policy, + AddressWithType fixed_address, + crypto_toolbox::Octet16 rotation_irk, + std::chrono::milliseconds minimum_rotation_time, + std::chrono::milliseconds maximum_rotation_time); - virtual void CancelLeConnect(AddressWithType address_with_type); - virtual void AddDeviceToConnectList(AddressWithType address_with_type); - virtual void AddDeviceToResolvingList( - AddressWithType address_with_type, - const std::array& peer_irk, - const std::array& local_irk); - virtual void RemoveDeviceFromConnectList(AddressWithType address_with_type); - virtual void RemoveDeviceFromResolvingList(AddressWithType address_with_type); + // Generates OnConnectFail with error code "terminated by local host 0x16" if cancelled, or OnConnectSuccess if not + // successfully cancelled and already connected + virtual void CancelConnect(Address address); - virtual void CentralLinkKey(KeyFlag key_flag); - virtual void SwitchRole(Address address, Role role); - virtual uint16_t ReadDefaultLinkPolicySettings(); - virtual void WriteDefaultLinkPolicySettings(uint16_t default_link_policy_settings); + virtual void CancelLeConnect(AddressWithType address_with_type); + virtual void AddDeviceToConnectList(AddressWithType address_with_type); + virtual void AddDeviceToResolvingList( + AddressWithType address_with_type, + const std::array& peer_irk, + const std::array& local_irk); + virtual void RemoveDeviceFromConnectList(AddressWithType address_with_type); + virtual void RemoveDeviceFromResolvingList(AddressWithType address_with_type); - // In order to avoid circular dependency use setter rather than module dependency. - virtual void SetSecurityModule(security::SecurityModule* security_module); + virtual void CentralLinkKey(KeyFlag key_flag); + virtual void SwitchRole(Address address, Role role); + virtual uint16_t ReadDefaultLinkPolicySettings(); + virtual void WriteDefaultLinkPolicySettings(uint16_t default_link_policy_settings); - virtual LeAddressManager* GetLeAddressManager(); + // In order to avoid circular dependency use setter rather than module dependency. + virtual void SetSecurityModule(security::SecurityModule* security_module); - static const ModuleFactory Factory; + virtual LeAddressManager* GetLeAddressManager(); - protected: - void ListDependencies(ModuleList* list) override; + static const ModuleFactory Factory; - void Start() override; +protected: + void ListDependencies(ModuleList* list) override; - void Stop() override; + void Start() override; - std::string ToString() const override; + void Stop() override; - DumpsysDataFinisher GetDumpsysData(flatbuffers::FlatBufferBuilder* builder) const override; // Module + std::string ToString() const override; - private: - virtual uint16_t HACK_GetHandle(const Address address); - virtual uint16_t HACK_GetLeHandle(const Address address); + DumpsysDataFinisher GetDumpsysData(flatbuffers::FlatBufferBuilder* builder) const override; // Module - struct impl; - std::unique_ptr pimpl_; +private: + virtual uint16_t HACK_GetHandle(const Address address); + virtual uint16_t HACK_GetLeHandle(const Address address); - DISALLOW_COPY_AND_ASSIGN(AclManager); + // Hack for the shim to get SCO disconnect callback. Shim needs to post to their handler! + virtual void HACK_SetScoDisconnectCallback(std::function); + + struct impl; + std::unique_ptr pimpl_; + + DISALLOW_COPY_AND_ASSIGN(AclManager); }; } // namespace hci diff --git a/gd/hci/acl_manager/classic_impl.h b/gd/hci/acl_manager/classic_impl.h index 046399242..9f2f21df5 100644 --- a/gd/hci/acl_manager/classic_impl.h +++ b/gd/hci/acl_manager/classic_impl.h @@ -134,6 +134,11 @@ struct classic_impl : public security::ISecurityManagerListener { round_robin_scheduler_->Unregister(handle); callbacks->OnDisconnection(reason); acl_connections_.erase(handle); + } else { + // This handle is probably for SCO, so we use the callback workaround. + if (sco_disconnect_callback_ != nullptr) { + sco_disconnect_callback_(handle, static_cast(reason)); + } } } @@ -631,6 +636,10 @@ struct classic_impl : public security::ISecurityManagerListener { return 0xFFFF; } + void HACK_SetScoDisconnectCallback(std::function callback) { + sco_disconnect_callback_ = callback; + } + HciLayer* hci_layer_ = nullptr; Controller* controller_ = nullptr; RoundRobinScheduler* round_robin_scheduler_ = nullptr; @@ -646,6 +655,8 @@ struct classic_impl : public security::ISecurityManagerListener { std::unique_ptr security_manager_; bool crash_on_unknown_handle_ = false; + + std::function sco_disconnect_callback_; }; } // namespace acl_manager diff --git a/main/shim/l2c_api.cc b/main/shim/l2c_api.cc index 26106e604..40e391bd4 100644 --- a/main/shim/l2c_api.cc +++ b/main/shim/l2c_api.cc @@ -585,6 +585,11 @@ bool L2CA_ReadRemoteVersion(const RawAddress& addr, uint8_t* lmp_version, return true; } +static void on_sco_disconnect(uint16_t handle, uint8_t reason) { + GetGdShimHandler()->Post( + base::BindOnce(base::IgnoreResult(&btm_sco_removed), handle, reason)); +} + void L2CA_UseLegacySecurityModule() { LOG_INFO("GD L2cap is using legacy security module"); GetL2capClassicModule()->SetLinkPropertyListener( @@ -616,6 +621,8 @@ void L2CA_UseLegacySecurityModule() { GetAclManager()->SetPrivacyPolicyForInitiatorAddress( address_policy, empty_address_with_type, rotation_irk, minimum_rotation_time, maximum_rotation_time); + + GetAclManager()->HACK_SetScoDisconnectCallback(on_sco_disconnect); } /** -- 2.11.0