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_scanning_manager.h"
17
18 #include <bluetooth/log.h>
19 #include <com_android_bluetooth_flags.h>
20
21 #include <memory>
22 #include <unordered_map>
23
24 #include "hci/acl_manager.h"
25 #include "hci/controller.h"
26 #include "hci/event_checkers.h"
27 #include "hci/hci_layer.h"
28 #include "hci/hci_packets.h"
29 #include "hci/le_periodic_sync_manager.h"
30 #include "hci/le_scanning_interface.h"
31 #include "hci/le_scanning_reassembler.h"
32 #include "module.h"
33 #include "os/handler.h"
34 #include "os/system_properties.h"
35 #include "storage/storage_module.h"
36
37 namespace bluetooth {
38 namespace hci {
39
40 constexpr uint16_t kLeScanWindowMin = 0x0004;
41 constexpr uint16_t kLeScanWindowMax = 0x4000;
42 constexpr int64_t kLeScanRssiMin = -127;
43 constexpr int64_t kLeScanRssiMax = 20;
44 constexpr int64_t kLeScanRssiUnknown = 127;
45 constexpr int64_t kLeRxPathLossCompMin = -128;
46 constexpr int64_t kLeRxPathLossCompMax = 127;
47 constexpr uint16_t kDefaultLeExtendedScanWindow = 4800;
48 constexpr uint16_t kLeExtendedScanWindowMax = 0xFFFF;
49 constexpr uint16_t kLeScanIntervalMin = 0x0004;
50 constexpr uint16_t kLeScanIntervalMax = 0x4000;
51 constexpr uint16_t kDefaultLeExtendedScanInterval = 4800;
52 constexpr uint16_t kLeExtendedScanIntervalMax = 0xFFFF;
53
54 constexpr uint8_t kScannableBit = 1;
55 constexpr uint8_t kDirectedBit = 2;
56 constexpr uint8_t kScanResponseBit = 3;
57 constexpr uint8_t kLegacyBit = 4;
58 constexpr uint8_t kDataStatusBits = 5;
59
60 // system properties
61 const std::string kLeRxPathLossCompProperty = "bluetooth.hardware.radio.le_rx_path_loss_comp_db";
62
63 const ModuleFactory LeScanningManager::Factory =
__anonddc426700102() 64 ModuleFactory([]() { return new LeScanningManager(); });
65
66 enum class ScanApiType {
67 LEGACY = 1,
68 ANDROID_HCI = 2,
69 EXTENDED = 3,
70 };
71
72 struct Scanner {
73 Uuid app_uuid;
74 bool in_use;
75 };
76
77 class NullScanningCallback : public ScanningCallback {
OnScannerRegistered(const Uuid,ScannerId,ScanningStatus)78 void OnScannerRegistered(const Uuid /* app_uuid */, ScannerId /* scanner_id */,
79 ScanningStatus /* status */) override {
80 log::info("OnScannerRegistered in NullScanningCallback");
81 }
OnSetScannerParameterComplete(ScannerId,ScanningStatus)82 void OnSetScannerParameterComplete(ScannerId /* scanner_id */,
83 ScanningStatus /* status */) override {
84 log::info("OnSetScannerParameterComplete in NullScanningCallback");
85 }
OnScanResult(uint16_t,uint8_t,Address,uint8_t,uint8_t,uint8_t,int8_t,int8_t,uint16_t,std::vector<uint8_t>)86 void OnScanResult(uint16_t /* event_type */, uint8_t /* address_type */, Address /* address */,
87 uint8_t /* primary_phy */, uint8_t /* secondary_phy */,
88 uint8_t /* advertising_sid */, int8_t /* tx_power */, int8_t /* rssi */,
89 uint16_t /* periodic_advertising_interval */,
90 std::vector<uint8_t> /* advertising_data */) override {
91 log::info("OnScanResult in NullScanningCallback");
92 }
OnTrackAdvFoundLost(AdvertisingFilterOnFoundOnLostInfo)93 void OnTrackAdvFoundLost(
94 AdvertisingFilterOnFoundOnLostInfo /* on_found_on_lost_info */) override {
95 log::info("OnTrackAdvFoundLost in NullScanningCallback");
96 }
OnBatchScanReports(int,int,int,int,std::vector<uint8_t>)97 void OnBatchScanReports(int /* client_if */, int /* status */, int /* report_format */,
98 int /* num_records */, std::vector<uint8_t> /* data */) override {
99 log::info("OnBatchScanReports in NullScanningCallback");
100 }
OnBatchScanThresholdCrossed(int)101 void OnBatchScanThresholdCrossed(int /* client_if */) override {
102 log::info("OnBatchScanThresholdCrossed in NullScanningCallback");
103 }
OnTimeout()104 void OnTimeout() override { log::info("OnTimeout in NullScanningCallback"); }
OnFilterEnable(Enable,uint8_t)105 void OnFilterEnable(Enable /* enable */, uint8_t /* status */) override {
106 log::info("OnFilterEnable in NullScanningCallback");
107 }
OnFilterParamSetup(uint8_t,ApcfAction,uint8_t)108 void OnFilterParamSetup(uint8_t /* available_spaces */, ApcfAction /* action */,
109 uint8_t /* status */) override {
110 log::info("OnFilterParamSetup in NullScanningCallback");
111 }
OnFilterConfigCallback(ApcfFilterType,uint8_t,ApcfAction,uint8_t)112 void OnFilterConfigCallback(ApcfFilterType /* filter_type */, uint8_t /* available_spaces */,
113 ApcfAction /* action */, uint8_t /* status */) override {
114 log::info("OnFilterConfigCallback in NullScanningCallback");
115 }
OnPeriodicSyncStarted(int,uint8_t,uint16_t,uint8_t,AddressWithType,uint8_t,uint16_t)116 void OnPeriodicSyncStarted(int /* reg_id */, uint8_t /* status */, uint16_t /* sync_handle */,
117 uint8_t /* advertising_sid */, AddressWithType /* address_with_type */,
118 uint8_t /* phy */, uint16_t /* interval */) override {
119 log::info("OnPeriodicSyncStarted in NullScanningCallback");
120 }
OnPeriodicSyncReport(uint16_t,int8_t,int8_t,uint8_t,std::vector<uint8_t>)121 void OnPeriodicSyncReport(uint16_t /* sync_handle */, int8_t /* tx_power */, int8_t /* rssi */,
122 uint8_t /* status */, std::vector<uint8_t> /* data */) override {
123 log::info("OnPeriodicSyncReport in NullScanningCallback");
124 }
OnPeriodicSyncLost(uint16_t)125 void OnPeriodicSyncLost(uint16_t /* sync_handle */) override {
126 log::info("OnPeriodicSyncLost in NullScanningCallback");
127 }
OnPeriodicSyncTransferred(int,uint8_t,Address)128 void OnPeriodicSyncTransferred(int /* pa_source */, uint8_t /* status */,
129 Address /* address */) override {
130 log::info("OnPeriodicSyncTransferred in NullScanningCallback");
131 }
OnBigInfoReport(uint16_t,bool)132 void OnBigInfoReport(uint16_t /* sync_handle */, bool /* encrypted */) {
133 log::info("OnBigInfoReport in NullScanningCallback");
134 }
135 };
136
137 enum class BatchScanState {
138 ERROR_STATE = 0,
139 ENABLE_CALLED = 1,
140 ENABLED_STATE = 2,
141 DISABLE_CALLED = 3,
142 DISABLED_STATE = 4,
143 };
144
145 #define BTM_BLE_BATCH_SCAN_MODE_DISABLE 0
146 #define BTM_BLE_BATCH_SCAN_MODE_PASS 1
147 #define BTM_BLE_BATCH_SCAN_MODE_ACTI 2
148 #define BTM_BLE_BATCH_SCAN_MODE_PASS_ACTI 3
149
150 struct BatchScanConfig {
151 BatchScanState current_state;
152 BatchScanMode scan_mode;
153 uint32_t scan_interval;
154 uint32_t scan_window;
155 BatchScanDiscardRule discard_rule;
156 ScannerId ref_value;
157 };
158
159 struct LeScanningManager::impl : public LeAddressManagerCallback {
implbluetooth::hci::LeScanningManager::impl160 impl(Module* module) : module_(module), le_scanning_interface_(nullptr) {}
161
~implbluetooth::hci::LeScanningManager::impl162 ~impl() {
163 if (address_manager_registered_) {
164 le_address_manager_->Unregister(this);
165 }
166 }
167
startbluetooth::hci::LeScanningManager::impl168 void start(os::Handler* handler, HciLayer* hci_layer, Controller* controller,
169 AclManager* acl_manager, storage::StorageModule* storage_module) {
170 module_handler_ = handler;
171 hci_layer_ = hci_layer;
172 controller_ = controller;
173 acl_manager_ = acl_manager;
174 storage_module_ = storage_module;
175 le_address_manager_ = acl_manager->GetLeAddressManager();
176 le_scanning_interface_ = hci_layer_->GetLeScanningInterface(
177 module_handler_->BindOn(this, &LeScanningManager::impl::handle_scan_results));
178 periodic_sync_manager_.Init(le_scanning_interface_, module_handler_);
179 /* Check to see if the opcode is supported and C19 (support for extended advertising). */
180 if (controller_->IsSupported(OpCode::LE_SET_EXTENDED_SCAN_PARAMETERS) &&
181 controller->SupportsBleExtendedAdvertising()) {
182 api_type_ = ScanApiType::EXTENDED;
183 interval_ms_ = kDefaultLeExtendedScanInterval;
184 window_ms_ = kDefaultLeExtendedScanWindow;
185 phy_ = static_cast<uint8_t>(PhyType::LE_1M);
186 } else if (controller_->IsSupported(OpCode::LE_EXTENDED_SCAN_PARAMS)) {
187 api_type_ = ScanApiType::ANDROID_HCI;
188 } else {
189 api_type_ = ScanApiType::LEGACY;
190 }
191 is_filter_supported_ = controller_->IsSupported(OpCode::LE_ADV_FILTER);
192 if (is_filter_supported_) {
193 le_scanning_interface_->EnqueueCommand(
194 LeAdvFilterReadExtendedFeaturesBuilder::Create(),
195 module_handler_->BindOnceOn(this, &impl::on_apcf_read_extended_features_complete));
196 }
197 is_batch_scan_supported_ = controller->IsSupported(OpCode::LE_BATCH_SCAN);
198 is_periodic_advertising_sync_transfer_sender_supported_ =
199 controller_->SupportsBlePeriodicAdvertisingSyncTransferSender();
200 total_num_of_advt_tracked_ = controller->GetVendorCapabilities().total_num_of_advt_tracked_;
201 if (is_batch_scan_supported_) {
202 hci_layer_->RegisterVendorSpecificEventHandler(
203 VseSubeventCode::BLE_THRESHOLD,
204 handler->BindOn(this, &LeScanningManager::impl::on_storage_threshold_breach));
205 hci_layer_->RegisterVendorSpecificEventHandler(
206 VseSubeventCode::BLE_TRACKING,
207 handler->BindOn(this, &LeScanningManager::impl::on_advertisement_tracking));
208 }
209 scanners_ = std::vector<Scanner>(kMaxAppNum + 1);
210 for (size_t i = 0; i < scanners_.size(); i++) {
211 scanners_[i].app_uuid = Uuid::kEmpty;
212 scanners_[i].in_use = false;
213 }
214 batch_scan_config_.current_state = BatchScanState::DISABLED_STATE;
215 batch_scan_config_.ref_value = kInvalidScannerId;
216 le_rx_path_loss_comp_ = get_rx_path_loss_compensation();
217 }
218
stopbluetooth::hci::LeScanningManager::impl219 void stop() {
220 for (auto subevent_code : LeScanningEvents) {
221 hci_layer_->UnregisterLeEventHandler(subevent_code);
222 }
223 if (is_batch_scan_supported_) {
224 // TODO implete vse module
225 // hci_layer_->UnregisterVesEventHandler(VseSubeventCode::BLE_THRESHOLD);
226 // hci_layer_->UnregisterVesEventHandler(VseSubeventCode::BLE_TRACKING);
227 }
228 batch_scan_config_.current_state = BatchScanState::DISABLED_STATE;
229 batch_scan_config_.ref_value = kInvalidScannerId;
230 scanning_callbacks_ = &null_scanning_callback_;
231 periodic_sync_manager_.SetScanningCallback(scanning_callbacks_);
232 }
233
handle_scan_resultsbluetooth::hci::LeScanningManager::impl234 void handle_scan_results(LeMetaEventView event) {
235 switch (event.GetSubeventCode()) {
236 case SubeventCode::ADVERTISING_REPORT:
237 handle_advertising_report(LeAdvertisingReportRawView::Create(event));
238 break;
239 case SubeventCode::DIRECTED_ADVERTISING_REPORT:
240 handle_directed_advertising_report(LeDirectedAdvertisingReportView::Create(event));
241 break;
242 case SubeventCode::EXTENDED_ADVERTISING_REPORT:
243 handle_extended_advertising_report(LeExtendedAdvertisingReportRawView::Create(event));
244 break;
245 case SubeventCode::PERIODIC_ADVERTISING_SYNC_ESTABLISHED:
246 LePeriodicAdvertisingSyncEstablishedView::Create(event);
247 periodic_sync_manager_.HandleLePeriodicAdvertisingSyncEstablished(
248 LePeriodicAdvertisingSyncEstablishedView::Create(event));
249 break;
250 case SubeventCode::PERIODIC_ADVERTISING_REPORT:
251 periodic_sync_manager_.HandleLePeriodicAdvertisingReport(
252 LePeriodicAdvertisingReportView::Create(event));
253 break;
254 case SubeventCode::PERIODIC_ADVERTISING_SYNC_LOST:
255 periodic_sync_manager_.HandleLePeriodicAdvertisingSyncLost(
256 LePeriodicAdvertisingSyncLostView::Create(event));
257 break;
258 case SubeventCode::PERIODIC_ADVERTISING_SYNC_TRANSFER_RECEIVED:
259 periodic_sync_manager_.HandleLePeriodicAdvertisingSyncTransferReceived(
260 LePeriodicAdvertisingSyncTransferReceivedView::Create(event));
261 break;
262 case SubeventCode::SCAN_TIMEOUT:
263 scanning_callbacks_->OnTimeout();
264 break;
265 case SubeventCode::BIG_INFO_ADVERTISING_REPORT:
266 periodic_sync_manager_.HandleLeBigInfoAdvertisingReport(
267 LeBigInfoAdvertisingReportView::Create(event));
268 break;
269 default:
270 log::fatal("Unknown advertising subevent {}", SubeventCodeText(event.GetSubeventCode()));
271 }
272 }
273
274 struct ExtendedEventTypeOptions {
275 bool connectable{false};
276 bool scannable{false};
277 bool directed{false};
278 bool scan_response{false};
279 bool legacy{false};
280 bool continuing{false};
281 bool truncated{false};
282 };
283
get_rx_path_loss_compensationbluetooth::hci::LeScanningManager::impl284 int8_t get_rx_path_loss_compensation() {
285 int8_t compensation = 0;
286 auto compensation_prop = os::GetSystemProperty(kLeRxPathLossCompProperty);
287 if (compensation_prop) {
288 auto compensation_number = common::Int64FromString(compensation_prop.value());
289 if (compensation_number) {
290 int64_t number = compensation_number.value();
291 if (number < kLeRxPathLossCompMin || number > kLeRxPathLossCompMax) {
292 log::error("Invalid number for rx path loss compensation: {}", number);
293 } else {
294 compensation = number;
295 }
296 }
297 }
298 log::info("Rx path loss compensation: {}", compensation);
299 return compensation;
300 }
301
get_rssi_after_calibrationbluetooth::hci::LeScanningManager::impl302 int8_t get_rssi_after_calibration(int8_t rssi) {
303 if (le_rx_path_loss_comp_ == 0 || rssi == kLeScanRssiUnknown) {
304 return rssi;
305 }
306 int8_t calibrated_rssi = rssi;
307 int64_t number = rssi + le_rx_path_loss_comp_;
308 if (number < kLeScanRssiMin || number > kLeScanRssiMax) {
309 log::error("Invalid number for calibrated rssi: {}", number);
310 } else {
311 calibrated_rssi = number;
312 }
313 return calibrated_rssi;
314 }
315
transform_to_extended_event_typebluetooth::hci::LeScanningManager::impl316 uint16_t transform_to_extended_event_type(ExtendedEventTypeOptions o) {
317 return (o.connectable ? 0x0001 << 0 : 0) | (o.scannable ? 0x0001 << 1 : 0) |
318 (o.directed ? 0x0001 << 2 : 0) | (o.scan_response ? 0x0001 << 3 : 0) |
319 (o.legacy ? 0x0001 << 4 : 0) | (o.continuing ? 0x0001 << 5 : 0) |
320 (o.truncated ? 0x0001 << 6 : 0);
321 }
322
handle_advertising_reportbluetooth::hci::LeScanningManager::impl323 void handle_advertising_report(LeAdvertisingReportRawView event_view) {
324 if (!event_view.IsValid()) {
325 log::info("Dropping invalid advertising event");
326 return;
327 }
328 std::vector<LeAdvertisingResponseRaw> reports = event_view.GetResponses();
329 if (reports.empty()) {
330 log::info("Zero results in advertising event");
331 return;
332 }
333
334 for (LeAdvertisingResponseRaw report : reports) {
335 uint16_t extended_event_type = 0;
336 switch (report.event_type_) {
337 case AdvertisingEventType::ADV_IND:
338 extended_event_type = transform_to_extended_event_type(
339 {.connectable = true, .scannable = true, .legacy = true});
340 break;
341 case AdvertisingEventType::ADV_DIRECT_IND:
342 extended_event_type = transform_to_extended_event_type(
343 {.connectable = true, .directed = true, .legacy = true});
344 break;
345 case AdvertisingEventType::ADV_SCAN_IND:
346 extended_event_type =
347 transform_to_extended_event_type({.scannable = true, .legacy = true});
348 break;
349 case AdvertisingEventType::ADV_NONCONN_IND:
350 extended_event_type = transform_to_extended_event_type({.legacy = true});
351 break;
352 case AdvertisingEventType::SCAN_RESPONSE:
353 if (com::android::bluetooth::flags::fix_nonconnectable_scannable_advertisement()) {
354 // We don't know if the initial advertising report was connectable or not.
355 // LeScanningReassembler fixes the connectable field.
356 extended_event_type = transform_to_extended_event_type(
357 {.scannable = true, .scan_response = true, .legacy = true});
358 } else {
359 extended_event_type = transform_to_extended_event_type({.connectable = true,
360 .scannable = true,
361 .scan_response = true,
362 .legacy = true});
363 }
364 break;
365 default:
366 log::warn("Unsupported event type:{}", (uint16_t)report.event_type_);
367 return;
368 }
369
370 process_advertising_package_content(
371 extended_event_type, (uint8_t)report.address_type_, report.address_,
372 (uint8_t)PrimaryPhyType::LE_1M, (uint8_t)SecondaryPhyType::NO_PACKETS,
373 kAdvertisingDataInfoNotPresent, kTxPowerInformationNotPresent, report.rssi_,
374 kNotPeriodicAdvertisement, report.advertising_data_);
375 }
376 }
377
handle_directed_advertising_reportbluetooth::hci::LeScanningManager::impl378 void handle_directed_advertising_report(LeDirectedAdvertisingReportView /*event_view*/) {
379 log::warn("HCI Directed Advertising Report events are not supported");
380 }
381
handle_extended_advertising_reportbluetooth::hci::LeScanningManager::impl382 void handle_extended_advertising_report(LeExtendedAdvertisingReportRawView event_view) {
383 if (!event_view.IsValid()) {
384 log::info("Dropping invalid advertising event");
385 return;
386 }
387
388 std::vector<LeExtendedAdvertisingResponseRaw> reports = event_view.GetResponses();
389 if (reports.empty()) {
390 log::info("Zero results in advertising event");
391 return;
392 }
393
394 for (LeExtendedAdvertisingResponseRaw& report : reports) {
395 uint16_t event_type =
396 report.connectable_ | (report.scannable_ << kScannableBit) |
397 (report.directed_ << kDirectedBit) | (report.scan_response_ << kScanResponseBit) |
398 (report.legacy_ << kLegacyBit) | ((uint16_t)report.data_status_ << kDataStatusBits);
399 process_advertising_package_content(
400 event_type, (uint8_t)report.address_type_, report.address_,
401 (uint8_t)report.primary_phy_, (uint8_t)report.secondary_phy_, report.advertising_sid_,
402 report.tx_power_, report.rssi_, report.periodic_advertising_interval_,
403 report.advertising_data_);
404 }
405 }
406
process_advertising_package_contentbluetooth::hci::LeScanningManager::impl407 void process_advertising_package_content(uint16_t event_type, uint8_t address_type,
408 Address address, uint8_t primary_phy,
409 uint8_t secondary_phy, uint8_t advertising_sid,
410 int8_t tx_power, int8_t rssi,
411 uint16_t periodic_advertising_interval,
412 const std::vector<uint8_t>& advertising_data) {
413 // When using the vendor command Le Set Extended Params to
414 // configure a filter accept list based e.g. on the service UUIDs
415 // found in the report, we ignore the scan responses as we cannot be
416 // certain that they will not be dropped by the filter.
417 // TODO(b/275754998): Improve the decision on what to do with scan responses: Only when used
418 // with hardware-filtering features should we ignore waiting for scan response, and make sure
419 // scan responses are still reported too.
420 scanning_reassembler_.SetIgnoreScanResponses(
421 le_scan_type_ == LeScanType::PASSIVE ||
422 filter_policy_ == LeScanningFilterPolicy::FILTER_ACCEPT_LIST_ONLY);
423
424 std::optional<LeScanningReassembler::CompleteAdvertisingData> processed_report =
425 scanning_reassembler_.ProcessAdvertisingReport(event_type, address_type, address,
426 advertising_sid, advertising_data);
427
428 if (processed_report.has_value()) {
429 switch (address_type) {
430 case (uint8_t)AddressType::PUBLIC_DEVICE_ADDRESS:
431 case (uint8_t)AddressType::PUBLIC_IDENTITY_ADDRESS:
432 address_type = (uint8_t)AddressType::PUBLIC_DEVICE_ADDRESS;
433 break;
434 case (uint8_t)AddressType::RANDOM_DEVICE_ADDRESS:
435 case (uint8_t)AddressType::RANDOM_IDENTITY_ADDRESS:
436 address_type = (uint8_t)AddressType::RANDOM_DEVICE_ADDRESS;
437 break;
438 }
439
440 const uint16_t result_event_type =
441 com::android::bluetooth::flags::fix_nonconnectable_scannable_advertisement()
442 ? processed_report->extended_event_type
443 : event_type;
444
445 scanning_callbacks_->OnScanResult(
446 result_event_type, address_type, address, primary_phy, secondary_phy, advertising_sid,
447 tx_power, get_rssi_after_calibration(rssi), periodic_advertising_interval,
448 std::move(processed_report->data));
449 }
450 }
451
configure_scanbluetooth::hci::LeScanningManager::impl452 void configure_scan() {
453 std::vector<PhyScanParameters> parameter_vector;
454 for (int i = 0; i < 7; i++) {
455 if ((phy_ & 1 << i) != 0) {
456 PhyScanParameters phy_scan_parameters;
457 phy_scan_parameters.le_scan_window_ = window_ms_;
458 phy_scan_parameters.le_scan_interval_ = interval_ms_;
459 phy_scan_parameters.le_scan_type_ = le_scan_type_;
460 parameter_vector.push_back(phy_scan_parameters);
461 }
462 }
463 uint8_t phys_in_use = phy_;
464
465 // The Host shall not issue set scan parameter command when scanning is enabled
466 stop_scan();
467
468 if (le_address_manager_->GetAddressPolicy() != LeAddressManager::USE_PUBLIC_ADDRESS) {
469 if (controller_->IsRpaGenerationSupported()) {
470 log::info("Support RPA offload, set own address type RESOLVABLE_OR_RANDOM_ADDRESS");
471 own_address_type_ = OwnAddressType::RESOLVABLE_OR_RANDOM_ADDRESS;
472 } else {
473 own_address_type_ = OwnAddressType::RANDOM_DEVICE_ADDRESS;
474 }
475 } else {
476 own_address_type_ = OwnAddressType::PUBLIC_DEVICE_ADDRESS;
477 }
478
479 switch (api_type_) {
480 case ScanApiType::EXTENDED:
481 le_scanning_interface_->EnqueueCommand(
482 LeSetExtendedScanParametersBuilder::Create(own_address_type_, filter_policy_,
483 phys_in_use, parameter_vector),
484 module_handler_->BindOnceOn(this, &impl::on_set_scan_parameter_complete));
485 break;
486 case ScanApiType::ANDROID_HCI:
487 le_scanning_interface_->EnqueueCommand(
488 LeExtendedScanParamsBuilder::Create(le_scan_type_, interval_ms_, window_ms_,
489 own_address_type_, filter_policy_),
490 module_handler_->BindOnceOn(this, &impl::on_set_scan_parameter_complete));
491
492 break;
493 case ScanApiType::LEGACY:
494 le_scanning_interface_->EnqueueCommand(
495
496 LeSetScanParametersBuilder::Create(le_scan_type_, interval_ms_, window_ms_,
497 own_address_type_, filter_policy_),
498 module_handler_->BindOnceOn(this, &impl::on_set_scan_parameter_complete));
499 break;
500 }
501 }
502
register_scannerbluetooth::hci::LeScanningManager::impl503 void register_scanner(const Uuid app_uuid) {
504 for (uint8_t i = 1; i <= kMaxAppNum; i++) {
505 if (scanners_[i].in_use && scanners_[i].app_uuid == app_uuid) {
506 log::error("Application already registered {}", app_uuid.ToString());
507 scanning_callbacks_->OnScannerRegistered(app_uuid, 0x00,
508 ScanningCallback::ScanningStatus::INTERNAL_ERROR);
509 return;
510 }
511 }
512
513 // valid value of scanner id : 1 ~ kMaxAppNum
514 for (uint8_t i = 1; i <= kMaxAppNum; i++) {
515 if (!scanners_[i].in_use) {
516 scanners_[i].app_uuid = app_uuid;
517 scanners_[i].in_use = true;
518 scanning_callbacks_->OnScannerRegistered(app_uuid, i,
519 ScanningCallback::ScanningStatus::SUCCESS);
520 return;
521 }
522 }
523
524 log::error("Unable to register scanner, max client reached:{}", kMaxAppNum);
525 scanning_callbacks_->OnScannerRegistered(app_uuid, 0x00,
526 ScanningCallback::ScanningStatus::NO_RESOURCES);
527 }
528
unregister_scannerbluetooth::hci::LeScanningManager::impl529 void unregister_scanner(ScannerId scanner_id) {
530 if (scanner_id <= 0 || scanner_id > kMaxAppNum) {
531 log::warn("Invalid scanner id");
532 return;
533 }
534
535 if (scanners_[scanner_id].in_use) {
536 scanners_[scanner_id].in_use = false;
537 scanners_[scanner_id].app_uuid = Uuid::kEmpty;
538 log::debug("Unregister scanner successful, scannerId={}", scanner_id);
539 } else {
540 log::warn("Unregister scanner with unused scanner id");
541 }
542 }
543
scanbluetooth::hci::LeScanningManager::impl544 void scan(bool start) {
545 // On-resume flag should always be reset if there is an explicit start/stop call.
546 scan_on_resume_ = false;
547 if (start) {
548 configure_scan();
549 start_scan();
550 } else {
551 if (address_manager_registered_) {
552 le_address_manager_->Unregister(this);
553 address_manager_registered_ = false;
554 paused_ = false;
555 }
556 stop_scan();
557 }
558 }
559
start_scanbluetooth::hci::LeScanningManager::impl560 void start_scan() {
561 // If we receive start_scan during paused, set scan_on_resume_ to true
562 if (paused_ && address_manager_registered_) {
563 scan_on_resume_ = true;
564 return;
565 }
566 is_scanning_ = true;
567 if (!address_manager_registered_) {
568 le_address_manager_->Register(this);
569 address_manager_registered_ = true;
570 }
571
572 switch (api_type_) {
573 case ScanApiType::EXTENDED:
574 le_scanning_interface_->EnqueueCommand(
575 LeSetExtendedScanEnableBuilder::Create(
576 Enable::ENABLED,
577 #if TARGET_FLOSS
578 FilterDuplicates::ENABLED /* filter duplicates */,
579 #else
580 FilterDuplicates::DISABLED /* filter duplicates */,
581 #endif
582 0, 0),
583 module_handler_->BindOnce(check_complete<LeSetExtendedScanEnableCompleteView>));
584 break;
585 case ScanApiType::ANDROID_HCI:
586 case ScanApiType::LEGACY:
587 le_scanning_interface_->EnqueueCommand(
588 LeSetScanEnableBuilder::Create(Enable::ENABLED,
589 Enable::DISABLED /* filter duplicates */),
590 module_handler_->BindOnce(check_complete<LeSetScanEnableCompleteView>));
591 break;
592 }
593 }
594
stop_scanbluetooth::hci::LeScanningManager::impl595 void stop_scan() {
596 if (!is_scanning_) {
597 log::info("Scanning already stopped, return!");
598 return;
599 }
600 is_scanning_ = false;
601
602 switch (api_type_) {
603 case ScanApiType::EXTENDED:
604 le_scanning_interface_->EnqueueCommand(
605 LeSetExtendedScanEnableBuilder::Create(
606 Enable::DISABLED,
607 #if TARGET_FLOSS
608 FilterDuplicates::ENABLED /* filter duplicates */,
609 #else
610 FilterDuplicates::DISABLED /* filter duplicates */,
611 #endif
612 0, 0),
613 module_handler_->BindOnce(check_complete<LeSetExtendedScanEnableCompleteView>));
614 break;
615 case ScanApiType::ANDROID_HCI:
616 case ScanApiType::LEGACY:
617 le_scanning_interface_->EnqueueCommand(
618 LeSetScanEnableBuilder::Create(Enable::DISABLED,
619 Enable::DISABLED /* filter duplicates */),
620 module_handler_->BindOnce(check_complete<LeSetScanEnableCompleteView>));
621 break;
622 }
623 }
624
set_scan_parametersbluetooth::hci::LeScanningManager::impl625 void set_scan_parameters(ScannerId scanner_id, LeScanType scan_type, uint16_t scan_interval,
626 uint16_t scan_window, uint8_t scan_phy) {
627 uint32_t max_scan_interval = kLeScanIntervalMax;
628 uint32_t max_scan_window = kLeScanWindowMax;
629 if (api_type_ == ScanApiType::EXTENDED) {
630 max_scan_interval = kLeExtendedScanIntervalMax;
631 max_scan_window = kLeExtendedScanWindowMax;
632 }
633
634 if (scan_type != LeScanType::ACTIVE && scan_type != LeScanType::PASSIVE) {
635 log::error("Invalid scan type");
636 scanning_callbacks_->OnSetScannerParameterComplete(
637 scanner_id, ScanningCallback::ScanningStatus::ILLEGAL_PARAMETER);
638 return;
639 }
640 if (scan_interval > max_scan_interval || scan_interval < kLeScanIntervalMin) {
641 log::error("Invalid scan_interval {}", scan_interval);
642 scanning_callbacks_->OnSetScannerParameterComplete(
643 scanner_id, ScanningCallback::ScanningStatus::ILLEGAL_PARAMETER);
644 return;
645 }
646 if (scan_window > max_scan_window || scan_window < kLeScanWindowMin) {
647 log::error("Invalid scan_window {}", scan_window);
648 scanning_callbacks_->OnSetScannerParameterComplete(
649 scanner_id, ScanningCallback::ScanningStatus::ILLEGAL_PARAMETER);
650 return;
651 }
652 le_scan_type_ = scan_type;
653 interval_ms_ = scan_interval;
654 window_ms_ = scan_window;
655 if (com::android::bluetooth::flags::phy_to_native()) {
656 phy_ = scan_phy;
657 }
658 scanning_callbacks_->OnSetScannerParameterComplete(scanner_id, ScanningCallback::SUCCESS);
659 }
660
set_scan_filter_policybluetooth::hci::LeScanningManager::impl661 void set_scan_filter_policy(LeScanningFilterPolicy filter_policy) {
662 filter_policy_ = filter_policy;
663 }
664
scan_filter_enablebluetooth::hci::LeScanningManager::impl665 void scan_filter_enable(bool enable) {
666 if (!is_filter_supported_) {
667 log::warn("Advertising filter is not supported");
668 return;
669 }
670
671 Enable apcf_enable = enable ? Enable::ENABLED : Enable::DISABLED;
672 le_scanning_interface_->EnqueueCommand(
673 LeAdvFilterEnableBuilder::Create(apcf_enable),
674 module_handler_->BindOnceOn(this, &impl::on_advertising_filter_complete));
675 }
676
is_bondedbluetooth::hci::LeScanningManager::impl677 bool is_bonded(Address target_address) {
678 for (auto device : storage_module_->GetBondedDevices()) {
679 if (device.GetAddress() == target_address) {
680 log::debug("Addresses match!");
681 return true;
682 }
683 }
684 log::debug("Addresse DON'Ts match!");
685 return false;
686 }
687
scan_filter_parameter_setupbluetooth::hci::LeScanningManager::impl688 void scan_filter_parameter_setup(ApcfAction action, uint8_t filter_index,
689 AdvertisingFilterParameter advertising_filter_parameter) {
690 if (!is_filter_supported_) {
691 log::warn("Advertising filter is not supported");
692 return;
693 }
694
695 auto entry = remove_me_later_map_.find(filter_index);
696 switch (action) {
697 case ApcfAction::ADD:
698 le_scanning_interface_->EnqueueCommand(
699 LeAdvFilterAddFilteringParametersBuilder::Create(
700 filter_index, advertising_filter_parameter.feature_selection,
701 advertising_filter_parameter.list_logic_type,
702 advertising_filter_parameter.filter_logic_type,
703 advertising_filter_parameter.rssi_high_thresh,
704 advertising_filter_parameter.delivery_mode,
705 advertising_filter_parameter.onfound_timeout,
706 advertising_filter_parameter.onfound_timeout_cnt,
707 advertising_filter_parameter.rssi_low_thresh,
708 advertising_filter_parameter.onlost_timeout,
709 advertising_filter_parameter.num_of_tracking_entries),
710 module_handler_->BindOnceOn(this, &impl::on_advertising_filter_complete));
711 break;
712 case ApcfAction::DELETE:
713 tracker_id_map_.erase(filter_index);
714 le_scanning_interface_->EnqueueCommand(
715 LeAdvFilterDeleteFilteringParametersBuilder::Create(filter_index),
716 module_handler_->BindOnceOn(this, &impl::on_advertising_filter_complete));
717
718 // IRK Scanning
719 if (entry != remove_me_later_map_.end()) {
720 // Don't want to remove for a bonded device
721 if (!is_bonded(entry->second.GetAddress())) {
722 le_address_manager_->RemoveDeviceFromResolvingList(
723 static_cast<PeerAddressType>(entry->second.GetAddressType()),
724 entry->second.GetAddress());
725 }
726 remove_me_later_map_.erase(filter_index);
727 }
728
729 break;
730 case ApcfAction::CLEAR:
731 le_scanning_interface_->EnqueueCommand(
732 LeAdvFilterClearFilteringParametersBuilder::Create(),
733 module_handler_->BindOnceOn(this, &impl::on_advertising_filter_complete));
734
735 // IRK Scanning
736 if (entry != remove_me_later_map_.end()) {
737 // Don't want to remove for a bonded device
738 if (!is_bonded(entry->second.GetAddress())) {
739 le_address_manager_->RemoveDeviceFromResolvingList(
740 static_cast<PeerAddressType>(entry->second.GetAddressType()),
741 entry->second.GetAddress());
742 }
743 remove_me_later_map_.erase(filter_index);
744 }
745
746 break;
747 default:
748 log::error("Unknown action type: {}", (uint16_t)action);
749 break;
750 }
751 }
752
scan_filter_addbluetooth::hci::LeScanningManager::impl753 void scan_filter_add(uint8_t filter_index,
754 std::vector<AdvertisingPacketContentFilterCommand> filters) {
755 if (!is_filter_supported_) {
756 log::warn("Advertising filter is not supported");
757 return;
758 }
759
760 ApcfAction apcf_action = ApcfAction::ADD;
761 for (auto filter : filters) {
762 /* If data is passed, both mask and data have to be the same length */
763 if (filter.data.size() != filter.data_mask.size() && filter.data.size() != 0 &&
764 filter.data_mask.size() != 0) {
765 log::error("data and data_mask are of different size");
766 continue;
767 }
768
769 switch (filter.filter_type) {
770 case ApcfFilterType::BROADCASTER_ADDRESS: {
771 update_address_filter(apcf_action, filter_index, filter.address,
772 filter.application_address_type, filter.irk);
773 break;
774 }
775 case ApcfFilterType::SERVICE_UUID:
776 case ApcfFilterType::SERVICE_SOLICITATION_UUID: {
777 update_uuid_filter(apcf_action, filter_index, filter.filter_type, filter.uuid,
778 filter.uuid_mask);
779 break;
780 }
781 case ApcfFilterType::LOCAL_NAME: {
782 update_local_name_filter(apcf_action, filter_index, filter.name);
783 break;
784 }
785 case ApcfFilterType::MANUFACTURER_DATA: {
786 update_manufacturer_data_filter(apcf_action, filter_index, filter.company,
787 filter.company_mask, filter.data, filter.data_mask);
788 break;
789 }
790 case ApcfFilterType::SERVICE_DATA: {
791 update_service_data_filter(apcf_action, filter_index, filter.data, filter.data_mask);
792 break;
793 }
794 case ApcfFilterType::TRANSPORT_DISCOVERY_DATA: {
795 update_transport_discovery_data_filter(
796 apcf_action, filter_index, filter.org_id, filter.tds_flags, filter.tds_flags_mask,
797 filter.data, filter.data_mask, filter.meta_data_type, filter.meta_data);
798 break;
799 }
800 case ApcfFilterType::AD_TYPE: {
801 update_ad_type_filter(apcf_action, filter_index, filter.ad_type, filter.data,
802 filter.data_mask);
803 break;
804 }
805 default:
806 log::error("Unknown filter type: {}", (uint16_t)filter.filter_type);
807 break;
808 }
809 }
810 }
811
812 std::unordered_map<uint8_t, AddressWithType> remove_me_later_map_;
813
update_address_filterbluetooth::hci::LeScanningManager::impl814 void update_address_filter(ApcfAction action, uint8_t filter_index, Address address,
815 ApcfApplicationAddressType address_type, std::array<uint8_t, 16> irk) {
816 if (action != ApcfAction::CLEAR) {
817 /*
818 * The vendor command (APCF Filtering 0x0157) takes Public (0) or Random (1)
819 * or Addresses type not applicable (2).
820 *
821 * Advertising results have four types:
822 *  - Public = 0
823 *  - Random = 1
824 *  - Public ID = 2
825 *  - Random ID = 3
826 *
827 * e.g. specifying PUBLIC (0) will only return results with a public
828 * address. It will ignore resolved addresses, since they return PUBLIC
829 * IDENTITY (2). For this, Addresses type not applicable (0x02) must be specified.
830 * This should also cover if the RPA is derived from RANDOM STATIC.
831 */
832 le_scanning_interface_->EnqueueCommand(
833 LeAdvFilterBroadcasterAddressBuilder::Create(
834 action, filter_index, address, ApcfApplicationAddressType::NOT_APPLICABLE),
835 module_handler_->BindOnceOn(this, &impl::on_advertising_filter_complete));
836 if (!is_empty_128bit(irk)) {
837 // If an entry exists for this filter index, replace data because the filter has been
838 // updated.
839 auto entry = remove_me_later_map_.find(filter_index);
840 // IRK Scanning
841 if (entry != remove_me_later_map_.end()) {
842 // Don't want to remove for a bonded device
843 if (!is_bonded(entry->second.GetAddress())) {
844 le_address_manager_->RemoveDeviceFromResolvingList(
845 static_cast<PeerAddressType>(entry->second.GetAddressType()),
846 entry->second.GetAddress());
847 }
848 remove_me_later_map_.erase(filter_index);
849 }
850
851 // Now replace it with a new one
852 std::array<uint8_t, 16> empty_irk;
853 le_address_manager_->AddDeviceToResolvingList(static_cast<PeerAddressType>(address_type),
854 address, irk, empty_irk);
855 remove_me_later_map_.emplace(
856 filter_index, AddressWithType(address, static_cast<AddressType>(address_type)));
857 }
858 } else {
859 le_scanning_interface_->EnqueueCommand(
860 LeAdvFilterClearBroadcasterAddressBuilder::Create(filter_index),
861 module_handler_->BindOnceOn(this, &impl::on_advertising_filter_complete));
862 auto entry = remove_me_later_map_.find(filter_index);
863 if (entry != remove_me_later_map_.end()) {
864 // TODO(optedoblivion): If not bonded
865 le_address_manager_->RemoveDeviceFromResolvingList(
866 static_cast<PeerAddressType>(address_type), address);
867 remove_me_later_map_.erase(filter_index);
868 }
869 }
870 }
871
is_empty_128bitbluetooth::hci::LeScanningManager::impl872 bool is_empty_128bit(const std::array<uint8_t, 16> data) {
873 for (int i = 0; i < 16; i++) {
874 if (data[i] != (uint8_t)0) {
875 return false;
876 }
877 }
878 return true;
879 }
880
update_uuid_filterbluetooth::hci::LeScanningManager::impl881 void update_uuid_filter(ApcfAction action, uint8_t filter_index, ApcfFilterType filter_type,
882 Uuid uuid, Uuid uuid_mask) {
883 std::vector<uint8_t> combined_data = {};
884 if (action != ApcfAction::CLEAR) {
885 uint8_t uuid_len = uuid.GetShortestRepresentationSize();
886 if (uuid_len == Uuid::kNumBytes16) {
887 uint16_t data = uuid.As16Bit();
888 combined_data.push_back((uint8_t)data);
889 combined_data.push_back((uint8_t)(data >> 8));
890 } else if (uuid_len == Uuid::kNumBytes32) {
891 uint32_t data = uuid.As32Bit();
892 combined_data.push_back((uint8_t)data);
893 combined_data.push_back((uint8_t)(data >> 8));
894 combined_data.push_back((uint8_t)(data >> 16));
895 combined_data.push_back((uint8_t)(data >> 24));
896 } else if (uuid_len == Uuid::kNumBytes128) {
897 auto data = uuid.To128BitLE();
898 combined_data.insert(combined_data.end(), data.begin(), data.end());
899 } else {
900 log::error("illegal UUID length: {}", (uint16_t)uuid_len);
901 return;
902 }
903
904 if (!uuid_mask.IsEmpty()) {
905 if (uuid_len == Uuid::kNumBytes16) {
906 uint16_t data = uuid_mask.As16Bit();
907 combined_data.push_back((uint8_t)data);
908 combined_data.push_back((uint8_t)(data >> 8));
909 } else if (uuid_len == Uuid::kNumBytes32) {
910 uint32_t data = uuid_mask.As32Bit();
911 combined_data.push_back((uint8_t)data);
912 combined_data.push_back((uint8_t)(data >> 8));
913 combined_data.push_back((uint8_t)(data >> 16));
914 combined_data.push_back((uint8_t)(data >> 24));
915 } else if (uuid_len == Uuid::kNumBytes128) {
916 auto data = uuid_mask.To128BitLE();
917 combined_data.insert(combined_data.end(), data.begin(), data.end());
918 }
919 } else {
920 std::vector<uint8_t> data(uuid_len, 0xFF);
921 combined_data.insert(combined_data.end(), data.begin(), data.end());
922 }
923 }
924
925 if (filter_type == ApcfFilterType::SERVICE_UUID) {
926 le_scanning_interface_->EnqueueCommand(
927 LeAdvFilterServiceUuidBuilder::Create(action, filter_index, combined_data),
928 module_handler_->BindOnceOn(this, &impl::on_advertising_filter_complete));
929 } else {
930 le_scanning_interface_->EnqueueCommand(
931 LeAdvFilterSolicitationUuidBuilder::Create(action, filter_index, combined_data),
932 module_handler_->BindOnceOn(this, &impl::on_advertising_filter_complete));
933 }
934 }
935
update_local_name_filterbluetooth::hci::LeScanningManager::impl936 void update_local_name_filter(ApcfAction action, uint8_t filter_index,
937 std::vector<uint8_t> name) {
938 le_scanning_interface_->EnqueueCommand(
939 LeAdvFilterLocalNameBuilder::Create(action, filter_index, name),
940 module_handler_->BindOnceOn(this, &impl::on_advertising_filter_complete));
941 }
942
update_manufacturer_data_filterbluetooth::hci::LeScanningManager::impl943 void update_manufacturer_data_filter(ApcfAction action, uint8_t filter_index, uint16_t company_id,
944 uint16_t company_id_mask, std::vector<uint8_t> data,
945 std::vector<uint8_t> data_mask) {
946 if (data.size() != data_mask.size()) {
947 log::error("manufacturer data mask should have the same length as manufacturer data");
948 return;
949 }
950 std::vector<uint8_t> combined_data = {};
951 if (action != ApcfAction::CLEAR) {
952 combined_data.push_back((uint8_t)company_id);
953 combined_data.push_back((uint8_t)(company_id >> 8));
954 if (data.size() != 0) {
955 combined_data.insert(combined_data.end(), data.begin(), data.end());
956 }
957 if (company_id_mask != 0) {
958 combined_data.push_back((uint8_t)company_id_mask);
959 combined_data.push_back((uint8_t)(company_id_mask >> 8));
960 } else {
961 combined_data.push_back(0xFF);
962 combined_data.push_back(0xFF);
963 }
964 if (data_mask.size() != 0) {
965 combined_data.insert(combined_data.end(), data_mask.begin(), data_mask.end());
966 }
967 }
968
969 le_scanning_interface_->EnqueueCommand(
970 LeAdvFilterManufacturerDataBuilder::Create(action, filter_index, combined_data),
971 module_handler_->BindOnceOn(this, &impl::on_advertising_filter_complete));
972 }
973
update_service_data_filterbluetooth::hci::LeScanningManager::impl974 void update_service_data_filter(ApcfAction action, uint8_t filter_index,
975 std::vector<uint8_t> data, std::vector<uint8_t> data_mask) {
976 if (data.size() != data_mask.size()) {
977 log::error("service data mask should have the same length as service data");
978 return;
979 }
980 std::vector<uint8_t> combined_data = {};
981 if (action != ApcfAction::CLEAR && data.size() != 0) {
982 combined_data.insert(combined_data.end(), data.begin(), data.end());
983 combined_data.insert(combined_data.end(), data_mask.begin(), data_mask.end());
984 }
985
986 le_scanning_interface_->EnqueueCommand(
987 LeAdvFilterServiceDataBuilder::Create(action, filter_index, combined_data),
988 module_handler_->BindOnceOn(this, &impl::on_advertising_filter_complete));
989 }
990
update_transport_discovery_data_filterbluetooth::hci::LeScanningManager::impl991 void update_transport_discovery_data_filter(ApcfAction action, uint8_t filter_index,
992 uint8_t org_id, uint8_t tds_flags,
993 uint8_t tds_flags_mask,
994 std::vector<uint8_t> transport_data,
995 std::vector<uint8_t> transport_data_mask,
996 ApcfMetaDataType meta_data_type,
997 std::vector<uint8_t> meta_data) {
998 LocalVersionInformation local_version_information = controller_->GetLocalVersionInformation();
999
1000 // In QTI controller, transport discovery data filter are supported by default. Check is added
1001 // to keep backward compatibility.
1002 if (!is_transport_discovery_data_filter_supported_ &&
1003 !(local_version_information.manufacturer_name_ == LMP_COMPID_QTI)) {
1004 log::warn("transport discovery data filter isn't supported");
1005 return;
1006 }
1007
1008 log::info(
1009 "org id: {}, tds_flags: {}, tds_flags_mask: {}, transport_data size: {}, "
1010 "transport_data_mask size: {}, meta_data_type: {}, meta_data size: {}",
1011 org_id, tds_flags, tds_flags_mask, transport_data.size(), transport_data_mask.size(),
1012 (uint8_t)meta_data_type, meta_data.size());
1013
1014 // 0x02 Wi-Fi Alliance Neighbor Awareness Networking & meta_data_type is 0x01 for NAN Hash.
1015 if (org_id == 0x02) {
1016 // meta data contains WIFI NAN hash, reverse it before sending controller.
1017 switch (meta_data_type) {
1018 case ApcfMetaDataType::WIFI_NAN_HASH:
1019 std::reverse(meta_data.begin(), meta_data.end());
1020 break;
1021 default:
1022 break;
1023 }
1024 }
1025
1026 if (is_transport_discovery_data_filter_supported_) {
1027 le_scanning_interface_->EnqueueCommand(
1028 LeAdvFilterTransportDiscoveryDataBuilder::Create(
1029 action, filter_index, org_id, tds_flags, tds_flags_mask, transport_data,
1030 transport_data_mask, meta_data_type, meta_data),
1031 module_handler_->BindOnceOn(this, &impl::on_advertising_filter_complete));
1032 } else {
1033 // In QTI controller, transport discovery data filter are supported by default.
1034 // keeping old version for backward compatibility
1035 std::vector<uint8_t> combined_data = {};
1036 if (action != ApcfAction::CLEAR) {
1037 combined_data.push_back((uint8_t)org_id);
1038 combined_data.push_back((uint8_t)tds_flags);
1039 combined_data.push_back((uint8_t)tds_flags_mask);
1040 if (org_id == 0x02 && meta_data_type == ApcfMetaDataType::WIFI_NAN_HASH) {
1041 // meta data contains WIFI NAN hash
1042 combined_data.insert(combined_data.end(), meta_data.begin(), meta_data.end());
1043 }
1044 }
1045 le_scanning_interface_->EnqueueCommand(
1046 LeAdvFilterTransportDiscoveryDataOldBuilder::Create(action, filter_index,
1047 combined_data),
1048 module_handler_->BindOnceOn(this, &impl::on_advertising_filter_complete));
1049 }
1050 }
1051
update_ad_type_filterbluetooth::hci::LeScanningManager::impl1052 void update_ad_type_filter(ApcfAction action, uint8_t filter_index, uint8_t ad_type,
1053 std::vector<uint8_t> data, std::vector<uint8_t> data_mask) {
1054 if (!is_ad_type_filter_supported_) {
1055 log::error("AD type filter isn't supported");
1056 return;
1057 }
1058
1059 if (data.size() != data_mask.size()) {
1060 log::error("ad type mask should have the same length as ad type data");
1061 return;
1062 }
1063 std::vector<uint8_t> combined_data = {};
1064 if (action != ApcfAction::CLEAR) {
1065 combined_data.push_back((uint8_t)ad_type);
1066 combined_data.push_back((uint8_t)(data.size()));
1067 if (data.size() != 0) {
1068 combined_data.insert(combined_data.end(), data.begin(), data.end());
1069 combined_data.insert(combined_data.end(), data_mask.begin(), data_mask.end());
1070 }
1071 }
1072
1073 le_scanning_interface_->EnqueueCommand(
1074 LeAdvFilterADTypeBuilder::Create(action, filter_index, combined_data),
1075 module_handler_->BindOnceOn(this, &impl::on_advertising_filter_complete));
1076 }
1077
batch_scan_set_storage_parameterbluetooth::hci::LeScanningManager::impl1078 void batch_scan_set_storage_parameter(uint8_t batch_scan_full_max,
1079 uint8_t batch_scan_truncated_max,
1080 uint8_t batch_scan_notify_threshold, ScannerId scanner_id) {
1081 if (!is_batch_scan_supported_) {
1082 log::warn("Batch scan is not supported");
1083 return;
1084 }
1085 // scanner id for OnBatchScanThresholdCrossed
1086 batch_scan_config_.ref_value = scanner_id;
1087
1088 if (batch_scan_config_.current_state == BatchScanState::ERROR_STATE ||
1089 batch_scan_config_.current_state == BatchScanState::DISABLED_STATE ||
1090 batch_scan_config_.current_state == BatchScanState::DISABLE_CALLED) {
1091 batch_scan_config_.current_state = BatchScanState::ENABLE_CALLED;
1092 le_scanning_interface_->EnqueueCommand(
1093 LeBatchScanEnableBuilder::Create(Enable::ENABLED),
1094 module_handler_->BindOnceOn(this, &impl::on_batch_scan_enable_complete));
1095 }
1096
1097 le_scanning_interface_->EnqueueCommand(
1098 LeBatchScanSetStorageParametersBuilder::Create(
1099 batch_scan_full_max, batch_scan_truncated_max, batch_scan_notify_threshold),
1100 module_handler_->BindOnceOn(this, &impl::on_batch_scan_complete));
1101 }
1102
batch_scan_enablebluetooth::hci::LeScanningManager::impl1103 void batch_scan_enable(BatchScanMode scan_mode, uint32_t duty_cycle_scan_window_slots,
1104 uint32_t duty_cycle_scan_interval_slots,
1105 BatchScanDiscardRule batch_scan_discard_rule) {
1106 if (!is_batch_scan_supported_) {
1107 log::warn("Batch scan is not supported");
1108 return;
1109 }
1110
1111 if (batch_scan_config_.current_state == BatchScanState::ERROR_STATE ||
1112 batch_scan_config_.current_state == BatchScanState::DISABLED_STATE ||
1113 batch_scan_config_.current_state == BatchScanState::DISABLE_CALLED) {
1114 batch_scan_config_.current_state = BatchScanState::ENABLE_CALLED;
1115 le_scanning_interface_->EnqueueCommand(
1116 LeBatchScanEnableBuilder::Create(Enable::ENABLED),
1117 module_handler_->BindOnceOn(this, &impl::on_batch_scan_enable_complete));
1118 }
1119
1120 batch_scan_config_.scan_mode = scan_mode;
1121 batch_scan_config_.scan_interval = duty_cycle_scan_interval_slots;
1122 batch_scan_config_.scan_window = duty_cycle_scan_window_slots;
1123 batch_scan_config_.discard_rule = batch_scan_discard_rule;
1124 /* This command starts batch scanning, if enabled */
1125 batch_scan_set_scan_parameter(scan_mode, duty_cycle_scan_window_slots,
1126 duty_cycle_scan_interval_slots, batch_scan_discard_rule);
1127 }
1128
batch_scan_disablebluetooth::hci::LeScanningManager::impl1129 void batch_scan_disable() {
1130 if (!is_batch_scan_supported_) {
1131 log::warn("Batch scan is not supported");
1132 return;
1133 }
1134 batch_scan_config_.current_state = BatchScanState::DISABLE_CALLED;
1135 batch_scan_set_scan_parameter(BatchScanMode::DISABLE, batch_scan_config_.scan_window,
1136 batch_scan_config_.scan_interval,
1137 batch_scan_config_.discard_rule);
1138 }
1139
batch_scan_set_scan_parameterbluetooth::hci::LeScanningManager::impl1140 void batch_scan_set_scan_parameter(BatchScanMode scan_mode, uint32_t duty_cycle_scan_window_slots,
1141 uint32_t duty_cycle_scan_interval_slots,
1142 BatchScanDiscardRule batch_scan_discard_rule) {
1143 if (!is_batch_scan_supported_) {
1144 log::warn("Batch scan is not supported");
1145 return;
1146 }
1147 PeerAddressType own_address_type = PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS;
1148 if (own_address_type_ == OwnAddressType::RANDOM_DEVICE_ADDRESS ||
1149 own_address_type_ == OwnAddressType::RESOLVABLE_OR_RANDOM_ADDRESS) {
1150 own_address_type = PeerAddressType::RANDOM_DEVICE_OR_IDENTITY_ADDRESS;
1151 }
1152 uint8_t truncated_mode_enabled = 0x00;
1153 uint8_t full_mode_enabled = 0x00;
1154 if (scan_mode == BatchScanMode::TRUNCATED || scan_mode == BatchScanMode::TRUNCATED_AND_FULL) {
1155 truncated_mode_enabled = 0x01;
1156 }
1157 if (scan_mode == BatchScanMode::FULL || scan_mode == BatchScanMode::TRUNCATED_AND_FULL) {
1158 full_mode_enabled = 0x01;
1159 }
1160
1161 if (scan_mode == BatchScanMode::DISABLE) {
1162 le_scanning_interface_->EnqueueCommand(
1163 LeBatchScanSetScanParametersBuilder::Create(
1164 truncated_mode_enabled, full_mode_enabled, duty_cycle_scan_window_slots,
1165 duty_cycle_scan_interval_slots, own_address_type, batch_scan_discard_rule),
1166 module_handler_->BindOnceOn(this, &impl::on_batch_scan_disable_complete));
1167 } else {
1168 le_scanning_interface_->EnqueueCommand(
1169 LeBatchScanSetScanParametersBuilder::Create(
1170 truncated_mode_enabled, full_mode_enabled, duty_cycle_scan_window_slots,
1171 duty_cycle_scan_interval_slots, own_address_type, batch_scan_discard_rule),
1172 module_handler_->BindOnceOn(this, &impl::on_batch_scan_complete));
1173 }
1174 }
1175
batch_scan_read_resultsbluetooth::hci::LeScanningManager::impl1176 void batch_scan_read_results(ScannerId scanner_id, uint16_t total_num_of_records,
1177 BatchScanMode scan_mode) {
1178 if (!is_batch_scan_supported_) {
1179 log::warn("Batch scan is not supported");
1180 int status = static_cast<int>(ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE);
1181 scanning_callbacks_->OnBatchScanReports(scanner_id, status, 0, 0, {});
1182 return;
1183 }
1184
1185 if (scan_mode != BatchScanMode::FULL && scan_mode != BatchScanMode::TRUNCATED) {
1186 log::warn("Invalid scan mode {}", (uint16_t)scan_mode);
1187 int status = static_cast<int>(ErrorCode::INVALID_HCI_COMMAND_PARAMETERS);
1188 scanning_callbacks_->OnBatchScanReports(scanner_id, status, 0, 0, {});
1189 return;
1190 }
1191
1192 if (batch_scan_result_cache_.find(scanner_id) == batch_scan_result_cache_.end()) {
1193 std::vector<uint8_t> empty_data = {};
1194 batch_scan_result_cache_.emplace(scanner_id, empty_data);
1195 }
1196
1197 le_scanning_interface_->EnqueueCommand(
1198 LeBatchScanReadResultParametersBuilder::Create(
1199 static_cast<BatchScanDataRead>(scan_mode)),
1200 module_handler_->BindOnceOn(this, &impl::on_batch_scan_read_result_complete, scanner_id,
1201 total_num_of_records));
1202 }
1203
start_syncbluetooth::hci::LeScanningManager::impl1204 void start_sync(uint8_t sid, const AddressWithType& address_with_type, uint16_t skip,
1205 uint16_t timeout, int request_id) {
1206 if (!is_periodic_advertising_sync_transfer_sender_supported_) {
1207 log::warn("PAST sender not supported on this device");
1208 int status = static_cast<int>(ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE);
1209 scanning_callbacks_->OnPeriodicSyncStarted(request_id, status, -1, sid, address_with_type, 0,
1210 0);
1211 return;
1212 }
1213 PeriodicSyncStates request{
1214 .request_id = request_id,
1215 .advertiser_sid = sid,
1216 .address_with_type = address_with_type,
1217 .sync_handle = 0,
1218 .sync_state = PeriodicSyncState::PERIODIC_SYNC_STATE_IDLE,
1219 };
1220 periodic_sync_manager_.StartSync(request, skip, timeout);
1221 }
1222
stop_syncbluetooth::hci::LeScanningManager::impl1223 void stop_sync(uint16_t handle) {
1224 if (!is_periodic_advertising_sync_transfer_sender_supported_) {
1225 log::warn("PAST sender not supported on this device");
1226 return;
1227 }
1228 periodic_sync_manager_.StopSync(handle);
1229 }
1230
cancel_create_syncbluetooth::hci::LeScanningManager::impl1231 void cancel_create_sync(uint8_t sid, const Address& address) {
1232 if (!is_periodic_advertising_sync_transfer_sender_supported_) {
1233 log::warn("PAST sender not supported on this device");
1234 return;
1235 }
1236 periodic_sync_manager_.CancelCreateSync(sid, address);
1237 }
1238
transfer_syncbluetooth::hci::LeScanningManager::impl1239 void transfer_sync(const Address& address, uint16_t connection_handle, uint16_t service_data,
1240 uint16_t sync_handle, int pa_source) {
1241 if (!is_periodic_advertising_sync_transfer_sender_supported_) {
1242 log::warn("PAST sender not supported on this device");
1243 int status = static_cast<int>(ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE);
1244 scanning_callbacks_->OnPeriodicSyncTransferred(pa_source, status, address);
1245 return;
1246 }
1247 if (connection_handle == 0xFFFF) {
1248 log::error("[PAST]: Invalid connection handle or no LE ACL link");
1249 int status = static_cast<int>(ErrorCode::UNKNOWN_CONNECTION);
1250 scanning_callbacks_->OnPeriodicSyncTransferred(pa_source, status, address);
1251 return;
1252 }
1253 periodic_sync_manager_.TransferSync(address, service_data, sync_handle, pa_source,
1254 connection_handle);
1255 }
1256
transfer_set_infobluetooth::hci::LeScanningManager::impl1257 void transfer_set_info(const Address& address, uint16_t connection_handle, uint16_t service_data,
1258 uint8_t adv_handle, int pa_source) {
1259 if (!is_periodic_advertising_sync_transfer_sender_supported_) {
1260 log::warn("PAST sender not supported on this device");
1261 int status = static_cast<int>(ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE);
1262 scanning_callbacks_->OnPeriodicSyncTransferred(pa_source, status, address);
1263 return;
1264 }
1265 if (connection_handle == 0xFFFF) {
1266 log::error("[PAST]:Invalid connection handle or no LE ACL link");
1267 int status = static_cast<int>(ErrorCode::UNKNOWN_CONNECTION);
1268 scanning_callbacks_->OnPeriodicSyncTransferred(pa_source, status, address);
1269 return;
1270 }
1271 periodic_sync_manager_.SyncSetInfo(address, service_data, adv_handle, pa_source,
1272 connection_handle);
1273 }
1274
sync_tx_parametersbluetooth::hci::LeScanningManager::impl1275 void sync_tx_parameters(const Address& address, uint8_t mode, uint16_t skip, uint16_t timeout,
1276 int reg_id) {
1277 if (!is_periodic_advertising_sync_transfer_sender_supported_) {
1278 log::warn("PAST sender not supported on this device");
1279 int status = static_cast<int>(ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE);
1280 AddressWithType address_with_type(address, AddressType::RANDOM_DEVICE_ADDRESS);
1281 scanning_callbacks_->OnPeriodicSyncStarted(reg_id, status, -1, -1, address_with_type, 0, 0);
1282 return;
1283 }
1284 periodic_sync_manager_.SyncTxParameters(address, mode, skip, timeout, reg_id);
1285 }
1286
track_advertiserbluetooth::hci::LeScanningManager::impl1287 void track_advertiser(uint8_t filter_index, ScannerId scanner_id) {
1288 if (total_num_of_advt_tracked_ <= 0) {
1289 log::warn("advertisement tracking is not supported");
1290 AdvertisingFilterOnFoundOnLostInfo on_found_on_lost_info = {};
1291 on_found_on_lost_info.scanner_id = scanner_id;
1292 on_found_on_lost_info.advertiser_info_present = AdvtInfoPresent::NO_ADVT_INFO_PRESENT;
1293 scanning_callbacks_->OnTrackAdvFoundLost(on_found_on_lost_info);
1294 return;
1295 } else if (tracker_id_map_.size() >= total_num_of_advt_tracked_) {
1296 AdvertisingFilterOnFoundOnLostInfo on_found_on_lost_info = {};
1297 on_found_on_lost_info.scanner_id = scanner_id;
1298 on_found_on_lost_info.advertiser_info_present = AdvtInfoPresent::NO_ADVT_INFO_PRESENT;
1299 scanning_callbacks_->OnTrackAdvFoundLost(on_found_on_lost_info);
1300 return;
1301 }
1302 log::info("track_advertiser scanner_id {}, filter_index {}", (uint16_t)scanner_id,
1303 (uint16_t)filter_index);
1304 tracker_id_map_[filter_index] = scanner_id;
1305 }
1306
register_scanning_callbackbluetooth::hci::LeScanningManager::impl1307 void register_scanning_callback(ScanningCallback* scanning_callbacks) {
1308 scanning_callbacks_ = scanning_callbacks;
1309 periodic_sync_manager_.SetScanningCallback(scanning_callbacks_);
1310 }
1311
is_ad_type_filter_supportedbluetooth::hci::LeScanningManager::impl1312 bool is_ad_type_filter_supported() { return is_ad_type_filter_supported_; }
1313
on_set_scan_parameter_completebluetooth::hci::LeScanningManager::impl1314 void on_set_scan_parameter_complete(CommandCompleteView view) {
1315 switch (view.GetCommandOpCode()) {
1316 case (OpCode::LE_SET_SCAN_PARAMETERS): {
1317 auto status_view = LeSetScanParametersCompleteView::Create(view);
1318 log::assert_that(status_view.IsValid(), "assert failed: status_view.IsValid()");
1319 if (status_view.GetStatus() != ErrorCode::SUCCESS) {
1320 log::info("Receive set scan parameter complete with error code {}",
1321 ErrorCodeText(status_view.GetStatus()));
1322 }
1323 } break;
1324 case (OpCode::LE_EXTENDED_SCAN_PARAMS): {
1325 auto status_view = LeExtendedScanParamsCompleteView::Create(view);
1326 log::assert_that(status_view.IsValid(), "assert failed: status_view.IsValid()");
1327 if (status_view.GetStatus() != ErrorCode::SUCCESS) {
1328 log::info("Receive extended scan parameter complete with error code {}",
1329 ErrorCodeText(status_view.GetStatus()));
1330 }
1331 } break;
1332 case (OpCode::LE_SET_EXTENDED_SCAN_PARAMETERS): {
1333 auto status_view = LeSetExtendedScanParametersCompleteView::Create(view);
1334 log::assert_that(status_view.IsValid(), "assert failed: status_view.IsValid()");
1335 if (status_view.GetStatus() != ErrorCode::SUCCESS) {
1336 log::info("Receive set extended scan parameter complete with error code {}",
1337 ErrorCodeText(status_view.GetStatus()));
1338 }
1339 } break;
1340 default:
1341 log::fatal("Unhandled event {}", OpCodeText(view.GetCommandOpCode()));
1342 }
1343 }
1344
on_advertising_filter_completebluetooth::hci::LeScanningManager::impl1345 void on_advertising_filter_complete(CommandCompleteView view) {
1346 log::assert_that(view.IsValid(), "assert failed: view.IsValid()");
1347 auto status_view = LeAdvFilterCompleteView::Create(view);
1348 log::assert_that(status_view.IsValid(), "assert failed: status_view.IsValid()");
1349 if (status_view.GetStatus() != ErrorCode::SUCCESS) {
1350 log::info("Got a Command complete {}, status {}", OpCodeText(view.GetCommandOpCode()),
1351 ErrorCodeText(status_view.GetStatus()));
1352 }
1353
1354 ApcfOpcode apcf_opcode = status_view.GetApcfOpcode();
1355 switch (apcf_opcode) {
1356 case ApcfOpcode::ENABLE: {
1357 auto complete_view = LeAdvFilterEnableCompleteView::Create(status_view);
1358 log::assert_that(complete_view.IsValid(), "assert failed: complete_view.IsValid()");
1359 scanning_callbacks_->OnFilterEnable(complete_view.GetApcfEnable(),
1360 (uint8_t)complete_view.GetStatus());
1361 } break;
1362 case ApcfOpcode::SET_FILTERING_PARAMETERS: {
1363 auto complete_view = LeAdvFilterSetFilteringParametersCompleteView::Create(status_view);
1364 log::assert_that(complete_view.IsValid(), "assert failed: complete_view.IsValid()");
1365 scanning_callbacks_->OnFilterParamSetup(complete_view.GetApcfAvailableSpaces(),
1366 complete_view.GetApcfAction(),
1367 (uint8_t)complete_view.GetStatus());
1368 } break;
1369 case ApcfOpcode::BROADCASTER_ADDRESS: {
1370 auto complete_view = LeAdvFilterBroadcasterAddressCompleteView::Create(status_view);
1371 log::assert_that(complete_view.IsValid(), "assert failed: complete_view.IsValid()");
1372 scanning_callbacks_->OnFilterConfigCallback(
1373 ApcfFilterType::BROADCASTER_ADDRESS, complete_view.GetApcfAvailableSpaces(),
1374 complete_view.GetApcfAction(), (uint8_t)complete_view.GetStatus());
1375 } break;
1376 case ApcfOpcode::SERVICE_UUID: {
1377 auto complete_view = LeAdvFilterServiceUuidCompleteView::Create(status_view);
1378 log::assert_that(complete_view.IsValid(), "assert failed: complete_view.IsValid()");
1379 scanning_callbacks_->OnFilterConfigCallback(
1380 ApcfFilterType::SERVICE_UUID, complete_view.GetApcfAvailableSpaces(),
1381 complete_view.GetApcfAction(), (uint8_t)complete_view.GetStatus());
1382 } break;
1383 case ApcfOpcode::SERVICE_SOLICITATION_UUID: {
1384 auto complete_view = LeAdvFilterSolicitationUuidCompleteView::Create(status_view);
1385 log::assert_that(complete_view.IsValid(), "assert failed: complete_view.IsValid()");
1386 scanning_callbacks_->OnFilterConfigCallback(
1387 ApcfFilterType::SERVICE_SOLICITATION_UUID, complete_view.GetApcfAvailableSpaces(),
1388 complete_view.GetApcfAction(), (uint8_t)complete_view.GetStatus());
1389 } break;
1390 case ApcfOpcode::LOCAL_NAME: {
1391 auto complete_view = LeAdvFilterLocalNameCompleteView::Create(status_view);
1392 log::assert_that(complete_view.IsValid(), "assert failed: complete_view.IsValid()");
1393 scanning_callbacks_->OnFilterConfigCallback(
1394 ApcfFilterType::LOCAL_NAME, complete_view.GetApcfAvailableSpaces(),
1395 complete_view.GetApcfAction(), (uint8_t)complete_view.GetStatus());
1396 } break;
1397 case ApcfOpcode::MANUFACTURER_DATA: {
1398 auto complete_view = LeAdvFilterManufacturerDataCompleteView::Create(status_view);
1399 log::assert_that(complete_view.IsValid(), "assert failed: complete_view.IsValid()");
1400 scanning_callbacks_->OnFilterConfigCallback(
1401 ApcfFilterType::MANUFACTURER_DATA, complete_view.GetApcfAvailableSpaces(),
1402 complete_view.GetApcfAction(), (uint8_t)complete_view.GetStatus());
1403 } break;
1404 case ApcfOpcode::SERVICE_DATA: {
1405 auto complete_view = LeAdvFilterServiceDataCompleteView::Create(status_view);
1406 log::assert_that(complete_view.IsValid(), "assert failed: complete_view.IsValid()");
1407 scanning_callbacks_->OnFilterConfigCallback(
1408 ApcfFilterType::SERVICE_DATA, complete_view.GetApcfAvailableSpaces(),
1409 complete_view.GetApcfAction(), (uint8_t)complete_view.GetStatus());
1410 } break;
1411 case ApcfOpcode::TRANSPORT_DISCOVERY_DATA: {
1412 auto complete_view = LeAdvFilterTransportDiscoveryDataCompleteView::Create(status_view);
1413 log::assert_that(complete_view.IsValid(), "assert failed: complete_view.IsValid()");
1414 scanning_callbacks_->OnFilterConfigCallback(
1415 ApcfFilterType::TRANSPORT_DISCOVERY_DATA, complete_view.GetApcfAvailableSpaces(),
1416 complete_view.GetApcfAction(), (uint8_t)complete_view.GetStatus());
1417 } break;
1418 case ApcfOpcode::AD_TYPE: {
1419 auto complete_view = LeAdvFilterADTypeCompleteView::Create(status_view);
1420 log::assert_that(complete_view.IsValid(), "assert failed: complete_view.IsValid()");
1421 scanning_callbacks_->OnFilterConfigCallback(
1422 ApcfFilterType::AD_TYPE, complete_view.GetApcfAvailableSpaces(),
1423 complete_view.GetApcfAction(), (uint8_t)complete_view.GetStatus());
1424 } break;
1425 default:
1426 log::warn("Unexpected event type {}", OpCodeText(view.GetCommandOpCode()));
1427 }
1428 }
1429
on_apcf_read_extended_features_completebluetooth::hci::LeScanningManager::impl1430 void on_apcf_read_extended_features_complete(CommandCompleteView view) {
1431 log::assert_that(view.IsValid(), "assert failed: view.IsValid()");
1432 auto status_view = LeAdvFilterCompleteView::Create(view);
1433 if (!status_view.IsValid()) {
1434 log::warn("Can not get valid LeAdvFilterCompleteView, return");
1435 return;
1436 }
1437 if (status_view.GetStatus() != ErrorCode::SUCCESS) {
1438 log::warn("Got a Command complete {}, status {}", OpCodeText(view.GetCommandOpCode()),
1439 ErrorCodeText(status_view.GetStatus()));
1440 return;
1441 }
1442 auto complete_view = LeAdvFilterReadExtendedFeaturesCompleteView::Create(status_view);
1443 log::assert_that(complete_view.IsValid(), "assert failed: complete_view.IsValid()");
1444 is_transport_discovery_data_filter_supported_ =
1445 complete_view.GetTransportDiscoveryDataFilter() == 1;
1446 is_ad_type_filter_supported_ = complete_view.GetAdTypeFilter() == 1;
1447 log::info(
1448 "set is_ad_type_filter_supported_ to {} & "
1449 "is_transport_discovery_data_filter_supported_ to {}",
1450 is_ad_type_filter_supported_, is_transport_discovery_data_filter_supported_);
1451 }
1452
on_batch_scan_completebluetooth::hci::LeScanningManager::impl1453 void on_batch_scan_complete(CommandCompleteView view) {
1454 log::assert_that(view.IsValid(), "assert failed: view.IsValid()");
1455 auto status_view = LeBatchScanCompleteView::Create(view);
1456 log::assert_that(status_view.IsValid(), "assert failed: status_view.IsValid()");
1457 if (status_view.GetStatus() != ErrorCode::SUCCESS) {
1458 log::info("Got a Command complete {}, status {}, batch_scan_opcode {}",
1459 OpCodeText(view.GetCommandOpCode()), ErrorCodeText(status_view.GetStatus()),
1460 BatchScanOpcodeText(status_view.GetBatchScanOpcode()));
1461 }
1462 }
1463
on_batch_scan_enable_completebluetooth::hci::LeScanningManager::impl1464 void on_batch_scan_enable_complete(CommandCompleteView view) {
1465 log::assert_that(view.IsValid(), "assert failed: view.IsValid()");
1466 auto status_view = LeBatchScanCompleteView::Create(view);
1467 log::assert_that(status_view.IsValid(), "assert failed: status_view.IsValid()");
1468 auto complete_view = LeBatchScanEnableCompleteView::Create(status_view);
1469 log::assert_that(complete_view.IsValid(), "assert failed: complete_view.IsValid()");
1470 if (status_view.GetStatus() != ErrorCode::SUCCESS) {
1471 log::info("Got batch scan enable complete, status {}",
1472 ErrorCodeText(status_view.GetStatus()));
1473 batch_scan_config_.current_state = BatchScanState::ERROR_STATE;
1474 } else {
1475 batch_scan_config_.current_state = BatchScanState::ENABLED_STATE;
1476 }
1477 }
1478
on_batch_scan_disable_completebluetooth::hci::LeScanningManager::impl1479 void on_batch_scan_disable_complete(CommandCompleteView view) {
1480 log::assert_that(view.IsValid(), "assert failed: view.IsValid()");
1481 auto status_view = LeBatchScanCompleteView::Create(view);
1482 log::assert_that(status_view.IsValid(), "assert failed: status_view.IsValid()");
1483 auto complete_view = LeBatchScanSetScanParametersCompleteView::Create(status_view);
1484 log::assert_that(complete_view.IsValid(), "assert failed: complete_view.IsValid()");
1485 log::assert_that(status_view.GetStatus() == ErrorCode::SUCCESS,
1486 "assert failed: status_view.GetStatus() == ErrorCode::SUCCESS");
1487 batch_scan_config_.current_state = BatchScanState::DISABLED_STATE;
1488 }
1489
on_batch_scan_read_result_completebluetooth::hci::LeScanningManager::impl1490 void on_batch_scan_read_result_complete(ScannerId scanner_id, uint16_t total_num_of_records,
1491 CommandCompleteView view) {
1492 log::assert_that(view.IsValid(), "assert failed: view.IsValid()");
1493 auto status_view = LeBatchScanCompleteView::Create(view);
1494 log::assert_that(status_view.IsValid(), "assert failed: status_view.IsValid()");
1495 auto complete_view = LeBatchScanReadResultParametersCompleteRawView::Create(status_view);
1496 log::assert_that(complete_view.IsValid(), "assert failed: complete_view.IsValid()");
1497 if (complete_view.GetStatus() != ErrorCode::SUCCESS) {
1498 log::info("Got batch scan read result complete, status {}",
1499 ErrorCodeText(status_view.GetStatus()));
1500 }
1501 uint8_t num_of_records = complete_view.GetNumOfRecords();
1502 auto report_format = complete_view.GetBatchScanDataRead();
1503 if (num_of_records == 0) {
1504 scanning_callbacks_->OnBatchScanReports(scanner_id, 0x00, (int)report_format,
1505 total_num_of_records,
1506 batch_scan_result_cache_[scanner_id]);
1507 batch_scan_result_cache_.erase(scanner_id);
1508 } else {
1509 auto raw_data = complete_view.GetRawData();
1510 batch_scan_result_cache_[scanner_id].insert(batch_scan_result_cache_[scanner_id].end(),
1511 raw_data.begin(), raw_data.end());
1512 total_num_of_records += num_of_records;
1513 batch_scan_read_results(scanner_id, total_num_of_records,
1514 static_cast<BatchScanMode>(report_format));
1515 }
1516 }
1517
on_storage_threshold_breachbluetooth::hci::LeScanningManager::impl1518 void on_storage_threshold_breach(VendorSpecificEventView /* event */) {
1519 if (batch_scan_config_.ref_value == kInvalidScannerId) {
1520 log::warn("storage threshold was not set !!");
1521 return;
1522 }
1523 scanning_callbacks_->OnBatchScanThresholdCrossed(
1524 static_cast<int>(batch_scan_config_.ref_value));
1525 }
1526
on_advertisement_trackingbluetooth::hci::LeScanningManager::impl1527 void on_advertisement_tracking(VendorSpecificEventView event) {
1528 auto view = LEAdvertisementTrackingEventView::Create(event);
1529 log::assert_that(view.IsValid(), "assert failed: view.IsValid()");
1530 uint8_t filter_index = view.GetApcfFilterIndex();
1531 if (tracker_id_map_.find(filter_index) == tracker_id_map_.end()) {
1532 log::warn("Advertisement track for filter_index {} is not register", (uint16_t)filter_index);
1533 return;
1534 }
1535 AdvertisingFilterOnFoundOnLostInfo on_found_on_lost_info = {};
1536 on_found_on_lost_info.scanner_id = tracker_id_map_[filter_index];
1537 on_found_on_lost_info.filter_index = filter_index;
1538 on_found_on_lost_info.advertiser_state = view.GetAdvertiserState();
1539 on_found_on_lost_info.advertiser_address = view.GetAdvertiserAddress();
1540 on_found_on_lost_info.advertiser_address_type = view.GetAdvertiserAddressType();
1541 on_found_on_lost_info.advertiser_info_present = view.GetAdvtInfoPresent();
1542 /* Extract the adv info details */
1543 if (on_found_on_lost_info.advertiser_info_present == AdvtInfoPresent::ADVT_INFO_PRESENT) {
1544 auto info_view = LEAdvertisementTrackingWithInfoEventView::Create(view);
1545 log::assert_that(info_view.IsValid(), "assert failed: info_view.IsValid()");
1546 on_found_on_lost_info.tx_power = info_view.GetTxPower();
1547 on_found_on_lost_info.rssi = info_view.GetRssi();
1548 on_found_on_lost_info.time_stamp = info_view.GetTimestamp();
1549 auto adv_data = info_view.GetAdvPacket();
1550 on_found_on_lost_info.adv_packet.reserve(adv_data.size());
1551 on_found_on_lost_info.adv_packet.insert(on_found_on_lost_info.adv_packet.end(),
1552 adv_data.begin(), adv_data.end());
1553 auto scan_rsp_data = info_view.GetScanResponse();
1554 on_found_on_lost_info.scan_response.reserve(scan_rsp_data.size());
1555 on_found_on_lost_info.scan_response.insert(on_found_on_lost_info.scan_response.end(),
1556 scan_rsp_data.begin(), scan_rsp_data.end());
1557 }
1558 scanning_callbacks_->OnTrackAdvFoundLost(on_found_on_lost_info);
1559 }
1560
OnPausebluetooth::hci::LeScanningManager::impl1561 void OnPause() override {
1562 if (!address_manager_registered_) {
1563 log::warn("Unregistered!");
1564 return;
1565 }
1566 paused_ = true;
1567 scan_on_resume_ = is_scanning_;
1568 stop_scan();
1569 ack_pause();
1570 }
1571
ack_pausebluetooth::hci::LeScanningManager::impl1572 void ack_pause() { le_address_manager_->AckPause(this); }
1573
OnResumebluetooth::hci::LeScanningManager::impl1574 void OnResume() override {
1575 if (!address_manager_registered_) {
1576 log::warn("Unregistered!");
1577 return;
1578 }
1579 paused_ = false;
1580 if (scan_on_resume_ == true) {
1581 scan_on_resume_ = false;
1582 start_scan();
1583 }
1584 le_address_manager_->AckResume(this);
1585 }
1586
1587 ScanApiType api_type_;
1588
1589 Module* module_;
1590 os::Handler* module_handler_;
1591 HciLayer* hci_layer_;
1592 Controller* controller_;
1593 AclManager* acl_manager_;
1594 storage::StorageModule* storage_module_;
1595 LeScanningInterface* le_scanning_interface_;
1596 LeAddressManager* le_address_manager_;
1597 bool address_manager_registered_ = false;
1598 NullScanningCallback null_scanning_callback_;
1599 ScanningCallback* scanning_callbacks_ = &null_scanning_callback_;
1600 PeriodicSyncManager periodic_sync_manager_{&null_scanning_callback_};
1601 std::vector<Scanner> scanners_;
1602 bool is_scanning_ = false;
1603 bool scan_on_resume_ = false;
1604 bool paused_ = false;
1605 LeScanningReassembler scanning_reassembler_;
1606 bool is_filter_supported_ = false;
1607 bool is_ad_type_filter_supported_ = false;
1608 bool is_batch_scan_supported_ = false;
1609 bool is_periodic_advertising_sync_transfer_sender_supported_ = false;
1610 bool is_transport_discovery_data_filter_supported_ = false;
1611
1612 LeScanType le_scan_type_ = LeScanType::ACTIVE;
1613 uint32_t interval_ms_{1000};
1614 uint16_t window_ms_{1000};
1615 uint8_t phy_{(uint8_t)PhyType::LE_1M};
1616 OwnAddressType own_address_type_{OwnAddressType::PUBLIC_DEVICE_ADDRESS};
1617 LeScanningFilterPolicy filter_policy_{LeScanningFilterPolicy::ACCEPT_ALL};
1618 BatchScanConfig batch_scan_config_;
1619 std::map<ScannerId, std::vector<uint8_t>> batch_scan_result_cache_;
1620 std::unordered_map<uint8_t, ScannerId> tracker_id_map_;
1621 uint16_t total_num_of_advt_tracked_ = 0x00;
1622 int8_t le_rx_path_loss_comp_ = 0;
1623 };
1624
LeScanningManager()1625 LeScanningManager::LeScanningManager() { pimpl_ = std::make_unique<impl>(this); }
1626
ListDependencies(ModuleList * list) const1627 void LeScanningManager::ListDependencies(ModuleList* list) const {
1628 list->add<HciLayer>();
1629 list->add<Controller>();
1630 list->add<AclManager>();
1631 list->add<storage::StorageModule>();
1632 }
1633
Start()1634 void LeScanningManager::Start() {
1635 pimpl_->start(GetHandler(), GetDependency<HciLayer>(), GetDependency<Controller>(),
1636 GetDependency<AclManager>(), GetDependency<storage::StorageModule>());
1637 }
1638
Stop()1639 void LeScanningManager::Stop() {
1640 pimpl_->stop();
1641 pimpl_.reset();
1642 }
1643
ToString() const1644 std::string LeScanningManager::ToString() const { return "Le Scanning Manager"; }
1645
RegisterScanner(Uuid app_uuid)1646 void LeScanningManager::RegisterScanner(Uuid app_uuid) {
1647 CallOn(pimpl_.get(), &impl::register_scanner, app_uuid);
1648 }
1649
Unregister(ScannerId scanner_id)1650 void LeScanningManager::Unregister(ScannerId scanner_id) {
1651 CallOn(pimpl_.get(), &impl::unregister_scanner, scanner_id);
1652 }
1653
Scan(bool start)1654 void LeScanningManager::Scan(bool start) { CallOn(pimpl_.get(), &impl::scan, start); }
1655
SetScanParameters(ScannerId scanner_id,LeScanType scan_type,uint16_t scan_interval,uint16_t scan_window,uint8_t scan_phy)1656 void LeScanningManager::SetScanParameters(ScannerId scanner_id, LeScanType scan_type,
1657 uint16_t scan_interval, uint16_t scan_window,
1658 uint8_t scan_phy) {
1659 CallOn(pimpl_.get(), &impl::set_scan_parameters, scanner_id, scan_type, scan_interval,
1660 scan_window, scan_phy);
1661 }
1662
SetScanFilterPolicy(LeScanningFilterPolicy filter_policy)1663 void LeScanningManager::SetScanFilterPolicy(LeScanningFilterPolicy filter_policy) {
1664 CallOn(pimpl_.get(), &impl::set_scan_filter_policy, filter_policy);
1665 }
1666
ScanFilterEnable(bool enable)1667 void LeScanningManager::ScanFilterEnable(bool enable) {
1668 CallOn(pimpl_.get(), &impl::scan_filter_enable, enable);
1669 }
1670
ScanFilterParameterSetup(ApcfAction action,uint8_t filter_index,AdvertisingFilterParameter advertising_filter_parameter)1671 void LeScanningManager::ScanFilterParameterSetup(
1672 ApcfAction action, uint8_t filter_index,
1673 AdvertisingFilterParameter advertising_filter_parameter) {
1674 CallOn(pimpl_.get(), &impl::scan_filter_parameter_setup, action, filter_index,
1675 advertising_filter_parameter);
1676 }
1677
ScanFilterAdd(uint8_t filter_index,std::vector<AdvertisingPacketContentFilterCommand> filters)1678 void LeScanningManager::ScanFilterAdd(uint8_t filter_index,
1679 std::vector<AdvertisingPacketContentFilterCommand> filters) {
1680 CallOn(pimpl_.get(), &impl::scan_filter_add, filter_index, filters);
1681 }
1682
BatchScanConifgStorage(uint8_t batch_scan_full_max,uint8_t batch_scan_truncated_max,uint8_t batch_scan_notify_threshold,ScannerId scanner_id)1683 void LeScanningManager::BatchScanConifgStorage(uint8_t batch_scan_full_max,
1684 uint8_t batch_scan_truncated_max,
1685 uint8_t batch_scan_notify_threshold,
1686 ScannerId scanner_id) {
1687 CallOn(pimpl_.get(), &impl::batch_scan_set_storage_parameter, batch_scan_full_max,
1688 batch_scan_truncated_max, batch_scan_notify_threshold, scanner_id);
1689 }
1690
BatchScanEnable(BatchScanMode scan_mode,uint32_t duty_cycle_scan_window_slots,uint32_t duty_cycle_scan_interval_slots,BatchScanDiscardRule batch_scan_discard_rule)1691 void LeScanningManager::BatchScanEnable(BatchScanMode scan_mode,
1692 uint32_t duty_cycle_scan_window_slots,
1693 uint32_t duty_cycle_scan_interval_slots,
1694 BatchScanDiscardRule batch_scan_discard_rule) {
1695 CallOn(pimpl_.get(), &impl::batch_scan_enable, scan_mode, duty_cycle_scan_window_slots,
1696 duty_cycle_scan_interval_slots, batch_scan_discard_rule);
1697 }
1698
BatchScanDisable()1699 void LeScanningManager::BatchScanDisable() { CallOn(pimpl_.get(), &impl::batch_scan_disable); }
1700
BatchScanReadReport(ScannerId scanner_id,BatchScanMode scan_mode)1701 void LeScanningManager::BatchScanReadReport(ScannerId scanner_id, BatchScanMode scan_mode) {
1702 CallOn(pimpl_.get(), &impl::batch_scan_read_results, scanner_id, 0, scan_mode);
1703 }
1704
StartSync(uint8_t sid,const AddressWithType & address_with_type,uint16_t skip,uint16_t timeout,int reg_id)1705 void LeScanningManager::StartSync(uint8_t sid, const AddressWithType& address_with_type,
1706 uint16_t skip, uint16_t timeout, int reg_id) {
1707 CallOn(pimpl_.get(), &impl::start_sync, sid, address_with_type, skip, timeout, reg_id);
1708 }
1709
StopSync(uint16_t handle)1710 void LeScanningManager::StopSync(uint16_t handle) {
1711 CallOn(pimpl_.get(), &impl::stop_sync, handle);
1712 }
1713
CancelCreateSync(uint8_t sid,const Address & address)1714 void LeScanningManager::CancelCreateSync(uint8_t sid, const Address& address) {
1715 CallOn(pimpl_.get(), &impl::cancel_create_sync, sid, address);
1716 }
1717
TransferSync(const Address & address,uint16_t handle,uint16_t service_data,uint16_t sync_handle,int pa_source)1718 void LeScanningManager::TransferSync(const Address& address, uint16_t handle, uint16_t service_data,
1719 uint16_t sync_handle, int pa_source) {
1720 CallOn(pimpl_.get(), &impl::transfer_sync, address, handle, service_data, sync_handle, pa_source);
1721 }
1722
TransferSetInfo(const Address & address,uint16_t handle,uint16_t service_data,uint8_t adv_handle,int pa_source)1723 void LeScanningManager::TransferSetInfo(const Address& address, uint16_t handle,
1724 uint16_t service_data, uint8_t adv_handle, int pa_source) {
1725 CallOn(pimpl_.get(), &impl::transfer_set_info, address, handle, service_data, adv_handle,
1726 pa_source);
1727 }
1728
SyncTxParameters(const Address & address,uint8_t mode,uint16_t skip,uint16_t timeout,int reg_id)1729 void LeScanningManager::SyncTxParameters(const Address& address, uint8_t mode, uint16_t skip,
1730 uint16_t timeout, int reg_id) {
1731 CallOn(pimpl_.get(), &impl::sync_tx_parameters, address, mode, skip, timeout, reg_id);
1732 }
1733
TrackAdvertiser(uint8_t filter_index,ScannerId scanner_id)1734 void LeScanningManager::TrackAdvertiser(uint8_t filter_index, ScannerId scanner_id) {
1735 CallOn(pimpl_.get(), &impl::track_advertiser, filter_index, scanner_id);
1736 }
1737
RegisterScanningCallback(ScanningCallback * scanning_callback)1738 void LeScanningManager::RegisterScanningCallback(ScanningCallback* scanning_callback) {
1739 CallOn(pimpl_.get(), &impl::register_scanning_callback, scanning_callback);
1740 }
1741
IsAdTypeFilterSupported() const1742 bool LeScanningManager::IsAdTypeFilterSupported() const {
1743 return pimpl_->is_ad_type_filter_supported();
1744 }
1745
1746 } // namespace hci
1747 } // namespace bluetooth
1748