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