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