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