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