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