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