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