Loading system/gd/security/channel/security_manager_channel.cc +42 −85 Original line number Diff line number Diff line Loading @@ -24,63 +24,50 @@ namespace bluetooth { namespace security { namespace channel { /** * Constructor for testing only */ SecurityManagerChannel::SecurityManagerChannel(os::Handler* handler, hci::HciLayer* hci_layer) : listener_(nullptr), hci_security_interface_(hci_layer->GetSecurityInterface( handler->BindOn(this, &SecurityManagerChannel::OnHciEventReceived))), handler_(handler) { is_test_mode_ = true; } /** * Main Constructor */ SecurityManagerChannel::SecurityManagerChannel( os::Handler* handler, hci::HciLayer* hci_layer, std::unique_ptr<l2cap::classic::FixedChannelManager> fixed_channel_manager) : listener_(nullptr), hci_security_interface_(hci_layer->GetSecurityInterface( handler->BindOn(this, &SecurityManagerChannel::OnHciEventReceived))), handler_(handler), fixed_channel_manager_(std::move(fixed_channel_manager)) { ASSERT_LOG(fixed_channel_manager_ != nullptr, "No channel manager!"); LOG_DEBUG("Registering for a fixed channel service"); fixed_channel_manager_->RegisterService( l2cap::kClassicPairingTriggerCid, common::BindOnce(&SecurityManagerChannel::OnRegistrationComplete, common::Unretained(this)), common::Bind(&SecurityManagerChannel::OnConnectionOpen, common::Unretained(this)), handler_); } SecurityManagerChannel::SecurityManagerChannel(os::Handler* handler, hci::HciLayer* hci_layer) : listener_(nullptr), hci_security_interface_( hci_layer->GetSecurityInterface(handler->BindOn(this, &SecurityManagerChannel::OnHciEventReceived))), handler_(handler), l2cap_security_interface_(nullptr) {} SecurityManagerChannel::~SecurityManagerChannel() { if (fixed_channel_service_ != nullptr) { fixed_channel_service_->Unregister(common::Bind(&SecurityManagerChannel::OnUnregistered, common::Unretained(this)), handler_); fixed_channel_service_.reset(); } l2cap_security_interface_->Unregister(); l2cap_security_interface_ = nullptr; } void SecurityManagerChannel::Connect(hci::Address address) { if (is_test_mode_) return; ASSERT_LOG(fixed_channel_manager_ != nullptr, "No channel manager!"); auto entry = fixed_channel_map_.find(address); if (entry != fixed_channel_map_.end()) { LOG_ERROR("Already connected to device: %s", address.ToString().c_str()); ASSERT_LOG(l2cap_security_interface_ != nullptr, "L2cap Security Interface is null!"); if (link_map_.find(address) != link_map_.end()) { LOG_WARN("Already connected to '%s'", address.ToString().c_str()); return; } fixed_channel_manager_->ConnectServices( address, common::Bind(&SecurityManagerChannel::OnConnectionFail, common::Unretained(this), address), handler_); l2cap_security_interface_->InitiateConnectionForSecurity(address); } void SecurityManagerChannel::Disconnect(hci::Address address) { if (is_test_mode_) return; auto entry = fixed_channel_map_.find(address); if (entry != fixed_channel_map_.end()) { void SecurityManagerChannel::Release(hci::Address address) { auto entry = link_map_.find(address); if (entry == link_map_.end()) { LOG_WARN("Unknown address '%s'", address.ToString().c_str()); return; } entry->second->Release(); entry->second.reset(); fixed_channel_map_.erase(entry); } else { link_map_.erase(entry); } void SecurityManagerChannel::Disconnect(hci::Address address) { auto entry = link_map_.find(address); if (entry == link_map_.end()) { LOG_WARN("Unknown address '%s'", address.ToString().c_str()); return; } entry->second->Disconnect(); entry->second.reset(); link_map_.erase(entry); } void SecurityManagerChannel::OnCommandComplete(hci::CommandCompleteView packet) { Loading @@ -98,53 +85,23 @@ void SecurityManagerChannel::OnHciEventReceived(hci::EventPacketView packet) { listener_->OnHciEventReceived(packet); } void SecurityManagerChannel::OnRegistrationComplete( l2cap::classic::FixedChannelManager::RegistrationResult result, std::unique_ptr<l2cap::classic::FixedChannelService> fixed_channel_service) { ASSERT(fixed_channel_service_ == nullptr); ASSERT_LOG(result == l2cap::classic::FixedChannelManager::RegistrationResult::SUCCESS, "Failed service registration!"); fixed_channel_service_ = std::move(fixed_channel_service); } void SecurityManagerChannel::OnUnregistered() { fixed_channel_manager_.reset(); } void SecurityManagerChannel::OnConnectionOpen(std::unique_ptr<l2cap::classic::FixedChannel> fixed_channel) { ASSERT_LOG(fixed_channel != nullptr, "Null channel passed in"); ASSERT_LOG(fixed_channel_map_.find(fixed_channel->GetDevice()) == fixed_channel_map_.end(), "Multiple fixed channel for a single device is not allowed."); fixed_channel->RegisterOnCloseCallback( handler_, common::BindOnce(&SecurityManagerChannel::OnConnectionClose, common::Unretained(this), fixed_channel->GetDevice())); fixed_channel->Acquire(); auto new_entry = std::pair<hci::Address, std::unique_ptr<l2cap::classic::FixedChannel>>(fixed_channel->GetDevice(), std::move(fixed_channel)); fixed_channel_map_.insert(std::move(new_entry)); void SecurityManagerChannel::OnLinkConnected(std::unique_ptr<l2cap::classic::LinkSecurityInterface> link) { // Multiple links possible? link->Hold(); link->EnsureAuthenticated(); link_map_.emplace(link->GetRemoteAddress(), std::move(link)); } void SecurityManagerChannel::OnConnectionFail(hci::Address address, l2cap::classic::FixedChannelManager::ConnectionResult result) { LOG_ERROR("Connection closed due to: %s ; %d", hci::ErrorCodeText(result.hci_error).c_str(), result.connection_result_code); auto entry = fixed_channel_map_.find(address); if (entry != fixed_channel_map_.end()) { entry->second.reset(); fixed_channel_map_.erase(entry); } listener_->OnConnectionFailed(address, result); void SecurityManagerChannel::OnLinkDisconnected(hci::Address address) { auto entry = link_map_.find(address); if (entry == link_map_.end()) { LOG_WARN("Unknown address '%s'", address.ToString().c_str()); return; } void SecurityManagerChannel::OnConnectionClose(hci::Address address, hci::ErrorCode error_code) { // Called when the connection gets closed LOG_ERROR("Connection closed due to: %s", hci::ErrorCodeText(error_code).c_str()); auto entry = fixed_channel_map_.find(address); if (entry != fixed_channel_map_.end()) { entry->second.reset(); fixed_channel_map_.erase(entry); } listener_->OnConnectionClosed(address, error_code); link_map_.erase(entry); ASSERT_LOG(listener_ != nullptr, "Set listener!"); listener_->OnConnectionClosed(address); } } // namespace channel Loading system/gd/security/channel/security_manager_channel.h +27 −22 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ #include "hci/hci_packets.h" #include "hci/security_interface.h" #include "l2cap/classic/l2cap_classic_module.h" #include "l2cap/classic/link_security_interface.h" namespace bluetooth { namespace security { Loading @@ -38,18 +39,15 @@ class ISecurityManagerChannelListener { public: virtual ~ISecurityManagerChannelListener() = default; virtual void OnHciEventReceived(hci::EventPacketView packet) = 0; virtual void OnConnectionClosed(hci::Address, bluetooth::hci::ErrorCode error_code) = 0; virtual void OnConnectionFailed(hci::Address, bluetooth::l2cap::classic::FixedChannelManager::ConnectionResult result) = 0; virtual void OnConnectionClosed(hci::Address) = 0; }; /** * Channel for consolidating traffic and making the transport agnostic. */ class SecurityManagerChannel { class SecurityManagerChannel : public l2cap::classic::LinkSecurityInterfaceListener { public: SecurityManagerChannel(os::Handler* handler, hci::HciLayer* hci_layer, std::unique_ptr<l2cap::classic::FixedChannelManager> fixed_channel_manager); SecurityManagerChannel(os::Handler* handler, hci::HciLayer* hci_layer); virtual ~SecurityManagerChannel(); Loading @@ -61,7 +59,20 @@ class SecurityManagerChannel { void Connect(hci::Address address); /** * Disconnects currently connected channel * Releases link hold so it can disconnect as normally * * i.e. signals we no longer need this if acl manager wants to clean it up * * @param address remote address to disconnect */ void Release(hci::Address address); /** * Immediately disconnects currently connected channel * * i.e. force disconnect * * @param address remote address to disconnect */ void Disconnect(hci::Address address); Loading @@ -81,6 +92,10 @@ class SecurityManagerChannel { listener_ = listener; } void SetSecurityInterface(l2cap::classic::SecurityInterface* security_interface) { l2cap_security_interface_ = security_interface; } /** * Called when an incoming HCI event happens * Loading @@ -95,26 +110,16 @@ class SecurityManagerChannel { */ void OnCommandComplete(hci::CommandCompleteView packet); protected: SecurityManagerChannel(os::Handler* handler, hci::HciLayer* hci_layer); virtual void OnRegistrationComplete(l2cap::classic::FixedChannelManager::RegistrationResult result, std::unique_ptr<l2cap::classic::FixedChannelService> fixed_channel_service); virtual void OnUnregistered(); virtual void OnConnectionOpen(std::unique_ptr<l2cap::classic::FixedChannel> fixed_channel); virtual void OnConnectionFail(hci::Address address, l2cap::classic::FixedChannelManager::ConnectionResult result); virtual void OnConnectionClose(hci::Address address, hci::ErrorCode error_code); bool is_test_mode_ = false; // Interface overrides void OnLinkConnected(std::unique_ptr<l2cap::classic::LinkSecurityInterface> link) override; void OnLinkDisconnected(hci::Address address) override; private: ISecurityManagerChannelListener* listener_{nullptr}; hci::SecurityInterface* hci_security_interface_{nullptr}; os::Handler* handler_{nullptr}; std::unique_ptr<l2cap::classic::FixedChannelManager> fixed_channel_manager_{nullptr}; std::unique_ptr<l2cap::classic::FixedChannelService> fixed_channel_service_{nullptr}; std::unordered_map<hci::Address, std::unique_ptr<l2cap::classic::FixedChannel>> fixed_channel_map_; l2cap::classic::SecurityInterface* l2cap_security_interface_{nullptr}; std::unordered_map<hci::Address, std::unique_ptr<l2cap::classic::LinkSecurityInterface>> link_map_; }; } // namespace channel Loading system/gd/security/channel/security_manager_channel_unittest.cc +32 −10 Original line number Diff line number Diff line Loading @@ -15,15 +15,16 @@ * limitations under the License. * */ #include "security_manager_channel.h" #include "security/channel/security_manager_channel.h" #include <gtest/gtest.h> #include "hci/address.h" #include "hci/hci_packets.h" #include "l2cap/classic/fixed_channel.h" #include "packet/raw_builder.h" #include "security/smp_packets.h" #include "security/test/fake_hci_layer.h" #include "security/test/fake_security_interface.h" namespace bluetooth { namespace security { Loading @@ -42,14 +43,21 @@ using os::Handler; using os::Thread; using packet::RawBuilder; static bool on_link_connected_called = false; static bool on_link_disconnected_called = false; class FakeSecurityManagerChannel : public SecurityManagerChannel { public: FakeSecurityManagerChannel(os::Handler* handler, hci::HciLayer* hci_layer) : SecurityManagerChannel(handler, hci_layer) {} ~FakeSecurityManagerChannel() {} void OnConnectionOpen(std::unique_ptr<l2cap::classic::FixedChannel> fixed_channel) override { LOG_ERROR("CALLED"); void OnLinkConnected(std::unique_ptr<l2cap::classic::LinkSecurityInterface> link) { on_link_connected_called = true; } void OnLinkDisconnected(hci::Address address) { on_link_disconnected_called = true; } }; Loading Loading @@ -197,19 +205,19 @@ class SecurityManagerChannelCallback : public ISecurityManagerChannelListener { } } void OnConnectionClosed(hci::Address address, bluetooth::hci::ErrorCode error_code) override { void OnConnectionClosed(hci::Address address) override { LOG_DEBUG("Called"); } void OnConnectionFailed(hci::Address address, bluetooth::l2cap::classic::FixedChannelManager::ConnectionResult result) override { LOG_DEBUG("Shouldn't be called"); } }; class SecurityManagerChannelTest : public ::testing::Test { protected: void SetUp() override { hci::Address address; hci::Address::FromString("01:23:45:67:89:AB:CD", address); device_ = hci::AddressWithType(address, hci::AddressType::PUBLIC_DEVICE_ADDRESS); on_link_connected_called = false; on_link_disconnected_called = false; handler_ = new Handler(&thread_); callback_ = new SecurityManagerChannelCallback(); hci_layer_ = new FakeHciLayer(); Loading @@ -217,6 +225,8 @@ class SecurityManagerChannelTest : public ::testing::Test { fake_registry_.Start<FakeHciLayer>(&thread_); channel_ = new FakeSecurityManagerChannel(handler_, hci_layer_); channel_->SetChannelListener(callback_); security_interface_ = new FakeSecurityInterface(handler_, channel_); channel_->SetSecurityInterface(security_interface_); } void TearDown() override { Loading @@ -227,6 +237,7 @@ class SecurityManagerChannelTest : public ::testing::Test { delete handler_; delete channel_; delete callback_; delete security_interface_; } void synchronize() { Loading @@ -237,6 +248,7 @@ class SecurityManagerChannelTest : public ::testing::Test { Thread& thread_ = fake_registry_.GetTestThread(); Handler* handler_ = nullptr; FakeHciLayer* hci_layer_ = nullptr; l2cap::classic::SecurityInterface* security_interface_ = nullptr; SecurityManagerChannel* channel_ = nullptr; SecurityManagerChannelCallback* callback_ = nullptr; hci::AddressWithType device_; Loading Loading @@ -673,6 +685,16 @@ TEST_F(SecurityManagerChannelTest, recv_user_passkey_request) { ASSERT_TRUE(callback_->receivedUserPasskeyRequest); } TEST_F(SecurityManagerChannelTest, test_l2cap_security_interface_api) { ASSERT_FALSE(on_link_connected_called); channel_->Connect(device_.GetAddress()); ASSERT_TRUE(on_link_connected_called); ASSERT_FALSE(on_link_disconnected_called); channel_->Release(device_.GetAddress()); // TODO(optedoblivion): Lock and wait // ASSERT_TRUE(on_link_disconnected_called); } } // namespace } // namespace channel } // namespace security Loading system/gd/security/internal/security_manager_impl.cc +3 −14 Original line number Diff line number Diff line Loading @@ -104,6 +104,7 @@ void SecurityManagerImpl::CancelBond(hci::AddressWithType device) { void SecurityManagerImpl::RemoveBond(hci::AddressWithType device) { CancelBond(device); security_database_.Remove(device); security_manager_channel_->Disconnect(device.GetAddress()); // Signal disconnect // Remove security record // Signal Remove from database Loading Loading @@ -250,19 +251,7 @@ void SecurityManagerImpl::OnHciEventReceived(hci::EventPacketView packet) { } } void SecurityManagerImpl::OnConnectionClosed(hci::Address address, bluetooth::hci::ErrorCode error_code) { LOG_DEBUG("Reason: %s ", hci::ErrorCodeText(error_code).c_str()); auto entry = pairing_handler_map_.find(address); if (entry != pairing_handler_map_.end()) { LOG_DEBUG("Cancelling pairing handler for '%s'", address.ToString().c_str()); entry->second->Cancel(); } } void SecurityManagerImpl::OnConnectionFailed(hci::Address address, bluetooth::l2cap::classic::FixedChannelManager::ConnectionResult result) { LOG_DEBUG("HCI Reason: %s ", hci::ErrorCodeText(result.hci_error).c_str()); LOG_DEBUG("L2CAP Reason: %d ", result.connection_result_code); void SecurityManagerImpl::OnConnectionClosed(hci::Address address) { auto entry = pairing_handler_map_.find(address); if (entry != pairing_handler_map_.end()) { LOG_DEBUG("Cancelling pairing handler for '%s'", address.ToString().c_str()); Loading Loading @@ -312,7 +301,7 @@ void SecurityManagerImpl::OnPairingHandlerComplete(hci::Address address, Pairing auto entry = pairing_handler_map_.find(address); if (entry != pairing_handler_map_.end()) { pairing_handler_map_.erase(entry); security_manager_channel_->Disconnect(address); security_manager_channel_->Release(address); } if (!std::holds_alternative<PairingFailure>(status)) { NotifyDeviceBonded(hci::AddressWithType(address, hci::AddressType::PUBLIC_DEVICE_ADDRESS)); Loading system/gd/security/internal/security_manager_impl.h +1 −11 Original line number Diff line number Diff line Loading @@ -122,18 +122,8 @@ class SecurityManagerImpl : public channel::ISecurityManagerChannelListener, pub * When a conncetion closes we should clean up the pairing handler * * @param address Remote address * @param error_code HCI error */ void OnConnectionClosed(hci::Address address, bluetooth::hci::ErrorCode error_code) override; /** * This can occur when a remote device isn't in range or doesn't agree with local device * * @param address Remote address * @param result holds hci error and connection error code */ void OnConnectionFailed(hci::Address address, bluetooth::l2cap::classic::FixedChannelManager::ConnectionResult result) override; void OnConnectionClosed(hci::Address address) override; /** * Pairing handler has finished or cancelled Loading Loading
system/gd/security/channel/security_manager_channel.cc +42 −85 Original line number Diff line number Diff line Loading @@ -24,63 +24,50 @@ namespace bluetooth { namespace security { namespace channel { /** * Constructor for testing only */ SecurityManagerChannel::SecurityManagerChannel(os::Handler* handler, hci::HciLayer* hci_layer) : listener_(nullptr), hci_security_interface_(hci_layer->GetSecurityInterface( handler->BindOn(this, &SecurityManagerChannel::OnHciEventReceived))), handler_(handler) { is_test_mode_ = true; } /** * Main Constructor */ SecurityManagerChannel::SecurityManagerChannel( os::Handler* handler, hci::HciLayer* hci_layer, std::unique_ptr<l2cap::classic::FixedChannelManager> fixed_channel_manager) : listener_(nullptr), hci_security_interface_(hci_layer->GetSecurityInterface( handler->BindOn(this, &SecurityManagerChannel::OnHciEventReceived))), handler_(handler), fixed_channel_manager_(std::move(fixed_channel_manager)) { ASSERT_LOG(fixed_channel_manager_ != nullptr, "No channel manager!"); LOG_DEBUG("Registering for a fixed channel service"); fixed_channel_manager_->RegisterService( l2cap::kClassicPairingTriggerCid, common::BindOnce(&SecurityManagerChannel::OnRegistrationComplete, common::Unretained(this)), common::Bind(&SecurityManagerChannel::OnConnectionOpen, common::Unretained(this)), handler_); } SecurityManagerChannel::SecurityManagerChannel(os::Handler* handler, hci::HciLayer* hci_layer) : listener_(nullptr), hci_security_interface_( hci_layer->GetSecurityInterface(handler->BindOn(this, &SecurityManagerChannel::OnHciEventReceived))), handler_(handler), l2cap_security_interface_(nullptr) {} SecurityManagerChannel::~SecurityManagerChannel() { if (fixed_channel_service_ != nullptr) { fixed_channel_service_->Unregister(common::Bind(&SecurityManagerChannel::OnUnregistered, common::Unretained(this)), handler_); fixed_channel_service_.reset(); } l2cap_security_interface_->Unregister(); l2cap_security_interface_ = nullptr; } void SecurityManagerChannel::Connect(hci::Address address) { if (is_test_mode_) return; ASSERT_LOG(fixed_channel_manager_ != nullptr, "No channel manager!"); auto entry = fixed_channel_map_.find(address); if (entry != fixed_channel_map_.end()) { LOG_ERROR("Already connected to device: %s", address.ToString().c_str()); ASSERT_LOG(l2cap_security_interface_ != nullptr, "L2cap Security Interface is null!"); if (link_map_.find(address) != link_map_.end()) { LOG_WARN("Already connected to '%s'", address.ToString().c_str()); return; } fixed_channel_manager_->ConnectServices( address, common::Bind(&SecurityManagerChannel::OnConnectionFail, common::Unretained(this), address), handler_); l2cap_security_interface_->InitiateConnectionForSecurity(address); } void SecurityManagerChannel::Disconnect(hci::Address address) { if (is_test_mode_) return; auto entry = fixed_channel_map_.find(address); if (entry != fixed_channel_map_.end()) { void SecurityManagerChannel::Release(hci::Address address) { auto entry = link_map_.find(address); if (entry == link_map_.end()) { LOG_WARN("Unknown address '%s'", address.ToString().c_str()); return; } entry->second->Release(); entry->second.reset(); fixed_channel_map_.erase(entry); } else { link_map_.erase(entry); } void SecurityManagerChannel::Disconnect(hci::Address address) { auto entry = link_map_.find(address); if (entry == link_map_.end()) { LOG_WARN("Unknown address '%s'", address.ToString().c_str()); return; } entry->second->Disconnect(); entry->second.reset(); link_map_.erase(entry); } void SecurityManagerChannel::OnCommandComplete(hci::CommandCompleteView packet) { Loading @@ -98,53 +85,23 @@ void SecurityManagerChannel::OnHciEventReceived(hci::EventPacketView packet) { listener_->OnHciEventReceived(packet); } void SecurityManagerChannel::OnRegistrationComplete( l2cap::classic::FixedChannelManager::RegistrationResult result, std::unique_ptr<l2cap::classic::FixedChannelService> fixed_channel_service) { ASSERT(fixed_channel_service_ == nullptr); ASSERT_LOG(result == l2cap::classic::FixedChannelManager::RegistrationResult::SUCCESS, "Failed service registration!"); fixed_channel_service_ = std::move(fixed_channel_service); } void SecurityManagerChannel::OnUnregistered() { fixed_channel_manager_.reset(); } void SecurityManagerChannel::OnConnectionOpen(std::unique_ptr<l2cap::classic::FixedChannel> fixed_channel) { ASSERT_LOG(fixed_channel != nullptr, "Null channel passed in"); ASSERT_LOG(fixed_channel_map_.find(fixed_channel->GetDevice()) == fixed_channel_map_.end(), "Multiple fixed channel for a single device is not allowed."); fixed_channel->RegisterOnCloseCallback( handler_, common::BindOnce(&SecurityManagerChannel::OnConnectionClose, common::Unretained(this), fixed_channel->GetDevice())); fixed_channel->Acquire(); auto new_entry = std::pair<hci::Address, std::unique_ptr<l2cap::classic::FixedChannel>>(fixed_channel->GetDevice(), std::move(fixed_channel)); fixed_channel_map_.insert(std::move(new_entry)); void SecurityManagerChannel::OnLinkConnected(std::unique_ptr<l2cap::classic::LinkSecurityInterface> link) { // Multiple links possible? link->Hold(); link->EnsureAuthenticated(); link_map_.emplace(link->GetRemoteAddress(), std::move(link)); } void SecurityManagerChannel::OnConnectionFail(hci::Address address, l2cap::classic::FixedChannelManager::ConnectionResult result) { LOG_ERROR("Connection closed due to: %s ; %d", hci::ErrorCodeText(result.hci_error).c_str(), result.connection_result_code); auto entry = fixed_channel_map_.find(address); if (entry != fixed_channel_map_.end()) { entry->second.reset(); fixed_channel_map_.erase(entry); } listener_->OnConnectionFailed(address, result); void SecurityManagerChannel::OnLinkDisconnected(hci::Address address) { auto entry = link_map_.find(address); if (entry == link_map_.end()) { LOG_WARN("Unknown address '%s'", address.ToString().c_str()); return; } void SecurityManagerChannel::OnConnectionClose(hci::Address address, hci::ErrorCode error_code) { // Called when the connection gets closed LOG_ERROR("Connection closed due to: %s", hci::ErrorCodeText(error_code).c_str()); auto entry = fixed_channel_map_.find(address); if (entry != fixed_channel_map_.end()) { entry->second.reset(); fixed_channel_map_.erase(entry); } listener_->OnConnectionClosed(address, error_code); link_map_.erase(entry); ASSERT_LOG(listener_ != nullptr, "Set listener!"); listener_->OnConnectionClosed(address); } } // namespace channel Loading
system/gd/security/channel/security_manager_channel.h +27 −22 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ #include "hci/hci_packets.h" #include "hci/security_interface.h" #include "l2cap/classic/l2cap_classic_module.h" #include "l2cap/classic/link_security_interface.h" namespace bluetooth { namespace security { Loading @@ -38,18 +39,15 @@ class ISecurityManagerChannelListener { public: virtual ~ISecurityManagerChannelListener() = default; virtual void OnHciEventReceived(hci::EventPacketView packet) = 0; virtual void OnConnectionClosed(hci::Address, bluetooth::hci::ErrorCode error_code) = 0; virtual void OnConnectionFailed(hci::Address, bluetooth::l2cap::classic::FixedChannelManager::ConnectionResult result) = 0; virtual void OnConnectionClosed(hci::Address) = 0; }; /** * Channel for consolidating traffic and making the transport agnostic. */ class SecurityManagerChannel { class SecurityManagerChannel : public l2cap::classic::LinkSecurityInterfaceListener { public: SecurityManagerChannel(os::Handler* handler, hci::HciLayer* hci_layer, std::unique_ptr<l2cap::classic::FixedChannelManager> fixed_channel_manager); SecurityManagerChannel(os::Handler* handler, hci::HciLayer* hci_layer); virtual ~SecurityManagerChannel(); Loading @@ -61,7 +59,20 @@ class SecurityManagerChannel { void Connect(hci::Address address); /** * Disconnects currently connected channel * Releases link hold so it can disconnect as normally * * i.e. signals we no longer need this if acl manager wants to clean it up * * @param address remote address to disconnect */ void Release(hci::Address address); /** * Immediately disconnects currently connected channel * * i.e. force disconnect * * @param address remote address to disconnect */ void Disconnect(hci::Address address); Loading @@ -81,6 +92,10 @@ class SecurityManagerChannel { listener_ = listener; } void SetSecurityInterface(l2cap::classic::SecurityInterface* security_interface) { l2cap_security_interface_ = security_interface; } /** * Called when an incoming HCI event happens * Loading @@ -95,26 +110,16 @@ class SecurityManagerChannel { */ void OnCommandComplete(hci::CommandCompleteView packet); protected: SecurityManagerChannel(os::Handler* handler, hci::HciLayer* hci_layer); virtual void OnRegistrationComplete(l2cap::classic::FixedChannelManager::RegistrationResult result, std::unique_ptr<l2cap::classic::FixedChannelService> fixed_channel_service); virtual void OnUnregistered(); virtual void OnConnectionOpen(std::unique_ptr<l2cap::classic::FixedChannel> fixed_channel); virtual void OnConnectionFail(hci::Address address, l2cap::classic::FixedChannelManager::ConnectionResult result); virtual void OnConnectionClose(hci::Address address, hci::ErrorCode error_code); bool is_test_mode_ = false; // Interface overrides void OnLinkConnected(std::unique_ptr<l2cap::classic::LinkSecurityInterface> link) override; void OnLinkDisconnected(hci::Address address) override; private: ISecurityManagerChannelListener* listener_{nullptr}; hci::SecurityInterface* hci_security_interface_{nullptr}; os::Handler* handler_{nullptr}; std::unique_ptr<l2cap::classic::FixedChannelManager> fixed_channel_manager_{nullptr}; std::unique_ptr<l2cap::classic::FixedChannelService> fixed_channel_service_{nullptr}; std::unordered_map<hci::Address, std::unique_ptr<l2cap::classic::FixedChannel>> fixed_channel_map_; l2cap::classic::SecurityInterface* l2cap_security_interface_{nullptr}; std::unordered_map<hci::Address, std::unique_ptr<l2cap::classic::LinkSecurityInterface>> link_map_; }; } // namespace channel Loading
system/gd/security/channel/security_manager_channel_unittest.cc +32 −10 Original line number Diff line number Diff line Loading @@ -15,15 +15,16 @@ * limitations under the License. * */ #include "security_manager_channel.h" #include "security/channel/security_manager_channel.h" #include <gtest/gtest.h> #include "hci/address.h" #include "hci/hci_packets.h" #include "l2cap/classic/fixed_channel.h" #include "packet/raw_builder.h" #include "security/smp_packets.h" #include "security/test/fake_hci_layer.h" #include "security/test/fake_security_interface.h" namespace bluetooth { namespace security { Loading @@ -42,14 +43,21 @@ using os::Handler; using os::Thread; using packet::RawBuilder; static bool on_link_connected_called = false; static bool on_link_disconnected_called = false; class FakeSecurityManagerChannel : public SecurityManagerChannel { public: FakeSecurityManagerChannel(os::Handler* handler, hci::HciLayer* hci_layer) : SecurityManagerChannel(handler, hci_layer) {} ~FakeSecurityManagerChannel() {} void OnConnectionOpen(std::unique_ptr<l2cap::classic::FixedChannel> fixed_channel) override { LOG_ERROR("CALLED"); void OnLinkConnected(std::unique_ptr<l2cap::classic::LinkSecurityInterface> link) { on_link_connected_called = true; } void OnLinkDisconnected(hci::Address address) { on_link_disconnected_called = true; } }; Loading Loading @@ -197,19 +205,19 @@ class SecurityManagerChannelCallback : public ISecurityManagerChannelListener { } } void OnConnectionClosed(hci::Address address, bluetooth::hci::ErrorCode error_code) override { void OnConnectionClosed(hci::Address address) override { LOG_DEBUG("Called"); } void OnConnectionFailed(hci::Address address, bluetooth::l2cap::classic::FixedChannelManager::ConnectionResult result) override { LOG_DEBUG("Shouldn't be called"); } }; class SecurityManagerChannelTest : public ::testing::Test { protected: void SetUp() override { hci::Address address; hci::Address::FromString("01:23:45:67:89:AB:CD", address); device_ = hci::AddressWithType(address, hci::AddressType::PUBLIC_DEVICE_ADDRESS); on_link_connected_called = false; on_link_disconnected_called = false; handler_ = new Handler(&thread_); callback_ = new SecurityManagerChannelCallback(); hci_layer_ = new FakeHciLayer(); Loading @@ -217,6 +225,8 @@ class SecurityManagerChannelTest : public ::testing::Test { fake_registry_.Start<FakeHciLayer>(&thread_); channel_ = new FakeSecurityManagerChannel(handler_, hci_layer_); channel_->SetChannelListener(callback_); security_interface_ = new FakeSecurityInterface(handler_, channel_); channel_->SetSecurityInterface(security_interface_); } void TearDown() override { Loading @@ -227,6 +237,7 @@ class SecurityManagerChannelTest : public ::testing::Test { delete handler_; delete channel_; delete callback_; delete security_interface_; } void synchronize() { Loading @@ -237,6 +248,7 @@ class SecurityManagerChannelTest : public ::testing::Test { Thread& thread_ = fake_registry_.GetTestThread(); Handler* handler_ = nullptr; FakeHciLayer* hci_layer_ = nullptr; l2cap::classic::SecurityInterface* security_interface_ = nullptr; SecurityManagerChannel* channel_ = nullptr; SecurityManagerChannelCallback* callback_ = nullptr; hci::AddressWithType device_; Loading Loading @@ -673,6 +685,16 @@ TEST_F(SecurityManagerChannelTest, recv_user_passkey_request) { ASSERT_TRUE(callback_->receivedUserPasskeyRequest); } TEST_F(SecurityManagerChannelTest, test_l2cap_security_interface_api) { ASSERT_FALSE(on_link_connected_called); channel_->Connect(device_.GetAddress()); ASSERT_TRUE(on_link_connected_called); ASSERT_FALSE(on_link_disconnected_called); channel_->Release(device_.GetAddress()); // TODO(optedoblivion): Lock and wait // ASSERT_TRUE(on_link_disconnected_called); } } // namespace } // namespace channel } // namespace security Loading
system/gd/security/internal/security_manager_impl.cc +3 −14 Original line number Diff line number Diff line Loading @@ -104,6 +104,7 @@ void SecurityManagerImpl::CancelBond(hci::AddressWithType device) { void SecurityManagerImpl::RemoveBond(hci::AddressWithType device) { CancelBond(device); security_database_.Remove(device); security_manager_channel_->Disconnect(device.GetAddress()); // Signal disconnect // Remove security record // Signal Remove from database Loading Loading @@ -250,19 +251,7 @@ void SecurityManagerImpl::OnHciEventReceived(hci::EventPacketView packet) { } } void SecurityManagerImpl::OnConnectionClosed(hci::Address address, bluetooth::hci::ErrorCode error_code) { LOG_DEBUG("Reason: %s ", hci::ErrorCodeText(error_code).c_str()); auto entry = pairing_handler_map_.find(address); if (entry != pairing_handler_map_.end()) { LOG_DEBUG("Cancelling pairing handler for '%s'", address.ToString().c_str()); entry->second->Cancel(); } } void SecurityManagerImpl::OnConnectionFailed(hci::Address address, bluetooth::l2cap::classic::FixedChannelManager::ConnectionResult result) { LOG_DEBUG("HCI Reason: %s ", hci::ErrorCodeText(result.hci_error).c_str()); LOG_DEBUG("L2CAP Reason: %d ", result.connection_result_code); void SecurityManagerImpl::OnConnectionClosed(hci::Address address) { auto entry = pairing_handler_map_.find(address); if (entry != pairing_handler_map_.end()) { LOG_DEBUG("Cancelling pairing handler for '%s'", address.ToString().c_str()); Loading Loading @@ -312,7 +301,7 @@ void SecurityManagerImpl::OnPairingHandlerComplete(hci::Address address, Pairing auto entry = pairing_handler_map_.find(address); if (entry != pairing_handler_map_.end()) { pairing_handler_map_.erase(entry); security_manager_channel_->Disconnect(address); security_manager_channel_->Release(address); } if (!std::holds_alternative<PairingFailure>(status)) { NotifyDeviceBonded(hci::AddressWithType(address, hci::AddressType::PUBLIC_DEVICE_ADDRESS)); Loading
system/gd/security/internal/security_manager_impl.h +1 −11 Original line number Diff line number Diff line Loading @@ -122,18 +122,8 @@ class SecurityManagerImpl : public channel::ISecurityManagerChannelListener, pub * When a conncetion closes we should clean up the pairing handler * * @param address Remote address * @param error_code HCI error */ void OnConnectionClosed(hci::Address address, bluetooth::hci::ErrorCode error_code) override; /** * This can occur when a remote device isn't in range or doesn't agree with local device * * @param address Remote address * @param result holds hci error and connection error code */ void OnConnectionFailed(hci::Address address, bluetooth::l2cap::classic::FixedChannelManager::ConnectionResult result) override; void OnConnectionClosed(hci::Address address) override; /** * Pairing handler has finished or cancelled Loading