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