1 /*
2 * Copyright 2020 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/le_address_manager.h"
18
19 #include "common/init_flags.h"
20 #include "os/log.h"
21 #include "os/rand.h"
22
23 namespace bluetooth {
24 namespace hci {
25
26 static constexpr uint8_t BLE_ADDR_MASK = 0xc0u;
27
LeAddressManager(common::Callback<void (std::unique_ptr<CommandBuilder>)> enqueue_command,os::Handler * handler,Address public_address,uint8_t connect_list_size,uint8_t resolving_list_size)28 LeAddressManager::LeAddressManager(
29 common::Callback<void(std::unique_ptr<CommandBuilder>)> enqueue_command,
30 os::Handler* handler,
31 Address public_address,
32 uint8_t connect_list_size,
33 uint8_t resolving_list_size)
34 : enqueue_command_(enqueue_command),
35 handler_(handler),
36 public_address_(public_address),
37 connect_list_size_(connect_list_size),
38 resolving_list_size_(resolving_list_size){};
39
~LeAddressManager()40 LeAddressManager::~LeAddressManager() {
41 if (address_rotation_alarm_ != nullptr) {
42 address_rotation_alarm_->Cancel();
43 address_rotation_alarm_.reset();
44 }
45 }
46
47 // Called on initialization, and on IRK rotation
SetPrivacyPolicyForInitiatorAddress(AddressPolicy address_policy,AddressWithType fixed_address,crypto_toolbox::Octet16 rotation_irk,bool supports_ble_privacy,std::chrono::milliseconds minimum_rotation_time,std::chrono::milliseconds maximum_rotation_time)48 void LeAddressManager::SetPrivacyPolicyForInitiatorAddress(
49 AddressPolicy address_policy,
50 AddressWithType fixed_address,
51 crypto_toolbox::Octet16 rotation_irk,
52 bool supports_ble_privacy,
53 std::chrono::milliseconds minimum_rotation_time,
54 std::chrono::milliseconds maximum_rotation_time) {
55 // Handle repeated calls to the function for IRK rotation
56 if (address_policy_ != AddressPolicy::POLICY_NOT_SET) {
57 // Need to update some parameteres like IRK if privacy is supported
58 if (supports_ble_privacy) {
59 LOG_INFO("Updating rotation parameters.");
60 handler_->CallOn(
61 this,
62 &LeAddressManager::prepare_to_update_irk,
63 UpdateIRKCommand{rotation_irk, minimum_rotation_time, maximum_rotation_time});
64 }
65 return;
66 }
67 ASSERT(address_policy_ == AddressPolicy::POLICY_NOT_SET);
68 ASSERT(address_policy != AddressPolicy::POLICY_NOT_SET);
69 ASSERT_LOG(registered_clients_.empty(), "Policy must be set before clients are registered.");
70 address_policy_ = address_policy;
71 supports_ble_privacy_ = supports_ble_privacy;
72 LOG_INFO("SetPrivacyPolicyForInitiatorAddress with policy %d", address_policy);
73
74 switch (address_policy_) {
75 case AddressPolicy::USE_PUBLIC_ADDRESS:
76 le_address_ = AddressWithType(public_address_, AddressType::PUBLIC_DEVICE_ADDRESS);
77 handler_->BindOnceOn(this, &LeAddressManager::resume_registered_clients).Invoke();
78 break;
79 case AddressPolicy::USE_STATIC_ADDRESS: {
80 auto addr = fixed_address.GetAddress();
81 auto address = addr.address;
82 // The two most significant bits of the static address shall be equal to 1
83 ASSERT_LOG((address[5] & BLE_ADDR_MASK) == BLE_ADDR_MASK, "The two most significant bits shall be equal to 1");
84 // Bits of the random part of the address shall not be all 1 or all 0
85 if ((address[0] == 0x00 && address[1] == 0x00 && address[2] == 0x00 && address[3] == 0x00 && address[4] == 0x00 &&
86 address[5] == BLE_ADDR_MASK) ||
87 (address[0] == 0xFF && address[1] == 0xFF && address[2] == 0xFF && address[3] == 0xFF && address[4] == 0xFF &&
88 address[5] == 0xFF)) {
89 LOG_ALWAYS_FATAL("Bits of the random part of the address shall not be all 1 or all 0");
90 }
91 le_address_ = fixed_address;
92 auto packet = hci::LeSetRandomAddressBuilder::Create(le_address_.GetAddress());
93 handler_->Post(common::BindOnce(enqueue_command_, std::move(packet)));
94 } break;
95 case AddressPolicy::USE_NON_RESOLVABLE_ADDRESS:
96 case AddressPolicy::USE_RESOLVABLE_ADDRESS:
97 le_address_ = fixed_address;
98 rotation_irk_ = rotation_irk;
99 minimum_rotation_time_ = minimum_rotation_time;
100 maximum_rotation_time_ = maximum_rotation_time;
101 address_rotation_alarm_ = std::make_unique<os::Alarm>(handler_);
102 set_random_address();
103 break;
104 case AddressPolicy::POLICY_NOT_SET:
105 LOG_ALWAYS_FATAL("invalid parameters");
106 }
107 }
108
109 // TODO(jpawlowski): remove once we have config file abstraction in cert tests
SetPrivacyPolicyForInitiatorAddressForTest(AddressPolicy address_policy,AddressWithType fixed_address,crypto_toolbox::Octet16 rotation_irk,std::chrono::milliseconds minimum_rotation_time,std::chrono::milliseconds maximum_rotation_time)110 void LeAddressManager::SetPrivacyPolicyForInitiatorAddressForTest(
111 AddressPolicy address_policy,
112 AddressWithType fixed_address,
113 crypto_toolbox::Octet16 rotation_irk,
114 std::chrono::milliseconds minimum_rotation_time,
115 std::chrono::milliseconds maximum_rotation_time) {
116 ASSERT(address_policy != AddressPolicy::POLICY_NOT_SET);
117 ASSERT_LOG(registered_clients_.empty(), "Policy must be set before clients are registered.");
118 address_policy_ = address_policy;
119
120 switch (address_policy_) {
121 case AddressPolicy::USE_PUBLIC_ADDRESS:
122 le_address_ = fixed_address;
123 break;
124 case AddressPolicy::USE_STATIC_ADDRESS: {
125 auto addr = fixed_address.GetAddress();
126 auto address = addr.address;
127 // The two most significant bits of the static address shall be equal to 1
128 ASSERT_LOG((address[5] & BLE_ADDR_MASK) == BLE_ADDR_MASK, "The two most significant bits shall be equal to 1");
129 // Bits of the random part of the address shall not be all 1 or all 0
130 if ((address[0] == 0x00 && address[1] == 0x00 && address[2] == 0x00 && address[3] == 0x00 && address[4] == 0x00 &&
131 address[5] == BLE_ADDR_MASK) ||
132 (address[0] == 0xFF && address[1] == 0xFF && address[2] == 0xFF && address[3] == 0xFF && address[4] == 0xFF &&
133 address[5] == 0xFF)) {
134 LOG_ALWAYS_FATAL("Bits of the random part of the address shall not be all 1 or all 0");
135 }
136 le_address_ = fixed_address;
137 auto packet = hci::LeSetRandomAddressBuilder::Create(le_address_.GetAddress());
138 handler_->Call(enqueue_command_, std::move(packet));
139 } break;
140 case AddressPolicy::USE_NON_RESOLVABLE_ADDRESS:
141 case AddressPolicy::USE_RESOLVABLE_ADDRESS:
142 rotation_irk_ = rotation_irk;
143 minimum_rotation_time_ = minimum_rotation_time;
144 maximum_rotation_time_ = maximum_rotation_time;
145 address_rotation_alarm_ = std::make_unique<os::Alarm>(handler_);
146 set_random_address();
147 break;
148 case AddressPolicy::POLICY_NOT_SET:
149 LOG_ALWAYS_FATAL("invalid parameters");
150 }
151 }
GetAddressPolicy()152 LeAddressManager::AddressPolicy LeAddressManager::GetAddressPolicy() {
153 return address_policy_;
154 }
RotatingAddress()155 bool LeAddressManager::RotatingAddress() {
156 return address_policy_ == AddressPolicy::USE_RESOLVABLE_ADDRESS ||
157 address_policy_ == AddressPolicy::USE_NON_RESOLVABLE_ADDRESS;
158 }
Register(LeAddressManagerCallback * callback)159 LeAddressManager::AddressPolicy LeAddressManager::Register(LeAddressManagerCallback* callback) {
160 handler_->BindOnceOn(this, &LeAddressManager::register_client, callback).Invoke();
161 return address_policy_;
162 }
163
register_client(LeAddressManagerCallback * callback)164 void LeAddressManager::register_client(LeAddressManagerCallback* callback) {
165 registered_clients_.insert(std::pair<LeAddressManagerCallback*, ClientState>(callback, ClientState::RESUMED));
166 if (address_policy_ == AddressPolicy::POLICY_NOT_SET) {
167 LOG_INFO("address policy isn't set yet, pause clients and return");
168 pause_registered_clients();
169 return;
170 } else if (
171 address_policy_ == AddressPolicy::USE_RESOLVABLE_ADDRESS ||
172 address_policy_ == AddressPolicy::USE_NON_RESOLVABLE_ADDRESS) {
173 if (registered_clients_.size() == 1) {
174 schedule_rotate_random_address();
175 LOG_INFO("Scheduled address rotation for first client registered");
176 }
177 }
178 LOG_INFO("Client registered");
179 }
180
Unregister(LeAddressManagerCallback * callback)181 void LeAddressManager::Unregister(LeAddressManagerCallback* callback) {
182 handler_->BindOnceOn(this, &LeAddressManager::unregister_client, callback).Invoke();
183 }
184
unregister_client(LeAddressManagerCallback * callback)185 void LeAddressManager::unregister_client(LeAddressManagerCallback* callback) {
186 if (registered_clients_.find(callback) != registered_clients_.end()) {
187 if (registered_clients_.find(callback)->second == ClientState::WAITING_FOR_PAUSE) {
188 ack_pause(callback);
189 } else if (registered_clients_.find(callback)->second == ClientState::WAITING_FOR_RESUME) {
190 ack_resume(callback);
191 }
192 registered_clients_.erase(callback);
193 LOG_INFO("Client unregistered");
194 }
195 if (registered_clients_.empty() && address_rotation_alarm_ != nullptr) {
196 address_rotation_alarm_->Cancel();
197 LOG_INFO("Cancelled address rotation alarm");
198 }
199 }
200
UnregisterSync(LeAddressManagerCallback * callback,std::chrono::milliseconds timeout)201 bool LeAddressManager::UnregisterSync(LeAddressManagerCallback* callback, std::chrono::milliseconds timeout) {
202 handler_->BindOnceOn(this, &LeAddressManager::unregister_client, callback).Invoke();
203 std::promise<void> promise;
204 auto future = promise.get_future();
205 handler_->Post(common::BindOnce(&std::promise<void>::set_value, common::Unretained(&promise)));
206 return future.wait_for(timeout) == std::future_status::ready;
207 }
208
AckPause(LeAddressManagerCallback * callback)209 void LeAddressManager::AckPause(LeAddressManagerCallback* callback) {
210 handler_->BindOnceOn(this, &LeAddressManager::ack_pause, callback).Invoke();
211 }
212
AckResume(LeAddressManagerCallback * callback)213 void LeAddressManager::AckResume(LeAddressManagerCallback* callback) {
214 handler_->BindOnceOn(this, &LeAddressManager::ack_resume, callback).Invoke();
215 }
216
GetInitiatorAddress()217 AddressWithType LeAddressManager::GetInitiatorAddress() {
218 ASSERT(address_policy_ != AddressPolicy::POLICY_NOT_SET);
219 return le_address_;
220 }
221
NewResolvableAddress()222 AddressWithType LeAddressManager::NewResolvableAddress() {
223 ASSERT(RotatingAddress());
224 hci::Address address = generate_rpa();
225 auto random_address = AddressWithType(address, AddressType::RANDOM_DEVICE_ADDRESS);
226 return random_address;
227 }
228
NewNonResolvableAddress()229 AddressWithType LeAddressManager::NewNonResolvableAddress() {
230 ASSERT(RotatingAddress());
231 hci::Address address = generate_nrpa();
232 auto random_address = AddressWithType(address, AddressType::RANDOM_DEVICE_ADDRESS);
233 return random_address;
234 }
235
pause_registered_clients()236 void LeAddressManager::pause_registered_clients() {
237 for (auto& client : registered_clients_) {
238 switch (client.second) {
239 case ClientState::PAUSED:
240 case ClientState::WAITING_FOR_PAUSE:
241 break;
242 case WAITING_FOR_RESUME:
243 case RESUMED:
244 client.second = ClientState::WAITING_FOR_PAUSE;
245 client.first->OnPause();
246 break;
247 }
248 }
249 }
250
push_command(Command command)251 void LeAddressManager::push_command(Command command) {
252 pause_registered_clients();
253 cached_commands_.push(std::move(command));
254 }
255
ack_pause(LeAddressManagerCallback * callback)256 void LeAddressManager::ack_pause(LeAddressManagerCallback* callback) {
257 if (registered_clients_.find(callback) == registered_clients_.end()) {
258 LOG_INFO("No clients registered to ack pause");
259 return;
260 }
261 registered_clients_.find(callback)->second = ClientState::PAUSED;
262 for (auto client : registered_clients_) {
263 switch (client.second) {
264 case ClientState::PAUSED:
265 LOG_INFO("Client already in paused state");
266 break;
267 case ClientState::WAITING_FOR_PAUSE:
268 // make sure all client paused
269 LOG_DEBUG("Wait all clients paused, return");
270 return;
271 case WAITING_FOR_RESUME:
272 case RESUMED:
273 LOG_DEBUG("Trigger OnPause for client that not paused and not waiting for pause");
274 client.second = ClientState::WAITING_FOR_PAUSE;
275 client.first->OnPause();
276 return;
277 default:
278 LOG_ERROR("Found client in unexpected state:%u", client.second);
279 }
280 }
281
282 if (address_policy_ != AddressPolicy::POLICY_NOT_SET) {
283 check_cached_commands();
284 }
285 }
286
resume_registered_clients()287 void LeAddressManager::resume_registered_clients() {
288 // Do not resume clients if cached command is not empty
289 if (!cached_commands_.empty()) {
290 handle_next_command();
291 return;
292 }
293
294 LOG_INFO("Resuming registered clients");
295 for (auto& client : registered_clients_) {
296 client.second = ClientState::WAITING_FOR_RESUME;
297 client.first->OnResume();
298 }
299 }
300
ack_resume(LeAddressManagerCallback * callback)301 void LeAddressManager::ack_resume(LeAddressManagerCallback* callback) {
302 if (registered_clients_.find(callback) != registered_clients_.end()) {
303 registered_clients_.find(callback)->second = ClientState::RESUMED;
304 }
305 }
306
prepare_to_rotate()307 void LeAddressManager::prepare_to_rotate() {
308 Command command = {CommandType::ROTATE_RANDOM_ADDRESS, RotateRandomAddressCommand{}};
309 cached_commands_.push(std::move(command));
310 pause_registered_clients();
311 }
312
schedule_rotate_random_address()313 void LeAddressManager::schedule_rotate_random_address() {
314 address_rotation_alarm_->Schedule(
315 common::BindOnce(&LeAddressManager::prepare_to_rotate, common::Unretained(this)),
316 GetNextPrivateAddressIntervalMs());
317 }
318
set_random_address()319 void LeAddressManager::set_random_address() {
320 if (address_policy_ != AddressPolicy::USE_RESOLVABLE_ADDRESS &&
321 address_policy_ != AddressPolicy::USE_NON_RESOLVABLE_ADDRESS) {
322 LOG_ALWAYS_FATAL("Invalid address policy!");
323 return;
324 }
325
326 hci::Address address;
327 if (address_policy_ == AddressPolicy::USE_RESOLVABLE_ADDRESS) {
328 address = generate_rpa();
329 } else {
330 address = generate_nrpa();
331 }
332 auto packet = hci::LeSetRandomAddressBuilder::Create(address);
333 enqueue_command_.Run(std::move(packet));
334 cached_address_ = AddressWithType(address, AddressType::RANDOM_DEVICE_ADDRESS);
335 }
336
rotate_random_address()337 void LeAddressManager::rotate_random_address() {
338 if (address_policy_ != AddressPolicy::USE_RESOLVABLE_ADDRESS &&
339 address_policy_ != AddressPolicy::USE_NON_RESOLVABLE_ADDRESS) {
340 LOG_ALWAYS_FATAL("Invalid address policy!");
341 return;
342 }
343
344 schedule_rotate_random_address();
345 set_random_address();
346 }
347
prepare_to_update_irk(UpdateIRKCommand update_irk_command)348 void LeAddressManager::prepare_to_update_irk(UpdateIRKCommand update_irk_command) {
349 Command command = {CommandType::UPDATE_IRK, update_irk_command};
350 cached_commands_.push(std::move(command));
351 if (registered_clients_.empty()) {
352 handle_next_command();
353 } else {
354 pause_registered_clients();
355 }
356 }
357
update_irk(UpdateIRKCommand command)358 void LeAddressManager::update_irk(UpdateIRKCommand command) {
359 rotation_irk_ = command.rotation_irk;
360 minimum_rotation_time_ = command.minimum_rotation_time;
361 maximum_rotation_time_ = command.maximum_rotation_time;
362 set_random_address();
363 for (auto& client : registered_clients_) {
364 client.first->NotifyOnIRKChange();
365 }
366 }
367
368 /* This function generates Resolvable Private Address (RPA) from Identity
369 * Resolving Key |irk| and |prand|*/
generate_rpa()370 hci::Address LeAddressManager::generate_rpa() {
371 // most significant bit, bit7, bit6 is 01 to be resolvable random
372 // Bits of the random part of prand shall not be all 1 or all 0
373 std::array<uint8_t, 3> prand = os::GenerateRandom<3>();
374 constexpr uint8_t BLE_RESOLVE_ADDR_MSB = 0x40;
375 prand[2] &= ~BLE_ADDR_MASK;
376 if ((prand[0] == 0x00 && prand[1] == 0x00 && prand[2] == 0x00) ||
377 (prand[0] == 0xFF && prand[1] == 0xFF && prand[2] == 0x3F)) {
378 prand[0] = (uint8_t)(os::GenerateRandom() % 0xFE + 1);
379 }
380 prand[2] |= BLE_RESOLVE_ADDR_MSB;
381
382 hci::Address address;
383 address.address[3] = prand[0];
384 address.address[4] = prand[1];
385 address.address[5] = prand[2];
386
387 /* encrypt with IRK */
388 crypto_toolbox::Octet16 p = crypto_toolbox::aes_128(rotation_irk_, prand.data(), 3);
389
390 /* set hash to be LSB of rpAddress */
391 address.address[0] = p[0];
392 address.address[1] = p[1];
393 address.address[2] = p[2];
394 return address;
395 }
396
397 // This function generates NON-Resolvable Private Address (NRPA)
generate_nrpa()398 hci::Address LeAddressManager::generate_nrpa() {
399 // The two most significant bits of the address shall be equal to 0
400 // Bits of the random part of the address shall not be all 1 or all 0
401 std::array<uint8_t, 6> random = os::GenerateRandom<6>();
402 random[5] &= ~BLE_ADDR_MASK;
403 if ((random[0] == 0x00 && random[1] == 0x00 && random[2] == 0x00 && random[3] == 0x00 && random[4] == 0x00 &&
404 random[5] == 0x00) ||
405 (random[0] == 0xFF && random[1] == 0xFF && random[2] == 0xFF && random[3] == 0xFF && random[4] == 0xFF &&
406 random[5] == 0x3F)) {
407 random[0] = (uint8_t)(os::GenerateRandom() % 0xFE + 1);
408 }
409
410 hci::Address address;
411 address.FromOctets(random.data());
412
413 // the address shall not be equal to the public address
414 while (address == public_address_) {
415 address.address[0] = (uint8_t)(os::GenerateRandom() % 0xFE + 1);
416 }
417
418 return address;
419 }
420
GetNextPrivateAddressIntervalMs()421 std::chrono::milliseconds LeAddressManager::GetNextPrivateAddressIntervalMs() {
422 auto interval_random_part_max_ms = maximum_rotation_time_ - minimum_rotation_time_;
423 auto random_ms = std::chrono::milliseconds(os::GenerateRandom()) % (interval_random_part_max_ms);
424 return minimum_rotation_time_ + random_ms;
425 }
426
GetFilterAcceptListSize()427 uint8_t LeAddressManager::GetFilterAcceptListSize() {
428 return connect_list_size_;
429 }
430
GetResolvingListSize()431 uint8_t LeAddressManager::GetResolvingListSize() {
432 return resolving_list_size_;
433 }
434
handle_next_command()435 void LeAddressManager::handle_next_command() {
436 for (auto client : registered_clients_) {
437 if (client.second != ClientState::PAUSED) {
438 // make sure all client paused, if not, this function will be trigger again by ack_pause
439 LOG_INFO("waiting for ack_pause, return");
440 return;
441 }
442 }
443
444 ASSERT(!cached_commands_.empty());
445 auto command = std::move(cached_commands_.front());
446 cached_commands_.pop();
447
448 std::visit(
449 [this](auto&& command) {
450 using T = std::decay_t<decltype(command)>;
451 if constexpr (std::is_same_v<T, UpdateIRKCommand>) {
452 update_irk(command);
453 } else if constexpr (std::is_same_v<T, RotateRandomAddressCommand>) {
454 rotate_random_address();
455 } else if constexpr (std::is_same_v<T, HCICommand>) {
456 enqueue_command_.Run(std::move(command.command));
457 } else {
458 static_assert(!sizeof(T*), "non-exhaustive visitor!");
459 }
460 },
461 command.contents);
462 }
463
AddDeviceToFilterAcceptList(FilterAcceptListAddressType connect_list_address_type,bluetooth::hci::Address address)464 void LeAddressManager::AddDeviceToFilterAcceptList(
465 FilterAcceptListAddressType connect_list_address_type, bluetooth::hci::Address address) {
466 auto packet_builder = hci::LeAddDeviceToFilterAcceptListBuilder::Create(connect_list_address_type, address);
467 Command command = {CommandType::ADD_DEVICE_TO_CONNECT_LIST, HCICommand{std::move(packet_builder)}};
468 handler_->BindOnceOn(this, &LeAddressManager::push_command, std::move(command)).Invoke();
469 }
470
AddDeviceToResolvingList(PeerAddressType peer_identity_address_type,Address peer_identity_address,const std::array<uint8_t,16> & peer_irk,const std::array<uint8_t,16> & local_irk)471 void LeAddressManager::AddDeviceToResolvingList(
472 PeerAddressType peer_identity_address_type,
473 Address peer_identity_address,
474 const std::array<uint8_t, 16>& peer_irk,
475 const std::array<uint8_t, 16>& local_irk) {
476 if (!supports_ble_privacy_) {
477 return;
478 }
479
480 // Disable Address resolution
481 auto disable_builder = hci::LeSetAddressResolutionEnableBuilder::Create(hci::Enable::DISABLED);
482 Command disable = {CommandType::SET_ADDRESS_RESOLUTION_ENABLE, HCICommand{std::move(disable_builder)}};
483 cached_commands_.push(std::move(disable));
484
485 auto packet_builder = hci::LeAddDeviceToResolvingListBuilder::Create(
486 peer_identity_address_type, peer_identity_address, peer_irk, local_irk);
487 Command command = {CommandType::ADD_DEVICE_TO_RESOLVING_LIST, HCICommand{std::move(packet_builder)}};
488 cached_commands_.push(std::move(command));
489
490 if (supports_ble_privacy_) {
491 auto packet_builder =
492 hci::LeSetPrivacyModeBuilder::Create(peer_identity_address_type, peer_identity_address, PrivacyMode::DEVICE);
493 Command command = {CommandType::LE_SET_PRIVACY_MODE, HCICommand{std::move(packet_builder)}};
494 cached_commands_.push(std::move(command));
495 }
496
497 // Enable Address resolution
498 auto enable_builder = hci::LeSetAddressResolutionEnableBuilder::Create(hci::Enable::ENABLED);
499 Command enable = {CommandType::SET_ADDRESS_RESOLUTION_ENABLE, HCICommand{std::move(enable_builder)}};
500 cached_commands_.push(std::move(enable));
501
502 if (registered_clients_.empty()) {
503 handler_->BindOnceOn(this, &LeAddressManager::handle_next_command).Invoke();
504 } else {
505 handler_->BindOnceOn(this, &LeAddressManager::pause_registered_clients).Invoke();
506 }
507 }
508
RemoveDeviceFromFilterAcceptList(FilterAcceptListAddressType connect_list_address_type,bluetooth::hci::Address address)509 void LeAddressManager::RemoveDeviceFromFilterAcceptList(
510 FilterAcceptListAddressType connect_list_address_type, bluetooth::hci::Address address) {
511 auto packet_builder = hci::LeRemoveDeviceFromFilterAcceptListBuilder::Create(connect_list_address_type, address);
512 Command command = {CommandType::REMOVE_DEVICE_FROM_CONNECT_LIST, HCICommand{std::move(packet_builder)}};
513 handler_->BindOnceOn(this, &LeAddressManager::push_command, std::move(command)).Invoke();
514 }
515
RemoveDeviceFromResolvingList(PeerAddressType peer_identity_address_type,Address peer_identity_address)516 void LeAddressManager::RemoveDeviceFromResolvingList(
517 PeerAddressType peer_identity_address_type, Address peer_identity_address) {
518 if (!supports_ble_privacy_) {
519 return;
520 }
521
522 // Disable Address resolution
523 auto disable_builder = hci::LeSetAddressResolutionEnableBuilder::Create(hci::Enable::DISABLED);
524 Command disable = {CommandType::SET_ADDRESS_RESOLUTION_ENABLE, HCICommand{std::move(disable_builder)}};
525 cached_commands_.push(std::move(disable));
526
527 auto packet_builder =
528 hci::LeRemoveDeviceFromResolvingListBuilder::Create(peer_identity_address_type, peer_identity_address);
529 Command command = {CommandType::REMOVE_DEVICE_FROM_RESOLVING_LIST, HCICommand{std::move(packet_builder)}};
530 cached_commands_.push(std::move(command));
531
532 // Enable Address resolution
533 auto enable_builder = hci::LeSetAddressResolutionEnableBuilder::Create(hci::Enable::ENABLED);
534 Command enable = {CommandType::SET_ADDRESS_RESOLUTION_ENABLE, HCICommand{std::move(enable_builder)}};
535 cached_commands_.push(std::move(enable));
536
537 if (registered_clients_.empty()) {
538 handler_->BindOnceOn(this, &LeAddressManager::handle_next_command).Invoke();
539 } else {
540 handler_->BindOnceOn(this, &LeAddressManager::pause_registered_clients).Invoke();
541 }
542 }
543
ClearFilterAcceptList()544 void LeAddressManager::ClearFilterAcceptList() {
545 auto packet_builder = hci::LeClearFilterAcceptListBuilder::Create();
546 Command command = {CommandType::CLEAR_CONNECT_LIST, HCICommand{std::move(packet_builder)}};
547 handler_->BindOnceOn(this, &LeAddressManager::push_command, std::move(command)).Invoke();
548 }
549
ClearResolvingList()550 void LeAddressManager::ClearResolvingList() {
551 if (!supports_ble_privacy_) {
552 return;
553 }
554
555 // Disable Address resolution
556 auto disable_builder = hci::LeSetAddressResolutionEnableBuilder::Create(hci::Enable::DISABLED);
557 Command disable = {CommandType::SET_ADDRESS_RESOLUTION_ENABLE, HCICommand{std::move(disable_builder)}};
558 cached_commands_.push(std::move(disable));
559
560 auto packet_builder = hci::LeClearResolvingListBuilder::Create();
561 Command command = {CommandType::CLEAR_RESOLVING_LIST, HCICommand{std::move(packet_builder)}};
562 cached_commands_.push(std::move(command));
563
564 // Enable Address resolution
565 auto enable_builder = hci::LeSetAddressResolutionEnableBuilder::Create(hci::Enable::ENABLED);
566 Command enable = {CommandType::SET_ADDRESS_RESOLUTION_ENABLE, HCICommand{std::move(enable_builder)}};
567 cached_commands_.push(std::move(enable));
568
569 handler_->BindOnceOn(this, &LeAddressManager::pause_registered_clients).Invoke();
570 }
571
572 template <class View>
on_command_complete(CommandCompleteView view)573 void LeAddressManager::on_command_complete(CommandCompleteView view) {
574 auto op_code = view.GetCommandOpCode();
575
576 auto complete_view = View::Create(view);
577 if (!complete_view.IsValid()) {
578 LOG_ERROR("Received %s complete with invalid packet", hci::OpCodeText(op_code).c_str());
579 return;
580 }
581 auto status = complete_view.GetStatus();
582 if (status != ErrorCode::SUCCESS) {
583 LOG_ERROR(
584 "Received %s complete with status %s",
585 hci::OpCodeText(op_code).c_str(),
586 ErrorCodeText(complete_view.GetStatus()).c_str());
587 }
588 }
589
OnCommandComplete(bluetooth::hci::CommandCompleteView view)590 void LeAddressManager::OnCommandComplete(bluetooth::hci::CommandCompleteView view) {
591 if (!view.IsValid()) {
592 LOG_ERROR("Received command complete with invalid packet");
593 return;
594 }
595 auto op_code = view.GetCommandOpCode();
596 LOG_INFO("Received command complete with op_code %s", OpCodeText(op_code).c_str());
597
598 switch (op_code) {
599 case OpCode::LE_SET_RANDOM_ADDRESS: {
600 // The command was sent before any client registered, we can make sure all the clients paused when command
601 // complete.
602 if (address_policy_ == AddressPolicy::USE_STATIC_ADDRESS) {
603 LOG_INFO("Received LE_SET_RANDOM_ADDRESS complete and Address policy is USE_STATIC_ADDRESS, return");
604 return;
605 }
606 auto complete_view = LeSetRandomAddressCompleteView::Create(view);
607 if (!complete_view.IsValid()) {
608 LOG_ERROR("Received LE_SET_RANDOM_ADDRESS complete with invalid packet");
609 } else {
610 if (complete_view.GetStatus() != ErrorCode::SUCCESS) {
611 LOG_ERROR(
612 "Received LE_SET_RANDOM_ADDRESS complete with status %s",
613 ErrorCodeText(complete_view.GetStatus()).c_str());
614 } else {
615 LOG_INFO("update random address : %s",
616 ADDRESS_TO_LOGGABLE_CSTR(cached_address_.GetAddress()));
617 le_address_ = cached_address_;
618 }
619 }
620 } break;
621
622 case OpCode::LE_SET_PRIVACY_MODE:
623 on_command_complete<LeSetPrivacyModeCompleteView>(view);
624 break;
625
626 case OpCode::LE_ADD_DEVICE_TO_RESOLVING_LIST:
627 on_command_complete<LeAddDeviceToResolvingListCompleteView>(view);
628 break;
629
630 case OpCode::LE_REMOVE_DEVICE_FROM_RESOLVING_LIST:
631 on_command_complete<LeRemoveDeviceFromResolvingListCompleteView>(view);
632 break;
633
634 case OpCode::LE_CLEAR_RESOLVING_LIST:
635 on_command_complete<LeClearResolvingListCompleteView>(view);
636 break;
637
638 case OpCode::LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST:
639 on_command_complete<LeAddDeviceToFilterAcceptListCompleteView>(view);
640 break;
641
642 case OpCode::LE_REMOVE_DEVICE_FROM_FILTER_ACCEPT_LIST:
643 on_command_complete<LeRemoveDeviceFromFilterAcceptListCompleteView>(view);
644 break;
645
646 case OpCode::LE_SET_ADDRESS_RESOLUTION_ENABLE:
647 on_command_complete<LeSetAddressResolutionEnableCompleteView>(view);
648 break;
649
650 case OpCode::LE_CLEAR_FILTER_ACCEPT_LIST:
651 on_command_complete<LeClearFilterAcceptListCompleteView>(view);
652 break;
653
654 default:
655 LOG_ERROR("Received UNSUPPORTED command %s complete", hci::OpCodeText(op_code).c_str());
656 break;
657 }
658
659 handler_->BindOnceOn(this, &LeAddressManager::check_cached_commands).Invoke();
660 }
661
check_cached_commands()662 void LeAddressManager::check_cached_commands() {
663 for (auto client : registered_clients_) {
664 if (client.second != ClientState::PAUSED && !cached_commands_.empty()) {
665 pause_registered_clients();
666 return;
667 }
668 }
669
670 if (cached_commands_.empty()) {
671 resume_registered_clients();
672 } else {
673 handle_next_command();
674 }
675 }
676
677 } // namespace hci
678 } // namespace bluetooth
679