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 <future>
21 #include <set>
22 
23 #include "common/bidi_queue.h"
24 #include "hci/acl_manager/classic_impl.h"
25 #include "hci/acl_manager/connection_management_callbacks.h"
26 #include "hci/acl_manager/le_acl_connection.h"
27 #include "hci/acl_manager/le_impl.h"
28 #include "hci/acl_manager/round_robin_scheduler.h"
29 #include "hci/controller.h"
30 #include "hci/hci_layer.h"
31 #include "hci_acl_manager_generated.h"
32 #include "security/security_module.h"
33 #include "storage/storage_module.h"
34 
35 namespace bluetooth {
36 namespace hci {
37 
38 constexpr uint16_t kQualcommDebugHandle = 0xedc;
39 
40 using acl_manager::AclConnection;
41 using common::Bind;
42 using common::BindOnce;
43 
44 using acl_manager::classic_impl;
45 using acl_manager::ClassicAclConnection;
46 using acl_manager::ConnectionCallbacks;
47 
48 using acl_manager::le_impl;
49 using acl_manager::LeAclConnection;
50 using acl_manager::LeConnectionCallbacks;
51 
52 using acl_manager::RoundRobinScheduler;
53 
54 struct AclManager::impl {
implbluetooth::hci::AclManager::impl55   impl(const AclManager& acl_manager) : acl_manager_(acl_manager) {}
56 
Startbluetooth::hci::AclManager::impl57   void Start() {
58     hci_layer_ = acl_manager_.GetDependency<HciLayer>();
59     handler_ = acl_manager_.GetHandler();
60     controller_ = acl_manager_.GetDependency<Controller>();
61     round_robin_scheduler_ = new RoundRobinScheduler(handler_, controller_, hci_layer_->GetAclQueueEnd());
62 
63     hci_queue_end_ = hci_layer_->GetAclQueueEnd();
64     hci_queue_end_->RegisterDequeue(
65         handler_, common::Bind(&impl::dequeue_and_route_acl_packet_to_connection, common::Unretained(this)));
66     bool crash_on_unknown_handle = false;
67     classic_impl_ =
68         new classic_impl(hci_layer_, controller_, handler_, round_robin_scheduler_, crash_on_unknown_handle);
69     le_impl_ = new le_impl(hci_layer_, controller_, handler_, round_robin_scheduler_, crash_on_unknown_handle);
70   }
71 
Stopbluetooth::hci::AclManager::impl72   void Stop() {
73     delete le_impl_;
74     delete classic_impl_;
75     hci_queue_end_->UnregisterDequeue();
76     delete round_robin_scheduler_;
77     if (enqueue_registered_.exchange(false)) {
78       hci_queue_end_->UnregisterEnqueue();
79     }
80     hci_queue_end_ = nullptr;
81     handler_ = nullptr;
82     hci_layer_ = nullptr;
83   }
84 
85   // Invoked from some external Queue Reactable context 2
dequeue_and_route_acl_packet_to_connectionbluetooth::hci::AclManager::impl86   void dequeue_and_route_acl_packet_to_connection() {
87     auto packet = hci_queue_end_->TryDequeue();
88     ASSERT(packet != nullptr);
89     if (!packet->IsValid()) {
90       LOG_INFO("Dropping invalid packet of size %zu", packet->size());
91       return;
92     }
93     uint16_t handle = packet->GetHandle();
94     if (handle == kQualcommDebugHandle) {
95       return;
96     }
97     auto connection_pair = classic_impl_->acl_connections_.find(handle);
98     if (connection_pair != classic_impl_->acl_connections_.end()) {
99       connection_pair->second.assembler_.on_incoming_packet(*packet);
100     } else {
101       auto le_connection_pair = le_impl_->le_acl_connections_.find(handle);
102       if (le_connection_pair == le_impl_->le_acl_connections_.end()) {
103         LOG_INFO("Dropping packet of size %zu to unknown connection 0x%0hx", packet->size(), handle);
104         return;
105       }
106       le_connection_pair->second.assembler_.on_incoming_packet(*packet);
107     }
108   }
109 
110   void Dump(
111       std::promise<flatbuffers::Offset<AclManagerData>> promise, flatbuffers::FlatBufferBuilder* fb_builder) const;
112 
113   const AclManager& acl_manager_;
114 
115   classic_impl* classic_impl_ = nullptr;
116   le_impl* le_impl_ = nullptr;
117   os::Handler* handler_ = nullptr;
118   Controller* controller_ = nullptr;
119   HciLayer* hci_layer_ = nullptr;
120   RoundRobinScheduler* round_robin_scheduler_ = nullptr;
121   common::BidiQueueEnd<AclBuilder, AclView>* hci_queue_end_ = nullptr;
122   std::atomic_bool enqueue_registered_ = false;
123   uint16_t default_link_policy_settings_ = 0xffff;
124 };
125 
AclManager()126 AclManager::AclManager() : pimpl_(std::make_unique<impl>(*this)) {}
127 
RegisterCallbacks(ConnectionCallbacks * callbacks,os::Handler * handler)128 void AclManager::RegisterCallbacks(ConnectionCallbacks* callbacks, os::Handler* handler) {
129   ASSERT(callbacks != nullptr && handler != nullptr);
130   GetHandler()->Post(common::BindOnce(&classic_impl::handle_register_callbacks,
131                                       common::Unretained(pimpl_->classic_impl_), common::Unretained(callbacks),
132                                       common::Unretained(handler)));
133 }
134 
UnregisterCallbacks(ConnectionCallbacks * callbacks,std::promise<void> promise)135 void AclManager::UnregisterCallbacks(ConnectionCallbacks* callbacks, std::promise<void> promise) {
136   ASSERT(callbacks != nullptr);
137   CallOn(
138       pimpl_->classic_impl_,
139       &classic_impl::handle_unregister_callbacks,
140       common::Unretained(callbacks),
141       std::move(promise));
142 }
143 
RegisterLeCallbacks(LeConnectionCallbacks * callbacks,os::Handler * handler)144 void AclManager::RegisterLeCallbacks(LeConnectionCallbacks* callbacks, os::Handler* handler) {
145   ASSERT(callbacks != nullptr && handler != nullptr);
146   CallOn(
147       pimpl_->le_impl_,
148       &le_impl::handle_register_le_callbacks,
149       common::Unretained(callbacks),
150       common::Unretained(handler));
151 }
152 
UnregisterLeCallbacks(LeConnectionCallbacks * callbacks,std::promise<void> promise)153 void AclManager::UnregisterLeCallbacks(LeConnectionCallbacks* callbacks, std::promise<void> promise) {
154   ASSERT(callbacks != nullptr);
155   CallOn(pimpl_->le_impl_, &le_impl::handle_unregister_le_callbacks, common::Unretained(callbacks), std::move(promise));
156 }
157 
CreateConnection(Address address)158 void AclManager::CreateConnection(Address address) {
159   CallOn(pimpl_->classic_impl_, &classic_impl::create_connection, address);
160 }
161 
CreateLeConnection(AddressWithType address_with_type,bool is_direct)162 void AclManager::CreateLeConnection(AddressWithType address_with_type, bool is_direct) {
163   CallOn(pimpl_->le_impl_, &le_impl::create_le_connection, address_with_type, true, is_direct);
164 }
165 
SetLeSuggestedDefaultDataParameters(uint16_t octets,uint16_t time)166 void AclManager::SetLeSuggestedDefaultDataParameters(uint16_t octets, uint16_t time) {
167   CallOn(pimpl_->le_impl_, &le_impl::set_le_suggested_default_data_parameters, octets, time);
168 }
169 
SetPrivacyPolicyForInitiatorAddress(LeAddressManager::AddressPolicy address_policy,AddressWithType fixed_address,std::chrono::milliseconds minimum_rotation_time,std::chrono::milliseconds maximum_rotation_time)170 void AclManager::SetPrivacyPolicyForInitiatorAddress(
171     LeAddressManager::AddressPolicy address_policy,
172     AddressWithType fixed_address,
173     std::chrono::milliseconds minimum_rotation_time,
174     std::chrono::milliseconds maximum_rotation_time) {
175   crypto_toolbox::Octet16 rotation_irk{};
176   auto irk = GetDependency<storage::StorageModule>()->GetAdapterConfig().GetLeIdentityResolvingKey();
177   if (irk.has_value()) {
178     rotation_irk = irk->bytes;
179   }
180   CallOn(
181       pimpl_->le_impl_,
182       &le_impl::set_privacy_policy_for_initiator_address,
183       address_policy,
184       fixed_address,
185       rotation_irk,
186       minimum_rotation_time,
187       maximum_rotation_time);
188 }
189 
190 // 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)191 void AclManager::SetPrivacyPolicyForInitiatorAddressForTest(
192     LeAddressManager::AddressPolicy address_policy,
193     AddressWithType fixed_address,
194     crypto_toolbox::Octet16 rotation_irk,
195     std::chrono::milliseconds minimum_rotation_time,
196     std::chrono::milliseconds maximum_rotation_time) {
197   CallOn(
198       pimpl_->le_impl_,
199       &le_impl::set_privacy_policy_for_initiator_address_for_test,
200       address_policy,
201       fixed_address,
202       rotation_irk,
203       minimum_rotation_time,
204       maximum_rotation_time);
205 }
206 
CancelConnect(Address address)207 void AclManager::CancelConnect(Address address) {
208   CallOn(pimpl_->classic_impl_, &classic_impl::cancel_connect, address);
209 }
210 
CancelLeConnect(AddressWithType address_with_type)211 void AclManager::CancelLeConnect(AddressWithType address_with_type) {
212   CallOn(pimpl_->le_impl_, &le_impl::cancel_connect, address_with_type);
213 }
214 
AddDeviceToConnectList(AddressWithType address_with_type)215 void AclManager::AddDeviceToConnectList(AddressWithType address_with_type) {
216   CallOn(pimpl_->le_impl_, &le_impl::add_device_to_connect_list, address_with_type);
217 }
218 
AddDeviceToResolvingList(AddressWithType address_with_type,const std::array<uint8_t,16> & peer_irk,const std::array<uint8_t,16> & local_irk)219 void AclManager::AddDeviceToResolvingList(
220     AddressWithType address_with_type,
221     const std::array<uint8_t, 16>& peer_irk,
222     const std::array<uint8_t, 16>& local_irk) {
223   CallOn(pimpl_->le_impl_, &le_impl::add_device_to_resolving_list, address_with_type, peer_irk, local_irk);
224 }
225 
RemoveDeviceFromConnectList(AddressWithType address_with_type)226 void AclManager::RemoveDeviceFromConnectList(AddressWithType address_with_type) {
227   CallOn(pimpl_->le_impl_, &le_impl::remove_device_from_connect_list, address_with_type);
228 }
229 
RemoveDeviceFromResolvingList(AddressWithType address_with_type)230 void AclManager::RemoveDeviceFromResolvingList(AddressWithType address_with_type) {
231   CallOn(pimpl_->le_impl_, &le_impl::remove_device_from_resolving_list, address_with_type);
232 }
233 
CentralLinkKey(KeyFlag key_flag)234 void AclManager::CentralLinkKey(KeyFlag key_flag) {
235   CallOn(pimpl_->classic_impl_, &classic_impl::central_link_key, key_flag);
236 }
237 
SwitchRole(Address address,Role role)238 void AclManager::SwitchRole(Address address, Role role) {
239   CallOn(pimpl_->classic_impl_, &classic_impl::switch_role, address, role);
240 }
241 
ReadDefaultLinkPolicySettings()242 uint16_t AclManager::ReadDefaultLinkPolicySettings() {
243   ASSERT_LOG(pimpl_->default_link_policy_settings_ != 0xffff, "Settings were never written");
244   return pimpl_->default_link_policy_settings_;
245 }
246 
WriteDefaultLinkPolicySettings(uint16_t default_link_policy_settings)247 void AclManager::WriteDefaultLinkPolicySettings(uint16_t default_link_policy_settings) {
248   pimpl_->default_link_policy_settings_ = default_link_policy_settings;
249   CallOn(pimpl_->classic_impl_, &classic_impl::write_default_link_policy_settings, default_link_policy_settings);
250 }
251 
OnAdvertisingSetTerminated(ErrorCode status,uint16_t conn_handle,hci::AddressWithType adv_address)252 void AclManager::OnAdvertisingSetTerminated(ErrorCode status, uint16_t conn_handle, hci::AddressWithType adv_address) {
253   if (status == ErrorCode::SUCCESS) {
254     CallOn(pimpl_->le_impl_, &le_impl::UpdateLocalAddress, conn_handle, adv_address);
255   }
256 }
257 
SetSecurityModule(security::SecurityModule * security_module)258 void AclManager::SetSecurityModule(security::SecurityModule* security_module) {
259   CallOn(pimpl_->classic_impl_, &classic_impl::set_security_module, security_module);
260 }
261 
GetLeAddressManager()262 LeAddressManager* AclManager::GetLeAddressManager() {
263   return pimpl_->le_impl_->le_address_manager_;
264 }
265 
HACK_GetHandle(Address address)266 uint16_t AclManager::HACK_GetHandle(Address address) {
267   return pimpl_->classic_impl_->HACK_get_handle(address);
268 }
269 
HACK_GetLeHandle(Address address)270 uint16_t AclManager::HACK_GetLeHandle(Address address) {
271   return pimpl_->le_impl_->HACK_get_handle(address);
272 }
273 
HACK_SetScoDisconnectCallback(std::function<void (uint16_t,uint8_t)> callback)274 void AclManager::HACK_SetScoDisconnectCallback(std::function<void(uint16_t, uint8_t)> callback) {
275   pimpl_->classic_impl_->HACK_SetScoDisconnectCallback(callback);
276 }
277 
HACK_SetAclTxPriority(uint8_t handle,bool high_priority)278 void AclManager::HACK_SetAclTxPriority(uint8_t handle, bool high_priority) {
279   CallOn(pimpl_->round_robin_scheduler_, &RoundRobinScheduler::SetLinkPriority, handle, high_priority);
280 }
281 
ListDependencies(ModuleList * list)282 void AclManager::ListDependencies(ModuleList* list) {
283   list->add<HciLayer>();
284   list->add<Controller>();
285   list->add<storage::StorageModule>();
286 }
287 
Start()288 void AclManager::Start() {
289   pimpl_->Start();
290 }
291 
Stop()292 void AclManager::Stop() {
293   pimpl_->Stop();
294 }
295 
ToString() const296 std::string AclManager::ToString() const {
297   return "Acl Manager";
298 }
299 
__anonba4926330102() 300 const ModuleFactory AclManager::Factory = ModuleFactory([]() { return new AclManager(); });
301 
302 AclManager::~AclManager() = default;
303 
Dump(std::promise<flatbuffers::Offset<AclManagerData>> promise,flatbuffers::FlatBufferBuilder * fb_builder) const304 void AclManager::impl::Dump(
305     std::promise<flatbuffers::Offset<AclManagerData>> promise, flatbuffers::FlatBufferBuilder* fb_builder) const {
306   auto title = fb_builder->CreateString("----- Acl Manager Dumpsys -----");
307   AclManagerDataBuilder builder(*fb_builder);
308   builder.add_title(title);
309   flatbuffers::Offset<AclManagerData> dumpsys_data = builder.Finish();
310   promise.set_value(dumpsys_data);
311 }
312 
GetDumpsysData(flatbuffers::FlatBufferBuilder * fb_builder) const313 DumpsysDataFinisher AclManager::GetDumpsysData(flatbuffers::FlatBufferBuilder* fb_builder) const {
314   ASSERT(fb_builder != nullptr);
315 
316   std::promise<flatbuffers::Offset<AclManagerData>> promise;
317   auto future = promise.get_future();
318   pimpl_->Dump(std::move(promise), fb_builder);
319 
320   auto dumpsys_data = future.get();
321 
322   return [dumpsys_data](DumpsysDataBuilder* dumpsys_builder) {
323     dumpsys_builder->add_hci_acl_manager_dumpsys_data(dumpsys_data);
324   };
325 }
326 
327 }  // namespace hci
328 }  // namespace bluetooth
329