Loading system/gd/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -110,6 +110,7 @@ cc_library { ":BluetoothHciSources", ":BluetoothL2capSources", ":BluetoothPacketSources", ":BluetoothShimSources", ":BluetoothSmpSources", ], generated_headers: [ Loading system/gd/l2cap/Android.bp +4 −2 Original line number Diff line number Diff line Loading @@ -6,8 +6,9 @@ filegroup { "classic_fixed_channel.cc", "classic_fixed_channel_manager.cc", "classic_fixed_channel_service.cc", "internal/classic_fixed_channel_service_manager_impl.cc", "internal/classic_fixed_channel_allocator.cc", "internal/classic_fixed_channel_impl.cc", "internal/classic_fixed_channel_service_manager_impl.cc", "internal/classic_link_manager.cc", "internal/scheduler_fifo.cc", ], Loading @@ -17,8 +18,9 @@ filegroup { name: "BluetoothL2capTestSources", srcs: [ "l2cap_packet_test.cc", "internal/classic_fixed_channel_service_manager_test.cc", "internal/classic_fixed_channel_allocator_test.cc", "internal/classic_fixed_channel_impl_test.cc", "internal/classic_fixed_channel_service_manager_test.cc", "internal/classic_link_manager_test.cc", "internal/scheduler_fifo_test.cc", "signal_id_test.cc", Loading system/gd/l2cap/classic_fixed_channel.cc +21 −3 Original line number Diff line number Diff line Loading @@ -15,12 +15,30 @@ */ #include "l2cap/classic_fixed_channel.h" #include "common/bind.h" #include "l2cap/internal/classic_fixed_channel_impl.h" namespace bluetooth { namespace l2cap { void ClassicFixedChannel::RegisterOnCloseCallback(os::Handler* handler, OnCloseCallback callback) {} void ClassicFixedChannel::Acquire() {} void ClassicFixedChannel::Release() {} hci::Address ClassicFixedChannel::GetDevice() const { return impl_->GetDevice(); } void ClassicFixedChannel::RegisterOnCloseCallback(os::Handler* user_handler, ClassicFixedChannel::OnCloseCallback on_close_callback) { l2cap_handler_->Post(common::BindOnce(&internal::ClassicFixedChannelImpl::RegisterOnCloseCallback, impl_, user_handler, std::move(on_close_callback))); } void ClassicFixedChannel::Acquire() { l2cap_handler_->Post(common::BindOnce(&internal::ClassicFixedChannelImpl::Acquire, impl_)); } void ClassicFixedChannel::Release() { l2cap_handler_->Post(common::BindOnce(&internal::ClassicFixedChannelImpl::Release, impl_)); } common::BidiQueueEnd<packet::PacketView<packet::kLittleEndian>, packet::BasePacketBuilder>* ClassicFixedChannel::GetQueueUpEnd() const { return nullptr; Loading system/gd/l2cap/classic_fixed_channel.h +20 −16 Original line number Diff line number Diff line Loading @@ -17,6 +17,8 @@ #include "common/bidi_queue.h" #include "common/callback.h" #include "hci/acl_manager.h" #include "l2cap/cid.h" #include "os/handler.h" #include "packet/base_packet_builder.h" #include "packet/packet_view.h" Loading @@ -31,33 +33,40 @@ class ClassicFixedChannelImpl; /** * L2CAP fixed channel object. When a new object is created, it must be * acquired through calling {@link FixedChannel#Acquire()} within X seconds. * Otherwise, {@link FixeChannel#Release()} will be called automatically. * Otherwise, {@link FixedChannel#Release()} will be called automatically. * */ class ClassicFixedChannel { public: using OnCloseCallback = common::Callback<void()>; // Should only be constructed by modules that have access to ClassicLinkManager ClassicFixedChannel(std::shared_ptr<internal::ClassicFixedChannelImpl> impl, os::Handler* l2cap_handler) : impl_(std::move(impl)), l2cap_handler_(l2cap_handler) { ASSERT(impl_ != nullptr); ASSERT(l2cap_handler_ != nullptr); } hci::Address GetDevice() const; /** * Register close callback. If close callback is registered, when a channel is closed, the channel's resource will * only be freed after on_close callback is invoked. Otherwise, if no on_close callback is registered, the channel's * resource will be freed immediately after closing. * * @param on_close The callback invoked upon channel closing. * @param user_handler The handler used to invoke the callback on * @param on_close_callback The callback invoked upon channel closing. */ void RegisterOnCloseCallback(os::Handler* handler, OnCloseCallback on_close); using OnCloseCallback = common::OnceCallback<void(hci::ErrorCode)>; void RegisterOnCloseCallback(os::Handler* user_handler, OnCloseCallback on_close_callback); /** * Indicate that this Fixed Channel is being used. This will prevent ACL * connection from being disconnected. * Indicate that this Fixed Channel is being used. This will prevent ACL connection from being disconnected. */ void Acquire(); /** * Indicate that this Fixed Channel is no longer being used. ACL connection * will be disconnected after X seconds if no other DynamicChannel is connected * or no other Fixed Channel is using this ACL connection. However a module can * still receive data on this channel as long as it remains open. * Indicate that this Fixed Channel is no longer being used. ACL connection will be disconnected after * kClassicLinkIdleDisconnectTimeout if no other DynamicChannel is connected or no other Fixed Channel is using this * ACL connection. However a module can still receive data on this channel as long as it remains open. */ void Release(); Loading @@ -70,14 +79,9 @@ class ClassicFixedChannel { */ common::BidiQueueEnd<packet::PacketView<packet::kLittleEndian>, packet::BasePacketBuilder>* GetQueueUpEnd() const; friend class internal::ClassicFixedChannelImpl; private: ClassicFixedChannel(os::Handler* l2cap_handler, internal::ClassicFixedChannelImpl* classic_fixed_channel_impl) : l2cap_handler_(l2cap_handler), classic_fixed_channel_impl_(classic_fixed_channel_impl) {} std::shared_ptr<internal::ClassicFixedChannelImpl> impl_; os::Handler* l2cap_handler_; internal::ClassicFixedChannelImpl* classic_fixed_channel_impl_; DISALLOW_COPY_AND_ASSIGN(ClassicFixedChannel); }; } // namespace l2cap Loading system/gd/l2cap/internal/classic_fixed_channel_allocator.cc +36 −11 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include "classic_fixed_channel_allocator.h" #include "l2cap/cid.h" #include "l2cap/internal/classic_fixed_channel_allocator.h" #include "l2cap/internal/classic_link.h" #include "l2cap/security_policy.h" #include "os/handler.h" #include "os/log.h" Loading @@ -27,30 +28,54 @@ namespace bluetooth { namespace l2cap { namespace internal { ClassicFixedChannelImpl* ClassicFixedChannelAllocator::AllocateChannel(Cid cid, SecurityPolicy security_policy) { ASSERT_LOG(!IsChannelInUse((cid)), "Cid %d is already in use", cid); std::shared_ptr<ClassicFixedChannelImpl> ClassicFixedChannelAllocator::AllocateChannel(Cid cid, SecurityPolicy security_policy) { ASSERT_LOG(!IsChannelAllocated((cid)), "Cid 0x%x for device %s is already in use", cid, link_->GetDevice().ToString().c_str()); ASSERT_LOG(cid >= kFirstFixedChannel && cid <= kLastFixedChannel, "Cid %d out of bound", cid); channels_.try_emplace(cid, cid, handler_); return &channels_.find(cid)->second; auto elem = channels_.try_emplace(cid, std::make_shared<ClassicFixedChannelImpl>(cid, link_, l2cap_handler_)); ASSERT_LOG(elem.second, "Failed to create channel for cid 0x%x device %s", cid, link_->GetDevice().ToString().c_str()); ASSERT(elem.first->second != nullptr); return elem.first->second; } bool ClassicFixedChannelAllocator::FreeChannel(Cid cid) { ASSERT_LOG(IsChannelInUse(cid), "Channel is not in use: cid %d", cid); void ClassicFixedChannelAllocator::FreeChannel(Cid cid) { ASSERT_LOG(IsChannelAllocated(cid), "Channel is not in use: cid %d, device %s", cid, link_->GetDevice().ToString().c_str()); channels_.erase(cid); return true; } bool ClassicFixedChannelAllocator::IsChannelInUse(Cid cid) const { bool ClassicFixedChannelAllocator::IsChannelAllocated(Cid cid) const { return channels_.find(cid) != channels_.end(); } ClassicFixedChannelImpl* ClassicFixedChannelAllocator::FindChannel(Cid cid) { ASSERT_LOG(IsChannelInUse(cid), "Channel is not in use: cid %d", cid); return &channels_.find(cid)->second; std::shared_ptr<ClassicFixedChannelImpl> ClassicFixedChannelAllocator::FindChannel(Cid cid) { ASSERT_LOG(IsChannelAllocated(cid), "Channel is not in use: cid %d, device %s", cid, link_->GetDevice().ToString().c_str()); return channels_.find(cid)->second; } size_t ClassicFixedChannelAllocator::NumberOfChannels() const { return channels_.size(); } void ClassicFixedChannelAllocator::OnAclDisconnected(hci::ErrorCode reason) { for (auto& elem : channels_) { elem.second->OnClosed(reason); } } int ClassicFixedChannelAllocator::GetRefCount() { int ref_count = 0; for (auto& elem : channels_) { if (elem.second->IsAcquired()) { ref_count++; } } return ref_count; } } // namespace internal } // namespace l2cap } // namespace bluetooth Loading
system/gd/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -110,6 +110,7 @@ cc_library { ":BluetoothHciSources", ":BluetoothL2capSources", ":BluetoothPacketSources", ":BluetoothShimSources", ":BluetoothSmpSources", ], generated_headers: [ Loading
system/gd/l2cap/Android.bp +4 −2 Original line number Diff line number Diff line Loading @@ -6,8 +6,9 @@ filegroup { "classic_fixed_channel.cc", "classic_fixed_channel_manager.cc", "classic_fixed_channel_service.cc", "internal/classic_fixed_channel_service_manager_impl.cc", "internal/classic_fixed_channel_allocator.cc", "internal/classic_fixed_channel_impl.cc", "internal/classic_fixed_channel_service_manager_impl.cc", "internal/classic_link_manager.cc", "internal/scheduler_fifo.cc", ], Loading @@ -17,8 +18,9 @@ filegroup { name: "BluetoothL2capTestSources", srcs: [ "l2cap_packet_test.cc", "internal/classic_fixed_channel_service_manager_test.cc", "internal/classic_fixed_channel_allocator_test.cc", "internal/classic_fixed_channel_impl_test.cc", "internal/classic_fixed_channel_service_manager_test.cc", "internal/classic_link_manager_test.cc", "internal/scheduler_fifo_test.cc", "signal_id_test.cc", Loading
system/gd/l2cap/classic_fixed_channel.cc +21 −3 Original line number Diff line number Diff line Loading @@ -15,12 +15,30 @@ */ #include "l2cap/classic_fixed_channel.h" #include "common/bind.h" #include "l2cap/internal/classic_fixed_channel_impl.h" namespace bluetooth { namespace l2cap { void ClassicFixedChannel::RegisterOnCloseCallback(os::Handler* handler, OnCloseCallback callback) {} void ClassicFixedChannel::Acquire() {} void ClassicFixedChannel::Release() {} hci::Address ClassicFixedChannel::GetDevice() const { return impl_->GetDevice(); } void ClassicFixedChannel::RegisterOnCloseCallback(os::Handler* user_handler, ClassicFixedChannel::OnCloseCallback on_close_callback) { l2cap_handler_->Post(common::BindOnce(&internal::ClassicFixedChannelImpl::RegisterOnCloseCallback, impl_, user_handler, std::move(on_close_callback))); } void ClassicFixedChannel::Acquire() { l2cap_handler_->Post(common::BindOnce(&internal::ClassicFixedChannelImpl::Acquire, impl_)); } void ClassicFixedChannel::Release() { l2cap_handler_->Post(common::BindOnce(&internal::ClassicFixedChannelImpl::Release, impl_)); } common::BidiQueueEnd<packet::PacketView<packet::kLittleEndian>, packet::BasePacketBuilder>* ClassicFixedChannel::GetQueueUpEnd() const { return nullptr; Loading
system/gd/l2cap/classic_fixed_channel.h +20 −16 Original line number Diff line number Diff line Loading @@ -17,6 +17,8 @@ #include "common/bidi_queue.h" #include "common/callback.h" #include "hci/acl_manager.h" #include "l2cap/cid.h" #include "os/handler.h" #include "packet/base_packet_builder.h" #include "packet/packet_view.h" Loading @@ -31,33 +33,40 @@ class ClassicFixedChannelImpl; /** * L2CAP fixed channel object. When a new object is created, it must be * acquired through calling {@link FixedChannel#Acquire()} within X seconds. * Otherwise, {@link FixeChannel#Release()} will be called automatically. * Otherwise, {@link FixedChannel#Release()} will be called automatically. * */ class ClassicFixedChannel { public: using OnCloseCallback = common::Callback<void()>; // Should only be constructed by modules that have access to ClassicLinkManager ClassicFixedChannel(std::shared_ptr<internal::ClassicFixedChannelImpl> impl, os::Handler* l2cap_handler) : impl_(std::move(impl)), l2cap_handler_(l2cap_handler) { ASSERT(impl_ != nullptr); ASSERT(l2cap_handler_ != nullptr); } hci::Address GetDevice() const; /** * Register close callback. If close callback is registered, when a channel is closed, the channel's resource will * only be freed after on_close callback is invoked. Otherwise, if no on_close callback is registered, the channel's * resource will be freed immediately after closing. * * @param on_close The callback invoked upon channel closing. * @param user_handler The handler used to invoke the callback on * @param on_close_callback The callback invoked upon channel closing. */ void RegisterOnCloseCallback(os::Handler* handler, OnCloseCallback on_close); using OnCloseCallback = common::OnceCallback<void(hci::ErrorCode)>; void RegisterOnCloseCallback(os::Handler* user_handler, OnCloseCallback on_close_callback); /** * Indicate that this Fixed Channel is being used. This will prevent ACL * connection from being disconnected. * Indicate that this Fixed Channel is being used. This will prevent ACL connection from being disconnected. */ void Acquire(); /** * Indicate that this Fixed Channel is no longer being used. ACL connection * will be disconnected after X seconds if no other DynamicChannel is connected * or no other Fixed Channel is using this ACL connection. However a module can * still receive data on this channel as long as it remains open. * Indicate that this Fixed Channel is no longer being used. ACL connection will be disconnected after * kClassicLinkIdleDisconnectTimeout if no other DynamicChannel is connected or no other Fixed Channel is using this * ACL connection. However a module can still receive data on this channel as long as it remains open. */ void Release(); Loading @@ -70,14 +79,9 @@ class ClassicFixedChannel { */ common::BidiQueueEnd<packet::PacketView<packet::kLittleEndian>, packet::BasePacketBuilder>* GetQueueUpEnd() const; friend class internal::ClassicFixedChannelImpl; private: ClassicFixedChannel(os::Handler* l2cap_handler, internal::ClassicFixedChannelImpl* classic_fixed_channel_impl) : l2cap_handler_(l2cap_handler), classic_fixed_channel_impl_(classic_fixed_channel_impl) {} std::shared_ptr<internal::ClassicFixedChannelImpl> impl_; os::Handler* l2cap_handler_; internal::ClassicFixedChannelImpl* classic_fixed_channel_impl_; DISALLOW_COPY_AND_ASSIGN(ClassicFixedChannel); }; } // namespace l2cap Loading
system/gd/l2cap/internal/classic_fixed_channel_allocator.cc +36 −11 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include "classic_fixed_channel_allocator.h" #include "l2cap/cid.h" #include "l2cap/internal/classic_fixed_channel_allocator.h" #include "l2cap/internal/classic_link.h" #include "l2cap/security_policy.h" #include "os/handler.h" #include "os/log.h" Loading @@ -27,30 +28,54 @@ namespace bluetooth { namespace l2cap { namespace internal { ClassicFixedChannelImpl* ClassicFixedChannelAllocator::AllocateChannel(Cid cid, SecurityPolicy security_policy) { ASSERT_LOG(!IsChannelInUse((cid)), "Cid %d is already in use", cid); std::shared_ptr<ClassicFixedChannelImpl> ClassicFixedChannelAllocator::AllocateChannel(Cid cid, SecurityPolicy security_policy) { ASSERT_LOG(!IsChannelAllocated((cid)), "Cid 0x%x for device %s is already in use", cid, link_->GetDevice().ToString().c_str()); ASSERT_LOG(cid >= kFirstFixedChannel && cid <= kLastFixedChannel, "Cid %d out of bound", cid); channels_.try_emplace(cid, cid, handler_); return &channels_.find(cid)->second; auto elem = channels_.try_emplace(cid, std::make_shared<ClassicFixedChannelImpl>(cid, link_, l2cap_handler_)); ASSERT_LOG(elem.second, "Failed to create channel for cid 0x%x device %s", cid, link_->GetDevice().ToString().c_str()); ASSERT(elem.first->second != nullptr); return elem.first->second; } bool ClassicFixedChannelAllocator::FreeChannel(Cid cid) { ASSERT_LOG(IsChannelInUse(cid), "Channel is not in use: cid %d", cid); void ClassicFixedChannelAllocator::FreeChannel(Cid cid) { ASSERT_LOG(IsChannelAllocated(cid), "Channel is not in use: cid %d, device %s", cid, link_->GetDevice().ToString().c_str()); channels_.erase(cid); return true; } bool ClassicFixedChannelAllocator::IsChannelInUse(Cid cid) const { bool ClassicFixedChannelAllocator::IsChannelAllocated(Cid cid) const { return channels_.find(cid) != channels_.end(); } ClassicFixedChannelImpl* ClassicFixedChannelAllocator::FindChannel(Cid cid) { ASSERT_LOG(IsChannelInUse(cid), "Channel is not in use: cid %d", cid); return &channels_.find(cid)->second; std::shared_ptr<ClassicFixedChannelImpl> ClassicFixedChannelAllocator::FindChannel(Cid cid) { ASSERT_LOG(IsChannelAllocated(cid), "Channel is not in use: cid %d, device %s", cid, link_->GetDevice().ToString().c_str()); return channels_.find(cid)->second; } size_t ClassicFixedChannelAllocator::NumberOfChannels() const { return channels_.size(); } void ClassicFixedChannelAllocator::OnAclDisconnected(hci::ErrorCode reason) { for (auto& elem : channels_) { elem.second->OnClosed(reason); } } int ClassicFixedChannelAllocator::GetRefCount() { int ref_count = 0; for (auto& elem : channels_) { if (elem.second->IsAcquired()) { ref_count++; } } return ref_count; } } // namespace internal } // namespace l2cap } // namespace bluetooth