1 /* 2 * Copyright 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <unordered_map> 20 #include <unordered_set> 21 22 #include "hci/acl_manager.h" 23 #include "l2cap/cid.h" 24 #include "l2cap/classic/security_policy.h" 25 #include "l2cap/internal/ilink.h" 26 #include "l2cap/psm.h" 27 #include "os/handler.h" 28 #include "os/log.h" 29 30 namespace bluetooth { 31 namespace l2cap { 32 33 namespace classic { 34 namespace internal { 35 class DumpsysHelper; 36 } // namespace internal 37 } // namespace classic 38 39 namespace internal { 40 41 class DynamicChannelImpl; 42 43 // Helper class for keeping channels in a Link. It allocates and frees Channel object, and supports querying whether a 44 // channel is in use 45 class DynamicChannelAllocator { 46 public: DynamicChannelAllocator(l2cap::internal::ILink * link,os::Handler * l2cap_handler)47 DynamicChannelAllocator(l2cap::internal::ILink* link, os::Handler* l2cap_handler) 48 : link_(link), l2cap_handler_(l2cap_handler) { 49 ASSERT(link_ != nullptr); 50 ASSERT(l2cap_handler_ != nullptr); 51 } 52 53 // Allocates a channel. If psm is used, OR the remote cid already exists, return nullptr. 54 // NOTE: The returned DynamicChannelImpl object is still owned by the channel allocator, NOT the client. 55 std::shared_ptr<DynamicChannelImpl> AllocateChannel(Psm psm, Cid remote_cid); 56 57 std::shared_ptr<DynamicChannelImpl> AllocateReservedChannel(Cid reserved_cid, Psm psm, Cid remote_cid); 58 59 // Gives an unused Cid to be used for opening a channel. If a channel is used, call AllocateReservedChannel. If no 60 // longer needed, use FreeChannel. 61 Cid ReserveChannel(); 62 63 // Frees a channel (existing or reserved) 64 void FreeChannel(Cid cid); 65 66 bool IsPsmUsed(Psm psm) const; 67 68 std::shared_ptr<DynamicChannelImpl> FindChannelByCid(Cid cid); 69 std::shared_ptr<DynamicChannelImpl> FindChannelByRemoteCid(Cid cid); 70 71 // Returns number of open, but not reserved channels 72 size_t NumberOfChannels() const; 73 74 void OnAclDisconnected(hci::ErrorCode hci_status); 75 76 private: 77 friend class bluetooth::l2cap::classic::internal::DumpsysHelper; 78 l2cap::internal::ILink* link_; 79 os::Handler* l2cap_handler_; 80 std::unordered_set<Cid> used_cid_; 81 std::unordered_map<Cid, std::shared_ptr<DynamicChannelImpl>> channels_; 82 std::unordered_set<Cid> used_remote_cid_; 83 }; 84 85 } // namespace internal 86 } // namespace l2cap 87 } // namespace bluetooth 88