/* * Copyright 2019 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. */ #pragma once #include #include #include "hci/acl_manager.h" #include "l2cap/cid.h" #include "l2cap/classic/security_policy.h" #include "l2cap/internal/ilink.h" #include "l2cap/psm.h" #include "os/handler.h" #include "os/log.h" namespace bluetooth { namespace l2cap { namespace classic { namespace internal { class DumpsysHelper; } // namespace internal } // namespace classic namespace internal { class DynamicChannelImpl; // Helper class for keeping channels in a Link. It allocates and frees Channel object, and supports querying whether a // channel is in use class DynamicChannelAllocator { public: DynamicChannelAllocator(l2cap::internal::ILink* link, os::Handler* l2cap_handler) : link_(link), l2cap_handler_(l2cap_handler) { ASSERT(link_ != nullptr); ASSERT(l2cap_handler_ != nullptr); } // Allocates a channel. If psm is used, OR the remote cid already exists, return nullptr. // NOTE: The returned DynamicChannelImpl object is still owned by the channel allocator, NOT the client. std::shared_ptr AllocateChannel(Psm psm, Cid remote_cid); std::shared_ptr AllocateReservedChannel(Cid reserved_cid, Psm psm, Cid remote_cid); // Gives an unused Cid to be used for opening a channel. If a channel is used, call AllocateReservedChannel. If no // longer needed, use FreeChannel. Cid ReserveChannel(); // Frees a channel (existing or reserved) void FreeChannel(Cid cid); bool IsPsmUsed(Psm psm) const; std::shared_ptr FindChannelByCid(Cid cid); std::shared_ptr FindChannelByRemoteCid(Cid cid); // Returns number of open, but not reserved channels size_t NumberOfChannels() const; void OnAclDisconnected(hci::ErrorCode hci_status); private: friend class bluetooth::l2cap::classic::internal::DumpsysHelper; l2cap::internal::ILink* link_; os::Handler* l2cap_handler_; std::unordered_set used_cid_; std::unordered_map> channels_; std::unordered_set used_remote_cid_; }; } // namespace internal } // namespace l2cap } // namespace bluetooth