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