Loading system/gd/l2cap/classic/dynamic_channel_manager.h +12 −6 Original line number Diff line number Diff line Loading @@ -94,7 +94,7 @@ class DynamicChannelManager { * * Returns: true if connection was able to be initiated, false otherwise. */ bool ConnectChannel(hci::Address device, DynamicChannelConfigurationOption configuration_option, Psm psm, virtual bool ConnectChannel(hci::Address device, DynamicChannelConfigurationOption configuration_option, Psm psm, OnConnectionOpenCallback on_connection_open, OnConnectionFailureCallback on_fail_callback, os::Handler* handler); Loading @@ -119,12 +119,18 @@ class DynamicChannelManager { * @param handler: The handler context in which to execute the @callback parameter. * @param configuration_option: The configuration options for this channel */ bool RegisterService(Psm psm, DynamicChannelConfigurationOption configuration_option, const SecurityPolicy& security_policy, OnRegistrationCompleteCallback on_registration_complete, virtual bool RegisterService(Psm psm, DynamicChannelConfigurationOption configuration_option, const SecurityPolicy& security_policy, OnRegistrationCompleteCallback on_registration_complete, OnConnectionOpenCallback on_connection_open, os::Handler* handler); friend class L2capClassicModule; virtual ~DynamicChannelManager() = default; protected: DynamicChannelManager() = default; private: // The constructor is not to be used by user code DynamicChannelManager(internal::DynamicChannelServiceManagerImpl* service_manager, Loading system/gd/shim/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ filegroup { filegroup { name: "BluetoothShimTestSources", srcs: [ "l2cap_test.cc", ], } Loading system/gd/shim/l2cap.cc +9 −2 Original line number Diff line number Diff line Loading @@ -137,6 +137,10 @@ class ConnectionInterface { void OnConnectionClosed(hci::ErrorCode error_code) { LOG_DEBUG("Channel interface closed reason:%s cid:%hd device:%s", hci::ErrorCodeText(error_code).c_str(), cid_, address_.ToString().c_str()); if (dequeue_registered_) { channel_->GetQueueUpEnd()->UnregisterDequeue(); dequeue_registered_ = false; } ASSERT(on_connection_closed_callback_ != nullptr); on_connection_closed_callback_(cid_, static_cast<int>(error_code)); deleter_(cid_); Loading Loading @@ -261,8 +265,11 @@ void ConnectionInterfaceManager::AddConnection(ConnectionInterfaceDescriptor cid } void ConnectionInterfaceManager::RemoveConnection(ConnectionInterfaceDescriptor cid) { ASSERT(cid_to_interface_map_.count(cid) == 1); if (cid_to_interface_map_.count(cid) == 1) { cid_to_interface_map_.find(cid)->second->Close(); } else { LOG_WARN("Closing a pending connection cid:%hd", cid); } } bool ConnectionInterfaceManager::HasResources() const { Loading system/gd/shim/l2cap_test.cc 0 → 100644 +180 −0 Original line number Diff line number Diff line /* * 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 "shim/l2cap.h" #include <algorithm> #include <chrono> #include <future> #include <map> #include <memory> #include <unistd.h> #include <gtest/gtest.h> #include "common/bind.h" #include "hci/address.h" #include "l2cap/classic/dynamic_channel_configuration_option.h" #include "l2cap/classic/l2cap_classic_module.h" #include "l2cap/psm.h" #include "l2cap/security_policy.h" #include "module.h" #include "os/handler.h" namespace bluetooth { namespace shim { namespace { constexpr uint16_t kPsm = 123; constexpr char device_address[] = "11:22:33:44:55:66"; class TestDynamicChannelManagerImpl { public: bool ConnectChannel(hci::Address device, l2cap::classic::DynamicChannelConfigurationOption configuration_option, l2cap::Psm psm, l2cap::classic::DynamicChannelManager::OnConnectionOpenCallback on_connection_open, l2cap::classic::DynamicChannelManager::OnConnectionFailureCallback on_fail_callback, os::Handler* handler) { connections_++; if (psm_to_connected_map_.find(psm) != psm_to_connected_map_.end()) { psm_to_connected_map_[psm]->set_value(); } return true; } bool RegisterService(l2cap::Psm psm, l2cap::classic::DynamicChannelConfigurationOption configuration_option, const l2cap::SecurityPolicy& security_policy, l2cap::classic::DynamicChannelManager::OnRegistrationCompleteCallback on_registration_complete, l2cap::classic::DynamicChannelManager::OnConnectionOpenCallback on_connection_open, os::Handler* handler) { services_++; return true; } std::map<uint16_t, std::promise<void>*> psm_to_connected_map_; int connections_{0}; int services_{0}; ~TestDynamicChannelManagerImpl() { for (auto& entry : psm_to_connected_map_) { delete (entry.second); } psm_to_connected_map_.clear(); } TestDynamicChannelManagerImpl() = default; }; class TestDynamicChannelManager : public l2cap::classic::DynamicChannelManager { public: bool ConnectChannel(hci::Address device, l2cap::classic::DynamicChannelConfigurationOption configuration_option, l2cap::Psm psm, l2cap::classic::DynamicChannelManager::OnConnectionOpenCallback on_connection_open, l2cap::classic::DynamicChannelManager::OnConnectionFailureCallback on_fail_callback, os::Handler* handler) override { return impl_.ConnectChannel(device, configuration_option, psm, std::move(on_connection_open), std::move(on_fail_callback), handler); } bool RegisterService(l2cap::Psm psm, l2cap::classic::DynamicChannelConfigurationOption configuration_option, const l2cap::SecurityPolicy& security_policy, l2cap::classic::DynamicChannelManager::OnRegistrationCompleteCallback on_registration_complete, l2cap::classic::DynamicChannelManager::OnConnectionOpenCallback on_connection_open, os::Handler* handler) override { return impl_.RegisterService(psm, configuration_option, security_policy, std::move(on_registration_complete), std::move(on_connection_open), handler); } TestDynamicChannelManager(TestDynamicChannelManagerImpl& impl) : impl_(impl) {} TestDynamicChannelManagerImpl& impl_; }; class TestL2capClassicModule : public l2cap::classic::L2capClassicModule { public: std::unique_ptr<l2cap::classic::DynamicChannelManager> GetDynamicChannelManager() override { ASSERT(impl_ != nullptr); return std::make_unique<TestDynamicChannelManager>(*impl_); } void ListDependencies(ModuleList* list) override {} void Start() override; void Stop() override; TestDynamicChannelManagerImpl* impl_{nullptr}; }; void TestL2capClassicModule::Start() { impl_ = new TestDynamicChannelManagerImpl(); } void TestL2capClassicModule::Stop() { delete impl_; } class ShimL2capTest : public ::testing::Test { public: void OnConnectionComplete(std::string string_address, uint16_t psm, uint16_t cid, bool connected) {} shim::L2cap* shim_l2cap_ = nullptr; TestL2capClassicModule* test_l2cap_classic_module_{nullptr}; protected: void SetUp() override { test_l2cap_classic_module_ = new TestL2capClassicModule(); test_l2cap_classic_module_->Start(); fake_registry_.InjectTestModule(&l2cap::classic::L2capClassicModule::Factory, test_l2cap_classic_module_); fake_registry_.Start<shim::L2cap>(&thread_); shim_l2cap_ = static_cast<shim::L2cap*>(fake_registry_.GetModuleUnderTest(&shim::L2cap::Factory)); } void TearDown() override { fake_registry_.StopAll(); } private: TestModuleRegistry fake_registry_; os::Thread& thread_ = fake_registry_.GetTestThread(); }; TEST_F(ShimL2capTest, Module) {} TEST_F(ShimL2capTest, ConnectThenDisconnectBeforeCompletion) { std::promise<uint16_t> promise; auto future = promise.get_future(); test_l2cap_classic_module_->impl_->psm_to_connected_map_[kPsm] = new std::promise<void>(); auto connection_started = test_l2cap_classic_module_->impl_->psm_to_connected_map_[kPsm]->get_future(); shim_l2cap_->CreateConnection( kPsm, device_address, std::bind(&bluetooth::shim::ShimL2capTest::OnConnectionComplete, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4), std::move(promise)); uint16_t cid = future.get(); ASSERT(cid != 0); connection_started.wait(); ASSERT(test_l2cap_classic_module_->impl_->connections_ == 1); shim_l2cap_->CloseConnection(cid); } } // namespace } // namespace shim } // namespace bluetooth system/main/shim/l2cap.cc +30 −21 Original line number Diff line number Diff line Loading @@ -170,8 +170,8 @@ void bluetooth::shim::legacy::L2cap::RegisterService( } Classic().RegisterPsm(psm, callbacks); std::promise<void> register_completed; auto completed = register_completed.get_future(); std::promise<void> register_pending; auto registered = register_pending.get_future(); bool use_ertm = false; if (p_ertm_info != nullptr && p_ertm_info->preferred_mode == L2CAP_FCR_ERTM_MODE) { Loading @@ -184,8 +184,8 @@ void bluetooth::shim::legacy::L2cap::RegisterService( &bluetooth::shim::legacy::L2cap::OnRemoteInitiatedConnectionCreated, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), std::move(register_completed)); completed.wait(); std::move(register_pending)); registered.wait(); LOG_DEBUG(LOG_TAG, "Successfully registered service on psm:%hd", psm); } Loading Loading @@ -233,10 +233,9 @@ uint16_t bluetooth::shim::legacy::L2cap::CreateConnection( return kInvalidConnectionInterfaceDescriptor; } std::promise<uint16_t> connect_completed; auto completed = connect_completed.get_future(); LOG_DEBUG(LOG_TAG, "Starting local initiated connection to psm:%hd address:%s", psm, std::promise<uint16_t> create_pending; auto created = create_pending.get_future(); LOG_DEBUG(LOG_TAG, "Initiating local connection to psm:%hd address:%s", psm, raw_address.ToString().c_str()); bluetooth::shim::GetL2cap()->CreateConnection( Loading @@ -245,16 +244,16 @@ uint16_t bluetooth::shim::legacy::L2cap::CreateConnection( &bluetooth::shim::legacy::L2cap::OnLocalInitiatedConnectionCreated, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4), std::move(connect_completed)); std::move(create_pending)); uint16_t cid = completed.get(); uint16_t cid = created.get(); if (cid == kInvalidConnectionInterfaceDescriptor) { LOG_WARN(LOG_TAG, "Failed to allocate resources to connect to psm:%hd address:%s", "Failed to initiate connection interface to psm:%hd address:%s", psm, raw_address.ToString().c_str()); } else { LOG_DEBUG(LOG_TAG, "Successfully started connection to psm:%hd address:%s" "Successfully initiated connection to psm:%hd address:%s" " connection_interface_descriptor:%hd", psm, raw_address.ToString().c_str(), cid); CHECK(!ConnectionExists(cid)); Loading @@ -265,15 +264,25 @@ uint16_t bluetooth::shim::legacy::L2cap::CreateConnection( void bluetooth::shim::legacy::L2cap::OnLocalInitiatedConnectionCreated( std::string string_address, uint16_t psm, uint16_t cid, bool connected) { LOG_DEBUG(LOG_TAG, "Sending connection confirm to the upper stack but really " "a connection to %s has already been done cid:%hd", string_address.c_str(), cid); if (cid_closing_set_.count(cid) == 0) { if (connected) { SetDownstreamCallbacks(cid); } else { LOG_WARN(LOG_TAG, "Failed intitiating connection remote:%s psm:%hd cid:%hd", string_address.c_str(), psm, cid); } Classic().Callbacks(psm)->pL2CA_ConnectCfm_Cb( cid, connected ? (kConnectionSuccess) : (kConnectionFail)); } else { LOG_DEBUG(LOG_TAG, "Connection Closed before presentation to upper layer"); if (connected) { SetDownstreamCallbacks(cid); bluetooth::shim::GetL2cap()->CloseConnection(cid); } else { LOG_DEBUG(LOG_TAG, "Connection failed after initiator closed"); } } } bool bluetooth::shim::legacy::L2cap::Write(uint16_t cid, BT_HDR* bt_hdr) { Loading Loading @@ -370,7 +379,7 @@ bool bluetooth::shim::legacy::L2cap::DisconnectRequest(uint16_t cid) { cid); return false; } LOG_DEBUG(LOG_TAG, "%s cid:%hu", __func__, cid); LOG_DEBUG(LOG_TAG, "%s initiated locally cid:%hu", __func__, cid); cid_closing_set_.insert(cid); bluetooth::shim::GetL2cap()->CloseConnection(cid); return true; Loading Loading
system/gd/l2cap/classic/dynamic_channel_manager.h +12 −6 Original line number Diff line number Diff line Loading @@ -94,7 +94,7 @@ class DynamicChannelManager { * * Returns: true if connection was able to be initiated, false otherwise. */ bool ConnectChannel(hci::Address device, DynamicChannelConfigurationOption configuration_option, Psm psm, virtual bool ConnectChannel(hci::Address device, DynamicChannelConfigurationOption configuration_option, Psm psm, OnConnectionOpenCallback on_connection_open, OnConnectionFailureCallback on_fail_callback, os::Handler* handler); Loading @@ -119,12 +119,18 @@ class DynamicChannelManager { * @param handler: The handler context in which to execute the @callback parameter. * @param configuration_option: The configuration options for this channel */ bool RegisterService(Psm psm, DynamicChannelConfigurationOption configuration_option, const SecurityPolicy& security_policy, OnRegistrationCompleteCallback on_registration_complete, virtual bool RegisterService(Psm psm, DynamicChannelConfigurationOption configuration_option, const SecurityPolicy& security_policy, OnRegistrationCompleteCallback on_registration_complete, OnConnectionOpenCallback on_connection_open, os::Handler* handler); friend class L2capClassicModule; virtual ~DynamicChannelManager() = default; protected: DynamicChannelManager() = default; private: // The constructor is not to be used by user code DynamicChannelManager(internal::DynamicChannelServiceManagerImpl* service_manager, Loading
system/gd/shim/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ filegroup { filegroup { name: "BluetoothShimTestSources", srcs: [ "l2cap_test.cc", ], } Loading
system/gd/shim/l2cap.cc +9 −2 Original line number Diff line number Diff line Loading @@ -137,6 +137,10 @@ class ConnectionInterface { void OnConnectionClosed(hci::ErrorCode error_code) { LOG_DEBUG("Channel interface closed reason:%s cid:%hd device:%s", hci::ErrorCodeText(error_code).c_str(), cid_, address_.ToString().c_str()); if (dequeue_registered_) { channel_->GetQueueUpEnd()->UnregisterDequeue(); dequeue_registered_ = false; } ASSERT(on_connection_closed_callback_ != nullptr); on_connection_closed_callback_(cid_, static_cast<int>(error_code)); deleter_(cid_); Loading Loading @@ -261,8 +265,11 @@ void ConnectionInterfaceManager::AddConnection(ConnectionInterfaceDescriptor cid } void ConnectionInterfaceManager::RemoveConnection(ConnectionInterfaceDescriptor cid) { ASSERT(cid_to_interface_map_.count(cid) == 1); if (cid_to_interface_map_.count(cid) == 1) { cid_to_interface_map_.find(cid)->second->Close(); } else { LOG_WARN("Closing a pending connection cid:%hd", cid); } } bool ConnectionInterfaceManager::HasResources() const { Loading
system/gd/shim/l2cap_test.cc 0 → 100644 +180 −0 Original line number Diff line number Diff line /* * 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 "shim/l2cap.h" #include <algorithm> #include <chrono> #include <future> #include <map> #include <memory> #include <unistd.h> #include <gtest/gtest.h> #include "common/bind.h" #include "hci/address.h" #include "l2cap/classic/dynamic_channel_configuration_option.h" #include "l2cap/classic/l2cap_classic_module.h" #include "l2cap/psm.h" #include "l2cap/security_policy.h" #include "module.h" #include "os/handler.h" namespace bluetooth { namespace shim { namespace { constexpr uint16_t kPsm = 123; constexpr char device_address[] = "11:22:33:44:55:66"; class TestDynamicChannelManagerImpl { public: bool ConnectChannel(hci::Address device, l2cap::classic::DynamicChannelConfigurationOption configuration_option, l2cap::Psm psm, l2cap::classic::DynamicChannelManager::OnConnectionOpenCallback on_connection_open, l2cap::classic::DynamicChannelManager::OnConnectionFailureCallback on_fail_callback, os::Handler* handler) { connections_++; if (psm_to_connected_map_.find(psm) != psm_to_connected_map_.end()) { psm_to_connected_map_[psm]->set_value(); } return true; } bool RegisterService(l2cap::Psm psm, l2cap::classic::DynamicChannelConfigurationOption configuration_option, const l2cap::SecurityPolicy& security_policy, l2cap::classic::DynamicChannelManager::OnRegistrationCompleteCallback on_registration_complete, l2cap::classic::DynamicChannelManager::OnConnectionOpenCallback on_connection_open, os::Handler* handler) { services_++; return true; } std::map<uint16_t, std::promise<void>*> psm_to_connected_map_; int connections_{0}; int services_{0}; ~TestDynamicChannelManagerImpl() { for (auto& entry : psm_to_connected_map_) { delete (entry.second); } psm_to_connected_map_.clear(); } TestDynamicChannelManagerImpl() = default; }; class TestDynamicChannelManager : public l2cap::classic::DynamicChannelManager { public: bool ConnectChannel(hci::Address device, l2cap::classic::DynamicChannelConfigurationOption configuration_option, l2cap::Psm psm, l2cap::classic::DynamicChannelManager::OnConnectionOpenCallback on_connection_open, l2cap::classic::DynamicChannelManager::OnConnectionFailureCallback on_fail_callback, os::Handler* handler) override { return impl_.ConnectChannel(device, configuration_option, psm, std::move(on_connection_open), std::move(on_fail_callback), handler); } bool RegisterService(l2cap::Psm psm, l2cap::classic::DynamicChannelConfigurationOption configuration_option, const l2cap::SecurityPolicy& security_policy, l2cap::classic::DynamicChannelManager::OnRegistrationCompleteCallback on_registration_complete, l2cap::classic::DynamicChannelManager::OnConnectionOpenCallback on_connection_open, os::Handler* handler) override { return impl_.RegisterService(psm, configuration_option, security_policy, std::move(on_registration_complete), std::move(on_connection_open), handler); } TestDynamicChannelManager(TestDynamicChannelManagerImpl& impl) : impl_(impl) {} TestDynamicChannelManagerImpl& impl_; }; class TestL2capClassicModule : public l2cap::classic::L2capClassicModule { public: std::unique_ptr<l2cap::classic::DynamicChannelManager> GetDynamicChannelManager() override { ASSERT(impl_ != nullptr); return std::make_unique<TestDynamicChannelManager>(*impl_); } void ListDependencies(ModuleList* list) override {} void Start() override; void Stop() override; TestDynamicChannelManagerImpl* impl_{nullptr}; }; void TestL2capClassicModule::Start() { impl_ = new TestDynamicChannelManagerImpl(); } void TestL2capClassicModule::Stop() { delete impl_; } class ShimL2capTest : public ::testing::Test { public: void OnConnectionComplete(std::string string_address, uint16_t psm, uint16_t cid, bool connected) {} shim::L2cap* shim_l2cap_ = nullptr; TestL2capClassicModule* test_l2cap_classic_module_{nullptr}; protected: void SetUp() override { test_l2cap_classic_module_ = new TestL2capClassicModule(); test_l2cap_classic_module_->Start(); fake_registry_.InjectTestModule(&l2cap::classic::L2capClassicModule::Factory, test_l2cap_classic_module_); fake_registry_.Start<shim::L2cap>(&thread_); shim_l2cap_ = static_cast<shim::L2cap*>(fake_registry_.GetModuleUnderTest(&shim::L2cap::Factory)); } void TearDown() override { fake_registry_.StopAll(); } private: TestModuleRegistry fake_registry_; os::Thread& thread_ = fake_registry_.GetTestThread(); }; TEST_F(ShimL2capTest, Module) {} TEST_F(ShimL2capTest, ConnectThenDisconnectBeforeCompletion) { std::promise<uint16_t> promise; auto future = promise.get_future(); test_l2cap_classic_module_->impl_->psm_to_connected_map_[kPsm] = new std::promise<void>(); auto connection_started = test_l2cap_classic_module_->impl_->psm_to_connected_map_[kPsm]->get_future(); shim_l2cap_->CreateConnection( kPsm, device_address, std::bind(&bluetooth::shim::ShimL2capTest::OnConnectionComplete, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4), std::move(promise)); uint16_t cid = future.get(); ASSERT(cid != 0); connection_started.wait(); ASSERT(test_l2cap_classic_module_->impl_->connections_ == 1); shim_l2cap_->CloseConnection(cid); } } // namespace } // namespace shim } // namespace bluetooth
system/main/shim/l2cap.cc +30 −21 Original line number Diff line number Diff line Loading @@ -170,8 +170,8 @@ void bluetooth::shim::legacy::L2cap::RegisterService( } Classic().RegisterPsm(psm, callbacks); std::promise<void> register_completed; auto completed = register_completed.get_future(); std::promise<void> register_pending; auto registered = register_pending.get_future(); bool use_ertm = false; if (p_ertm_info != nullptr && p_ertm_info->preferred_mode == L2CAP_FCR_ERTM_MODE) { Loading @@ -184,8 +184,8 @@ void bluetooth::shim::legacy::L2cap::RegisterService( &bluetooth::shim::legacy::L2cap::OnRemoteInitiatedConnectionCreated, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), std::move(register_completed)); completed.wait(); std::move(register_pending)); registered.wait(); LOG_DEBUG(LOG_TAG, "Successfully registered service on psm:%hd", psm); } Loading Loading @@ -233,10 +233,9 @@ uint16_t bluetooth::shim::legacy::L2cap::CreateConnection( return kInvalidConnectionInterfaceDescriptor; } std::promise<uint16_t> connect_completed; auto completed = connect_completed.get_future(); LOG_DEBUG(LOG_TAG, "Starting local initiated connection to psm:%hd address:%s", psm, std::promise<uint16_t> create_pending; auto created = create_pending.get_future(); LOG_DEBUG(LOG_TAG, "Initiating local connection to psm:%hd address:%s", psm, raw_address.ToString().c_str()); bluetooth::shim::GetL2cap()->CreateConnection( Loading @@ -245,16 +244,16 @@ uint16_t bluetooth::shim::legacy::L2cap::CreateConnection( &bluetooth::shim::legacy::L2cap::OnLocalInitiatedConnectionCreated, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4), std::move(connect_completed)); std::move(create_pending)); uint16_t cid = completed.get(); uint16_t cid = created.get(); if (cid == kInvalidConnectionInterfaceDescriptor) { LOG_WARN(LOG_TAG, "Failed to allocate resources to connect to psm:%hd address:%s", "Failed to initiate connection interface to psm:%hd address:%s", psm, raw_address.ToString().c_str()); } else { LOG_DEBUG(LOG_TAG, "Successfully started connection to psm:%hd address:%s" "Successfully initiated connection to psm:%hd address:%s" " connection_interface_descriptor:%hd", psm, raw_address.ToString().c_str(), cid); CHECK(!ConnectionExists(cid)); Loading @@ -265,15 +264,25 @@ uint16_t bluetooth::shim::legacy::L2cap::CreateConnection( void bluetooth::shim::legacy::L2cap::OnLocalInitiatedConnectionCreated( std::string string_address, uint16_t psm, uint16_t cid, bool connected) { LOG_DEBUG(LOG_TAG, "Sending connection confirm to the upper stack but really " "a connection to %s has already been done cid:%hd", string_address.c_str(), cid); if (cid_closing_set_.count(cid) == 0) { if (connected) { SetDownstreamCallbacks(cid); } else { LOG_WARN(LOG_TAG, "Failed intitiating connection remote:%s psm:%hd cid:%hd", string_address.c_str(), psm, cid); } Classic().Callbacks(psm)->pL2CA_ConnectCfm_Cb( cid, connected ? (kConnectionSuccess) : (kConnectionFail)); } else { LOG_DEBUG(LOG_TAG, "Connection Closed before presentation to upper layer"); if (connected) { SetDownstreamCallbacks(cid); bluetooth::shim::GetL2cap()->CloseConnection(cid); } else { LOG_DEBUG(LOG_TAG, "Connection failed after initiator closed"); } } } bool bluetooth::shim::legacy::L2cap::Write(uint16_t cid, BT_HDR* bt_hdr) { Loading Loading @@ -370,7 +379,7 @@ bool bluetooth::shim::legacy::L2cap::DisconnectRequest(uint16_t cid) { cid); return false; } LOG_DEBUG(LOG_TAG, "%s cid:%hu", __func__, cid); LOG_DEBUG(LOG_TAG, "%s initiated locally cid:%hu", __func__, cid); cid_closing_set_.insert(cid); bluetooth::shim::GetL2cap()->CloseConnection(cid); return true; Loading