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