Loading system/gd/l2cap/classic/dynamic_channel_manager.cc +2 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include "l2cap/classic/dynamic_channel_manager.h" #include "l2cap/classic/internal/dynamic_channel_service_impl.h" #include "l2cap/classic/internal/dynamic_channel_service_manager_impl.h" #include "l2cap/classic/internal/link.h" #include "l2cap/classic/internal/link_manager.h" namespace bluetooth { Loading @@ -25,7 +26,7 @@ namespace classic { bool DynamicChannelManager::ConnectChannel(hci::Address device, Psm psm, OnConnectionOpenCallback on_connection_open, OnConnectionFailureCallback on_fail_callback, os::Handler* handler) { internal::LinkManager::PendingDynamicChannelConnection pending_dynamic_channel_connection{ internal::Link::PendingDynamicChannelConnection pending_dynamic_channel_connection{ .handler_ = handler, .on_open_callback_ = std::move(on_connection_open), .on_fail_callback_ = std::move(on_fail_callback), Loading system/gd/l2cap/classic/internal/dynamic_channel_impl.h +3 −0 Original line number Diff line number Diff line Loading @@ -78,6 +78,9 @@ class DynamicChannelImpl { return incoming_configuration_status_; } // TODO(cmanton) Do something a little bit better than this bool local_initiated_{false}; private: const Psm psm_; const Cid cid_; Loading system/gd/l2cap/classic/internal/link.cc +29 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <memory> #include "hci/acl_manager.h" #include "l2cap/classic/dynamic_channel_manager.h" #include "l2cap/classic/internal/fixed_channel_impl.h" #include "l2cap/classic/internal/link.h" #include "l2cap/internal/parameter_provider.h" Loading Loading @@ -76,6 +77,12 @@ void Link::SendConnectionRequest(Psm psm, Cid local_cid) { signalling_manager_.SendConnectionRequest(psm, local_cid); } void Link::SendConnectionRequest(Psm psm, Cid local_cid, PendingDynamicChannelConnection pending_dynamic_channel_connection) { local_cid_to_pending_dynamic_channel_connection_map_[local_cid] = std::move(pending_dynamic_channel_connection); signalling_manager_.SendConnectionRequest(psm, local_cid); } void Link::SendDisconnectionRequest(Cid local_cid, Cid remote_cid) { signalling_manager_.SendDisconnectionRequest(local_cid, remote_cid); } Loading @@ -91,6 +98,7 @@ std::shared_ptr<DynamicChannelImpl> Link::AllocateDynamicChannel(Psm psm, Cid re scheduler_->AttachChannel(channel->GetCid(), channel->GetQueueDownEnd(), channel->GetRemoteCid()); reassembler_.AttachChannel(channel->GetCid(), channel->GetQueueDownEnd(), {}); } channel->local_initiated_ = false; return channel; } Loading @@ -101,6 +109,7 @@ std::shared_ptr<DynamicChannelImpl> Link::AllocateReservedDynamicChannel(Cid res scheduler_->AttachChannel(channel->GetCid(), channel->GetQueueDownEnd(), channel->GetRemoteCid()); reassembler_.AttachChannel(channel->GetCid(), channel->GetQueueDownEnd(), {}); } channel->local_initiated_ = true; return channel; } Loading @@ -125,6 +134,26 @@ void Link::RefreshRefCount() { } } void Link::NotifyChannelCreation(Cid cid, std::unique_ptr<DynamicChannel> channel) { ASSERT(local_cid_to_pending_dynamic_channel_connection_map_.find(cid) != local_cid_to_pending_dynamic_channel_connection_map_.end()); auto& pending_dynamic_channel_connection = local_cid_to_pending_dynamic_channel_connection_map_[cid]; pending_dynamic_channel_connection.handler_->Post( common::BindOnce(std::move(pending_dynamic_channel_connection.on_open_callback_), std::move(channel))); local_cid_to_pending_dynamic_channel_connection_map_.erase(cid); } void Link::NotifyChannelFail(Cid cid) { ASSERT(local_cid_to_pending_dynamic_channel_connection_map_.find(cid) != local_cid_to_pending_dynamic_channel_connection_map_.end()); auto& pending_dynamic_channel_connection = local_cid_to_pending_dynamic_channel_connection_map_[cid]; // TODO(cmanton) Pass proper connection falure result to user DynamicChannelManager::ConnectionResult result; pending_dynamic_channel_connection.handler_->Post( common::BindOnce(std::move(pending_dynamic_channel_connection.on_fail_callback_), result)); local_cid_to_pending_dynamic_channel_connection_map_.erase(cid); } } // namespace internal } // namespace classic } // namespace l2cap Loading system/gd/l2cap/classic/internal/link.h +13 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #pragma once #include <memory> #include <unordered_map> #include "hci/acl_manager.h" #include "l2cap/classic/internal/dynamic_channel_allocator.h" Loading Loading @@ -50,6 +51,12 @@ class Link { return acl_connection_->GetAddress(); } struct PendingDynamicChannelConnection { os::Handler* handler_; DynamicChannelManager::OnConnectionOpenCallback on_open_callback_; DynamicChannelManager::OnConnectionFailureCallback on_fail_callback_; }; // ACL methods virtual void OnAclDisconnected(hci::ErrorCode status); Loading @@ -67,6 +74,8 @@ class Link { virtual Cid ReserveDynamicChannel(); virtual void SendConnectionRequest(Psm psm, Cid local_cid); virtual void SendConnectionRequest(Psm psm, Cid local_cid, PendingDynamicChannelConnection pending_dynamic_channel_connection); virtual void SendInformationRequest(InformationRequestInfoType type); Loading @@ -83,6 +92,9 @@ class Link { // Check how many channels are acquired or in use, if zero, start tear down timer, if non-zero, cancel tear down timer virtual void RefreshRefCount(); virtual void NotifyChannelCreation(Cid cid, std::unique_ptr<DynamicChannel> channel); virtual void NotifyChannelFail(Cid cid); private: os::Handler* l2cap_handler_; l2cap::internal::FixedChannelAllocator<FixedChannelImpl, Link> fixed_channel_allocator_{this, l2cap_handler_}; Loading @@ -94,6 +106,7 @@ class Link { DynamicChannelServiceManagerImpl* dynamic_service_manager_; FixedChannelServiceManagerImpl* fixed_service_manager_; ClassicSignallingManager signalling_manager_; std::unordered_map<Cid, PendingDynamicChannelConnection> local_cid_to_pending_dynamic_channel_connection_map_; os::Alarm link_idle_disconnect_alarm_{l2cap_handler_}; DISALLOW_COPY_AND_ASSIGN(Link); }; Loading system/gd/l2cap/classic/internal/link_manager.cc +7 −6 Original line number Diff line number Diff line Loading @@ -82,9 +82,8 @@ void LinkManager::ConnectFixedChannelServices(hci::Address device, acl_manager_->CreateConnection(device); } void LinkManager::ConnectDynamicChannelServices(hci::Address device, PendingDynamicChannelConnection pending_dynamic_channel_connection, Psm psm) { void LinkManager::ConnectDynamicChannelServices( hci::Address device, Link::PendingDynamicChannelConnection pending_dynamic_channel_connection, Psm psm) { auto* link = GetLink(device); if (link == nullptr) { acl_manager_->CreateConnection(device); Loading @@ -97,7 +96,7 @@ void LinkManager::ConnectDynamicChannelServices(hci::Address device, } return; } link->SendConnectionRequest(psm, link->ReserveDynamicChannel()); link->SendConnectionRequest(psm, link->ReserveDynamicChannel(), std::move(pending_dynamic_channel_connection)); } Link* LinkManager::GetLink(const hci::Address device) { Loading Loading @@ -133,7 +132,9 @@ void LinkManager::OnConnectSuccess(std::unique_ptr<hci::AclConnection> acl_conne } if (pending_dynamic_channels_.find(device) != pending_dynamic_channels_.end()) { for (Psm psm : pending_dynamic_channels_[device]) { link->SendConnectionRequest(psm, link->ReserveDynamicChannel()); auto& callbacks = pending_dynamic_channels_callbacks_[device].front(); pending_dynamic_channels_callbacks_[device].pop_front(); link->SendConnectionRequest(psm, link->ReserveDynamicChannel(), std::move(callbacks)); } pending_dynamic_channels_.erase(device); pending_dynamic_channels_callbacks_.erase(device); Loading @@ -155,7 +156,7 @@ void LinkManager::OnConnectFail(hci::Address device, hci::ErrorCode reason) { // There is no pending link, exit LOG_DEBUG("Connection to %s failed without a pending link", device.ToString().c_str()); if (pending_dynamic_channels_callbacks_.find(device) != pending_dynamic_channels_callbacks_.end()) { for (PendingDynamicChannelConnection& callbacks : pending_dynamic_channels_callbacks_[device]) { for (Link::PendingDynamicChannelConnection& callbacks : pending_dynamic_channels_callbacks_[device]) { callbacks.handler_->Post(common::BindOnce(std::move(callbacks.on_fail_callback_), DynamicChannelManager::ConnectionResult{ .hci_error = hci::ErrorCode::CONNECTION_TIMEOUT, Loading Loading
system/gd/l2cap/classic/dynamic_channel_manager.cc +2 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include "l2cap/classic/dynamic_channel_manager.h" #include "l2cap/classic/internal/dynamic_channel_service_impl.h" #include "l2cap/classic/internal/dynamic_channel_service_manager_impl.h" #include "l2cap/classic/internal/link.h" #include "l2cap/classic/internal/link_manager.h" namespace bluetooth { Loading @@ -25,7 +26,7 @@ namespace classic { bool DynamicChannelManager::ConnectChannel(hci::Address device, Psm psm, OnConnectionOpenCallback on_connection_open, OnConnectionFailureCallback on_fail_callback, os::Handler* handler) { internal::LinkManager::PendingDynamicChannelConnection pending_dynamic_channel_connection{ internal::Link::PendingDynamicChannelConnection pending_dynamic_channel_connection{ .handler_ = handler, .on_open_callback_ = std::move(on_connection_open), .on_fail_callback_ = std::move(on_fail_callback), Loading
system/gd/l2cap/classic/internal/dynamic_channel_impl.h +3 −0 Original line number Diff line number Diff line Loading @@ -78,6 +78,9 @@ class DynamicChannelImpl { return incoming_configuration_status_; } // TODO(cmanton) Do something a little bit better than this bool local_initiated_{false}; private: const Psm psm_; const Cid cid_; Loading
system/gd/l2cap/classic/internal/link.cc +29 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <memory> #include "hci/acl_manager.h" #include "l2cap/classic/dynamic_channel_manager.h" #include "l2cap/classic/internal/fixed_channel_impl.h" #include "l2cap/classic/internal/link.h" #include "l2cap/internal/parameter_provider.h" Loading Loading @@ -76,6 +77,12 @@ void Link::SendConnectionRequest(Psm psm, Cid local_cid) { signalling_manager_.SendConnectionRequest(psm, local_cid); } void Link::SendConnectionRequest(Psm psm, Cid local_cid, PendingDynamicChannelConnection pending_dynamic_channel_connection) { local_cid_to_pending_dynamic_channel_connection_map_[local_cid] = std::move(pending_dynamic_channel_connection); signalling_manager_.SendConnectionRequest(psm, local_cid); } void Link::SendDisconnectionRequest(Cid local_cid, Cid remote_cid) { signalling_manager_.SendDisconnectionRequest(local_cid, remote_cid); } Loading @@ -91,6 +98,7 @@ std::shared_ptr<DynamicChannelImpl> Link::AllocateDynamicChannel(Psm psm, Cid re scheduler_->AttachChannel(channel->GetCid(), channel->GetQueueDownEnd(), channel->GetRemoteCid()); reassembler_.AttachChannel(channel->GetCid(), channel->GetQueueDownEnd(), {}); } channel->local_initiated_ = false; return channel; } Loading @@ -101,6 +109,7 @@ std::shared_ptr<DynamicChannelImpl> Link::AllocateReservedDynamicChannel(Cid res scheduler_->AttachChannel(channel->GetCid(), channel->GetQueueDownEnd(), channel->GetRemoteCid()); reassembler_.AttachChannel(channel->GetCid(), channel->GetQueueDownEnd(), {}); } channel->local_initiated_ = true; return channel; } Loading @@ -125,6 +134,26 @@ void Link::RefreshRefCount() { } } void Link::NotifyChannelCreation(Cid cid, std::unique_ptr<DynamicChannel> channel) { ASSERT(local_cid_to_pending_dynamic_channel_connection_map_.find(cid) != local_cid_to_pending_dynamic_channel_connection_map_.end()); auto& pending_dynamic_channel_connection = local_cid_to_pending_dynamic_channel_connection_map_[cid]; pending_dynamic_channel_connection.handler_->Post( common::BindOnce(std::move(pending_dynamic_channel_connection.on_open_callback_), std::move(channel))); local_cid_to_pending_dynamic_channel_connection_map_.erase(cid); } void Link::NotifyChannelFail(Cid cid) { ASSERT(local_cid_to_pending_dynamic_channel_connection_map_.find(cid) != local_cid_to_pending_dynamic_channel_connection_map_.end()); auto& pending_dynamic_channel_connection = local_cid_to_pending_dynamic_channel_connection_map_[cid]; // TODO(cmanton) Pass proper connection falure result to user DynamicChannelManager::ConnectionResult result; pending_dynamic_channel_connection.handler_->Post( common::BindOnce(std::move(pending_dynamic_channel_connection.on_fail_callback_), result)); local_cid_to_pending_dynamic_channel_connection_map_.erase(cid); } } // namespace internal } // namespace classic } // namespace l2cap Loading
system/gd/l2cap/classic/internal/link.h +13 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #pragma once #include <memory> #include <unordered_map> #include "hci/acl_manager.h" #include "l2cap/classic/internal/dynamic_channel_allocator.h" Loading Loading @@ -50,6 +51,12 @@ class Link { return acl_connection_->GetAddress(); } struct PendingDynamicChannelConnection { os::Handler* handler_; DynamicChannelManager::OnConnectionOpenCallback on_open_callback_; DynamicChannelManager::OnConnectionFailureCallback on_fail_callback_; }; // ACL methods virtual void OnAclDisconnected(hci::ErrorCode status); Loading @@ -67,6 +74,8 @@ class Link { virtual Cid ReserveDynamicChannel(); virtual void SendConnectionRequest(Psm psm, Cid local_cid); virtual void SendConnectionRequest(Psm psm, Cid local_cid, PendingDynamicChannelConnection pending_dynamic_channel_connection); virtual void SendInformationRequest(InformationRequestInfoType type); Loading @@ -83,6 +92,9 @@ class Link { // Check how many channels are acquired or in use, if zero, start tear down timer, if non-zero, cancel tear down timer virtual void RefreshRefCount(); virtual void NotifyChannelCreation(Cid cid, std::unique_ptr<DynamicChannel> channel); virtual void NotifyChannelFail(Cid cid); private: os::Handler* l2cap_handler_; l2cap::internal::FixedChannelAllocator<FixedChannelImpl, Link> fixed_channel_allocator_{this, l2cap_handler_}; Loading @@ -94,6 +106,7 @@ class Link { DynamicChannelServiceManagerImpl* dynamic_service_manager_; FixedChannelServiceManagerImpl* fixed_service_manager_; ClassicSignallingManager signalling_manager_; std::unordered_map<Cid, PendingDynamicChannelConnection> local_cid_to_pending_dynamic_channel_connection_map_; os::Alarm link_idle_disconnect_alarm_{l2cap_handler_}; DISALLOW_COPY_AND_ASSIGN(Link); }; Loading
system/gd/l2cap/classic/internal/link_manager.cc +7 −6 Original line number Diff line number Diff line Loading @@ -82,9 +82,8 @@ void LinkManager::ConnectFixedChannelServices(hci::Address device, acl_manager_->CreateConnection(device); } void LinkManager::ConnectDynamicChannelServices(hci::Address device, PendingDynamicChannelConnection pending_dynamic_channel_connection, Psm psm) { void LinkManager::ConnectDynamicChannelServices( hci::Address device, Link::PendingDynamicChannelConnection pending_dynamic_channel_connection, Psm psm) { auto* link = GetLink(device); if (link == nullptr) { acl_manager_->CreateConnection(device); Loading @@ -97,7 +96,7 @@ void LinkManager::ConnectDynamicChannelServices(hci::Address device, } return; } link->SendConnectionRequest(psm, link->ReserveDynamicChannel()); link->SendConnectionRequest(psm, link->ReserveDynamicChannel(), std::move(pending_dynamic_channel_connection)); } Link* LinkManager::GetLink(const hci::Address device) { Loading Loading @@ -133,7 +132,9 @@ void LinkManager::OnConnectSuccess(std::unique_ptr<hci::AclConnection> acl_conne } if (pending_dynamic_channels_.find(device) != pending_dynamic_channels_.end()) { for (Psm psm : pending_dynamic_channels_[device]) { link->SendConnectionRequest(psm, link->ReserveDynamicChannel()); auto& callbacks = pending_dynamic_channels_callbacks_[device].front(); pending_dynamic_channels_callbacks_[device].pop_front(); link->SendConnectionRequest(psm, link->ReserveDynamicChannel(), std::move(callbacks)); } pending_dynamic_channels_.erase(device); pending_dynamic_channels_callbacks_.erase(device); Loading @@ -155,7 +156,7 @@ void LinkManager::OnConnectFail(hci::Address device, hci::ErrorCode reason) { // There is no pending link, exit LOG_DEBUG("Connection to %s failed without a pending link", device.ToString().c_str()); if (pending_dynamic_channels_callbacks_.find(device) != pending_dynamic_channels_callbacks_.end()) { for (PendingDynamicChannelConnection& callbacks : pending_dynamic_channels_callbacks_[device]) { for (Link::PendingDynamicChannelConnection& callbacks : pending_dynamic_channels_callbacks_[device]) { callbacks.handler_->Post(common::BindOnce(std::move(callbacks.on_fail_callback_), DynamicChannelManager::ConnectionResult{ .hci_error = hci::ErrorCode::CONNECTION_TIMEOUT, Loading