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/internal/ilink.h" 25 #include "l2cap/psm.h" 26 #include "l2cap/security_policy.h" 27 #include "os/handler.h" 28 #include "os/log.h" 29 30 namespace bluetooth { 31 namespace l2cap { 32 namespace internal { 33 34 class DynamicChannelImpl; 35 36 // Helper class for keeping channels in a Link. It allocates and frees Channel object, and supports querying whether a 37 // channel is in use 38 class DynamicChannelAllocator { 39 public: 40 DynamicChannelAllocator(l2cap::internal::ILink* link, os::Handler* l2cap_handler) 41 : link_(link), l2cap_handler_(l2cap_handler) { 42 ASSERT(link_ != nullptr); 43 ASSERT(l2cap_handler_ != nullptr); 44 } 45 46 // Allocates a channel. If psm is used, OR the remote cid already exists, return nullptr. 47 // NOTE: The returned DynamicChannelImpl object is still owned by the channel allocator, NOT the client. 48 std::shared_ptr<DynamicChannelImpl> AllocateChannel(Psm psm, Cid remote_cid, SecurityPolicy security_policy); 49 50 std::shared_ptr<DynamicChannelImpl> AllocateReservedChannel(Cid reserved_cid, Psm psm, Cid remote_cid, 51 SecurityPolicy security_policy); 52 53 // Gives an unused Cid to be used for opening a channel. If a channel is used, call AllocateReservedChannel. If no 54 // longer needed, use FreeChannel. 55 Cid ReserveChannel(); 56 57 // Frees a channel. If psm doesn't exist, it will crash 58 void FreeChannel(Cid cid); 59 60 bool IsPsmUsed(Psm psm) const; 61 62 std::shared_ptr<DynamicChannelImpl> FindChannelByCid(Cid cid); 63 std::shared_ptr<DynamicChannelImpl> FindChannelByRemoteCid(Cid cid); 64 65 // Returns number of open, but not reserved channels 66 size_t NumberOfChannels() const; 67 68 void OnAclDisconnected(hci::ErrorCode hci_status); 69 70 private: 71 l2cap::internal::ILink* link_; 72 os::Handler* l2cap_handler_; 73 std::unordered_set<Cid> used_cid_; 74 std::unordered_map<Cid, std::shared_ptr<DynamicChannelImpl>> channels_; 75 std::unordered_set<Cid> used_remote_cid_; 76 }; 77 78 } // namespace internal 79 } // namespace l2cap 80 } // namespace bluetooth 81