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 }
155
Register(LeAddressManagerCallback * callback)156 LeAddressManager::AddressPolicy LeAddressManager::Register(LeAddressManagerCallback* callback) {
157 handler_->BindOnceOn(this, &LeAddressManager::register_client, callback).Invoke();
158 return address_policy_;
159 }
160
register_client(LeAddressManagerCallback * callback)161 void LeAddressManager::register_client(LeAddressManagerCallback* callback) {
162 registered_clients_.insert(std::pair<LeAddressManagerCallback*, ClientState>(callback, ClientState::RESUMED));
163 if (address_policy_ == AddressPolicy::POLICY_NOT_SET) {
164 LOG_INFO("address policy isn't set yet, pause clients and return");
165 pause_registered_clients();
166 return;
167 } else if (
168 address_policy_ == AddressPolicy::USE_RESOLVABLE_ADDRESS ||
169 address_policy_ == AddressPolicy::USE_NON_RESOLVABLE_ADDRESS) {
170 if (registered_clients_.size() == 1) {
171 schedule_rotate_random_address();
172 LOG_INFO("Scheduled address rotation for first client registered");
173 }
174 }
175 LOG_INFO("Client registered");
176 }
177
Unregister(LeAddressManagerCallback * callback)178 void LeAddressManager::Unregister(LeAddressManagerCallback* callback) {
179 handler_->BindOnceOn(this, &LeAddressManager::unregister_client, callback).Invoke();
180 }
181
unregister_client(LeAddressManagerCallback * callback)182 void LeAddressManager::unregister_client(LeAddressManagerCallback* callback) {
183 if (registered_clients_.find(callback) != registered_clients_.end()) {
184 if (registered_clients_.find(callback)->second == ClientState::WAITING_FOR_PAUSE) {
185 ack_pause(callback);
186 } else if (registered_clients_.find(callback)->second == ClientState::WAITING_FOR_RESUME) {
187 ack_resume(callback);
188 }
189 registered_clients_.erase(callback);
190 LOG_INFO("Client unregistered");
191 }
192 if (registered_clients_.empty() && address_rotation_alarm_ != nullptr) {
193 address_rotation_alarm_->Cancel();
194 LOG_INFO("Cancelled address rotation alarm");
195 }
196 }
197
UnregisterSync(LeAddressManagerCallback * callback,std::chrono::milliseconds timeout)198 bool LeAddressManager::UnregisterSync(LeAddressManagerCallback* callback, std::chrono::milliseconds timeout) {
199 handler_->BindOnceOn(this, &LeAddressManager::unregister_client, callback).Invoke();
200 std::promise<void> promise;
201 auto future = promise.get_future();
202 handler_->Post(common::BindOnce(&std::promise<void>::set_value, common::Unretained(&promise)));
203 return future.wait_for(timeout) == std::future_status::ready;
204 }
205
AckPause(LeAddressManagerCallback * callback)206 void LeAddressManager::AckPause(LeAddressManagerCallback* callback) {
207 handler_->BindOnceOn(this, &LeAddressManager::ack_pause, callback).Invoke();
208 }
209
AckResume(LeAddressManagerCallback * callback)210 void LeAddressManager::AckResume(LeAddressManagerCallback* callback) {
211 handler_->BindOnceOn(this, &LeAddressManager::ack_resume, callback).Invoke();
212 }
213
GetCurrentAddress()214 AddressWithType LeAddressManager::GetCurrentAddress() {
215 ASSERT(address_policy_ != AddressPolicy::POLICY_NOT_SET);
216 return le_address_;
217 }
218
GetAnotherAddress()219 AddressWithType LeAddressManager::GetAnotherAddress() {
220 ASSERT(
221 address_policy_ == AddressPolicy::USE_NON_RESOLVABLE_ADDRESS ||
222 address_policy_ == AddressPolicy::USE_RESOLVABLE_ADDRESS);
223 hci::Address address = generate_rpa();
224 auto random_address = AddressWithType(address, AddressType::RANDOM_DEVICE_ADDRESS);
225 return random_address;
226 }
227
pause_registered_clients()228 void LeAddressManager::pause_registered_clients() {
229 for (auto& client : registered_clients_) {
230 switch (client.second) {
231 case ClientState::PAUSED:
232 case ClientState::WAITING_FOR_PAUSE:
233 break;
234 case WAITING_FOR_RESUME:
235 case RESUMED:
236 client.second = ClientState::WAITING_FOR_PAUSE;
237 client.first->OnPause();
238 break;
239 }
240 }
241 }
242
push_command(Command command)243 void LeAddressManager::push_command(Command command) {
244 pause_registered_clients();
245 cached_commands_.push(std::move(command));
246 }
247
ack_pause(LeAddressManagerCallback * callback)248 void LeAddressManager::ack_pause(LeAddressManagerCallback* callback) {
249 if (registered_clients_.find(callback) == registered_clients_.end()) {
250 LOG_INFO("No clients registered to ack pause");
251 return;
252 }
253 registered_clients_.find(callback)->second = ClientState::PAUSED;
254 for (auto client : registered_clients_) {
255 switch (client.second) {
256 case ClientState::PAUSED:
257 LOG_INFO("Client already in paused state");
258 break;
259 case ClientState::WAITING_FOR_PAUSE:
260 // make sure all client paused
261 LOG_DEBUG("Wait all clients paused, return");
262 return;
263 case WAITING_FOR_RESUME:
264 case RESUMED:
265 LOG_DEBUG("Trigger OnPause for client that not paused and not waiting for pause");
266 client.second = ClientState::WAITING_FOR_PAUSE;
267 client.first->OnPause();
268 return;
269 default:
270 LOG_ERROR("Found client in unexpected state:%u", client.second);
271 }
272 }
273
274 if (address_policy_ != AddressPolicy::POLICY_NOT_SET) {
275 check_cached_commands();
276 }
277 }
278
resume_registered_clients()279 void LeAddressManager::resume_registered_clients() {
280 // Do not resume clients if cached command is not empty
281 if (!cached_commands_.empty()) {
282 handle_next_command();
283 return;
284 }
285
286 LOG_INFO("Resuming registered clients");
287 for (auto& client : registered_clients_) {
288 client.second = ClientState::WAITING_FOR_RESUME;
289 client.first->OnResume();
290 }
291 }
292
ack_resume(LeAddressManagerCallback * callback)293 void LeAddressManager::ack_resume(LeAddressManagerCallback* callback) {
294 if (registered_clients_.find(callback) != registered_clients_.end()) {
295 registered_clients_.find(callback)->second = ClientState::RESUMED;
296 }
297 }
298
prepare_to_rotate()299 void LeAddressManager::prepare_to_rotate() {
300 Command command = {CommandType::ROTATE_RANDOM_ADDRESS, RotateRandomAddressCommand{}};
301 cached_commands_.push(std::move(command));
302 pause_registered_clients();
303 }
304
schedule_rotate_random_address()305 void LeAddressManager::schedule_rotate_random_address() {
306 address_rotation_alarm_->Schedule(
307 common::BindOnce(&LeAddressManager::prepare_to_rotate, common::Unretained(this)),
308 GetNextPrivateAddressIntervalMs());
309 }
310
set_random_address()311 void LeAddressManager::set_random_address() {
312 if (address_policy_ != AddressPolicy::USE_RESOLVABLE_ADDRESS &&
313 address_policy_ != AddressPolicy::USE_NON_RESOLVABLE_ADDRESS) {
314 LOG_ALWAYS_FATAL("Invalid address policy!");
315 return;
316 }
317
318 hci::Address address;
319 if (address_policy_ == AddressPolicy::USE_RESOLVABLE_ADDRESS) {
320 address = generate_rpa();
321 } else {
322 address = generate_nrpa();
323 }
324 auto packet = hci::LeSetRandomAddressBuilder::Create(address);
325 enqueue_command_.Run(std::move(packet));
326 cached_address_ = AddressWithType(address, AddressType::RANDOM_DEVICE_ADDRESS);
327 }
328
rotate_random_address()329 void LeAddressManager::rotate_random_address() {
330 if (address_policy_ != AddressPolicy::USE_RESOLVABLE_ADDRESS &&
331 address_policy_ != AddressPolicy::USE_NON_RESOLVABLE_ADDRESS) {
332 LOG_ALWAYS_FATAL("Invalid address policy!");
333 return;
334 }
335
336 schedule_rotate_random_address();
337 set_random_address();
338 }
339
prepare_to_update_irk(UpdateIRKCommand update_irk_command)340 void LeAddressManager::prepare_to_update_irk(UpdateIRKCommand update_irk_command) {
341 Command command = {CommandType::UPDATE_IRK, update_irk_command};
342 cached_commands_.push(std::move(command));
343 if (registered_clients_.empty()) {
344 handle_next_command();
345 } else {
346 pause_registered_clients();
347 }
348 }
349
update_irk(UpdateIRKCommand command)350 void LeAddressManager::update_irk(UpdateIRKCommand command) {
351 rotation_irk_ = command.rotation_irk;
352 minimum_rotation_time_ = command.minimum_rotation_time;
353 maximum_rotation_time_ = command.maximum_rotation_time;
354 set_random_address();
355 for (auto& client : registered_clients_) {
356 client.first->NotifyOnIRKChange();
357 }
358 }
359
360 /* This function generates Resolvable Private Address (RPA) from Identity
361 * Resolving Key |irk| and |prand|*/
generate_rpa()362 hci::Address LeAddressManager::generate_rpa() {
363 // most significant bit, bit7, bit6 is 01 to be resolvable random
364 // Bits of the random part of prand shall not be all 1 or all 0
365 std::array<uint8_t, 3> prand = os::GenerateRandom<3>();
366 constexpr uint8_t BLE_RESOLVE_ADDR_MSB = 0x40;
367 prand[2] &= ~BLE_ADDR_MASK;
368 if ((prand[0] == 0x00 && prand[1] == 0x00 && prand[2] == 0x00) ||
369 (prand[0] == 0xFF && prand[1] == 0xFF && prand[2] == 0x3F)) {
370 prand[0] = (uint8_t)(os::GenerateRandom() % 0xFE + 1);
371 }
372 prand[2] |= BLE_RESOLVE_ADDR_MSB;
373
374 hci::Address address;
375 address.address[3] = prand[0];
376 address.address[4] = prand[1];
377 address.address[5] = prand[2];
378
379 /* encrypt with IRK */
380 crypto_toolbox::Octet16 p = crypto_toolbox::aes_128(rotation_irk_, prand.data(), 3);
381
382 /* set hash to be LSB of rpAddress */
383 address.address[0] = p[0];
384 address.address[1] = p[1];
385 address.address[2] = p[2];
386 return address;
387 }
388
389 // This function generates NON-Resolvable Private Address (NRPA)
generate_nrpa()390 hci::Address LeAddressManager::generate_nrpa() {
391 // The two most significant bits of the address shall be equal to 0
392 // Bits of the random part of the address shall not be all 1 or all 0
393 std::array<uint8_t, 6> random = os::GenerateRandom<6>();
394 random[5] &= ~BLE_ADDR_MASK;
395 if ((random[0] == 0x00 && random[1] == 0x00 && random[2] == 0x00 && random[3] == 0x00 && random[4] == 0x00 &&
396 random[5] == 0x00) ||
397 (random[0] == 0xFF && random[1] == 0xFF && random[2] == 0xFF && random[3] == 0xFF && random[4] == 0xFF &&
398 random[5] == 0x3F)) {
399 random[0] = (uint8_t)(os::GenerateRandom() % 0xFE + 1);
400 }
401
402 hci::Address address;
403 address.FromOctets(random.data());
404
405 // the address shall not be equal to the public address
406 while (address == public_address_) {
407 address.address[0] = (uint8_t)(os::GenerateRandom() % 0xFE + 1);
408 }
409
410 return address;
411 }
412
GetNextPrivateAddressIntervalMs()413 std::chrono::milliseconds LeAddressManager::GetNextPrivateAddressIntervalMs() {
414 auto interval_random_part_max_ms = maximum_rotation_time_ - minimum_rotation_time_;
415 auto random_ms = std::chrono::milliseconds(os::GenerateRandom()) % (interval_random_part_max_ms);
416 return minimum_rotation_time_ + random_ms;
417 }
418
GetFilterAcceptListSize()419 uint8_t LeAddressManager::GetFilterAcceptListSize() {
420 return connect_list_size_;
421 }
422
GetResolvingListSize()423 uint8_t LeAddressManager::GetResolvingListSize() {
424 return resolving_list_size_;
425 }
426
handle_next_command()427 void LeAddressManager::handle_next_command() {
428 for (auto client : registered_clients_) {
429 if (client.second != ClientState::PAUSED) {
430 // make sure all client paused, if not, this function will be trigger again by ack_pause
431 LOG_INFO("waiting for ack_pause, return");
432 return;
433 }
434 }
435
436 ASSERT(!cached_commands_.empty());
437 auto command = std::move(cached_commands_.front());
438 cached_commands_.pop();
439
440 std::visit(
441 [this](auto&& command) {
442 using T = std::decay_t<decltype(command)>;
443 if constexpr (std::is_same_v<T, UpdateIRKCommand>) {
444 update_irk(command);
445 } else if constexpr (std::is_same_v<T, RotateRandomAddressCommand>) {
446 rotate_random_address();
447 } else if constexpr (std::is_same_v<T, HCICommand>) {
448 enqueue_command_.Run(std::move(command.command));
449 } else {
450 static_assert(!sizeof(T*), "non-exhaustive visitor!");
451 }
452 },
453 command.contents);
454 }
455
AddDeviceToFilterAcceptList(FilterAcceptListAddressType connect_list_address_type,bluetooth::hci::Address address)456 void LeAddressManager::AddDeviceToFilterAcceptList(
457 FilterAcceptListAddressType connect_list_address_type, bluetooth::hci::Address address) {
458 auto packet_builder = hci::LeAddDeviceToFilterAcceptListBuilder::Create(connect_list_address_type, address);
459 Command command = {CommandType::ADD_DEVICE_TO_CONNECT_LIST, HCICommand{std::move(packet_builder)}};
460 handler_->BindOnceOn(this, &LeAddressManager::push_command, std::move(command)).Invoke();
461 }
462
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)463 void LeAddressManager::AddDeviceToResolvingList(
464 PeerAddressType peer_identity_address_type,
465 Address peer_identity_address,
466 const std::array<uint8_t, 16>& peer_irk,
467 const std::array<uint8_t, 16>& local_irk) {
468 // Disable Address resolution
469 auto disable_builder = hci::LeSetAddressResolutionEnableBuilder::Create(hci::Enable::DISABLED);
470 Command disable = {CommandType::SET_ADDRESS_RESOLUTION_ENABLE, HCICommand{std::move(disable_builder)}};
471 cached_commands_.push(std::move(disable));
472
473 auto packet_builder = hci::LeAddDeviceToResolvingListBuilder::Create(
474 peer_identity_address_type, peer_identity_address, peer_irk, local_irk);
475 Command command = {CommandType::ADD_DEVICE_TO_RESOLVING_LIST, HCICommand{std::move(packet_builder)}};
476 cached_commands_.push(std::move(command));
477
478 if (supports_ble_privacy_) {
479 auto packet_builder =
480 hci::LeSetPrivacyModeBuilder::Create(peer_identity_address_type, peer_identity_address, PrivacyMode::DEVICE);
481 Command command = {CommandType::LE_SET_PRIVACY_MODE, HCICommand{std::move(packet_builder)}};
482 cached_commands_.push(std::move(command));
483 }
484
485 // Enable Address resolution
486 auto enable_builder = hci::LeSetAddressResolutionEnableBuilder::Create(hci::Enable::ENABLED);
487 Command enable = {CommandType::SET_ADDRESS_RESOLUTION_ENABLE, HCICommand{std::move(enable_builder)}};
488 cached_commands_.push(std::move(enable));
489
490 if (registered_clients_.empty()) {
491 handler_->BindOnceOn(this, &LeAddressManager::handle_next_command).Invoke();
492 } else {
493 handler_->BindOnceOn(this, &LeAddressManager::pause_registered_clients).Invoke();
494 }
495 }
496
RemoveDeviceFromFilterAcceptList(FilterAcceptListAddressType connect_list_address_type,bluetooth::hci::Address address)497 void LeAddressManager::RemoveDeviceFromFilterAcceptList(
498 FilterAcceptListAddressType connect_list_address_type, bluetooth::hci::Address address) {
499 auto packet_builder = hci::LeRemoveDeviceFromFilterAcceptListBuilder::Create(connect_list_address_type, address);
500 Command command = {CommandType::REMOVE_DEVICE_FROM_CONNECT_LIST, HCICommand{std::move(packet_builder)}};
501 handler_->BindOnceOn(this, &LeAddressManager::push_command, std::move(command)).Invoke();
502 }
503
RemoveDeviceFromResolvingList(PeerAddressType peer_identity_address_type,Address peer_identity_address)504 void LeAddressManager::RemoveDeviceFromResolvingList(
505 PeerAddressType peer_identity_address_type, Address peer_identity_address) {
506 // Disable Address resolution
507 auto disable_builder = hci::LeSetAddressResolutionEnableBuilder::Create(hci::Enable::DISABLED);
508 Command disable = {CommandType::SET_ADDRESS_RESOLUTION_ENABLE, HCICommand{std::move(disable_builder)}};
509 cached_commands_.push(std::move(disable));
510
511 auto packet_builder =
512 hci::LeRemoveDeviceFromResolvingListBuilder::Create(peer_identity_address_type, peer_identity_address);
513 Command command = {CommandType::REMOVE_DEVICE_FROM_RESOLVING_LIST, HCICommand{std::move(packet_builder)}};
514 cached_commands_.push(std::move(command));
515
516 // Enable Address resolution
517 auto enable_builder = hci::LeSetAddressResolutionEnableBuilder::Create(hci::Enable::ENABLED);
518 Command enable = {CommandType::SET_ADDRESS_RESOLUTION_ENABLE, HCICommand{std::move(enable_builder)}};
519 cached_commands_.push(std::move(enable));
520
521 if (registered_clients_.empty()) {
522 handler_->BindOnceOn(this, &LeAddressManager::handle_next_command).Invoke();
523 } else {
524 handler_->BindOnceOn(this, &LeAddressManager::pause_registered_clients).Invoke();
525 }
526 }
527
ClearFilterAcceptList()528 void LeAddressManager::ClearFilterAcceptList() {
529 auto packet_builder = hci::LeClearFilterAcceptListBuilder::Create();
530 Command command = {CommandType::CLEAR_CONNECT_LIST, HCICommand{std::move(packet_builder)}};
531 handler_->BindOnceOn(this, &LeAddressManager::push_command, std::move(command)).Invoke();
532 }
533
ClearResolvingList()534 void LeAddressManager::ClearResolvingList() {
535 // Disable Address resolution
536 auto disable_builder = hci::LeSetAddressResolutionEnableBuilder::Create(hci::Enable::DISABLED);
537 Command disable = {CommandType::SET_ADDRESS_RESOLUTION_ENABLE, HCICommand{std::move(disable_builder)}};
538 cached_commands_.push(std::move(disable));
539
540 auto packet_builder = hci::LeClearResolvingListBuilder::Create();
541 Command command = {CommandType::CLEAR_RESOLVING_LIST, HCICommand{std::move(packet_builder)}};
542 cached_commands_.push(std::move(command));
543
544 // Enable Address resolution
545 auto enable_builder = hci::LeSetAddressResolutionEnableBuilder::Create(hci::Enable::ENABLED);
546 Command enable = {CommandType::SET_ADDRESS_RESOLUTION_ENABLE, HCICommand{std::move(enable_builder)}};
547 cached_commands_.push(std::move(enable));
548
549 handler_->BindOnceOn(this, &LeAddressManager::pause_registered_clients).Invoke();
550 }
551
552 template <class View>
on_command_complete(CommandCompleteView view)553 void LeAddressManager::on_command_complete(CommandCompleteView view) {
554 auto op_code = view.GetCommandOpCode();
555
556 auto complete_view = View::Create(view);
557 if (!complete_view.IsValid()) {
558 LOG_ERROR("Received %s complete with invalid packet", hci::OpCodeText(op_code).c_str());
559 return;
560 }
561 auto status = complete_view.GetStatus();
562 if (status != ErrorCode::SUCCESS) {
563 LOG_ERROR(
564 "Received %s complete with status %s",
565 hci::OpCodeText(op_code).c_str(),
566 ErrorCodeText(complete_view.GetStatus()).c_str());
567 }
568 }
569
OnCommandComplete(bluetooth::hci::CommandCompleteView view)570 void LeAddressManager::OnCommandComplete(bluetooth::hci::CommandCompleteView view) {
571 if (!view.IsValid()) {
572 LOG_ERROR("Received command complete with invalid packet");
573 return;
574 }
575 auto op_code = view.GetCommandOpCode();
576 LOG_INFO("Received command complete with op_code %s", OpCodeText(op_code).c_str());
577
578 switch (op_code) {
579 case OpCode::LE_SET_RANDOM_ADDRESS: {
580 // The command was sent before any client registered, we can make sure all the clients paused when command
581 // complete.
582 if (address_policy_ == AddressPolicy::USE_STATIC_ADDRESS) {
583 LOG_INFO("Received LE_SET_RANDOM_ADDRESS complete and Address policy is USE_STATIC_ADDRESS, return");
584 return;
585 }
586 auto complete_view = LeSetRandomAddressCompleteView::Create(view);
587 if (!complete_view.IsValid()) {
588 LOG_ERROR("Received LE_SET_RANDOM_ADDRESS complete with invalid packet");
589 } else {
590 if (complete_view.GetStatus() != ErrorCode::SUCCESS) {
591 LOG_ERROR(
592 "Received LE_SET_RANDOM_ADDRESS complete with status %s",
593 ErrorCodeText(complete_view.GetStatus()).c_str());
594 } else {
595 LOG_INFO("update random address : %s", cached_address_.GetAddress().ToString().c_str());
596 le_address_ = cached_address_;
597 }
598 }
599 } break;
600
601 case OpCode::LE_SET_PRIVACY_MODE:
602 on_command_complete<LeSetPrivacyModeCompleteView>(view);
603 break;
604
605 case OpCode::LE_ADD_DEVICE_TO_RESOLVING_LIST:
606 on_command_complete<LeAddDeviceToResolvingListCompleteView>(view);
607 break;
608
609 case OpCode::LE_REMOVE_DEVICE_FROM_RESOLVING_LIST:
610 on_command_complete<LeRemoveDeviceFromResolvingListCompleteView>(view);
611 break;
612
613 case OpCode::LE_CLEAR_RESOLVING_LIST:
614 on_command_complete<LeClearResolvingListCompleteView>(view);
615 break;
616
617 case OpCode::LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST:
618 on_command_complete<LeAddDeviceToFilterAcceptListCompleteView>(view);
619 break;
620
621 case OpCode::LE_REMOVE_DEVICE_FROM_FILTER_ACCEPT_LIST:
622 on_command_complete<LeRemoveDeviceFromFilterAcceptListCompleteView>(view);
623 break;
624
625 case OpCode::LE_SET_ADDRESS_RESOLUTION_ENABLE:
626 on_command_complete<LeSetAddressResolutionEnableCompleteView>(view);
627 break;
628
629 case OpCode::LE_CLEAR_FILTER_ACCEPT_LIST:
630 on_command_complete<LeClearFilterAcceptListCompleteView>(view);
631 break;
632
633 default:
634 LOG_ERROR("Received UNSUPPORTED command %s complete", hci::OpCodeText(op_code).c_str());
635 break;
636 }
637
638 handler_->BindOnceOn(this, &LeAddressManager::check_cached_commands).Invoke();
639 }
640
check_cached_commands()641 void LeAddressManager::check_cached_commands() {
642 for (auto client : registered_clients_) {
643 if (client.second != ClientState::PAUSED && !cached_commands_.empty()) {
644 pause_registered_clients();
645 return;
646 }
647 }
648
649 if (cached_commands_.empty()) {
650 resume_registered_clients();
651 } else {
652 handle_next_command();
653 }
654 }
655
656 } // namespace hci
657 } // namespace bluetooth
658