1 /*
2  * Copyright 2019 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 #include "hci/le_advertising_manager.h"
17 
18 #include <memory>
19 #include <mutex>
20 
21 #include "common/init_flags.h"
22 #include "common/strings.h"
23 #include "hci/acl_manager.h"
24 #include "hci/controller.h"
25 #include "hci/hci_layer.h"
26 #include "hci/hci_packets.h"
27 #include "hci/le_advertising_interface.h"
28 #include "hci/vendor_specific_event_manager.h"
29 #include "module.h"
30 #include "os/handler.h"
31 #include "os/log.h"
32 #include "os/system_properties.h"
33 
34 namespace bluetooth {
35 namespace hci {
36 
__anon5e56a3ce0102() 37 const ModuleFactory LeAdvertisingManager::Factory = ModuleFactory([]() { return new LeAdvertisingManager(); });
38 constexpr int kIdLocal = 0xff;  // Id for advertiser not register from Java layer
39 constexpr uint16_t kLenOfFlags = 0x03;
40 constexpr int64_t kLeAdvertisingTxPowerMin = -127;
41 constexpr int64_t kLeAdvertisingTxPowerMax = 20;
42 constexpr int64_t kLeTxPathLossCompMin = -128;
43 constexpr int64_t kLeTxPathLossCompMax = 127;
44 
45 // system properties
46 const std::string kLeTxPathLossCompProperty = "bluetooth.hardware.radio.le_tx_path_loss_comp_db";
47 
48 enum class AdvertisingApiType {
49   LEGACY = 1,
50   ANDROID_HCI = 2,
51   EXTENDED = 3,
52 };
53 
54 enum class AdvertisingFlag : uint8_t {
55   LE_LIMITED_DISCOVERABLE = 0x01,
56   LE_GENERAL_DISCOVERABLE = 0x02,
57   BR_EDR_NOT_SUPPORTED = 0x04,
58   SIMULTANEOUS_LE_AND_BR_EDR_CONTROLLER = 0x08,
59   SIMULTANEOUS_LE_AND_BR_EDR_HOST = 0x10,
60 };
61 
62 struct Advertiser {
63   os::Handler* handler;
64   AddressWithType current_address;
65   // note: may not be the same as the requested_address_type, depending on the address policy
66   AdvertiserAddressType address_type;
67   base::OnceCallback<void(uint8_t /* status */)> status_callback;
68   base::OnceCallback<void(uint8_t /* status */)> timeout_callback;
69   common::Callback<void(Address, AddressType)> scan_callback;
70   common::Callback<void(ErrorCode, uint8_t, uint8_t)> set_terminated_callback;
71   int8_t tx_power;
72   uint16_t duration;
73   uint8_t max_extended_advertising_events;
74   bool started = false;
75   bool connectable = false;
76   bool discoverable = false;
77   bool directed = false;
78   bool in_use = false;
79   std::unique_ptr<os::Alarm> address_rotation_alarm;
80 };
81 
82 /**
83  * Determines the address type to use, based on the requested type and the address manager policy,
84  * by selecting the "strictest" of the two. Strictness is defined in ascending order as
85  * RPA -> NRPA -> Public. Thus:
86  * (1) if the host only supports the public/static address policy, all advertisements will be public
87  * (2) if the host supports only non-resolvable addresses, then advertisements will never use RPA
88  * (3) if the host supports RPAs, then the requested type will always be honored
89  */
GetAdvertiserAddressTypeFromRequestedTypeAndPolicy(AdvertiserAddressType requested_address_type,LeAddressManager::AddressPolicy address_policy)90 AdvertiserAddressType GetAdvertiserAddressTypeFromRequestedTypeAndPolicy(
91     AdvertiserAddressType requested_address_type, LeAddressManager::AddressPolicy address_policy) {
92   switch (address_policy) {
93     case LeAddressManager::AddressPolicy::USE_PUBLIC_ADDRESS:
94     case LeAddressManager::AddressPolicy::USE_STATIC_ADDRESS:
95       return AdvertiserAddressType::PUBLIC;
96     case LeAddressManager::AddressPolicy::USE_RESOLVABLE_ADDRESS:
97       return requested_address_type;
98     case LeAddressManager::AddressPolicy::USE_NON_RESOLVABLE_ADDRESS:
99       return requested_address_type == AdvertiserAddressType::RESOLVABLE_RANDOM
100                  ? AdvertiserAddressType::NONRESOLVABLE_RANDOM
101                  : requested_address_type;
102     default:
103       LOG_ALWAYS_FATAL("unreachable");
104   }
105 }
106 
107 struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallback {
implbluetooth::hci::LeAdvertisingManager::impl108   impl(Module* module) : module_(module), le_advertising_interface_(nullptr), num_instances_(0) {}
109 
~implbluetooth::hci::LeAdvertisingManager::impl110   ~impl() {
111     if (address_manager_registered) {
112       le_address_manager_->Unregister(this);
113     }
114     advertising_sets_.clear();
115   }
116 
startbluetooth::hci::LeAdvertisingManager::impl117   void start(
118       os::Handler* handler,
119       hci::HciLayer* hci_layer,
120       hci::Controller* controller,
121       hci::AclManager* acl_manager,
122       hci::VendorSpecificEventManager* vendor_specific_event_manager) {
123     module_handler_ = handler;
124     hci_layer_ = hci_layer;
125     controller_ = controller;
126     le_maximum_advertising_data_length_ = controller_->GetLeMaximumAdvertisingDataLength();
127     acl_manager_ = acl_manager;
128     le_address_manager_ = acl_manager->GetLeAddressManager();
129     num_instances_ = controller_->GetLeNumberOfSupportedAdverisingSets();
130 
131     le_advertising_interface_ =
132         hci_layer_->GetLeAdvertisingInterface(module_handler_->BindOn(this, &LeAdvertisingManager::impl::handle_event));
133     vendor_specific_event_manager->RegisterEventHandler(
134         hci::VseSubeventCode::BLE_STCHANGE,
135         handler->BindOn(this, &LeAdvertisingManager::impl::multi_advertising_state_change));
136 
137     if (controller_->SupportsBleExtendedAdvertising()) {
138       advertising_api_type_ = AdvertisingApiType::EXTENDED;
139     } else if (controller_->IsSupported(hci::OpCode::LE_MULTI_ADVT)) {
140       advertising_api_type_ = AdvertisingApiType::ANDROID_HCI;
141       num_instances_ = controller_->GetVendorCapabilities().max_advt_instances_;
142       // number of LE_MULTI_ADVT start from 1
143       num_instances_ += 1;
144     } else {
145       advertising_api_type_ = AdvertisingApiType::LEGACY;
146       int vendor_version = os::GetAndroidVendorReleaseVersion();
147       if (vendor_version != 0 && vendor_version <= 11 && os::IsRootCanalEnabled()) {
148         LOG_INFO("LeReadAdvertisingPhysicalChannelTxPower is not supported on Android R RootCanal, default to 0");
149         le_physical_channel_tx_power_ = 0;
150       } else {
151         hci_layer_->EnqueueCommand(
152             LeReadAdvertisingPhysicalChannelTxPowerBuilder::Create(),
153             handler->BindOnceOn(this, &impl::on_read_advertising_physical_channel_tx_power));
154       }
155     }
156     enabled_sets_ = std::vector<EnabledSet>(num_instances_);
157     for (size_t i = 0; i < enabled_sets_.size(); i++) {
158       enabled_sets_[i].advertising_handle_ = kInvalidHandle;
159     }
160     le_tx_path_loss_comp_ = get_tx_path_loss_compensation();
161   }
162 
get_tx_path_loss_compensationbluetooth::hci::LeAdvertisingManager::impl163   int8_t get_tx_path_loss_compensation() {
164     int8_t compensation = 0;
165     auto compensation_prop = os::GetSystemProperty(kLeTxPathLossCompProperty);
166     if (compensation_prop) {
167       auto compensation_number = common::Int64FromString(compensation_prop.value());
168       if (compensation_number) {
169         int64_t number = compensation_number.value();
170         if (number < kLeTxPathLossCompMin || number > kLeTxPathLossCompMax) {
171           LOG_ERROR("Invalid number for tx path loss compensation: %" PRId64, number);
172         } else {
173           compensation = number;
174         }
175       }
176     }
177     LOG_INFO("Tx path loss compensation: %d", compensation);
178     return compensation;
179   }
180 
get_tx_power_after_calibrationbluetooth::hci::LeAdvertisingManager::impl181   int8_t get_tx_power_after_calibration(int8_t tx_power) {
182     if (le_tx_path_loss_comp_ == 0) {
183       return tx_power;
184     }
185     int8_t calibrated_tx_power = tx_power;
186     int64_t number = tx_power + le_tx_path_loss_comp_;
187     if (number < kLeAdvertisingTxPowerMin || number > kLeAdvertisingTxPowerMax) {
188       LOG_ERROR("Invalid number for calibrated tx power: %" PRId64, number);
189     } else {
190       calibrated_tx_power = number;
191     }
192     LOG_INFO("tx_power: %d, calibrated_tx_power: %d", tx_power, calibrated_tx_power);
193     return calibrated_tx_power;
194   }
195 
GetNumberOfAdvertisingInstancesbluetooth::hci::LeAdvertisingManager::impl196   size_t GetNumberOfAdvertisingInstances() const {
197     return num_instances_;
198   }
199 
get_advertising_api_typebluetooth::hci::LeAdvertisingManager::impl200   AdvertisingApiType get_advertising_api_type() const {
201     return advertising_api_type_;
202   }
203 
register_advertising_callbackbluetooth::hci::LeAdvertisingManager::impl204   void register_advertising_callback(AdvertisingCallback* advertising_callback) {
205     advertising_callbacks_ = advertising_callback;
206   }
207 
multi_advertising_state_changebluetooth::hci::LeAdvertisingManager::impl208   void multi_advertising_state_change(hci::VendorSpecificEventView event) {
209     auto view = hci::LEAdvertiseStateChangeEventView::Create(event);
210     ASSERT(view.IsValid());
211 
212     auto advertiser_id = view.GetAdvertisingInstance();
213 
214     LOG_INFO(
215         "Instance: 0x%x StateChangeReason: 0x%s Handle: 0x%x Address: %s",
216         advertiser_id,
217         VseStateChangeReasonText(view.GetStateChangeReason()).c_str(),
218         view.GetConnectionHandle(),
219         advertising_sets_[view.GetAdvertisingInstance()].current_address.ToString().c_str());
220 
221     if (view.GetStateChangeReason() == VseStateChangeReason::CONNECTION_RECEIVED) {
222       acl_manager_->OnAdvertisingSetTerminated(
223           ErrorCode::SUCCESS,
224           view.GetConnectionHandle(),
225           advertiser_id,
226           advertising_sets_[advertiser_id].current_address,
227           advertising_sets_[advertiser_id].discoverable);
228 
229       enabled_sets_[advertiser_id].advertising_handle_ = kInvalidHandle;
230 
231       if (!advertising_sets_[advertiser_id].directed) {
232         // TODO(250666237) calculate remaining duration and advertising events
233         LOG_INFO("Resuming advertising, since not directed");
234         enable_advertiser(advertiser_id, true, 0, 0);
235       }
236     }
237   }
238 
handle_eventbluetooth::hci::LeAdvertisingManager::impl239   void handle_event(LeMetaEventView event) {
240     switch (event.GetSubeventCode()) {
241       case hci::SubeventCode::SCAN_REQUEST_RECEIVED:
242         handle_scan_request(LeScanRequestReceivedView::Create(event));
243         break;
244       case hci::SubeventCode::ADVERTISING_SET_TERMINATED:
245         handle_set_terminated(LeAdvertisingSetTerminatedView::Create(event));
246         break;
247       default:
248         LOG_INFO("Unknown subevent in scanner %s", hci::SubeventCodeText(event.GetSubeventCode()).c_str());
249     }
250   }
251 
handle_scan_requestbluetooth::hci::LeAdvertisingManager::impl252   void handle_scan_request(LeScanRequestReceivedView event_view) {
253     if (!event_view.IsValid()) {
254       LOG_INFO("Dropping invalid scan request event");
255       return;
256     }
257     registered_handler_->Post(
258         common::BindOnce(scan_callback_, event_view.GetScannerAddress(), event_view.GetScannerAddressType()));
259   }
260 
handle_set_terminatedbluetooth::hci::LeAdvertisingManager::impl261   void handle_set_terminated(LeAdvertisingSetTerminatedView event_view) {
262     if (!event_view.IsValid()) {
263       LOG_INFO("Dropping invalid advertising event");
264       return;
265     }
266 
267     auto status = event_view.GetStatus();
268     LOG_VERBOSE(
269         "Received LE Advertising Set Terminated with status %s", ErrorCodeText(status).c_str());
270 
271     /* The Bluetooth Core 5.3 specification clearly states that this event
272      * shall not be sent when the Host disables the advertising set. So in
273      * case of HCI_ERROR_CANCELLED_BY_HOST, just ignore the event.
274      */
275     if (status == ErrorCode::OPERATION_CANCELLED_BY_HOST) {
276       LOG_WARN(
277           "Unexpected advertising set terminated event status: %s", ErrorCodeText(status).c_str());
278       return;
279     }
280 
281     uint8_t advertiser_id = event_view.GetAdvertisingHandle();
282 
283     bool was_rotating_address = false;
284     if (advertising_sets_[advertiser_id].address_rotation_alarm != nullptr) {
285       was_rotating_address = true;
286       advertising_sets_[advertiser_id].address_rotation_alarm->Cancel();
287       advertising_sets_[advertiser_id].address_rotation_alarm.reset();
288     }
289     enabled_sets_[advertiser_id].advertising_handle_ = kInvalidHandle;
290 
291     AddressWithType advertiser_address = advertising_sets_[event_view.GetAdvertisingHandle()].current_address;
292     bool is_discoverable = advertising_sets_[event_view.GetAdvertisingHandle()].discoverable;
293 
294     acl_manager_->OnAdvertisingSetTerminated(
295         status,
296         event_view.GetConnectionHandle(),
297         advertiser_id,
298         advertiser_address,
299         is_discoverable);
300 
301     if (status == ErrorCode::LIMIT_REACHED || status == ErrorCode::ADVERTISING_TIMEOUT) {
302       if (id_map_[advertiser_id] == kIdLocal) {
303         if (!advertising_sets_[advertiser_id].timeout_callback.is_null()) {
304           std::move(advertising_sets_[advertiser_id].timeout_callback).Run((uint8_t)status);
305           advertising_sets_[advertiser_id].timeout_callback.Reset();
306         }
307       } else {
308         advertising_callbacks_->OnAdvertisingEnabled(advertiser_id, false, (uint8_t)status);
309       }
310       return;
311     }
312 
313     if (!advertising_sets_[advertiser_id].directed) {
314       // TODO calculate remaining duration and advertising events
315       if (advertising_sets_[advertiser_id].duration == 0 &&
316           advertising_sets_[advertiser_id].max_extended_advertising_events == 0) {
317         LOG_INFO("Reenable advertising");
318         if (was_rotating_address) {
319           advertising_sets_[advertiser_id].address_rotation_alarm = std::make_unique<os::Alarm>(module_handler_);
320           advertising_sets_[advertiser_id].address_rotation_alarm->Schedule(
321               common::BindOnce(
322                   &impl::set_advertising_set_random_address_on_timer, common::Unretained(this), advertiser_id),
323               le_address_manager_->GetNextPrivateAddressIntervalMs());
324         }
325         enable_advertiser(advertiser_id, true, 0, 0);
326       }
327     }
328   }
329 
allocate_advertiserbluetooth::hci::LeAdvertisingManager::impl330   AdvertiserId allocate_advertiser() {
331     // number of LE_MULTI_ADVT start from 1
332     AdvertiserId id = advertising_api_type_ == AdvertisingApiType::ANDROID_HCI ? 1 : 0;
333     while (id < num_instances_ && advertising_sets_.count(id) != 0) {
334       id++;
335     }
336     if (id == num_instances_) {
337       LOG_WARN("Number of max instances %d reached", (uint16_t)num_instances_);
338       return kInvalidId;
339     }
340     advertising_sets_[id].in_use = true;
341     return id;
342   }
343 
remove_advertiserbluetooth::hci::LeAdvertisingManager::impl344   void remove_advertiser(AdvertiserId advertiser_id) {
345     stop_advertising(advertiser_id);
346     std::unique_lock lock(id_mutex_);
347     if (advertising_sets_.count(advertiser_id) == 0) {
348       return;
349     }
350     if (advertising_api_type_ == AdvertisingApiType::EXTENDED) {
351       le_advertising_interface_->EnqueueCommand(
352           hci::LeRemoveAdvertisingSetBuilder::Create(advertiser_id),
353           module_handler_->BindOnce(impl::check_status<LeRemoveAdvertisingSetCompleteView>));
354 
355       if (advertising_sets_[advertiser_id].address_rotation_alarm != nullptr) {
356         advertising_sets_[advertiser_id].address_rotation_alarm->Cancel();
357         advertising_sets_[advertiser_id].address_rotation_alarm.reset();
358       }
359     }
360     advertising_sets_.erase(advertiser_id);
361     if (advertising_sets_.empty() && address_manager_registered) {
362       le_address_manager_->Unregister(this);
363       address_manager_registered = false;
364       paused = false;
365     }
366   }
367 
368   /// Generates an address for the advertiser
new_advertiser_addressbluetooth::hci::LeAdvertisingManager::impl369   AddressWithType new_advertiser_address(AdvertiserId id) {
370     switch (advertising_sets_[id].address_type) {
371       case AdvertiserAddressType::PUBLIC:
372         if (le_address_manager_->GetAddressPolicy() ==
373             LeAddressManager::AddressPolicy::USE_STATIC_ADDRESS) {
374           return le_address_manager_->GetInitiatorAddress();
375         } else {
376           return AddressWithType(controller_->GetMacAddress(), AddressType::PUBLIC_DEVICE_ADDRESS);
377         }
378       case AdvertiserAddressType::RESOLVABLE_RANDOM:
379         if (advertising_api_type_ == AdvertisingApiType::LEGACY) {
380           // we reuse the initiator address if we are a legacy advertiser using privacy,
381           // since there's no way to use a different address
382           return le_address_manager_->GetInitiatorAddress();
383         }
384         return le_address_manager_->NewResolvableAddress();
385       case AdvertiserAddressType::NONRESOLVABLE_RANDOM:
386         return le_address_manager_->NewNonResolvableAddress();
387       default:
388         LOG_ALWAYS_FATAL("unreachable");
389     }
390   }
391 
create_advertiserbluetooth::hci::LeAdvertisingManager::impl392   void create_advertiser(
393       int reg_id,
394       const AdvertisingConfig config,
395       common::Callback<void(Address, AddressType)> scan_callback,
396       common::Callback<void(ErrorCode, uint8_t, uint8_t)> set_terminated_callback,
397       os::Handler* handler) {
398     AdvertiserId id = allocate_advertiser();
399     if (id == kInvalidId) {
400       LOG_WARN("Number of max instances reached");
401       start_advertising_fail(reg_id, AdvertisingCallback::AdvertisingStatus::TOO_MANY_ADVERTISERS);
402       return;
403     }
404 
405     create_advertiser_with_id(reg_id, id, config, scan_callback, set_terminated_callback, handler);
406   }
407 
create_advertiser_with_idbluetooth::hci::LeAdvertisingManager::impl408   void create_advertiser_with_id(
409       int reg_id,
410       AdvertiserId id,
411       const AdvertisingConfig config,
412       common::Callback<void(Address, AddressType)> scan_callback,
413       common::Callback<void(ErrorCode, uint8_t, uint8_t)> set_terminated_callback,
414       os::Handler* handler) {
415     // check advertising data is valid before start advertising
416     if (!check_advertising_data(config.advertisement, config.connectable && config.discoverable) ||
417         !check_advertising_data(config.scan_response, false)) {
418       advertising_callbacks_->OnAdvertisingSetStarted(
419           reg_id, id, le_physical_channel_tx_power_, AdvertisingCallback::AdvertisingStatus::DATA_TOO_LARGE);
420       return;
421     }
422 
423     id_map_[id] = reg_id;
424     advertising_sets_[id].scan_callback = scan_callback;
425     advertising_sets_[id].set_terminated_callback = set_terminated_callback;
426     advertising_sets_[id].handler = handler;
427 
428     if (!address_manager_registered) {
429       le_address_manager_->Register(this);
430       address_manager_registered = true;
431     }
432 
433     advertising_sets_[id].address_type = GetAdvertiserAddressTypeFromRequestedTypeAndPolicy(
434         config.requested_advertiser_address_type, le_address_manager_->GetAddressPolicy());
435 
436     advertising_sets_[id].current_address = new_advertiser_address(id);
437     set_parameters(id, config);
438 
439     switch (advertising_api_type_) {
440       case (AdvertisingApiType::LEGACY): {
441         if (config.advertising_type == AdvertisingType::ADV_IND ||
442             config.advertising_type == AdvertisingType::ADV_NONCONN_IND) {
443           set_data(id, true, config.scan_response);
444         }
445         set_data(id, false, config.advertisement);
446         if (!paused) {
447           enable_advertiser(id, true, 0, 0);
448         } else {
449           enabled_sets_[id].advertising_handle_ = id;
450         }
451       } break;
452       case (AdvertisingApiType::ANDROID_HCI): {
453         if (config.advertising_type == AdvertisingType::ADV_IND ||
454             config.advertising_type == AdvertisingType::ADV_NONCONN_IND) {
455           set_data(id, true, config.scan_response);
456         }
457         set_data(id, false, config.advertisement);
458         if (advertising_sets_[id].address_type != AdvertiserAddressType::PUBLIC) {
459           le_advertising_interface_->EnqueueCommand(
460               hci::LeMultiAdvtSetRandomAddrBuilder::Create(advertising_sets_[id].current_address.GetAddress(), id),
461               module_handler_->BindOnce(impl::check_status<LeMultiAdvtCompleteView>));
462         }
463         if (!paused) {
464           enable_advertiser(id, true, 0, 0);
465         } else {
466           enabled_sets_[id].advertising_handle_ = id;
467         }
468       } break;
469       case (AdvertisingApiType::EXTENDED): {
470         LOG_WARN("Unexpected AdvertisingApiType EXTENDED");
471       } break;
472     }
473   }
474 
start_advertisingbluetooth::hci::LeAdvertisingManager::impl475   void start_advertising(
476       AdvertiserId id,
477       const AdvertisingConfig config,
478       uint16_t duration,
479       base::OnceCallback<void(uint8_t /* status */)> status_callback,
480       base::OnceCallback<void(uint8_t /* status */)> timeout_callback,
481       const common::Callback<void(Address, AddressType)> scan_callback,
482       const common::Callback<void(ErrorCode, uint8_t, uint8_t)> set_terminated_callback,
483       os::Handler* handler) {
484     advertising_sets_[id].status_callback = std::move(status_callback);
485     advertising_sets_[id].timeout_callback = std::move(timeout_callback);
486 
487     create_extended_advertiser_with_id(
488         kIdLocal, id, config, scan_callback, set_terminated_callback, duration, 0, handler);
489   }
490 
create_extended_advertiserbluetooth::hci::LeAdvertisingManager::impl491   void create_extended_advertiser(
492       int reg_id,
493       const AdvertisingConfig config,
494       common::Callback<void(Address, AddressType)> scan_callback,
495       common::Callback<void(ErrorCode, uint8_t, uint8_t)> set_terminated_callback,
496       uint16_t duration,
497       uint8_t max_ext_adv_events,
498       os::Handler* handler) {
499     AdvertiserId id = allocate_advertiser();
500     if (id == kInvalidId) {
501       LOG_WARN("Number of max instances reached");
502       start_advertising_fail(reg_id, AdvertisingCallback::AdvertisingStatus::TOO_MANY_ADVERTISERS);
503       return;
504     }
505     create_extended_advertiser_with_id(
506         reg_id,
507         id,
508         config,
509         scan_callback,
510         set_terminated_callback,
511         duration,
512         max_ext_adv_events,
513         handler);
514   }
515 
create_extended_advertiser_with_idbluetooth::hci::LeAdvertisingManager::impl516   void create_extended_advertiser_with_id(
517       int reg_id,
518       AdvertiserId id,
519       const AdvertisingConfig config,
520       common::Callback<void(Address, AddressType)> scan_callback,
521       common::Callback<void(ErrorCode, uint8_t, uint8_t)> set_terminated_callback,
522       uint16_t duration,
523       uint8_t max_ext_adv_events,
524       os::Handler* handler) {
525     id_map_[id] = reg_id;
526 
527     if (advertising_api_type_ != AdvertisingApiType::EXTENDED) {
528       create_advertiser_with_id(
529           reg_id, id, config, scan_callback, set_terminated_callback, handler);
530       return;
531     }
532 
533     // check extended advertising data is valid before start advertising
534     if (!check_extended_advertising_data(
535             config.advertisement, config.connectable && config.discoverable) ||
536         !check_extended_advertising_data(config.scan_response, false)) {
537       advertising_callbacks_->OnAdvertisingSetStarted(
538           reg_id, id, le_physical_channel_tx_power_, AdvertisingCallback::AdvertisingStatus::DATA_TOO_LARGE);
539       return;
540     }
541 
542     if (!address_manager_registered) {
543       le_address_manager_->Register(this);
544       address_manager_registered = true;
545     }
546 
547     advertising_sets_[id].scan_callback = scan_callback;
548     advertising_sets_[id].set_terminated_callback = set_terminated_callback;
549     advertising_sets_[id].duration = duration;
550     advertising_sets_[id].max_extended_advertising_events = max_ext_adv_events;
551     advertising_sets_[id].handler = handler;
552     advertising_sets_[id].address_type = GetAdvertiserAddressTypeFromRequestedTypeAndPolicy(
553         config.requested_advertiser_address_type, le_address_manager_->GetAddressPolicy());
554     advertising_sets_[id].current_address = new_advertiser_address(id);
555 
556     set_parameters(id, config);
557 
558     if (advertising_sets_[id].current_address.GetAddressType() !=
559         AddressType::PUBLIC_DEVICE_ADDRESS) {
560       // if we aren't using the public address type at the HCI level, we need to set the random
561       // address
562       le_advertising_interface_->EnqueueCommand(
563           hci::LeSetAdvertisingSetRandomAddressBuilder::Create(
564               id, advertising_sets_[id].current_address.GetAddress()),
565           module_handler_->BindOnceOn(
566               this,
567               &impl::on_set_advertising_set_random_address_complete<
568                   LeSetAdvertisingSetRandomAddressCompleteView>,
569               id,
570               advertising_sets_[id].current_address));
571 
572       // but we only rotate if the AdvertiserAddressType is non-public (since static random
573       // addresses don't rotate)
574       if (advertising_sets_[id].address_type != AdvertiserAddressType::PUBLIC) {
575         // start timer for random address
576         advertising_sets_[id].address_rotation_alarm = std::make_unique<os::Alarm>(module_handler_);
577         advertising_sets_[id].address_rotation_alarm->Schedule(
578             common::BindOnce(
579                 &impl::set_advertising_set_random_address_on_timer, common::Unretained(this), id),
580             le_address_manager_->GetNextPrivateAddressIntervalMs());
581       }
582     }
583     if (config.advertising_type == AdvertisingType::ADV_IND ||
584         config.advertising_type == AdvertisingType::ADV_NONCONN_IND) {
585       set_data(id, true, config.scan_response);
586     }
587     set_data(id, false, config.advertisement);
588 
589     if (!config.periodic_data.empty()) {
590       set_periodic_parameter(id, config.periodic_advertising_parameters);
591       set_periodic_data(id, config.periodic_data);
592       enable_periodic_advertising(
593           id, config.periodic_advertising_parameters.enable, config.periodic_advertising_parameters.include_adi);
594     }
595 
596     if (!paused) {
597       enable_advertiser(id, true, duration, max_ext_adv_events);
598     } else {
599       EnabledSet curr_set;
600       curr_set.advertising_handle_ = id;
601       curr_set.duration_ = duration;
602       curr_set.max_extended_advertising_events_ = max_ext_adv_events;
603       std::vector<EnabledSet> enabled_sets = {curr_set};
604       enabled_sets_[id] = curr_set;
605     }
606   }
607 
stop_advertisingbluetooth::hci::LeAdvertisingManager::impl608   void stop_advertising(AdvertiserId advertiser_id) {
609     if (advertising_sets_.find(advertiser_id) == advertising_sets_.end()) {
610       LOG_INFO("Unknown advertising set %u", advertiser_id);
611       return;
612     }
613     EnabledSet curr_set;
614     curr_set.advertising_handle_ = advertiser_id;
615     std::vector<EnabledSet> enabled_vector{curr_set};
616 
617     // If advertising or periodic advertising on the advertising set is enabled,
618     // then the Controller will return the error code Command Disallowed (0x0C).
619     // Thus, we should disable it before removing it.
620     switch (advertising_api_type_) {
621       case (AdvertisingApiType::LEGACY):
622         le_advertising_interface_->EnqueueCommand(
623             hci::LeSetAdvertisingEnableBuilder::Create(Enable::DISABLED),
624             module_handler_->BindOnce(impl::check_status<LeSetAdvertisingEnableCompleteView>));
625         break;
626       case (AdvertisingApiType::ANDROID_HCI):
627         le_advertising_interface_->EnqueueCommand(
628             hci::LeMultiAdvtSetEnableBuilder::Create(Enable::DISABLED, advertiser_id),
629             module_handler_->BindOnce(impl::check_status<LeMultiAdvtCompleteView>));
630         break;
631       case (AdvertisingApiType::EXTENDED): {
632         le_advertising_interface_->EnqueueCommand(
633             hci::LeSetExtendedAdvertisingEnableBuilder::Create(Enable::DISABLED, enabled_vector),
634             module_handler_->BindOnce(impl::check_status<LeSetExtendedAdvertisingEnableCompleteView>));
635 
636         // Only set periodic advertising if supported.
637         if (controller_->SupportsBlePeriodicAdvertising()) {
638           le_advertising_interface_->EnqueueCommand(
639               hci::LeSetPeriodicAdvertisingEnableBuilder::Create(false, false, advertiser_id),
640               module_handler_->BindOnce(
641                   impl::check_status<LeSetPeriodicAdvertisingEnableCompleteView>));
642         }
643       } break;
644     }
645 
646     std::unique_lock lock(id_mutex_);
647     enabled_sets_[advertiser_id].advertising_handle_ = kInvalidHandle;
648   }
649 
rotate_advertiser_addressbluetooth::hci::LeAdvertisingManager::impl650   void rotate_advertiser_address(AdvertiserId advertiser_id) {
651     if (advertising_api_type_ == AdvertisingApiType::EXTENDED) {
652       AddressWithType address_with_type = new_advertiser_address(advertiser_id);
653       le_advertising_interface_->EnqueueCommand(
654           hci::LeSetAdvertisingSetRandomAddressBuilder::Create(advertiser_id, address_with_type.GetAddress()),
655           module_handler_->BindOnceOn(
656               this,
657               &impl::on_set_advertising_set_random_address_complete<LeSetAdvertisingSetRandomAddressCompleteView>,
658               advertiser_id,
659               address_with_type));
660     }
661   }
662 
set_advertising_set_random_address_on_timerbluetooth::hci::LeAdvertisingManager::impl663   void set_advertising_set_random_address_on_timer(AdvertiserId advertiser_id) {
664     // This function should only be trigger by enabled advertising set or IRK rotation
665     if (enabled_sets_[advertiser_id].advertising_handle_ == kInvalidHandle) {
666       if (advertising_sets_[advertiser_id].address_rotation_alarm != nullptr) {
667         advertising_sets_[advertiser_id].address_rotation_alarm->Cancel();
668         advertising_sets_[advertiser_id].address_rotation_alarm.reset();
669       }
670       return;
671     }
672 
673     // TODO handle duration and max_extended_advertising_events_
674     EnabledSet curr_set;
675     curr_set.advertising_handle_ = advertiser_id;
676     curr_set.duration_ = advertising_sets_[advertiser_id].duration;
677     curr_set.max_extended_advertising_events_ = advertising_sets_[advertiser_id].max_extended_advertising_events;
678     std::vector<EnabledSet> enabled_sets = {curr_set};
679 
680     // For connectable advertising, we should disable it first
681     if (advertising_sets_[advertiser_id].connectable) {
682       le_advertising_interface_->EnqueueCommand(
683           hci::LeSetExtendedAdvertisingEnableBuilder::Create(Enable::DISABLED, enabled_sets),
684           module_handler_->BindOnce(impl::check_status<LeSetExtendedAdvertisingEnableCompleteView>));
685     }
686 
687     rotate_advertiser_address(advertiser_id);
688 
689     // If we are paused, we will be enabled in OnResume(), so don't resume now.
690     // Note that OnResume() can never re-enable us while we are changing our address, since the
691     // DISABLED and ENABLED commands are enqueued synchronously, so OnResume() doesn't need an
692     // analogous check.
693     if (advertising_sets_[advertiser_id].connectable && !paused) {
694       le_advertising_interface_->EnqueueCommand(
695           hci::LeSetExtendedAdvertisingEnableBuilder::Create(Enable::ENABLED, enabled_sets),
696           module_handler_->BindOnce(impl::check_status<LeSetExtendedAdvertisingEnableCompleteView>));
697     }
698 
699     advertising_sets_[advertiser_id].address_rotation_alarm->Schedule(
700         common::BindOnce(&impl::set_advertising_set_random_address_on_timer, common::Unretained(this), advertiser_id),
701         le_address_manager_->GetNextPrivateAddressIntervalMs());
702   }
703 
register_advertiserbluetooth::hci::LeAdvertisingManager::impl704   void register_advertiser(
705       common::ContextualOnceCallback<void(uint8_t /* inst_id */, uint8_t /* status */)> callback) {
706     AdvertiserId id = allocate_advertiser();
707     if (id == kInvalidId) {
708       callback.Invoke(kInvalidId, AdvertisingCallback::AdvertisingStatus::TOO_MANY_ADVERTISERS);
709     } else {
710       callback.Invoke(id, AdvertisingCallback::AdvertisingStatus::SUCCESS);
711     }
712   }
713 
get_own_addressbluetooth::hci::LeAdvertisingManager::impl714   void get_own_address(AdvertiserId advertiser_id) {
715     if (advertising_sets_.find(advertiser_id) == advertising_sets_.end()) {
716       LOG_INFO("Unknown advertising id %u", advertiser_id);
717       return;
718     }
719     auto current_address = advertising_sets_[advertiser_id].current_address;
720     advertising_callbacks_->OnOwnAddressRead(
721         advertiser_id, static_cast<uint8_t>(current_address.GetAddressType()), current_address.GetAddress());
722   }
723 
set_parametersbluetooth::hci::LeAdvertisingManager::impl724   void set_parameters(AdvertiserId advertiser_id, AdvertisingConfig config) {
725     config.tx_power = get_tx_power_after_calibration(static_cast<int8_t>(config.tx_power));
726     advertising_sets_[advertiser_id].connectable = config.connectable;
727     advertising_sets_[advertiser_id].discoverable = config.discoverable;
728     advertising_sets_[advertiser_id].tx_power = config.tx_power;
729     advertising_sets_[advertiser_id].directed = config.directed;
730 
731     // based on logic in new_advertiser_address
732     auto own_address_type = static_cast<OwnAddressType>(
733         advertising_sets_[advertiser_id].current_address.GetAddressType());
734 
735     switch (advertising_api_type_) {
736       case (AdvertisingApiType::LEGACY): {
737         le_advertising_interface_->EnqueueCommand(
738             hci::LeSetAdvertisingParametersBuilder::Create(
739                 config.interval_min,
740                 config.interval_max,
741                 config.advertising_type,
742                 own_address_type,
743                 config.peer_address_type,
744                 config.peer_address,
745                 config.channel_map,
746                 config.filter_policy),
747             module_handler_->BindOnceOn(
748                 this,
749                 &impl::check_status_with_id<LeSetAdvertisingParametersCompleteView>,
750                 advertiser_id));
751       } break;
752       case (AdvertisingApiType::ANDROID_HCI): {
753         le_advertising_interface_->EnqueueCommand(
754             hci::LeMultiAdvtParamBuilder::Create(
755                 config.interval_min,
756                 config.interval_max,
757                 config.advertising_type,
758                 own_address_type,
759                 advertising_sets_[advertiser_id].current_address.GetAddress(),
760                 config.peer_address_type,
761                 config.peer_address,
762                 config.channel_map,
763                 config.filter_policy,
764                 advertiser_id,
765                 config.tx_power),
766             module_handler_->BindOnceOn(this, &impl::check_status_with_id<LeMultiAdvtCompleteView>, advertiser_id));
767       } break;
768       case (AdvertisingApiType::EXTENDED): {
769         // sid must be in range 0x00 to 0x0F. Since no controller supports more than
770         // 16 advertisers, it's safe to make sid equal to id.
771         config.sid = advertiser_id % kAdvertisingSetIdMask;
772 
773         if (config.legacy_pdus) {
774           LegacyAdvertisingEventProperties legacy_properties = LegacyAdvertisingEventProperties::ADV_IND;
775           if (config.connectable && config.directed) {
776             if (config.high_duty_directed_connectable) {
777               legacy_properties = LegacyAdvertisingEventProperties::ADV_DIRECT_IND_HIGH;
778             } else {
779               legacy_properties = LegacyAdvertisingEventProperties::ADV_DIRECT_IND_LOW;
780             }
781           }
782           if (config.scannable && !config.connectable) {
783             legacy_properties = LegacyAdvertisingEventProperties::ADV_SCAN_IND;
784           }
785           if (!config.scannable && !config.connectable) {
786             legacy_properties = LegacyAdvertisingEventProperties::ADV_NONCONN_IND;
787           }
788 
789           le_advertising_interface_->EnqueueCommand(
790               LeSetExtendedAdvertisingParametersLegacyBuilder::Create(
791                   advertiser_id,
792                   legacy_properties,
793                   config.interval_min,
794                   config.interval_max,
795                   config.channel_map,
796                   own_address_type,
797                   config.peer_address_type,
798                   config.peer_address,
799                   config.filter_policy,
800                   config.tx_power,
801                   config.sid,
802                   config.enable_scan_request_notifications),
803               module_handler_->BindOnceOn(
804                   this,
805                   &impl::on_set_extended_advertising_parameters_complete<
806                       LeSetExtendedAdvertisingParametersCompleteView>,
807                   advertiser_id));
808         } else {
809           AdvertisingEventProperties extended_properties;
810           extended_properties.connectable_ = config.connectable;
811           extended_properties.scannable_ = config.scannable;
812           extended_properties.directed_ = config.directed;
813           extended_properties.high_duty_cycle_ = config.high_duty_directed_connectable;
814           extended_properties.legacy_ = false;
815           extended_properties.anonymous_ = config.anonymous;
816           extended_properties.tx_power_ = config.include_tx_power;
817 
818           le_advertising_interface_->EnqueueCommand(
819               hci::LeSetExtendedAdvertisingParametersBuilder::Create(
820                   advertiser_id,
821                   extended_properties,
822                   config.interval_min,
823                   config.interval_max,
824                   config.channel_map,
825                   own_address_type,
826                   config.peer_address_type,
827                   config.peer_address,
828                   config.filter_policy,
829                   config.tx_power,
830                   (config.use_le_coded_phy ? PrimaryPhyType::LE_CODED : PrimaryPhyType::LE_1M),
831                   config.secondary_max_skip,
832                   config.secondary_advertising_phy,
833                   config.sid,
834                   config.enable_scan_request_notifications),
835               module_handler_->BindOnceOn(
836                   this,
837                   &impl::on_set_extended_advertising_parameters_complete<
838                       LeSetExtendedAdvertisingParametersCompleteView>,
839                   advertiser_id));
840         }
841       } break;
842     }
843   }
844 
data_has_flagsbluetooth::hci::LeAdvertisingManager::impl845   bool data_has_flags(std::vector<GapData> data) {
846     for (auto& gap_data : data) {
847       if (gap_data.data_type_ == GapDataType::FLAGS) {
848         return true;
849       }
850     }
851     return false;
852   }
853 
check_advertising_databluetooth::hci::LeAdvertisingManager::impl854   bool check_advertising_data(std::vector<GapData> data, bool include_flag) {
855     uint16_t data_len = 0;
856     // check data size
857     for (size_t i = 0; i < data.size(); i++) {
858       data_len += data[i].size();
859     }
860 
861     // The Flags data type shall be included when any of the Flag bits are non-zero and the
862     // advertising packet is connectable and discoverable. It will be added by set_data() function,
863     // we should count it here.
864     if (include_flag && !data_has_flags(data)) {
865       data_len += kLenOfFlags;
866     }
867 
868     if (data_len > le_maximum_advertising_data_length_) {
869       LOG_WARN(
870           "advertising data len %d exceeds le_maximum_advertising_data_length_ %d",
871           data_len,
872           le_maximum_advertising_data_length_);
873       return false;
874     }
875     return true;
876   };
877 
check_extended_advertising_databluetooth::hci::LeAdvertisingManager::impl878   bool check_extended_advertising_data(std::vector<GapData> data, bool include_flag) {
879     uint16_t data_len = 0;
880     // check data size
881     for (size_t i = 0; i < data.size(); i++) {
882       if (data[i].size() > kLeMaximumFragmentLength) {
883         LOG_WARN("AD data len shall not greater than %d", kLeMaximumFragmentLength);
884         return false;
885       }
886       data_len += data[i].size();
887     }
888 
889     // The Flags data type shall be included when any of the Flag bits are non-zero and the
890     // advertising packet is connectable and discoverable. It will be added by set_data() function,
891     // we should count it here.
892     if (include_flag && !data_has_flags(data)) {
893       data_len += kLenOfFlags;
894     }
895 
896     if (data_len > le_maximum_advertising_data_length_) {
897       LOG_WARN(
898           "advertising data len %d exceeds le_maximum_advertising_data_length_ %d",
899           data_len,
900           le_maximum_advertising_data_length_);
901       return false;
902     }
903     return true;
904   };
905 
set_databluetooth::hci::LeAdvertisingManager::impl906   void set_data(AdvertiserId advertiser_id, bool set_scan_rsp, std::vector<GapData> data) {
907     // The Flags data type shall be included when any of the Flag bits are non-zero and the
908     // advertising packet is connectable and discoverable.
909     if (!set_scan_rsp && advertising_sets_[advertiser_id].connectable &&
910         advertising_sets_[advertiser_id].discoverable && !data_has_flags(data)) {
911       GapData gap_data;
912       gap_data.data_type_ = GapDataType::FLAGS;
913       if (advertising_sets_[advertiser_id].duration == 0) {
914         gap_data.data_.push_back(static_cast<uint8_t>(AdvertisingFlag::LE_GENERAL_DISCOVERABLE));
915       } else {
916         gap_data.data_.push_back(static_cast<uint8_t>(AdvertisingFlag::LE_LIMITED_DISCOVERABLE));
917       }
918       data.insert(data.begin(), gap_data);
919     }
920 
921     // Find and fill TX Power with the correct value.
922     for (auto& gap_data : data) {
923       if (gap_data.data_type_ == GapDataType::TX_POWER_LEVEL) {
924         gap_data.data_[0] = advertising_sets_[advertiser_id].tx_power;
925         break;
926       }
927     }
928 
929     if (advertising_api_type_ != AdvertisingApiType::EXTENDED && !check_advertising_data(data, false)) {
930       if (set_scan_rsp) {
931         advertising_callbacks_->OnScanResponseDataSet(
932             advertiser_id, AdvertisingCallback::AdvertisingStatus::DATA_TOO_LARGE);
933       } else {
934         advertising_callbacks_->OnAdvertisingDataSet(
935             advertiser_id, AdvertisingCallback::AdvertisingStatus::DATA_TOO_LARGE);
936       }
937       return;
938     }
939 
940     switch (advertising_api_type_) {
941       case (AdvertisingApiType::LEGACY): {
942         if (set_scan_rsp) {
943           le_advertising_interface_->EnqueueCommand(
944               hci::LeSetScanResponseDataBuilder::Create(data),
945               module_handler_->BindOnceOn(
946                   this, &impl::check_status_with_id<LeSetScanResponseDataCompleteView>, advertiser_id));
947         } else {
948           le_advertising_interface_->EnqueueCommand(
949               hci::LeSetAdvertisingDataBuilder::Create(data),
950               module_handler_->BindOnceOn(
951                   this, &impl::check_status_with_id<LeSetAdvertisingDataCompleteView>, advertiser_id));
952         }
953       } break;
954       case (AdvertisingApiType::ANDROID_HCI): {
955         if (set_scan_rsp) {
956           le_advertising_interface_->EnqueueCommand(
957               hci::LeMultiAdvtSetScanRespBuilder::Create(data, advertiser_id),
958               module_handler_->BindOnceOn(this, &impl::check_status_with_id<LeMultiAdvtCompleteView>, advertiser_id));
959         } else {
960           le_advertising_interface_->EnqueueCommand(
961               hci::LeMultiAdvtSetDataBuilder::Create(data, advertiser_id),
962               module_handler_->BindOnceOn(this, &impl::check_status_with_id<LeMultiAdvtCompleteView>, advertiser_id));
963         }
964       } break;
965       case (AdvertisingApiType::EXTENDED): {
966         uint16_t data_len = 0;
967         // check data size
968         for (size_t i = 0; i < data.size(); i++) {
969           if (data[i].size() > kLeMaximumFragmentLength) {
970             LOG_WARN("AD data len shall not greater than %d", kLeMaximumFragmentLength);
971             if (advertising_callbacks_ != nullptr) {
972               if (set_scan_rsp) {
973                 advertising_callbacks_->OnScanResponseDataSet(
974                     advertiser_id, AdvertisingCallback::AdvertisingStatus::INTERNAL_ERROR);
975               } else {
976                 advertising_callbacks_->OnAdvertisingDataSet(
977                     advertiser_id, AdvertisingCallback::AdvertisingStatus::INTERNAL_ERROR);
978               }
979             }
980             return;
981           }
982           data_len += data[i].size();
983         }
984 
985         if (data_len > le_maximum_advertising_data_length_) {
986           LOG_WARN(
987               "advertising data len exceeds le_maximum_advertising_data_length_ %d",
988               le_maximum_advertising_data_length_);
989           if (advertising_callbacks_ != nullptr) {
990             if (set_scan_rsp) {
991               advertising_callbacks_->OnScanResponseDataSet(
992                   advertiser_id, AdvertisingCallback::AdvertisingStatus::DATA_TOO_LARGE);
993             } else {
994               advertising_callbacks_->OnAdvertisingDataSet(
995                   advertiser_id, AdvertisingCallback::AdvertisingStatus::DATA_TOO_LARGE);
996             }
997           }
998           return;
999         }
1000 
1001         if (data_len <= kLeMaximumFragmentLength) {
1002           send_data_fragment(advertiser_id, set_scan_rsp, data, Operation::COMPLETE_ADVERTISEMENT);
1003         } else {
1004           std::vector<GapData> sub_data;
1005           uint16_t sub_data_len = 0;
1006           Operation operation = Operation::FIRST_FRAGMENT;
1007 
1008           for (size_t i = 0; i < data.size(); i++) {
1009             if (sub_data_len + data[i].size() > kLeMaximumFragmentLength) {
1010               send_data_fragment(advertiser_id, set_scan_rsp, sub_data, operation);
1011               operation = Operation::INTERMEDIATE_FRAGMENT;
1012               sub_data_len = 0;
1013               sub_data.clear();
1014             }
1015             sub_data.push_back(data[i]);
1016             sub_data_len += data[i].size();
1017           }
1018           send_data_fragment(advertiser_id, set_scan_rsp, sub_data, Operation::LAST_FRAGMENT);
1019         }
1020       } break;
1021     }
1022   }
1023 
send_data_fragmentbluetooth::hci::LeAdvertisingManager::impl1024   void send_data_fragment(
1025       AdvertiserId advertiser_id, bool set_scan_rsp, std::vector<GapData> data, Operation operation) {
1026     if (operation == Operation::COMPLETE_ADVERTISEMENT || operation == Operation::LAST_FRAGMENT) {
1027       if (set_scan_rsp) {
1028         le_advertising_interface_->EnqueueCommand(
1029             hci::LeSetExtendedScanResponseDataBuilder::Create(advertiser_id, operation, kFragment_preference, data),
1030             module_handler_->BindOnceOn(
1031                 this, &impl::check_status_with_id<LeSetExtendedScanResponseDataCompleteView>, advertiser_id));
1032       } else {
1033         le_advertising_interface_->EnqueueCommand(
1034             hci::LeSetExtendedAdvertisingDataBuilder::Create(advertiser_id, operation, kFragment_preference, data),
1035             module_handler_->BindOnceOn(
1036                 this, &impl::check_status_with_id<LeSetExtendedAdvertisingDataCompleteView>, advertiser_id));
1037       }
1038     } else {
1039       // For first and intermediate fragment, do not trigger advertising_callbacks_.
1040       if (set_scan_rsp) {
1041         le_advertising_interface_->EnqueueCommand(
1042             hci::LeSetExtendedScanResponseDataBuilder::Create(advertiser_id, operation, kFragment_preference, data),
1043             module_handler_->BindOnce(impl::check_status<LeSetExtendedScanResponseDataCompleteView>));
1044       } else {
1045         le_advertising_interface_->EnqueueCommand(
1046             hci::LeSetExtendedAdvertisingDataBuilder::Create(advertiser_id, operation, kFragment_preference, data),
1047             module_handler_->BindOnce(impl::check_status<LeSetExtendedAdvertisingDataCompleteView>));
1048       }
1049     }
1050   }
1051 
enable_advertiserbluetooth::hci::LeAdvertisingManager::impl1052   void enable_advertiser(
1053       AdvertiserId advertiser_id, bool enable, uint16_t duration, uint8_t max_extended_advertising_events) {
1054     EnabledSet curr_set;
1055     curr_set.advertising_handle_ = advertiser_id;
1056     curr_set.duration_ = duration;
1057     curr_set.max_extended_advertising_events_ = max_extended_advertising_events;
1058     std::vector<EnabledSet> enabled_sets = {curr_set};
1059     Enable enable_value = enable ? Enable::ENABLED : Enable::DISABLED;
1060 
1061     if (!advertising_sets_.count(advertiser_id)) {
1062       LOG_WARN("No advertising set with key: %d", advertiser_id);
1063       return;
1064     }
1065 
1066     switch (advertising_api_type_) {
1067       case (AdvertisingApiType::LEGACY): {
1068         le_advertising_interface_->EnqueueCommand(
1069             hci::LeSetAdvertisingEnableBuilder::Create(enable_value),
1070             module_handler_->BindOnceOn(
1071                 this,
1072                 &impl::on_set_advertising_enable_complete<LeSetAdvertisingEnableCompleteView>,
1073                 enable,
1074                 enabled_sets,
1075                 true /* trigger callbacks */));
1076       } break;
1077       case (AdvertisingApiType::ANDROID_HCI): {
1078         le_advertising_interface_->EnqueueCommand(
1079             hci::LeMultiAdvtSetEnableBuilder::Create(enable_value, advertiser_id),
1080             module_handler_->BindOnceOn(
1081                 this,
1082                 &impl::on_set_advertising_enable_complete<LeMultiAdvtCompleteView>,
1083                 enable,
1084                 enabled_sets,
1085                 true /* trigger callbacks */));
1086       } break;
1087       case (AdvertisingApiType::EXTENDED): {
1088         le_advertising_interface_->EnqueueCommand(
1089             hci::LeSetExtendedAdvertisingEnableBuilder::Create(enable_value, enabled_sets),
1090             module_handler_->BindOnceOn(
1091                 this,
1092                 &impl::on_set_extended_advertising_enable_complete<
1093                     LeSetExtendedAdvertisingEnableCompleteView>,
1094                 enable,
1095                 enabled_sets,
1096                 true /* trigger callbacks */));
1097       } break;
1098     }
1099 
1100     if (enable) {
1101       enabled_sets_[advertiser_id].advertising_handle_ = advertiser_id;
1102       advertising_sets_[advertiser_id].duration = duration;
1103       advertising_sets_[advertiser_id].max_extended_advertising_events = max_extended_advertising_events;
1104     } else {
1105       enabled_sets_[advertiser_id].advertising_handle_ = kInvalidHandle;
1106       if (advertising_sets_[advertiser_id].address_rotation_alarm != nullptr) {
1107         advertising_sets_[advertiser_id].address_rotation_alarm->Cancel();
1108         advertising_sets_[advertiser_id].address_rotation_alarm.reset();
1109       }
1110     }
1111   }
1112 
set_periodic_parameterbluetooth::hci::LeAdvertisingManager::impl1113   void set_periodic_parameter(
1114       AdvertiserId advertiser_id, PeriodicAdvertisingParameters periodic_advertising_parameters) {
1115     uint8_t include_tx_power = periodic_advertising_parameters.properties >>
1116                                PeriodicAdvertisingParameters::AdvertisingProperty::INCLUDE_TX_POWER;
1117 
1118     le_advertising_interface_->EnqueueCommand(
1119         hci::LeSetPeriodicAdvertisingParametersBuilder::Create(
1120             advertiser_id,
1121             periodic_advertising_parameters.min_interval,
1122             periodic_advertising_parameters.max_interval,
1123             include_tx_power),
1124         module_handler_->BindOnceOn(
1125             this,
1126             &impl::check_status_with_id<LeSetPeriodicAdvertisingParametersCompleteView>,
1127             advertiser_id));
1128   }
1129 
set_periodic_databluetooth::hci::LeAdvertisingManager::impl1130   void set_periodic_data(AdvertiserId advertiser_id, std::vector<GapData> data) {
1131     uint16_t data_len = 0;
1132     // check data size
1133     for (size_t i = 0; i < data.size(); i++) {
1134       if (data[i].size() > kLeMaximumFragmentLength) {
1135         LOG_WARN("AD data len shall not greater than %d", kLeMaximumFragmentLength);
1136         if (advertising_callbacks_ != nullptr) {
1137           advertising_callbacks_->OnPeriodicAdvertisingDataSet(
1138               advertiser_id, AdvertisingCallback::AdvertisingStatus::INTERNAL_ERROR);
1139         }
1140         return;
1141       }
1142       data_len += data[i].size();
1143     }
1144 
1145     if (data_len > le_maximum_advertising_data_length_) {
1146       LOG_WARN(
1147           "advertising data len exceeds le_maximum_advertising_data_length_ %d", le_maximum_advertising_data_length_);
1148       if (advertising_callbacks_ != nullptr) {
1149         advertising_callbacks_->OnPeriodicAdvertisingDataSet(
1150             advertiser_id, AdvertisingCallback::AdvertisingStatus::DATA_TOO_LARGE);
1151       }
1152       return;
1153     }
1154 
1155     if (data_len <= kLeMaximumFragmentLength) {
1156       send_periodic_data_fragment(advertiser_id, data, Operation::COMPLETE_ADVERTISEMENT);
1157     } else {
1158       std::vector<GapData> sub_data;
1159       uint16_t sub_data_len = 0;
1160       Operation operation = Operation::FIRST_FRAGMENT;
1161 
1162       for (size_t i = 0; i < data.size(); i++) {
1163         if (sub_data_len + data[i].size() > kLeMaximumFragmentLength) {
1164           send_periodic_data_fragment(advertiser_id, sub_data, operation);
1165           operation = Operation::INTERMEDIATE_FRAGMENT;
1166           sub_data_len = 0;
1167           sub_data.clear();
1168         }
1169         sub_data.push_back(data[i]);
1170         sub_data_len += data[i].size();
1171       }
1172       send_periodic_data_fragment(advertiser_id, sub_data, Operation::LAST_FRAGMENT);
1173     }
1174   }
1175 
send_periodic_data_fragmentbluetooth::hci::LeAdvertisingManager::impl1176   void send_periodic_data_fragment(AdvertiserId advertiser_id, std::vector<GapData> data, Operation operation) {
1177     if (operation == Operation::COMPLETE_ADVERTISEMENT || operation == Operation::LAST_FRAGMENT) {
1178       le_advertising_interface_->EnqueueCommand(
1179           hci::LeSetPeriodicAdvertisingDataBuilder::Create(advertiser_id, operation, data),
1180           module_handler_->BindOnceOn(
1181               this, &impl::check_status_with_id<LeSetPeriodicAdvertisingDataCompleteView>, advertiser_id));
1182     } else {
1183       // For first and intermediate fragment, do not trigger advertising_callbacks_.
1184       le_advertising_interface_->EnqueueCommand(
1185           hci::LeSetPeriodicAdvertisingDataBuilder::Create(advertiser_id, operation, data),
1186           module_handler_->BindOnce(impl::check_status<LeSetPeriodicAdvertisingDataCompleteView>));
1187     }
1188   }
1189 
enable_periodic_advertisingbluetooth::hci::LeAdvertisingManager::impl1190   void enable_periodic_advertising(AdvertiserId advertiser_id, bool enable, bool include_adi) {
1191     if (!controller_->SupportsBlePeriodicAdvertising()) {
1192       return;
1193     }
1194 
1195     if (include_adi && !controller_->SupportsBlePeriodicAdvertisingAdi()) {
1196       include_adi = false;
1197     }
1198     le_advertising_interface_->EnqueueCommand(
1199         hci::LeSetPeriodicAdvertisingEnableBuilder::Create(enable, include_adi, advertiser_id),
1200         module_handler_->BindOnceOn(
1201             this,
1202             &impl::on_set_periodic_advertising_enable_complete<LeSetPeriodicAdvertisingEnableCompleteView>,
1203             enable,
1204             advertiser_id));
1205   }
1206 
OnPausebluetooth::hci::LeAdvertisingManager::impl1207   void OnPause() override {
1208     if (!address_manager_registered) {
1209       LOG_WARN("Unregistered!");
1210       return;
1211     }
1212     paused = true;
1213     if (!advertising_sets_.empty()) {
1214       std::vector<EnabledSet> enabled_sets = {};
1215       for (size_t i = 0; i < enabled_sets_.size(); i++) {
1216         EnabledSet curr_set = enabled_sets_[i];
1217         if (enabled_sets_[i].advertising_handle_ != kInvalidHandle) {
1218           enabled_sets.push_back(enabled_sets_[i]);
1219         }
1220       }
1221 
1222       switch (advertising_api_type_) {
1223         case (AdvertisingApiType::LEGACY): {
1224           le_advertising_interface_->EnqueueCommand(
1225               hci::LeSetAdvertisingEnableBuilder::Create(Enable::DISABLED),
1226               module_handler_->BindOnce(impl::check_status<LeSetAdvertisingEnableCompleteView>));
1227         } break;
1228         case (AdvertisingApiType::ANDROID_HCI): {
1229           for (size_t i = 0; i < enabled_sets_.size(); i++) {
1230             uint8_t id = enabled_sets_[i].advertising_handle_;
1231             if (id != kInvalidHandle) {
1232               le_advertising_interface_->EnqueueCommand(
1233                   hci::LeMultiAdvtSetEnableBuilder::Create(Enable::DISABLED, id),
1234                   module_handler_->BindOnce(impl::check_status<LeMultiAdvtCompleteView>));
1235             }
1236           }
1237         } break;
1238         case (AdvertisingApiType::EXTENDED): {
1239           if (enabled_sets.size() != 0) {
1240             le_advertising_interface_->EnqueueCommand(
1241                 hci::LeSetExtendedAdvertisingEnableBuilder::Create(Enable::DISABLED, enabled_sets),
1242                 module_handler_->BindOnce(impl::check_status<LeSetExtendedAdvertisingEnableCompleteView>));
1243           }
1244         } break;
1245       }
1246     }
1247     le_address_manager_->AckPause(this);
1248   }
1249 
OnResumebluetooth::hci::LeAdvertisingManager::impl1250   void OnResume() override {
1251     if (!address_manager_registered) {
1252       LOG_WARN("Unregistered!");
1253       return;
1254     }
1255     paused = false;
1256     if (!advertising_sets_.empty()) {
1257       std::vector<EnabledSet> enabled_sets = {};
1258       for (size_t i = 0; i < enabled_sets_.size(); i++) {
1259         EnabledSet curr_set = enabled_sets_[i];
1260         if (enabled_sets_[i].advertising_handle_ != kInvalidHandle) {
1261           enabled_sets.push_back(enabled_sets_[i]);
1262         }
1263       }
1264 
1265       switch (advertising_api_type_) {
1266         case (AdvertisingApiType::LEGACY): {
1267           le_advertising_interface_->EnqueueCommand(
1268               hci::LeSetAdvertisingEnableBuilder::Create(Enable::ENABLED),
1269               common::init_flags::
1270                       trigger_advertising_callbacks_on_first_resume_after_pause_is_enabled()
1271                   ? module_handler_->BindOnceOn(
1272                         this,
1273                         &impl::on_set_advertising_enable_complete<
1274                             LeSetAdvertisingEnableCompleteView>,
1275                         true,
1276                         enabled_sets,
1277                         false /* trigger_callbacks */)
1278                   : module_handler_->BindOnce(
1279                         impl::check_status<LeSetAdvertisingEnableCompleteView>));
1280         } break;
1281         case (AdvertisingApiType::ANDROID_HCI): {
1282           for (size_t i = 0; i < enabled_sets_.size(); i++) {
1283             uint8_t id = enabled_sets_[i].advertising_handle_;
1284             if (id != kInvalidHandle) {
1285               le_advertising_interface_->EnqueueCommand(
1286                   hci::LeMultiAdvtSetEnableBuilder::Create(Enable::ENABLED, id),
1287                   common::init_flags::
1288                           trigger_advertising_callbacks_on_first_resume_after_pause_is_enabled()
1289                       ? module_handler_->BindOnceOn(
1290                             this,
1291                             &impl::on_set_advertising_enable_complete<LeMultiAdvtCompleteView>,
1292                             true,
1293                             enabled_sets,
1294                             false /* trigger_callbacks */)
1295                       : module_handler_->BindOnce(impl::check_status<LeMultiAdvtCompleteView>));
1296             }
1297           }
1298         } break;
1299         case (AdvertisingApiType::EXTENDED): {
1300           if (enabled_sets.size() != 0) {
1301             le_advertising_interface_->EnqueueCommand(
1302                 hci::LeSetExtendedAdvertisingEnableBuilder::Create(Enable::ENABLED, enabled_sets),
1303                 common::init_flags::
1304                         trigger_advertising_callbacks_on_first_resume_after_pause_is_enabled()
1305                     ? module_handler_->BindOnceOn(
1306                           this,
1307                           &impl::on_set_extended_advertising_enable_complete<
1308                               LeSetExtendedAdvertisingEnableCompleteView>,
1309                           true,
1310                           enabled_sets,
1311                           false /* trigger_callbacks */)
1312                     : module_handler_->BindOnce(
1313                           impl::check_status<LeSetExtendedAdvertisingEnableCompleteView>));
1314           }
1315         } break;
1316       }
1317     }
1318     le_address_manager_->AckResume(this);
1319   }
1320 
1321   // Note: this needs to be synchronous (i.e. NOT on a handler) for two reasons:
1322   // 1. For parity with OnPause() and OnResume()
1323   // 2. If we don't enqueue our HCI commands SYNCHRONOUSLY, then it is possible that we OnResume() in addressManager
1324   // before our commands complete. So then our commands reach the HCI layer *after* the resume commands from address
1325   // manager, which is racey (even if it might not matter).
1326   //
1327   // If you are a future developer making this asynchronous, you need to add some kind of ->AckIRKChange() method to the
1328   // address manager so we can defer resumption to after this completes.
NotifyOnIRKChangebluetooth::hci::LeAdvertisingManager::impl1329   void NotifyOnIRKChange() override {
1330     for (size_t i = 0; i < enabled_sets_.size(); i++) {
1331       if (enabled_sets_[i].advertising_handle_ != kInvalidHandle) {
1332         rotate_advertiser_address(i);
1333       }
1334     }
1335   }
1336 
1337   common::Callback<void(Address, AddressType)> scan_callback_;
1338   common::ContextualCallback<void(ErrorCode, uint16_t, hci::AddressWithType)> set_terminated_callback_{};
1339   AdvertisingCallback* advertising_callbacks_ = nullptr;
1340   os::Handler* registered_handler_{nullptr};
1341   Module* module_;
1342   os::Handler* module_handler_;
1343   hci::HciLayer* hci_layer_;
1344   hci::Controller* controller_;
1345   uint16_t le_maximum_advertising_data_length_;
1346   int8_t le_physical_channel_tx_power_ = 0;
1347   int8_t le_tx_path_loss_comp_ = 0;
1348   hci::LeAdvertisingInterface* le_advertising_interface_;
1349   std::map<AdvertiserId, Advertiser> advertising_sets_;
1350   hci::LeAddressManager* le_address_manager_;
1351   hci::AclManager* acl_manager_;
1352   bool address_manager_registered = false;
1353   bool paused = false;
1354 
1355   std::mutex id_mutex_;
1356   size_t num_instances_;
1357   std::vector<hci::EnabledSet> enabled_sets_;
1358   // map to mapping the id from java layer and advertier id
1359   std::map<uint8_t, int> id_map_;
1360 
1361   AdvertisingApiType advertising_api_type_{0};
1362 
on_read_advertising_physical_channel_tx_powerbluetooth::hci::LeAdvertisingManager::impl1363   void on_read_advertising_physical_channel_tx_power(CommandCompleteView view) {
1364     auto complete_view = LeReadAdvertisingPhysicalChannelTxPowerCompleteView::Create(view);
1365     if (!complete_view.IsValid()) {
1366       auto payload = view.GetPayload();
1367       if (payload.size() == 1 && payload[0] == static_cast<uint8_t>(ErrorCode::UNKNOWN_HCI_COMMAND)) {
1368         LOG_INFO("Unknown command, not setting tx power");
1369         return;
1370       }
1371     }
1372     ASSERT(complete_view.IsValid());
1373     if (complete_view.GetStatus() != ErrorCode::SUCCESS) {
1374       LOG_INFO("Got a command complete with status %s", ErrorCodeText(complete_view.GetStatus()).c_str());
1375       return;
1376     }
1377     le_physical_channel_tx_power_ = complete_view.GetTransmitPowerLevel();
1378   }
1379 
1380   template <class View>
on_set_advertising_enable_completebluetooth::hci::LeAdvertisingManager::impl1381   void on_set_advertising_enable_complete(
1382       bool enable,
1383       std::vector<EnabledSet> enabled_sets,
1384       bool trigger_callbacks,
1385       CommandCompleteView view) {
1386     ASSERT(view.IsValid());
1387     auto complete_view = View::Create(view);
1388     ASSERT(complete_view.IsValid());
1389     AdvertisingCallback::AdvertisingStatus advertising_status = AdvertisingCallback::AdvertisingStatus::SUCCESS;
1390     if (complete_view.GetStatus() != ErrorCode::SUCCESS) {
1391       LOG_INFO("Got a command complete with status %s", ErrorCodeText(complete_view.GetStatus()).c_str());
1392     }
1393 
1394     if (advertising_callbacks_ == nullptr) {
1395       return;
1396     }
1397     for (EnabledSet enabled_set : enabled_sets) {
1398       bool started = advertising_sets_[enabled_set.advertising_handle_].started;
1399       uint8_t id = enabled_set.advertising_handle_;
1400       if (id == kInvalidHandle) {
1401         continue;
1402       }
1403 
1404       int reg_id = id_map_[id];
1405       if (reg_id == kIdLocal) {
1406         if (!advertising_sets_[enabled_set.advertising_handle_].status_callback.is_null()) {
1407           std::move(advertising_sets_[enabled_set.advertising_handle_].status_callback).Run(advertising_status);
1408           advertising_sets_[enabled_set.advertising_handle_].status_callback.Reset();
1409         }
1410         continue;
1411       }
1412 
1413       if (started) {
1414         if (trigger_callbacks) {
1415           advertising_callbacks_->OnAdvertisingEnabled(id, enable, advertising_status);
1416         }
1417       } else {
1418         advertising_sets_[enabled_set.advertising_handle_].started = true;
1419         advertising_callbacks_->OnAdvertisingSetStarted(reg_id, id, le_physical_channel_tx_power_, advertising_status);
1420       }
1421     }
1422   }
1423 
1424   template <class View>
on_set_extended_advertising_enable_completebluetooth::hci::LeAdvertisingManager::impl1425   void on_set_extended_advertising_enable_complete(
1426       bool enable,
1427       std::vector<EnabledSet> enabled_sets,
1428       bool trigger_callbacks,
1429       CommandCompleteView view) {
1430     ASSERT(view.IsValid());
1431     auto complete_view = LeSetExtendedAdvertisingEnableCompleteView::Create(view);
1432     ASSERT(complete_view.IsValid());
1433     AdvertisingCallback::AdvertisingStatus advertising_status = AdvertisingCallback::AdvertisingStatus::SUCCESS;
1434     if (complete_view.GetStatus() != ErrorCode::SUCCESS) {
1435       LOG_INFO("Got a command complete with status %s", ErrorCodeText(complete_view.GetStatus()).c_str());
1436       advertising_status = AdvertisingCallback::AdvertisingStatus::INTERNAL_ERROR;
1437     }
1438 
1439     if (advertising_callbacks_ == nullptr) {
1440       return;
1441     }
1442 
1443     for (EnabledSet enabled_set : enabled_sets) {
1444       int8_t tx_power = advertising_sets_[enabled_set.advertising_handle_].tx_power;
1445       bool started = advertising_sets_[enabled_set.advertising_handle_].started;
1446       uint8_t id = enabled_set.advertising_handle_;
1447       if (id == kInvalidHandle) {
1448         continue;
1449       }
1450 
1451       int reg_id = id_map_[id];
1452       if (reg_id == kIdLocal) {
1453         if (!advertising_sets_[enabled_set.advertising_handle_].status_callback.is_null()) {
1454           std::move(advertising_sets_[enabled_set.advertising_handle_].status_callback).Run(advertising_status);
1455           advertising_sets_[enabled_set.advertising_handle_].status_callback.Reset();
1456         }
1457         continue;
1458       }
1459 
1460       if (started) {
1461         if (trigger_callbacks) {
1462           advertising_callbacks_->OnAdvertisingEnabled(id, enable, advertising_status);
1463         }
1464       } else {
1465         advertising_sets_[enabled_set.advertising_handle_].started = true;
1466         advertising_callbacks_->OnAdvertisingSetStarted(reg_id, id, tx_power, advertising_status);
1467       }
1468     }
1469   }
1470 
1471   template <class View>
on_set_extended_advertising_parameters_completebluetooth::hci::LeAdvertisingManager::impl1472   void on_set_extended_advertising_parameters_complete(AdvertiserId id, CommandCompleteView view) {
1473     ASSERT(view.IsValid());
1474     auto complete_view = LeSetExtendedAdvertisingParametersCompleteView::Create(view);
1475     ASSERT(complete_view.IsValid());
1476     AdvertisingCallback::AdvertisingStatus advertising_status = AdvertisingCallback::AdvertisingStatus::SUCCESS;
1477     if (complete_view.GetStatus() != ErrorCode::SUCCESS) {
1478       LOG_INFO("Got a command complete with status %s", ErrorCodeText(complete_view.GetStatus()).c_str());
1479       advertising_status = AdvertisingCallback::AdvertisingStatus::INTERNAL_ERROR;
1480     }
1481     advertising_sets_[id].tx_power = complete_view.GetSelectedTxPower();
1482 
1483     if (advertising_sets_[id].started && id_map_[id] != kIdLocal) {
1484       advertising_callbacks_->OnAdvertisingParametersUpdated(id, advertising_sets_[id].tx_power, advertising_status);
1485     }
1486   }
1487 
1488   template <class View>
on_set_periodic_advertising_enable_completebluetooth::hci::LeAdvertisingManager::impl1489   void on_set_periodic_advertising_enable_complete(bool enable, AdvertiserId id, CommandCompleteView view) {
1490     ASSERT(view.IsValid());
1491     auto complete_view = LeSetPeriodicAdvertisingEnableCompleteView::Create(view);
1492     ASSERT(complete_view.IsValid());
1493     AdvertisingCallback::AdvertisingStatus advertising_status = AdvertisingCallback::AdvertisingStatus::SUCCESS;
1494     if (complete_view.GetStatus() != ErrorCode::SUCCESS) {
1495       LOG_INFO("Got a command complete with status %s", ErrorCodeText(complete_view.GetStatus()).c_str());
1496       advertising_status = AdvertisingCallback::AdvertisingStatus::INTERNAL_ERROR;
1497     }
1498 
1499     if (advertising_callbacks_ == nullptr || !advertising_sets_[id].started || id_map_[id] == kIdLocal) {
1500       return;
1501     }
1502 
1503     advertising_callbacks_->OnPeriodicAdvertisingEnabled(id, enable, advertising_status);
1504   }
1505 
1506   template <class View>
on_set_advertising_set_random_address_completebluetooth::hci::LeAdvertisingManager::impl1507   void on_set_advertising_set_random_address_complete(
1508       AdvertiserId advertiser_id, AddressWithType address_with_type, CommandCompleteView view) {
1509     ASSERT(view.IsValid());
1510     auto complete_view = LeSetAdvertisingSetRandomAddressCompleteView::Create(view);
1511     ASSERT(complete_view.IsValid());
1512     if (complete_view.GetStatus() != ErrorCode::SUCCESS) {
1513       LOG_ERROR("Got a command complete with status %s", ErrorCodeText(complete_view.GetStatus()).c_str());
1514     } else {
1515       LOG_INFO(
1516           "update random address for advertising set %d : %s",
1517           advertiser_id,
1518           ADDRESS_TO_LOGGABLE_CSTR(address_with_type.GetAddress()));
1519       advertising_sets_[advertiser_id].current_address = address_with_type;
1520     }
1521   }
1522 
1523   template <class View>
check_status_with_idbluetooth::hci::LeAdvertisingManager::impl1524   void check_status_with_id(AdvertiserId id, CommandCompleteView view) {
1525     ASSERT(view.IsValid());
1526     auto status_view = View::Create(view);
1527     ASSERT(status_view.IsValid());
1528     if (status_view.GetStatus() != ErrorCode::SUCCESS) {
1529       LOG_INFO(
1530           "Got a Command complete %s, status %s",
1531           OpCodeText(view.GetCommandOpCode()).c_str(),
1532           ErrorCodeText(status_view.GetStatus()).c_str());
1533     }
1534     AdvertisingCallback::AdvertisingStatus advertising_status = AdvertisingCallback::AdvertisingStatus::SUCCESS;
1535     if (status_view.GetStatus() != ErrorCode::SUCCESS) {
1536       LOG_INFO("Got a command complete with status %s", ErrorCodeText(status_view.GetStatus()).c_str());
1537       advertising_status = AdvertisingCallback::AdvertisingStatus::INTERNAL_ERROR;
1538     }
1539 
1540     // Do not trigger callback if the advertiser not stated yet, or the advertiser is not register
1541     // from Java layer
1542     if (advertising_callbacks_ == nullptr || !advertising_sets_[id].started || id_map_[id] == kIdLocal) {
1543       return;
1544     }
1545 
1546     OpCode opcode = view.GetCommandOpCode();
1547 
1548     switch (opcode) {
1549       case OpCode::LE_SET_ADVERTISING_PARAMETERS:
1550         advertising_callbacks_->OnAdvertisingParametersUpdated(id, le_physical_channel_tx_power_, advertising_status);
1551         break;
1552       case OpCode::LE_SET_ADVERTISING_DATA:
1553       case OpCode::LE_SET_EXTENDED_ADVERTISING_DATA:
1554         advertising_callbacks_->OnAdvertisingDataSet(id, advertising_status);
1555         break;
1556       case OpCode::LE_SET_SCAN_RESPONSE_DATA:
1557       case OpCode::LE_SET_EXTENDED_SCAN_RESPONSE_DATA:
1558         advertising_callbacks_->OnScanResponseDataSet(id, advertising_status);
1559         break;
1560       case OpCode::LE_SET_PERIODIC_ADVERTISING_PARAMETERS:
1561         advertising_callbacks_->OnPeriodicAdvertisingParametersUpdated(id, advertising_status);
1562         break;
1563       case OpCode::LE_SET_PERIODIC_ADVERTISING_DATA:
1564         advertising_callbacks_->OnPeriodicAdvertisingDataSet(id, advertising_status);
1565         break;
1566       case OpCode::LE_MULTI_ADVT: {
1567         auto command_view = LeMultiAdvtCompleteView::Create(view);
1568         ASSERT(command_view.IsValid());
1569         auto sub_opcode = command_view.GetSubCmd();
1570         switch (sub_opcode) {
1571           case SubOcf::SET_PARAM:
1572             advertising_callbacks_->OnAdvertisingParametersUpdated(
1573                 id, le_physical_channel_tx_power_, advertising_status);
1574             break;
1575           case SubOcf::SET_DATA:
1576             advertising_callbacks_->OnAdvertisingDataSet(id, advertising_status);
1577             break;
1578           case SubOcf::SET_SCAN_RESP:
1579             advertising_callbacks_->OnScanResponseDataSet(id, advertising_status);
1580             break;
1581           default:
1582             LOG_WARN("Unexpected sub event type %s", SubOcfText(command_view.GetSubCmd()).c_str());
1583         }
1584       } break;
1585       default:
1586         LOG_WARN("Unexpected event type %s", OpCodeText(view.GetCommandOpCode()).c_str());
1587     }
1588   }
1589 
1590   template <class View>
check_statusbluetooth::hci::LeAdvertisingManager::impl1591   static void check_status(CommandCompleteView view) {
1592     ASSERT(view.IsValid());
1593     auto status_view = View::Create(view);
1594     ASSERT(status_view.IsValid());
1595     if (status_view.GetStatus() != ErrorCode::SUCCESS) {
1596       LOG_INFO(
1597           "Got a Command complete %s, status %s",
1598           OpCodeText(view.GetCommandOpCode()).c_str(),
1599           ErrorCodeText(status_view.GetStatus()).c_str());
1600     }
1601   }
1602 
start_advertising_failbluetooth::hci::LeAdvertisingManager::impl1603   void start_advertising_fail(int reg_id, AdvertisingCallback::AdvertisingStatus status) {
1604     ASSERT(status != AdvertisingCallback::AdvertisingStatus::SUCCESS);
1605     advertising_callbacks_->OnAdvertisingSetStarted(reg_id, kInvalidId, 0, status);
1606   }
1607 };
1608 
LeAdvertisingManager()1609 LeAdvertisingManager::LeAdvertisingManager() {
1610   pimpl_ = std::make_unique<impl>(this);
1611 }
1612 
ListDependencies(ModuleList * list) const1613 void LeAdvertisingManager::ListDependencies(ModuleList* list) const {
1614   list->add<hci::HciLayer>();
1615   list->add<hci::Controller>();
1616   list->add<hci::AclManager>();
1617   list->add<hci::VendorSpecificEventManager>();
1618 }
1619 
Start()1620 void LeAdvertisingManager::Start() {
1621   pimpl_->start(
1622       GetHandler(),
1623       GetDependency<hci::HciLayer>(),
1624       GetDependency<hci::Controller>(),
1625       GetDependency<AclManager>(),
1626       GetDependency<VendorSpecificEventManager>());
1627 }
1628 
Stop()1629 void LeAdvertisingManager::Stop() {
1630   pimpl_.reset();
1631 }
1632 
ToString() const1633 std::string LeAdvertisingManager::ToString() const {
1634   return "Le Advertising Manager";
1635 }
1636 
GetNumberOfAdvertisingInstances() const1637 size_t LeAdvertisingManager::GetNumberOfAdvertisingInstances() const {
1638   return pimpl_->GetNumberOfAdvertisingInstances();
1639 }
1640 
ExtendedCreateAdvertiser(int reg_id,const AdvertisingConfig config,common::Callback<void (Address,AddressType)> scan_callback,common::Callback<void (ErrorCode,uint8_t,uint8_t)> set_terminated_callback,uint16_t duration,uint8_t max_extended_advertising_events,os::Handler * handler)1641 void LeAdvertisingManager::ExtendedCreateAdvertiser(
1642     int reg_id,
1643     const AdvertisingConfig config,
1644     common::Callback<void(Address, AddressType)> scan_callback,
1645     common::Callback<void(ErrorCode, uint8_t, uint8_t)> set_terminated_callback,
1646     uint16_t duration,
1647     uint8_t max_extended_advertising_events,
1648     os::Handler* handler) {
1649   AdvertisingApiType advertising_api_type = pimpl_->get_advertising_api_type();
1650   if (advertising_api_type != AdvertisingApiType::EXTENDED) {
1651     if (config.peer_address == Address::kEmpty) {
1652       if (config.advertising_type == hci::AdvertisingType::ADV_DIRECT_IND_HIGH ||
1653           config.advertising_type == hci::AdvertisingType::ADV_DIRECT_IND_LOW) {
1654         LOG_WARN("Peer address can not be empty for directed advertising");
1655         CallOn(
1656             pimpl_.get(),
1657             &impl::start_advertising_fail,
1658             reg_id,
1659             AdvertisingCallback::AdvertisingStatus::INTERNAL_ERROR);
1660         return;
1661       }
1662     }
1663     GetHandler()->Post(common::BindOnce(
1664         &impl::create_advertiser,
1665         common::Unretained(pimpl_.get()),
1666         reg_id,
1667         config,
1668         scan_callback,
1669         set_terminated_callback,
1670         handler));
1671 
1672     return;
1673   };
1674 
1675   if (config.directed) {
1676     if (config.peer_address == Address::kEmpty) {
1677       LOG_INFO("Peer address can not be empty for directed advertising");
1678       CallOn(
1679           pimpl_.get(), &impl::start_advertising_fail, reg_id, AdvertisingCallback::AdvertisingStatus::INTERNAL_ERROR);
1680       return;
1681     }
1682   }
1683   if (config.channel_map == 0) {
1684     LOG_INFO("At least one channel must be set in the map");
1685     CallOn(pimpl_.get(), &impl::start_advertising_fail, reg_id, AdvertisingCallback::AdvertisingStatus::INTERNAL_ERROR);
1686     return;
1687   }
1688   if (!config.legacy_pdus) {
1689     if (config.connectable && config.scannable) {
1690       LOG_INFO("Extended advertising PDUs can not be connectable and scannable");
1691       CallOn(
1692           pimpl_.get(), &impl::start_advertising_fail, reg_id, AdvertisingCallback::AdvertisingStatus::INTERNAL_ERROR);
1693       return;
1694     }
1695     if (config.high_duty_directed_connectable) {
1696       LOG_INFO("Extended advertising PDUs can not be high duty cycle");
1697       CallOn(
1698           pimpl_.get(), &impl::start_advertising_fail, reg_id, AdvertisingCallback::AdvertisingStatus::INTERNAL_ERROR);
1699       return;
1700     }
1701   }
1702   if (config.interval_min > config.interval_max) {
1703     LOG_INFO("Advertising interval: min (%hu) > max (%hu)", config.interval_min, config.interval_max);
1704     CallOn(pimpl_.get(), &impl::start_advertising_fail, reg_id, AdvertisingCallback::AdvertisingStatus::INTERNAL_ERROR);
1705     return;
1706   }
1707   CallOn(
1708       pimpl_.get(),
1709       &impl::create_extended_advertiser,
1710       reg_id,
1711       config,
1712       scan_callback,
1713       set_terminated_callback,
1714       duration,
1715       max_extended_advertising_events,
1716       handler);
1717   return;
1718 }
1719 
StartAdvertising(AdvertiserId advertiser_id,const AdvertisingConfig config,uint16_t duration,base::OnceCallback<void (uint8_t)> status_callback,base::OnceCallback<void (uint8_t)> timeout_callback,common::Callback<void (Address,AddressType)> scan_callback,common::Callback<void (ErrorCode,uint8_t,uint8_t)> set_terminated_callback,os::Handler * handler)1720 void LeAdvertisingManager::StartAdvertising(
1721     AdvertiserId advertiser_id,
1722     const AdvertisingConfig config,
1723     uint16_t duration,
1724     base::OnceCallback<void(uint8_t /* status */)> status_callback,
1725     base::OnceCallback<void(uint8_t /* status */)> timeout_callback,
1726     common::Callback<void(Address, AddressType)> scan_callback,
1727     common::Callback<void(ErrorCode, uint8_t, uint8_t)> set_terminated_callback,
1728     os::Handler* handler) {
1729   CallOn(
1730       pimpl_.get(),
1731       &impl::start_advertising,
1732       advertiser_id,
1733       config,
1734       duration,
1735       std::move(status_callback),
1736       std::move(timeout_callback),
1737       scan_callback,
1738       set_terminated_callback,
1739       handler);
1740 }
1741 
RegisterAdvertiser(common::ContextualOnceCallback<void (uint8_t,uint8_t)> callback)1742 void LeAdvertisingManager::RegisterAdvertiser(
1743     common::ContextualOnceCallback<void(uint8_t /* inst_id */, uint8_t /* status */)> callback) {
1744   CallOn(pimpl_.get(), &impl::register_advertiser, std::move(callback));
1745 }
1746 
GetOwnAddress(uint8_t advertiser_id)1747 void LeAdvertisingManager::GetOwnAddress(uint8_t advertiser_id) {
1748   CallOn(pimpl_.get(), &impl::get_own_address, advertiser_id);
1749 }
1750 
SetParameters(AdvertiserId advertiser_id,AdvertisingConfig config)1751 void LeAdvertisingManager::SetParameters(AdvertiserId advertiser_id, AdvertisingConfig config) {
1752   CallOn(pimpl_.get(), &impl::set_parameters, advertiser_id, config);
1753 }
1754 
SetData(AdvertiserId advertiser_id,bool set_scan_rsp,std::vector<GapData> data)1755 void LeAdvertisingManager::SetData(AdvertiserId advertiser_id, bool set_scan_rsp, std::vector<GapData> data) {
1756   CallOn(pimpl_.get(), &impl::set_data, advertiser_id, set_scan_rsp, data);
1757 }
1758 
EnableAdvertiser(AdvertiserId advertiser_id,bool enable,uint16_t duration,uint8_t max_extended_advertising_events)1759 void LeAdvertisingManager::EnableAdvertiser(
1760     AdvertiserId advertiser_id, bool enable, uint16_t duration, uint8_t max_extended_advertising_events) {
1761   CallOn(pimpl_.get(), &impl::enable_advertiser, advertiser_id, enable, duration, max_extended_advertising_events);
1762 }
1763 
SetPeriodicParameters(AdvertiserId advertiser_id,PeriodicAdvertisingParameters periodic_advertising_parameters)1764 void LeAdvertisingManager::SetPeriodicParameters(
1765     AdvertiserId advertiser_id, PeriodicAdvertisingParameters periodic_advertising_parameters) {
1766   CallOn(pimpl_.get(), &impl::set_periodic_parameter, advertiser_id, periodic_advertising_parameters);
1767 }
1768 
SetPeriodicData(AdvertiserId advertiser_id,std::vector<GapData> data)1769 void LeAdvertisingManager::SetPeriodicData(AdvertiserId advertiser_id, std::vector<GapData> data) {
1770   CallOn(pimpl_.get(), &impl::set_periodic_data, advertiser_id, data);
1771 }
1772 
EnablePeriodicAdvertising(AdvertiserId advertiser_id,bool enable,bool include_adi)1773 void LeAdvertisingManager::EnablePeriodicAdvertising(AdvertiserId advertiser_id, bool enable, bool include_adi) {
1774   CallOn(pimpl_.get(), &impl::enable_periodic_advertising, advertiser_id, enable, include_adi);
1775 }
1776 
RemoveAdvertiser(AdvertiserId advertiser_id)1777 void LeAdvertisingManager::RemoveAdvertiser(AdvertiserId advertiser_id) {
1778   CallOn(pimpl_.get(), &impl::remove_advertiser, advertiser_id);
1779 }
1780 
RegisterAdvertisingCallback(AdvertisingCallback * advertising_callback)1781 void LeAdvertisingManager::RegisterAdvertisingCallback(AdvertisingCallback* advertising_callback) {
1782   CallOn(pimpl_.get(), &impl::register_advertising_callback, advertising_callback);
1783 }
1784 
1785 }  // namespace hci
1786 }  // namespace bluetooth
1787