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 #include "l2cap/classic/internal/fixed_channel_service_manager_impl.h"
18 
19 #include "common/bind.h"
20 #include "l2cap/cid.h"
21 #include "l2cap/classic/internal/fixed_channel_service_impl.h"
22 #include "os/log.h"
23 
24 namespace bluetooth {
25 namespace l2cap {
26 namespace classic {
27 namespace internal {
28 
Register(Cid cid,FixedChannelServiceImpl::PendingRegistration pending_registration)29 void FixedChannelServiceManagerImpl::Register(Cid cid,
30                                               FixedChannelServiceImpl::PendingRegistration pending_registration) {
31   if (cid < kFirstFixedChannel || cid > kLastFixedChannel || cid == kClassicSignallingCid) {
32     std::unique_ptr<FixedChannelService> invalid_service(new FixedChannelService());
33     pending_registration.user_handler_->Post(
34         common::BindOnce(std::move(pending_registration.on_registration_complete_callback_),
35                          FixedChannelManager::RegistrationResult::FAIL_INVALID_SERVICE, std::move(invalid_service)));
36   } else if (IsServiceRegistered(cid)) {
37     std::unique_ptr<FixedChannelService> invalid_service(new FixedChannelService());
38     pending_registration.user_handler_->Post(
39         common::BindOnce(std::move(pending_registration.on_registration_complete_callback_),
40                          FixedChannelManager::RegistrationResult::FAIL_DUPLICATE_SERVICE, std::move(invalid_service)));
41   } else {
42     service_map_.try_emplace(cid,
43                              FixedChannelServiceImpl(pending_registration.user_handler_,
44                                                      std::move(pending_registration.on_connection_open_callback_)));
45     std::unique_ptr<FixedChannelService> user_service(new FixedChannelService(cid, this, l2cap_layer_handler_));
46     pending_registration.user_handler_->Post(
47         common::BindOnce(std::move(pending_registration.on_registration_complete_callback_),
48                          FixedChannelManager::RegistrationResult::SUCCESS, std::move(user_service)));
49   }
50 }
51 
Unregister(Cid cid,FixedChannelService::OnUnregisteredCallback callback,os::Handler * handler)52 void FixedChannelServiceManagerImpl::Unregister(Cid cid, FixedChannelService::OnUnregisteredCallback callback,
53                                                 os::Handler* handler) {
54   if (IsServiceRegistered(cid)) {
55     service_map_.erase(cid);
56     handler->Post(std::move(callback));
57   } else {
58     LOG_ERROR("service not registered cid:%d", cid);
59   }
60 }
61 
IsServiceRegistered(Cid cid) const62 bool FixedChannelServiceManagerImpl::IsServiceRegistered(Cid cid) const {
63   return service_map_.find(cid) != service_map_.end();
64 }
65 
GetService(Cid cid)66 FixedChannelServiceImpl* FixedChannelServiceManagerImpl::GetService(Cid cid) {
67   ASSERT(IsServiceRegistered(cid));
68   return &service_map_.find(cid)->second;
69 }
70 
GetRegisteredServices()71 std::vector<std::pair<Cid, FixedChannelServiceImpl*>> FixedChannelServiceManagerImpl::GetRegisteredServices() {
72   std::vector<std::pair<Cid, FixedChannelServiceImpl*>> results;
73   for (auto& elem : service_map_) {
74     results.emplace_back(elem.first, &elem.second);
75   }
76   return results;
77 }
78 
79 namespace {
80 constexpr uint64_t kSignallingChannelMask = 0x02;
81 constexpr uint64_t kConnectionlessReceptionMask = 0x04;
82 constexpr uint64_t kBrEdrSecurityManager = 0x80;
83 }  // namespace
84 
GetSupportedFixedChannelMask()85 uint64_t FixedChannelServiceManagerImpl::GetSupportedFixedChannelMask() {
86   uint64_t result = 0;
87   result |= kSignallingChannelMask;  // Signalling channel is mandatory
88   for (const auto& elem : service_map_) {
89     Cid cid = elem.first;
90     switch (cid) {
91       case kConnectionlessCid:
92         result |= kConnectionlessReceptionMask;
93         continue;
94       case kSmpBrCid:
95         result |= kBrEdrSecurityManager;
96         continue;
97       default:
98         LOG_WARN("Unknown fixed channel is registered: 0x%x", cid);
99         continue;
100     }
101   }
102   return result;
103 }
104 }  // namespace internal
105 }  // namespace classic
106 }  // namespace l2cap
107 }  // namespace bluetooth
108