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 "hci/acl_manager.h"
18 
19 #include <atomic>
20 #include <set>
21 
22 #include "common/bidi_queue.h"
23 #include "hci/acl_manager/classic_impl.h"
24 #include "hci/acl_manager/connection_management_callbacks.h"
25 #include "hci/acl_manager/le_acl_connection.h"
26 #include "hci/acl_manager/le_impl.h"
27 #include "hci/acl_manager/round_robin_scheduler.h"
28 #include "hci/controller.h"
29 #include "hci/hci_layer.h"
30 #include "security/security_module.h"
31 
32 namespace bluetooth {
33 namespace hci {
34 
35 constexpr uint16_t kQualcommDebugHandle = 0xedc;
36 
37 using acl_manager::AclConnection;
38 using common::Bind;
39 using common::BindOnce;
40 
41 using acl_manager::classic_impl;
42 using acl_manager::ClassicAclConnection;
43 using acl_manager::ConnectionCallbacks;
44 
45 using acl_manager::le_impl;
46 using acl_manager::LeAclConnection;
47 using acl_manager::LeConnectionCallbacks;
48 
49 using acl_manager::RoundRobinScheduler;
50 
51 struct AclManager::impl {
implbluetooth::hci::AclManager::impl52   impl(const AclManager& acl_manager) : acl_manager_(acl_manager) {}
53 
Startbluetooth::hci::AclManager::impl54   void Start() {
55     hci_layer_ = acl_manager_.GetDependency<HciLayer>();
56     handler_ = acl_manager_.GetHandler();
57     controller_ = acl_manager_.GetDependency<Controller>();
58     round_robin_scheduler_ = new RoundRobinScheduler(handler_, controller_, hci_layer_->GetAclQueueEnd());
59 
60     hci_queue_end_ = hci_layer_->GetAclQueueEnd();
61     hci_queue_end_->RegisterDequeue(
62         handler_, common::Bind(&impl::dequeue_and_route_acl_packet_to_connection, common::Unretained(this)));
63     classic_impl_ = new classic_impl(hci_layer_, controller_, handler_, round_robin_scheduler_);
64     le_impl_ = new le_impl(hci_layer_, controller_, handler_, round_robin_scheduler_, classic_impl_);
65   }
66 
Stopbluetooth::hci::AclManager::impl67   void Stop() {
68     delete le_impl_;
69     delete classic_impl_;
70     hci_queue_end_->UnregisterDequeue();
71     delete round_robin_scheduler_;
72     if (enqueue_registered_.exchange(false)) {
73       hci_queue_end_->UnregisterEnqueue();
74     }
75     hci_queue_end_ = nullptr;
76     handler_ = nullptr;
77     hci_layer_ = nullptr;
78   }
79 
80   // Invoked from some external Queue Reactable context 2
dequeue_and_route_acl_packet_to_connectionbluetooth::hci::AclManager::impl81   void dequeue_and_route_acl_packet_to_connection() {
82     auto packet = hci_queue_end_->TryDequeue();
83     ASSERT(packet != nullptr);
84     if (!packet->IsValid()) {
85       LOG_INFO("Dropping invalid packet of size %zu", packet->size());
86       return;
87     }
88     uint16_t handle = packet->GetHandle();
89     if (handle == kQualcommDebugHandle) {
90       return;
91     }
92     auto connection_pair = classic_impl_->acl_connections_.find(handle);
93     if (connection_pair != classic_impl_->acl_connections_.end()) {
94       connection_pair->second.assembler_.on_incoming_packet(*packet);
95     } else {
96       auto le_connection_pair = le_impl_->le_acl_connections_.find(handle);
97       if (le_connection_pair == le_impl_->le_acl_connections_.end()) {
98         LOG_INFO("Dropping packet of size %zu to unknown connection 0x%0hx", packet->size(), handle);
99         return;
100       }
101       le_connection_pair->second.assembler_.on_incoming_packet(*packet);
102     }
103   }
104 
105   const AclManager& acl_manager_;
106 
107   classic_impl* classic_impl_ = nullptr;
108   le_impl* le_impl_ = nullptr;
109   os::Handler* handler_ = nullptr;
110   Controller* controller_ = nullptr;
111   HciLayer* hci_layer_ = nullptr;
112   RoundRobinScheduler* round_robin_scheduler_ = nullptr;
113   common::BidiQueueEnd<AclPacketBuilder, AclPacketView>* hci_queue_end_ = nullptr;
114   std::atomic_bool enqueue_registered_ = false;
115   uint16_t default_link_policy_settings_ = 0xffff;
116 };
117 
AclManager()118 AclManager::AclManager() : pimpl_(std::make_unique<impl>(*this)) {}
119 
RegisterCallbacks(ConnectionCallbacks * callbacks,os::Handler * handler)120 void AclManager::RegisterCallbacks(ConnectionCallbacks* callbacks, os::Handler* handler) {
121   ASSERT(callbacks != nullptr && handler != nullptr);
122   GetHandler()->Post(common::BindOnce(&classic_impl::handle_register_callbacks,
123                                       common::Unretained(pimpl_->classic_impl_), common::Unretained(callbacks),
124                                       common::Unretained(handler)));
125 }
126 
RegisterLeCallbacks(LeConnectionCallbacks * callbacks,os::Handler * handler)127 void AclManager::RegisterLeCallbacks(LeConnectionCallbacks* callbacks, os::Handler* handler) {
128   ASSERT(callbacks != nullptr && handler != nullptr);
129   CallOn(
130       pimpl_->le_impl_,
131       &le_impl::handle_register_le_callbacks,
132       common::Unretained(callbacks),
133       common::Unretained(handler));
134 }
135 
CreateConnection(Address address)136 void AclManager::CreateConnection(Address address) {
137   CallOn(pimpl_->classic_impl_, &classic_impl::create_connection, address);
138 }
139 
CreateLeConnection(AddressWithType address_with_type)140 void AclManager::CreateLeConnection(AddressWithType address_with_type) {
141   CallOn(pimpl_->le_impl_, &le_impl::create_le_connection, address_with_type, true);
142 }
143 
SetPrivacyPolicyForInitiatorAddress(LeAddressManager::AddressPolicy address_policy,AddressWithType fixed_address,crypto_toolbox::Octet16 rotation_irk,std::chrono::milliseconds minimum_rotation_time,std::chrono::milliseconds maximum_rotation_time)144 void AclManager::SetPrivacyPolicyForInitiatorAddress(
145     LeAddressManager::AddressPolicy address_policy,
146     AddressWithType fixed_address,
147     crypto_toolbox::Octet16 rotation_irk,
148     std::chrono::milliseconds minimum_rotation_time,
149     std::chrono::milliseconds maximum_rotation_time) {
150   CallOn(
151       pimpl_->le_impl_,
152       &le_impl::set_privacy_policy_for_initiator_address,
153       address_policy,
154       fixed_address,
155       rotation_irk,
156       minimum_rotation_time,
157       maximum_rotation_time);
158 }
159 
160 // TODO(jpawlowski): remove once we have config file abstraction in cert tests
SetPrivacyPolicyForInitiatorAddressForTest(LeAddressManager::AddressPolicy address_policy,AddressWithType fixed_address,crypto_toolbox::Octet16 rotation_irk,std::chrono::milliseconds minimum_rotation_time,std::chrono::milliseconds maximum_rotation_time)161 void AclManager::SetPrivacyPolicyForInitiatorAddressForTest(
162     LeAddressManager::AddressPolicy address_policy,
163     AddressWithType fixed_address,
164     crypto_toolbox::Octet16 rotation_irk,
165     std::chrono::milliseconds minimum_rotation_time,
166     std::chrono::milliseconds maximum_rotation_time) {
167   CallOn(
168       pimpl_->le_impl_,
169       &le_impl::set_privacy_policy_for_initiator_address_for_test,
170       address_policy,
171       fixed_address,
172       rotation_irk,
173       minimum_rotation_time,
174       maximum_rotation_time);
175 }
176 
CancelConnect(Address address)177 void AclManager::CancelConnect(Address address) {
178   CallOn(pimpl_->classic_impl_, &classic_impl::cancel_connect, address);
179 }
180 
CancelLeConnect(AddressWithType address_with_type)181 void AclManager::CancelLeConnect(AddressWithType address_with_type) {
182   CallOn(pimpl_->le_impl_, &le_impl::cancel_connect, address_with_type);
183 }
184 
AddDeviceToConnectList(AddressWithType address_with_type)185 void AclManager::AddDeviceToConnectList(AddressWithType address_with_type) {
186   CallOn(pimpl_->le_impl_, &le_impl::add_device_to_connect_list, address_with_type);
187 }
188 
AddDeviceToResolvingList(AddressWithType address_with_type,const std::array<uint8_t,16> & peer_irk,const std::array<uint8_t,16> & local_irk)189 void AclManager::AddDeviceToResolvingList(
190     AddressWithType address_with_type,
191     const std::array<uint8_t, 16>& peer_irk,
192     const std::array<uint8_t, 16>& local_irk) {
193   CallOn(pimpl_->le_impl_, &le_impl::add_device_to_resolving_list, address_with_type, peer_irk, local_irk);
194 }
195 
RemoveDeviceFromConnectList(AddressWithType address_with_type)196 void AclManager::RemoveDeviceFromConnectList(AddressWithType address_with_type) {
197   CallOn(pimpl_->le_impl_, &le_impl::remove_device_from_connect_list, address_with_type);
198 }
199 
RemoveDeviceFromResolvingList(AddressWithType address_with_type)200 void AclManager::RemoveDeviceFromResolvingList(AddressWithType address_with_type) {
201   CallOn(pimpl_->le_impl_, &le_impl::remove_device_from_resolving_list, address_with_type);
202 }
203 
MasterLinkKey(KeyFlag key_flag)204 void AclManager::MasterLinkKey(KeyFlag key_flag) {
205   CallOn(pimpl_->classic_impl_, &classic_impl::master_link_key, key_flag);
206 }
207 
SwitchRole(Address address,Role role)208 void AclManager::SwitchRole(Address address, Role role) {
209   CallOn(pimpl_->classic_impl_, &classic_impl::switch_role, address, role);
210 }
211 
ReadDefaultLinkPolicySettings()212 uint16_t AclManager::ReadDefaultLinkPolicySettings() {
213   ASSERT_LOG(pimpl_->default_link_policy_settings_ != 0xffff, "Settings were never written");
214   return pimpl_->default_link_policy_settings_;
215 }
216 
WriteDefaultLinkPolicySettings(uint16_t default_link_policy_settings)217 void AclManager::WriteDefaultLinkPolicySettings(uint16_t default_link_policy_settings) {
218   pimpl_->default_link_policy_settings_ = default_link_policy_settings;
219   CallOn(pimpl_->classic_impl_, &classic_impl::write_default_link_policy_settings, default_link_policy_settings);
220 }
221 
SetSecurityModule(security::SecurityModule * security_module)222 void AclManager::SetSecurityModule(security::SecurityModule* security_module) {
223   CallOn(pimpl_->classic_impl_, &classic_impl::set_security_module, security_module);
224 }
225 
GetLeAddressManager()226 LeAddressManager* AclManager::GetLeAddressManager() {
227   return pimpl_->le_impl_->le_address_manager_;
228 }
229 
HACK_GetHandle(Address address)230 uint16_t AclManager::HACK_GetHandle(Address address) {
231   return pimpl_->classic_impl_->HACK_get_handle(address);
232 }
233 
HACK_GetLeHandle(Address address)234 uint16_t AclManager::HACK_GetLeHandle(Address address) {
235   return pimpl_->le_impl_->HACK_get_handle(address);
236 }
237 
ListDependencies(ModuleList * list)238 void AclManager::ListDependencies(ModuleList* list) {
239   list->add<HciLayer>();
240   list->add<Controller>();
241 }
242 
Start()243 void AclManager::Start() {
244   pimpl_->Start();
245 }
246 
Stop()247 void AclManager::Stop() {
248   pimpl_->Stop();
249 }
250 
ToString() const251 std::string AclManager::ToString() const {
252   return "Acl Manager";
253 }
254 
__anonba4926330102() 255 const ModuleFactory AclManager::Factory = ModuleFactory([]() { return new AclManager(); });
256 
257 AclManager::~AclManager() = default;
258 
259 }  // namespace hci
260 }  // namespace bluetooth
261