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 <memory>
17 #include <mutex>
18 #include <set>
19
20 #include "hci/acl_manager.h"
21 #include "hci/controller.h"
22 #include "hci/hci_layer.h"
23 #include "hci/hci_packets.h"
24 #include "hci/le_scanning_interface.h"
25 #include "hci/le_scanning_manager.h"
26 #include "hci/vendor_specific_event_manager.h"
27 #include "module.h"
28 #include "os/handler.h"
29 #include "os/log.h"
30
31 namespace bluetooth {
32 namespace hci {
33
34 constexpr uint16_t kLeScanWindowMin = 0x0004;
35 constexpr uint16_t kLeScanWindowMax = 0x4000;
36 constexpr uint16_t kDefaultLeExtendedScanWindow = 4800;
37 constexpr uint16_t kLeExtendedScanWindowMax = 0xFFFF;
38 constexpr uint16_t kLeScanIntervalMin = 0x0004;
39 constexpr uint16_t kLeScanIntervalMax = 0x4000;
40 constexpr uint16_t kDefaultLeExtendedScanInterval = 4800;
41 constexpr uint16_t kLeExtendedScanIntervalMax = 0xFFFF;
42
43 constexpr uint8_t kScannableBit = 1;
44 constexpr uint8_t kDirectedBit = 2;
45 constexpr uint8_t kScanResponseBit = 3;
46 constexpr uint8_t kLegacyBit = 4;
47 constexpr uint8_t kDataStatusBits = 5;
48
__anon3483c8a40102() 49 const ModuleFactory LeScanningManager::Factory = ModuleFactory([]() { return new LeScanningManager(); });
50
51 enum class ScanApiType {
52 LEGACY = 1,
53 ANDROID_HCI = 2,
54 EXTENDED = 3,
55 };
56
57 struct Scanner {
58 Uuid app_uuid;
59 bool in_use;
60 };
61
62 class AdvertisingCache {
63 public:
Set(const AddressWithType & address_with_type,std::vector<uint8_t> data)64 const std::vector<uint8_t>& Set(const AddressWithType& address_with_type, std::vector<uint8_t> data) {
65 auto it = Find(address_with_type);
66 if (it != items.end()) {
67 it->data = std::move(data);
68 return it->data;
69 }
70
71 if (items.size() > cache_max) {
72 items.pop_back();
73 }
74
75 items.emplace_front(address_with_type, std::move(data));
76 return items.front().data;
77 }
78
Exist(const AddressWithType & address_with_type)79 bool Exist(const AddressWithType& address_with_type) {
80 auto it = Find(address_with_type);
81 if (it == items.end()) {
82 return false;
83 }
84 return true;
85 }
86
Append(const AddressWithType & address_with_type,std::vector<uint8_t> data)87 const std::vector<uint8_t>& Append(const AddressWithType& address_with_type, std::vector<uint8_t> data) {
88 auto it = Find(address_with_type);
89 if (it != items.end()) {
90 it->data.insert(it->data.end(), data.begin(), data.end());
91 return it->data;
92 }
93
94 if (items.size() > cache_max) {
95 items.pop_back();
96 }
97
98 items.emplace_front(address_with_type, std::move(data));
99 return items.front().data;
100 }
101
102 /* Clear data for device |addr_type, addr| */
Clear(AddressWithType address_with_type)103 void Clear(AddressWithType address_with_type) {
104 auto it = Find(address_with_type);
105 if (it != items.end()) {
106 items.erase(it);
107 }
108 }
109
ClearAll()110 void ClearAll() {
111 items.clear();
112 }
113
114 struct Item {
115 AddressWithType address_with_type;
116 std::vector<uint8_t> data;
117
Itembluetooth::hci::AdvertisingCache::Item118 Item(const AddressWithType& address_with_type, std::vector<uint8_t> data)
119 : address_with_type(address_with_type), data(data) {}
120 };
121
Find(const AddressWithType & address_with_type)122 std::list<Item>::iterator Find(const AddressWithType& address_with_type) {
123 for (auto it = items.begin(); it != items.end(); it++) {
124 if (it->address_with_type == address_with_type) {
125 return it;
126 }
127 }
128 return items.end();
129 }
130
131 /* we keep maximum 7 devices in the cache */
132 const size_t cache_max = 1000;
133 std::list<Item> items;
134 };
135
136 class NullScanningCallback : public ScanningCallback {
OnScannerRegistered(const bluetooth::hci::Uuid app_uuid,ScannerId scanner_id,ScanningStatus status)137 void OnScannerRegistered(const bluetooth::hci::Uuid app_uuid, ScannerId scanner_id, ScanningStatus status) {
138 LOG_INFO("OnScannerRegistered in NullScanningCallback");
139 }
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)140 void OnScanResult(
141 uint16_t event_type,
142 uint8_t address_type,
143 Address address,
144 uint8_t primary_phy,
145 uint8_t secondary_phy,
146 uint8_t advertising_sid,
147 int8_t tx_power,
148 int8_t rssi,
149 uint16_t periodic_advertising_interval,
150 std::vector<uint8_t> advertising_data) {
151 LOG_INFO("OnScanResult in NullScanningCallback");
152 }
OnTrackAdvFoundLost(AdvertisingFilterOnFoundOnLostInfo on_found_on_lost_info)153 void OnTrackAdvFoundLost(AdvertisingFilterOnFoundOnLostInfo on_found_on_lost_info) {
154 LOG_INFO("OnTrackAdvFoundLost in NullScanningCallback");
155 }
OnBatchScanReports(int client_if,int status,int report_format,int num_records,std::vector<uint8_t> data)156 void OnBatchScanReports(int client_if, int status, int report_format, int num_records, std::vector<uint8_t> data) {
157 LOG_INFO("OnBatchScanReports in NullScanningCallback");
158 }
OnBatchScanThresholdCrossed(int client_if)159 void OnBatchScanThresholdCrossed(int client_if) {
160 LOG_INFO("OnBatchScanThresholdCrossed in NullScanningCallback");
161 }
OnTimeout()162 void OnTimeout() {
163 LOG_INFO("OnTimeout in NullScanningCallback");
164 }
OnFilterEnable(Enable enable,uint8_t status)165 void OnFilterEnable(Enable enable, uint8_t status) {
166 LOG_INFO("OnFilterEnable in NullScanningCallback");
167 }
OnFilterParamSetup(uint8_t available_spaces,ApcfAction action,uint8_t status)168 void OnFilterParamSetup(uint8_t available_spaces, ApcfAction action, uint8_t status) {
169 LOG_INFO("OnFilterParamSetup in NullScanningCallback");
170 }
OnFilterConfigCallback(ApcfFilterType filter_type,uint8_t available_spaces,ApcfAction action,uint8_t status)171 void OnFilterConfigCallback(
172 ApcfFilterType filter_type, uint8_t available_spaces, ApcfAction action, uint8_t status) {
173 LOG_INFO("OnFilterConfigCallback in NullScanningCallback");
174 }
175 };
176
177 enum class BatchScanState {
178 ERROR_STATE = 0,
179 ENABLE_CALLED = 1,
180 ENABLED_STATE = 2,
181 DISABLE_CALLED = 3,
182 DISABLED_STATE = 4,
183 };
184
185 #define BTM_BLE_BATCH_SCAN_MODE_DISABLE 0
186 #define BTM_BLE_BATCH_SCAN_MODE_PASS 1
187 #define BTM_BLE_BATCH_SCAN_MODE_ACTI 2
188 #define BTM_BLE_BATCH_SCAN_MODE_PASS_ACTI 3
189
190 struct BatchScanConfig {
191 BatchScanState current_state;
192 BatchScanMode scan_mode;
193 uint32_t scan_interval;
194 uint32_t scan_window;
195 BatchScanDiscardRule discard_rule;
196 ScannerId ref_value;
197 };
198
199 struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback {
implbluetooth::hci::LeScanningManager::impl200 impl(Module* module) : module_(module), le_scanning_interface_(nullptr) {}
201
~implbluetooth::hci::LeScanningManager::impl202 ~impl() {
203 if (address_manager_registered_) {
204 le_address_manager_->Unregister(this);
205 }
206 }
207
startbluetooth::hci::LeScanningManager::impl208 void start(
209 os::Handler* handler,
210 hci::HciLayer* hci_layer,
211 hci::Controller* controller,
212 hci::AclManager* acl_manager,
213 hci::VendorSpecificEventManager* vendor_specific_event_manager) {
214 module_handler_ = handler;
215 hci_layer_ = hci_layer;
216 controller_ = controller;
217 vendor_specific_event_manager_ = vendor_specific_event_manager;
218 le_address_manager_ = acl_manager->GetLeAddressManager();
219 le_scanning_interface_ = hci_layer_->GetLeScanningInterface(
220 module_handler_->BindOn(this, &LeScanningManager::impl::handle_scan_results));
221 if (controller_->IsSupported(OpCode::LE_SET_EXTENDED_SCAN_PARAMETERS)) {
222 api_type_ = ScanApiType::EXTENDED;
223 interval_ms_ = kDefaultLeExtendedScanInterval;
224 window_ms_ = kDefaultLeExtendedScanWindow;
225 } else if (controller_->IsSupported(OpCode::LE_EXTENDED_SCAN_PARAMS)) {
226 api_type_ = ScanApiType::ANDROID_HCI;
227 } else {
228 api_type_ = ScanApiType::LEGACY;
229 }
230 is_filter_support_ = controller_->IsSupported(OpCode::LE_ADV_FILTER);
231 is_batch_scan_support_ = controller->IsSupported(OpCode::LE_BATCH_SCAN);
232 if (is_batch_scan_support_) {
233 vendor_specific_event_manager_->RegisterEventHandler(
234 VseSubeventCode::BLE_THRESHOLD, handler->BindOn(this, &LeScanningManager::impl::on_storage_threshold_breach));
235 vendor_specific_event_manager_->RegisterEventHandler(
236 VseSubeventCode::BLE_TRACKING, handler->BindOn(this, &LeScanningManager::impl::on_advertisement_tracking));
237 }
238 scanners_ = std::vector<Scanner>(kMaxAppNum + 1);
239 for (size_t i = 0; i < scanners_.size(); i++) {
240 scanners_[i].app_uuid = Uuid::kEmpty;
241 scanners_[i].in_use = false;
242 }
243 batch_scan_config_.current_state = BatchScanState::DISABLED_STATE;
244 batch_scan_config_.ref_value = kInvalidScannerId;
245 configure_scan();
246 }
247
stopbluetooth::hci::LeScanningManager::impl248 void stop() {
249 for (auto subevent_code : LeScanningEvents) {
250 hci_layer_->UnregisterLeEventHandler(subevent_code);
251 }
252 if (is_batch_scan_support_) {
253 // TODO implete vse module
254 // hci_layer_->UnregisterVesEventHandler(VseSubeventCode::BLE_THRESHOLD);
255 // hci_layer_->UnregisterVesEventHandler(VseSubeventCode::BLE_TRACKING);
256 }
257 batch_scan_config_.current_state = BatchScanState::DISABLED_STATE;
258 batch_scan_config_.ref_value = kInvalidScannerId;
259 scanning_callbacks_ = &null_scanning_callback_;
260 }
261
handle_scan_resultsbluetooth::hci::LeScanningManager::impl262 void handle_scan_results(LeMetaEventView event) {
263 switch (event.GetSubeventCode()) {
264 case hci::SubeventCode::ADVERTISING_REPORT:
265 handle_advertising_report(LeAdvertisingReportView::Create(event));
266 break;
267 case hci::SubeventCode::DIRECTED_ADVERTISING_REPORT:
268 handle_directed_advertising_report(LeDirectedAdvertisingReportView::Create(event));
269 break;
270 case hci::SubeventCode::EXTENDED_ADVERTISING_REPORT:
271 handle_extended_advertising_report(LeExtendedAdvertisingReportView::Create(event));
272 break;
273 case hci::SubeventCode::SCAN_TIMEOUT:
274 scanning_callbacks_->OnTimeout();
275 break;
276 default:
277 LOG_ALWAYS_FATAL("Unknown advertising subevent %s", hci::SubeventCodeText(event.GetSubeventCode()).c_str());
278 }
279 }
280
281 struct ExtendedEventTypeOptions {
282 bool connectable{false};
283 bool scannable{false};
284 bool directed{false};
285 bool scan_response{false};
286 bool legacy{false};
287 bool continuing{false};
288 bool truncated{false};
289 };
290
transform_to_extended_event_typebluetooth::hci::LeScanningManager::impl291 void transform_to_extended_event_type(uint16_t* extended_event_type, ExtendedEventTypeOptions o) {
292 ASSERT(extended_event_type != nullptr);
293 *extended_event_type = (o.connectable ? 0x0001 << 0 : 0) | (o.scannable ? 0x0001 << 1 : 0) |
294 (o.directed ? 0x0001 << 2 : 0) | (o.scan_response ? 0x0001 << 3 : 0) |
295 (o.legacy ? 0x0001 << 4 : 0) | (o.continuing ? 0x0001 << 5 : 0) |
296 (o.truncated ? 0x0001 << 6 : 0);
297 }
298
handle_advertising_reportbluetooth::hci::LeScanningManager::impl299 void handle_advertising_report(LeAdvertisingReportView event_view) {
300 if (!event_view.IsValid()) {
301 LOG_INFO("Dropping invalid advertising event");
302 return;
303 }
304 std::vector<LeAdvertisingReport> reports = event_view.GetAdvertisingReports();
305 if (reports.empty()) {
306 LOG_INFO("Zero results in advertising event");
307 return;
308 }
309
310 for (LeAdvertisingReport report : reports) {
311 uint16_t extended_event_type = 0;
312 switch (report.event_type_) {
313 case hci::AdvertisingEventType::ADV_IND:
314 transform_to_extended_event_type(
315 &extended_event_type, {.connectable = true, .scannable = true, .legacy = true});
316 break;
317 case hci::AdvertisingEventType::ADV_DIRECT_IND:
318 transform_to_extended_event_type(
319 &extended_event_type, {.connectable = true, .directed = true, .legacy = true});
320 break;
321 case hci::AdvertisingEventType::ADV_SCAN_IND:
322 transform_to_extended_event_type(&extended_event_type, {.scannable = true, .legacy = true});
323 break;
324 case hci::AdvertisingEventType::ADV_NONCONN_IND:
325 transform_to_extended_event_type(&extended_event_type, {.legacy = true});
326 break;
327 case hci::AdvertisingEventType::SCAN_RESPONSE:
328 transform_to_extended_event_type(
329 &extended_event_type, {.connectable = true, .scannable = true, .scan_response = true, .legacy = true});
330 break;
331 default:
332 LOG_WARN("Unsupported event type:%d", (uint16_t)report.event_type_);
333 return;
334 }
335
336 std::vector<uint8_t> advertising_data = {};
337 for (auto gap_data : report.advertising_data_) {
338 advertising_data.push_back((uint8_t)gap_data.size() - 1);
339 advertising_data.push_back((uint8_t)gap_data.data_type_);
340 advertising_data.insert(advertising_data.end(), gap_data.data_.begin(), gap_data.data_.end());
341 }
342
343 process_advertising_package_content(
344 extended_event_type,
345 (uint8_t)report.address_type_,
346 report.address_,
347 (uint8_t)PrimaryPhyType::LE_1M,
348 (uint8_t)SecondaryPhyType::NO_PACKETS,
349 kAdvertisingDataInfoNotPresent,
350 kTxPowerInformationNotPresent,
351 report.rssi_,
352 kNotPeriodicAdvertisement,
353 advertising_data);
354 }
355 }
356
handle_directed_advertising_reportbluetooth::hci::LeScanningManager::impl357 void handle_directed_advertising_report(LeDirectedAdvertisingReportView event_view) {
358 if (!event_view.IsValid()) {
359 LOG_INFO("Dropping invalid advertising event");
360 return;
361 }
362 std::vector<LeDirectedAdvertisingReport> reports = event_view.GetAdvertisingReports();
363 if (reports.empty()) {
364 LOG_INFO("Zero results in advertising event");
365 return;
366 }
367 uint16_t extended_event_type = 0;
368 transform_to_extended_event_type(&extended_event_type, {.connectable = true, .directed = true, .legacy = true});
369 // TODO: parse report
370 }
371
handle_extended_advertising_reportbluetooth::hci::LeScanningManager::impl372 void handle_extended_advertising_report(LeExtendedAdvertisingReportView event_view) {
373 if (!event_view.IsValid()) {
374 LOG_INFO("Dropping invalid advertising event");
375 return;
376 }
377 std::vector<LeExtendedAdvertisingReport> reports = event_view.GetAdvertisingReports();
378 if (reports.empty()) {
379 LOG_INFO("Zero results in advertising event");
380 return;
381 }
382
383 for (LeExtendedAdvertisingReport report : reports) {
384 uint16_t event_type = report.connectable_ | (report.scannable_ << kScannableBit) |
385 (report.directed_ << kDirectedBit) | (report.scan_response_ << kScanResponseBit) |
386 (report.legacy_ << kLegacyBit) | ((uint16_t)report.data_status_ << kDataStatusBits);
387 process_advertising_package_content(
388 event_type,
389 (uint8_t)report.address_type_,
390 report.address_,
391 (uint8_t)report.primary_phy_,
392 (uint8_t)report.secondary_phy_,
393 report.advertising_sid_,
394 report.tx_power_,
395 report.rssi_,
396 report.periodic_advertising_interval_,
397 report.advertising_data_);
398 }
399 }
400
process_advertising_package_contentbluetooth::hci::LeScanningManager::impl401 void process_advertising_package_content(
402 uint16_t event_type,
403 uint8_t address_type,
404 Address address,
405 uint8_t primary_phy,
406 uint8_t secondary_phy,
407 uint8_t advertising_sid,
408 int8_t tx_power,
409 int8_t rssi,
410 uint16_t periodic_advertising_interval,
411 std::vector<uint8_t> advertising_data) {
412 bool is_scannable = event_type & (1 << kScannableBit);
413 bool is_scan_response = event_type & (1 << kScanResponseBit);
414 bool is_legacy = event_type & (1 << kLegacyBit);
415
416 if (address_type == (uint8_t)DirectAdvertisingAddressType::NO_ADDRESS) {
417 scanning_callbacks_->OnScanResult(
418 event_type,
419 address_type,
420 address,
421 primary_phy,
422 secondary_phy,
423 advertising_sid,
424 tx_power,
425 rssi,
426 periodic_advertising_interval,
427 advertising_data);
428 return;
429 } else if (address == Address::kEmpty) {
430 LOG_WARN("Receive non-anonymous advertising report with empty address, skip!");
431 return;
432 }
433
434 AddressWithType address_with_type(address, (AddressType)address_type);
435
436 if (is_legacy && is_scan_response && !advertising_cache_.Exist(address_with_type)) {
437 return;
438 }
439
440 bool is_start = is_legacy && is_scannable && !is_scan_response;
441
442 std::vector<uint8_t> const& adv_data = is_start ? advertising_cache_.Set(address_with_type, advertising_data)
443 : advertising_cache_.Append(address_with_type, advertising_data);
444
445 uint8_t data_status = event_type >> kDataStatusBits;
446 if (data_status == (uint8_t)DataStatus::CONTINUING) {
447 // Waiting for whole data
448 return;
449 }
450
451 if (is_scannable && !is_scan_response) {
452 // Waiting for scan response
453 return;
454 }
455
456 scanning_callbacks_->OnScanResult(
457 event_type,
458 address_type,
459 address,
460 primary_phy,
461 secondary_phy,
462 advertising_sid,
463 tx_power,
464 rssi,
465 periodic_advertising_interval,
466 adv_data);
467
468 advertising_cache_.Clear(address_with_type);
469 }
470
configure_scanbluetooth::hci::LeScanningManager::impl471 void configure_scan() {
472 std::vector<PhyScanParameters> parameter_vector;
473 PhyScanParameters phy_scan_parameters;
474 phy_scan_parameters.le_scan_window_ = window_ms_;
475 phy_scan_parameters.le_scan_interval_ = interval_ms_;
476 phy_scan_parameters.le_scan_type_ = le_scan_type_;
477 parameter_vector.push_back(phy_scan_parameters);
478 uint8_t phys_in_use = 1;
479
480 // The Host shall not issue set scan parameter command when scanning is enabled
481 stop_scan();
482
483 if (le_address_manager_->GetAddressPolicy() != LeAddressManager::USE_PUBLIC_ADDRESS) {
484 own_address_type_ = OwnAddressType::RANDOM_DEVICE_ADDRESS;
485 }
486
487 switch (api_type_) {
488 case ScanApiType::EXTENDED:
489 le_scanning_interface_->EnqueueCommand(hci::LeSetExtendedScanParametersBuilder::Create(
490 own_address_type_, filter_policy_, phys_in_use, parameter_vector),
491 module_handler_->BindOnce(impl::check_status));
492 break;
493 case ScanApiType::ANDROID_HCI:
494 le_scanning_interface_->EnqueueCommand(
495 hci::LeExtendedScanParamsBuilder::Create(LeScanType::ACTIVE, interval_ms_, window_ms_, own_address_type_,
496 filter_policy_),
497 module_handler_->BindOnce(impl::check_status));
498
499 break;
500 case ScanApiType::LEGACY:
501 le_scanning_interface_->EnqueueCommand(
502 hci::LeSetScanParametersBuilder::Create(LeScanType::ACTIVE, interval_ms_, window_ms_, own_address_type_,
503 filter_policy_),
504 module_handler_->BindOnce(impl::check_status));
505 break;
506 }
507 }
508
register_scannerbluetooth::hci::LeScanningManager::impl509 void register_scanner(const Uuid app_uuid) {
510 for (uint8_t i = 1; i <= kMaxAppNum; i++) {
511 if (scanners_[i].in_use && scanners_[i].app_uuid == app_uuid) {
512 LOG_ERROR("Application already registered %s", app_uuid.ToString().c_str());
513 scanning_callbacks_->OnScannerRegistered(app_uuid, 0x00, ScanningCallback::ScanningStatus::INTERNAL_ERROR);
514 return;
515 }
516 }
517
518 // valid value of scanner id : 1 ~ kMaxAppNum
519 for (uint8_t i = 1; i <= kMaxAppNum; i++) {
520 if (!scanners_[i].in_use) {
521 scanners_[i].app_uuid = app_uuid;
522 scanners_[i].in_use = true;
523 scanning_callbacks_->OnScannerRegistered(app_uuid, i, ScanningCallback::ScanningStatus::SUCCESS);
524 return;
525 }
526 }
527
528 LOG_ERROR("Unable to register scanner, max client reached:%d", kMaxAppNum);
529 scanning_callbacks_->OnScannerRegistered(app_uuid, 0x00, ScanningCallback::ScanningStatus::NO_RESOURCES);
530 }
531
unregister_scannerbluetooth::hci::LeScanningManager::impl532 void unregister_scanner(ScannerId scanner_id) {
533 if (scanner_id <= 0 || scanner_id > kMaxAppNum) {
534 LOG_WARN("Invalid scanner id");
535 return;
536 }
537
538 if (scanners_[scanner_id].in_use) {
539 scanners_[scanner_id].in_use = false;
540 scanners_[scanner_id].app_uuid = Uuid::kEmpty;
541 } else {
542 LOG_WARN("Unregister scanner with unused scanner id");
543 }
544 }
545
scanbluetooth::hci::LeScanningManager::impl546 void scan(bool start) {
547 if (start) {
548 configure_scan();
549 start_scan();
550 } else {
551 if (address_manager_registered_) {
552 le_address_manager_->Unregister(this);
553 address_manager_registered_ = false;
554 }
555 stop_scan();
556 }
557 }
558
start_scanbluetooth::hci::LeScanningManager::impl559 void start_scan() {
560 // If we receive start_scan during paused, set scan_on_resume_ to true
561 if (paused_) {
562 scan_on_resume_ = true;
563 return;
564 }
565 is_scanning_ = true;
566 if (!address_manager_registered_) {
567 le_address_manager_->Register(this);
568 address_manager_registered_ = true;
569 }
570
571 switch (api_type_) {
572 case ScanApiType::EXTENDED:
573 le_scanning_interface_->EnqueueCommand(
574 hci::LeSetExtendedScanEnableBuilder::Create(
575 Enable::ENABLED, FilterDuplicates::DISABLED /* filter duplicates */, 0, 0),
576 module_handler_->BindOnce(impl::check_status));
577 break;
578 case ScanApiType::ANDROID_HCI:
579 case ScanApiType::LEGACY:
580 le_scanning_interface_->EnqueueCommand(
581 hci::LeSetScanEnableBuilder::Create(Enable::ENABLED, Enable::DISABLED /* filter duplicates */),
582 module_handler_->BindOnce(impl::check_status));
583 break;
584 }
585 }
586
stop_scanbluetooth::hci::LeScanningManager::impl587 void stop_scan() {
588 is_scanning_ = false;
589
590 switch (api_type_) {
591 case ScanApiType::EXTENDED:
592 le_scanning_interface_->EnqueueCommand(
593 hci::LeSetExtendedScanEnableBuilder::Create(
594 Enable::DISABLED, FilterDuplicates::DISABLED /* filter duplicates */, 0, 0),
595 module_handler_->BindOnce(impl::check_status));
596 break;
597 case ScanApiType::ANDROID_HCI:
598 case ScanApiType::LEGACY:
599 le_scanning_interface_->EnqueueCommand(
600 hci::LeSetScanEnableBuilder::Create(Enable::DISABLED, Enable::DISABLED /* filter duplicates */),
601 module_handler_->BindOnce(impl::check_status));
602 break;
603 }
604 }
605
set_scan_parametersbluetooth::hci::LeScanningManager::impl606 void set_scan_parameters(LeScanType scan_type, uint16_t scan_interval, uint16_t scan_window) {
607 uint32_t max_scan_interval = kLeScanIntervalMax;
608 uint32_t max_scan_window = kLeScanWindowMax;
609 if (api_type_ == ScanApiType::EXTENDED) {
610 max_scan_interval = kLeExtendedScanIntervalMax;
611 max_scan_window = kLeExtendedScanWindowMax;
612 }
613
614 if (scan_type != LeScanType::ACTIVE && scan_type != LeScanType::PASSIVE) {
615 LOG_ERROR("Invalid scan type");
616 return;
617 }
618 if (scan_interval > max_scan_interval || scan_interval < kLeScanIntervalMin) {
619 LOG_ERROR("Invalid scan_interval %d", scan_interval);
620 return;
621 }
622 if (scan_window > max_scan_window || scan_window < kLeScanWindowMin) {
623 LOG_ERROR("Invalid scan_window %d", scan_window);
624 return;
625 }
626 le_scan_type_ = scan_type;
627 interval_ms_ = scan_interval;
628 window_ms_ = scan_window;
629 }
630
scan_filter_enablebluetooth::hci::LeScanningManager::impl631 void scan_filter_enable(bool enable) {
632 if (!is_filter_support_) {
633 LOG_WARN("Advertising filter is not supported");
634 return;
635 }
636
637 Enable apcf_enable = enable ? Enable::ENABLED : Enable::DISABLED;
638 le_scanning_interface_->EnqueueCommand(
639 LeAdvFilterEnableBuilder::Create(apcf_enable),
640 module_handler_->BindOnceOn(this, &impl::on_advertising_filter_complete));
641 }
642
scan_filter_parameter_setupbluetooth::hci::LeScanningManager::impl643 void scan_filter_parameter_setup(
644 ApcfAction action, uint8_t filter_index, AdvertisingFilterParameter advertising_filter_parameter) {
645 if (!is_filter_support_) {
646 LOG_WARN("Advertising filter is not supported");
647 return;
648 }
649
650 switch (action) {
651 case ApcfAction::ADD:
652 le_scanning_interface_->EnqueueCommand(
653 LeAdvFilterAddFilteringParametersBuilder::Create(
654 filter_index,
655 advertising_filter_parameter.feature_selection,
656 advertising_filter_parameter.list_logic_type,
657 advertising_filter_parameter.filter_logic_type,
658 advertising_filter_parameter.rssi_high_thresh,
659 advertising_filter_parameter.delivery_mode,
660 advertising_filter_parameter.onfound_timeout,
661 advertising_filter_parameter.onfound_timeout_cnt,
662 advertising_filter_parameter.rssi_low_thres,
663 advertising_filter_parameter.onlost_timeout,
664 advertising_filter_parameter.num_of_tracking_entries),
665 module_handler_->BindOnceOn(this, &impl::on_advertising_filter_complete));
666 break;
667 case ApcfAction::DELETE:
668 le_scanning_interface_->EnqueueCommand(
669 LeAdvFilterDeleteFilteringParametersBuilder::Create(filter_index),
670 module_handler_->BindOnceOn(this, &impl::on_advertising_filter_complete));
671 break;
672 case ApcfAction::CLEAR:
673 le_scanning_interface_->EnqueueCommand(
674 LeAdvFilterClearFilteringParametersBuilder::Create(),
675 module_handler_->BindOnceOn(this, &impl::on_advertising_filter_complete));
676 break;
677 default:
678 LOG_ERROR("Unknown action type: %d", (uint16_t)action);
679 break;
680 }
681 }
682
scan_filter_addbluetooth::hci::LeScanningManager::impl683 void scan_filter_add(uint8_t filter_index, std::vector<AdvertisingPacketContentFilterCommand> filters) {
684 if (!is_filter_support_) {
685 LOG_WARN("Advertising filter is not supported");
686 return;
687 }
688
689 ApcfAction apcf_action = ApcfAction::ADD;
690 for (auto filter : filters) {
691 /* If data is passed, both mask and data have to be the same length */
692 if (filter.data.size() != filter.data_mask.size() && filter.data.size() != 0 && filter.data_mask.size() != 0) {
693 LOG_ERROR("data and data_mask are of different size");
694 continue;
695 }
696
697 switch (filter.filter_type) {
698 case ApcfFilterType::BROADCASTER_ADDRESS: {
699 update_address_filter(apcf_action, filter_index, filter.address, filter.application_address_type);
700 break;
701 }
702 case ApcfFilterType::SERVICE_UUID:
703 case ApcfFilterType::SERVICE_SOLICITATION_UUID: {
704 update_uuid_filter(apcf_action, filter_index, filter.filter_type, filter.uuid, filter.uuid_mask);
705 break;
706 }
707 case ApcfFilterType::LOCAL_NAME: {
708 update_local_name_filter(apcf_action, filter_index, filter.name);
709 break;
710 }
711 case ApcfFilterType::MANUFACTURER_DATA: {
712 update_manufacturer_data_filter(
713 apcf_action, filter_index, filter.company, filter.company_mask, filter.data, filter.data_mask);
714 break;
715 }
716 case ApcfFilterType::SERVICE_DATA: {
717 update_service_data_filter(apcf_action, filter_index, filter.data, filter.data_mask);
718 break;
719 }
720 default:
721 LOG_ERROR("Unknown filter type: %d", (uint16_t)filter.filter_type);
722 break;
723 }
724 }
725 }
726
update_address_filterbluetooth::hci::LeScanningManager::impl727 void update_address_filter(
728 ApcfAction action, uint8_t filter_index, Address address, ApcfApplicationAddressType address_type) {
729 if (action != ApcfAction::CLEAR) {
730 le_scanning_interface_->EnqueueCommand(
731 LeAdvFilterBroadcasterAddressBuilder::Create(action, filter_index, address, address_type),
732 module_handler_->BindOnceOn(this, &impl::on_advertising_filter_complete));
733 } else {
734 le_scanning_interface_->EnqueueCommand(
735 LeAdvFilterClearBroadcasterAddressBuilder::Create(filter_index),
736 module_handler_->BindOnceOn(this, &impl::on_advertising_filter_complete));
737 }
738 }
739
update_uuid_filterbluetooth::hci::LeScanningManager::impl740 void update_uuid_filter(
741 ApcfAction action, uint8_t filter_index, ApcfFilterType filter_type, Uuid uuid, Uuid uuid_mask) {
742 std::vector<uint8_t> combined_data = {};
743 if (action != ApcfAction::CLEAR) {
744 uint8_t uuid_len = uuid.GetShortestRepresentationSize();
745 if (uuid_len == Uuid::kNumBytes16) {
746 uint16_t data = uuid.As16Bit();
747 combined_data.push_back((uint8_t)data);
748 combined_data.push_back((uint8_t)(data >> 8));
749 } else if (uuid_len == Uuid::kNumBytes32) {
750 uint16_t data = uuid.As32Bit();
751 combined_data.push_back((uint8_t)data);
752 combined_data.push_back((uint8_t)(data >> 8));
753 combined_data.push_back((uint8_t)(data >> 16));
754 combined_data.push_back((uint8_t)(data >> 24));
755 } else if (uuid_len == Uuid::kNumBytes128) {
756 auto data = uuid.To128BitLE();
757 combined_data.insert(combined_data.end(), data.begin(), data.end());
758 } else {
759 LOG_ERROR("illegal UUID length: %d", (uint16_t)uuid_len);
760 return;
761 }
762
763 if (!uuid_mask.IsEmpty()) {
764 if (uuid_len == Uuid::kNumBytes16) {
765 uint16_t data = uuid_mask.As16Bit();
766 combined_data.push_back((uint8_t)data);
767 combined_data.push_back((uint8_t)(data >> 8));
768 } else if (uuid_len == Uuid::kNumBytes32) {
769 uint16_t data = uuid_mask.As32Bit();
770 combined_data.push_back((uint8_t)data);
771 combined_data.push_back((uint8_t)(data >> 8));
772 combined_data.push_back((uint8_t)(data >> 16));
773 combined_data.push_back((uint8_t)(data >> 24));
774 } else if (uuid_len == Uuid::kNumBytes128) {
775 auto data = uuid_mask.To128BitLE();
776 combined_data.insert(combined_data.end(), data.begin(), data.end());
777 }
778 } else {
779 std::vector<uint8_t> data(uuid_len, 0xFF);
780 combined_data.insert(combined_data.end(), data.begin(), data.end());
781 }
782 }
783
784 if (filter_type == ApcfFilterType::SERVICE_UUID) {
785 le_scanning_interface_->EnqueueCommand(
786 LeAdvFilterServiceUuidBuilder::Create(action, filter_index, combined_data),
787 module_handler_->BindOnceOn(this, &impl::on_advertising_filter_complete));
788 } else {
789 le_scanning_interface_->EnqueueCommand(
790 LeAdvFilterSolicitationUuidBuilder::Create(action, filter_index, combined_data),
791 module_handler_->BindOnceOn(this, &impl::on_advertising_filter_complete));
792 }
793 }
794
update_local_name_filterbluetooth::hci::LeScanningManager::impl795 void update_local_name_filter(ApcfAction action, uint8_t filter_index, std::vector<uint8_t> name) {
796 le_scanning_interface_->EnqueueCommand(
797 LeAdvFilterLocalNameBuilder::Create(action, filter_index, name),
798 module_handler_->BindOnceOn(this, &impl::on_advertising_filter_complete));
799 }
800
update_manufacturer_data_filterbluetooth::hci::LeScanningManager::impl801 void update_manufacturer_data_filter(
802 ApcfAction action,
803 uint8_t filter_index,
804 uint16_t company_id,
805 uint16_t company_id_mask,
806 std::vector<uint8_t> data,
807 std::vector<uint8_t> data_mask) {
808 if (data.size() != data_mask.size()) {
809 LOG_ERROR("manufacturer data mask should have the same length as manufacturer data");
810 return;
811 }
812 std::vector<uint8_t> combined_data = {};
813 if (action != ApcfAction::CLEAR) {
814 combined_data.push_back((uint8_t)company_id);
815 combined_data.push_back((uint8_t)(company_id >> 8));
816 if (data.size() != 0) {
817 combined_data.insert(combined_data.end(), data.begin(), data.end());
818 }
819 if (company_id_mask != 0) {
820 combined_data.push_back((uint8_t)company_id_mask);
821 combined_data.push_back((uint8_t)(company_id_mask >> 8));
822 } else {
823 combined_data.push_back(0xFF);
824 combined_data.push_back(0xFF);
825 }
826 if (data_mask.size() != 0) {
827 combined_data.insert(combined_data.end(), data_mask.begin(), data_mask.end());
828 }
829 }
830
831 le_scanning_interface_->EnqueueCommand(
832 LeAdvFilterManufacturerDataBuilder::Create(action, filter_index, combined_data),
833 module_handler_->BindOnceOn(this, &impl::on_advertising_filter_complete));
834 }
835
update_service_data_filterbluetooth::hci::LeScanningManager::impl836 void update_service_data_filter(
837 ApcfAction action, uint8_t filter_index, std::vector<uint8_t> data, std::vector<uint8_t> data_mask) {
838 if (data.size() != data_mask.size()) {
839 LOG_ERROR("service data mask should have the same length as service data");
840 return;
841 }
842 std::vector<uint8_t> combined_data = {};
843 if (action != ApcfAction::CLEAR && data.size() != 0) {
844 combined_data.insert(combined_data.end(), data.begin(), data.end());
845 combined_data.insert(combined_data.end(), data_mask.begin(), data_mask.end());
846 }
847
848 le_scanning_interface_->EnqueueCommand(
849 LeAdvFilterServiceDataBuilder::Create(action, filter_index, combined_data),
850 module_handler_->BindOnceOn(this, &impl::on_advertising_filter_complete));
851 }
852
batch_scan_set_storage_parameterbluetooth::hci::LeScanningManager::impl853 void batch_scan_set_storage_parameter(
854 uint8_t batch_scan_full_max,
855 uint8_t batch_scan_truncated_max,
856 uint8_t batch_scan_notify_threshold,
857 ScannerId scanner_id) {
858 if (!is_batch_scan_support_) {
859 LOG_WARN("Batch scan is not supported");
860 return;
861 }
862 // scanner id for OnBatchScanThresholdCrossed
863 batch_scan_config_.ref_value = scanner_id;
864
865 if (batch_scan_config_.current_state == BatchScanState::ERROR_STATE ||
866 batch_scan_config_.current_state == BatchScanState::DISABLED_STATE ||
867 batch_scan_config_.current_state == BatchScanState::DISABLE_CALLED) {
868 batch_scan_config_.current_state = BatchScanState::ENABLE_CALLED;
869 le_scanning_interface_->EnqueueCommand(
870 LeBatchScanEnableBuilder::Create(Enable::ENABLED),
871 module_handler_->BindOnceOn(this, &impl::on_batch_scan_enable_complete));
872 }
873
874 le_scanning_interface_->EnqueueCommand(
875 LeBatchScanSetStorageParametersBuilder::Create(
876 batch_scan_full_max, batch_scan_truncated_max, batch_scan_notify_threshold),
877 module_handler_->BindOnceOn(this, &impl::on_batch_scan_complete));
878 }
879
batch_scan_enablebluetooth::hci::LeScanningManager::impl880 void batch_scan_enable(
881 BatchScanMode scan_mode,
882 uint32_t duty_cycle_scan_window_slots,
883 uint32_t duty_cycle_scan_interval_slots,
884 BatchScanDiscardRule batch_scan_discard_rule) {
885 if (!is_batch_scan_support_) {
886 LOG_WARN("Batch scan is not supported");
887 return;
888 }
889
890 if (batch_scan_config_.current_state == BatchScanState::ERROR_STATE ||
891 batch_scan_config_.current_state == BatchScanState::DISABLED_STATE ||
892 batch_scan_config_.current_state == BatchScanState::DISABLE_CALLED) {
893 batch_scan_config_.current_state = BatchScanState::ENABLE_CALLED;
894 le_scanning_interface_->EnqueueCommand(
895 LeBatchScanEnableBuilder::Create(Enable::ENABLED),
896 module_handler_->BindOnceOn(this, &impl::on_batch_scan_enable_complete));
897 }
898
899 batch_scan_config_.scan_mode = scan_mode;
900 batch_scan_config_.scan_interval = duty_cycle_scan_interval_slots;
901 batch_scan_config_.scan_window = duty_cycle_scan_window_slots;
902 batch_scan_config_.discard_rule = batch_scan_discard_rule;
903 /* This command starts batch scanning, if enabled */
904 batch_scan_set_scan_parameter(
905 scan_mode, duty_cycle_scan_window_slots, duty_cycle_scan_interval_slots, batch_scan_discard_rule);
906 }
907
batch_scan_disablebluetooth::hci::LeScanningManager::impl908 void batch_scan_disable() {
909 if (!is_batch_scan_support_) {
910 LOG_WARN("Batch scan is not supported");
911 return;
912 }
913 batch_scan_config_.current_state = BatchScanState::DISABLE_CALLED;
914 batch_scan_set_scan_parameter(
915 BatchScanMode::DISABLE,
916 batch_scan_config_.scan_window,
917 batch_scan_config_.scan_interval,
918 batch_scan_config_.discard_rule);
919 }
920
batch_scan_set_scan_parameterbluetooth::hci::LeScanningManager::impl921 void batch_scan_set_scan_parameter(
922 BatchScanMode scan_mode,
923 uint32_t duty_cycle_scan_window_slots,
924 uint32_t duty_cycle_scan_interval_slots,
925 BatchScanDiscardRule batch_scan_discard_rule) {
926 if (!is_batch_scan_support_) {
927 LOG_WARN("Batch scan is not supported");
928 return;
929 }
930 AdvertisingAddressType own_address_type = AdvertisingAddressType::PUBLIC_ADDRESS;
931 if (own_address_type_ == OwnAddressType::RANDOM_DEVICE_ADDRESS ||
932 own_address_type_ == OwnAddressType::RESOLVABLE_OR_RANDOM_ADDRESS) {
933 own_address_type = AdvertisingAddressType::RANDOM_ADDRESS;
934 }
935 uint8_t truncated_mode_enabled = 0x00;
936 uint8_t full_mode_enabled = 0x00;
937 if (scan_mode == BatchScanMode::TRUNCATED || scan_mode == BatchScanMode::TRUNCATED_AND_FULL) {
938 truncated_mode_enabled = 0x01;
939 }
940 if (scan_mode == BatchScanMode::FULL || scan_mode == BatchScanMode::TRUNCATED_AND_FULL) {
941 full_mode_enabled = 0x01;
942 }
943
944 if (scan_mode == BatchScanMode::DISABLE) {
945 le_scanning_interface_->EnqueueCommand(
946 LeBatchScanSetScanParametersBuilder::Create(
947 truncated_mode_enabled,
948 full_mode_enabled,
949 duty_cycle_scan_window_slots,
950 duty_cycle_scan_interval_slots,
951 own_address_type,
952 batch_scan_discard_rule),
953 module_handler_->BindOnceOn(this, &impl::on_batch_scan_disable_complete));
954 } else {
955 le_scanning_interface_->EnqueueCommand(
956 LeBatchScanSetScanParametersBuilder::Create(
957 truncated_mode_enabled,
958 full_mode_enabled,
959 duty_cycle_scan_window_slots,
960 duty_cycle_scan_interval_slots,
961 own_address_type,
962 batch_scan_discard_rule),
963 module_handler_->BindOnceOn(this, &impl::on_batch_scan_complete));
964 }
965 }
966
batch_scan_read_resultsbluetooth::hci::LeScanningManager::impl967 void batch_scan_read_results(ScannerId scanner_id, uint16_t total_num_of_records, BatchScanMode scan_mode) {
968 if (!is_batch_scan_support_) {
969 LOG_WARN("Batch scan is not supported");
970 int status = static_cast<int>(ErrorCode::UNSUPORTED_FEATURE_OR_PARAMETER_VALUE);
971 scanning_callbacks_->OnBatchScanReports(scanner_id, status, 0, 0, {});
972 return;
973 }
974
975 if (scan_mode != BatchScanMode::FULL && scan_mode != BatchScanMode::TRUNCATED) {
976 LOG_WARN("Invalid scan mode %d", (uint16_t)scan_mode);
977 int status = static_cast<int>(ErrorCode::INVALID_HCI_COMMAND_PARAMETERS);
978 scanning_callbacks_->OnBatchScanReports(scanner_id, status, 0, 0, {});
979 return;
980 }
981
982 if (batch_scan_result_cache_.find(scanner_id) == batch_scan_result_cache_.end()) {
983 std::vector<uint8_t> empty_data = {};
984 batch_scan_result_cache_.emplace(scanner_id, empty_data);
985 }
986
987 le_scanning_interface_->EnqueueCommand(
988 LeBatchScanReadResultParametersBuilder::Create(static_cast<BatchScanDataRead>(scan_mode)),
989 module_handler_->BindOnceOn(this, &impl::on_batch_scan_read_result_complete, scanner_id, total_num_of_records));
990 }
991
track_advertiserbluetooth::hci::LeScanningManager::impl992 void track_advertiser(ScannerId scanner_id) {
993 if (!is_batch_scan_support_) {
994 LOG_WARN("Batch scan is not supported");
995 AdvertisingFilterOnFoundOnLostInfo on_found_on_lost_info = {};
996 on_found_on_lost_info.scanner_id = scanner_id;
997 on_found_on_lost_info.advertiser_info_present = AdvtInfoPresent::NO_ADVT_INFO_PRESENT;
998 scanning_callbacks_->OnTrackAdvFoundLost(on_found_on_lost_info);
999 return;
1000 }
1001 tracker_id = scanner_id;
1002 }
1003
register_scanning_callbackbluetooth::hci::LeScanningManager::impl1004 void register_scanning_callback(ScanningCallback* scanning_callbacks) {
1005 scanning_callbacks_ = scanning_callbacks;
1006 }
1007
on_advertising_filter_completebluetooth::hci::LeScanningManager::impl1008 void on_advertising_filter_complete(CommandCompleteView view) {
1009 ASSERT(view.IsValid());
1010 auto status_view = LeAdvFilterCompleteView::Create(view);
1011 ASSERT(status_view.IsValid());
1012 if (status_view.GetStatus() != ErrorCode::SUCCESS) {
1013 LOG_INFO(
1014 "Got a Command complete %s, status %s",
1015 OpCodeText(view.GetCommandOpCode()).c_str(),
1016 ErrorCodeText(status_view.GetStatus()).c_str());
1017 }
1018
1019 ApcfOpcode apcf_opcode = status_view.GetApcfOpcode();
1020 switch (apcf_opcode) {
1021 case ApcfOpcode::ENABLE: {
1022 auto complete_view = LeAdvFilterEnableCompleteView::Create(status_view);
1023 ASSERT(complete_view.IsValid());
1024 scanning_callbacks_->OnFilterEnable(complete_view.GetApcfEnable(), (uint8_t)complete_view.GetStatus());
1025 } break;
1026 case ApcfOpcode::SET_FILTERING_PARAMETERS: {
1027 auto complete_view = LeAdvFilterSetFilteringParametersCompleteView::Create(status_view);
1028 ASSERT(complete_view.IsValid());
1029 scanning_callbacks_->OnFilterParamSetup(
1030 complete_view.GetApcfAvailableSpaces(), complete_view.GetApcfAction(), (uint8_t)complete_view.GetStatus());
1031 } break;
1032 case ApcfOpcode::BROADCASTER_ADDRESS: {
1033 auto complete_view = LeAdvFilterBroadcasterAddressCompleteView::Create(status_view);
1034 ASSERT(complete_view.IsValid());
1035 scanning_callbacks_->OnFilterConfigCallback(
1036 ApcfFilterType::BROADCASTER_ADDRESS,
1037 complete_view.GetApcfAvailableSpaces(),
1038 complete_view.GetApcfAction(),
1039 (uint8_t)complete_view.GetStatus());
1040 } break;
1041 case ApcfOpcode::SERVICE_UUID: {
1042 auto complete_view = LeAdvFilterServiceUuidCompleteView::Create(status_view);
1043 ASSERT(complete_view.IsValid());
1044 scanning_callbacks_->OnFilterConfigCallback(
1045 ApcfFilterType::SERVICE_UUID,
1046 complete_view.GetApcfAvailableSpaces(),
1047 complete_view.GetApcfAction(),
1048 (uint8_t)complete_view.GetStatus());
1049 } break;
1050 case ApcfOpcode::SERVICE_SOLICITATION_UUID: {
1051 auto complete_view = LeAdvFilterSolicitationUuidCompleteView::Create(status_view);
1052 ASSERT(complete_view.IsValid());
1053 scanning_callbacks_->OnFilterConfigCallback(
1054 ApcfFilterType::SERVICE_SOLICITATION_UUID,
1055 complete_view.GetApcfAvailableSpaces(),
1056 complete_view.GetApcfAction(),
1057 (uint8_t)complete_view.GetStatus());
1058 } break;
1059 case ApcfOpcode::LOCAL_NAME: {
1060 auto complete_view = LeAdvFilterLocalNameCompleteView::Create(status_view);
1061 ASSERT(complete_view.IsValid());
1062 scanning_callbacks_->OnFilterConfigCallback(
1063 ApcfFilterType::LOCAL_NAME,
1064 complete_view.GetApcfAvailableSpaces(),
1065 complete_view.GetApcfAction(),
1066 (uint8_t)complete_view.GetStatus());
1067 } break;
1068 case ApcfOpcode::MANUFACTURER_DATA: {
1069 auto complete_view = LeAdvFilterManufacturerDataCompleteView::Create(status_view);
1070 ASSERT(complete_view.IsValid());
1071 scanning_callbacks_->OnFilterConfigCallback(
1072 ApcfFilterType::MANUFACTURER_DATA,
1073 complete_view.GetApcfAvailableSpaces(),
1074 complete_view.GetApcfAction(),
1075 (uint8_t)complete_view.GetStatus());
1076 } break;
1077 case ApcfOpcode::SERVICE_DATA: {
1078 auto complete_view = LeAdvFilterServiceDataCompleteView::Create(status_view);
1079 ASSERT(complete_view.IsValid());
1080 scanning_callbacks_->OnFilterConfigCallback(
1081 ApcfFilterType::SERVICE_DATA,
1082 complete_view.GetApcfAvailableSpaces(),
1083 complete_view.GetApcfAction(),
1084 (uint8_t)complete_view.GetStatus());
1085 } break;
1086 default:
1087 LOG_WARN("Unexpected event type %s", OpCodeText(view.GetCommandOpCode()).c_str());
1088 }
1089 }
1090
on_batch_scan_completebluetooth::hci::LeScanningManager::impl1091 void on_batch_scan_complete(CommandCompleteView view) {
1092 ASSERT(view.IsValid());
1093 auto status_view = LeBatchScanCompleteView::Create(view);
1094 ASSERT(status_view.IsValid());
1095 if (status_view.GetStatus() != ErrorCode::SUCCESS) {
1096 LOG_INFO(
1097 "Got a Command complete %s, status %s, batch_scan_opcode %s",
1098 OpCodeText(view.GetCommandOpCode()).c_str(),
1099 ErrorCodeText(status_view.GetStatus()).c_str(),
1100 BatchScanOpcodeText(status_view.GetBatchScanOpcode()).c_str());
1101 }
1102 }
1103
on_batch_scan_enable_completebluetooth::hci::LeScanningManager::impl1104 void on_batch_scan_enable_complete(CommandCompleteView view) {
1105 ASSERT(view.IsValid());
1106 auto status_view = LeBatchScanCompleteView::Create(view);
1107 ASSERT(status_view.IsValid());
1108 auto complete_view = LeBatchScanEnableCompleteView::Create(status_view);
1109 ASSERT(complete_view.IsValid());
1110 if (status_view.GetStatus() != ErrorCode::SUCCESS) {
1111 LOG_INFO("Got batch scan enable complete, status %s", ErrorCodeText(status_view.GetStatus()).c_str());
1112 batch_scan_config_.current_state = BatchScanState::ERROR_STATE;
1113 } else {
1114 batch_scan_config_.current_state = BatchScanState::ENABLED_STATE;
1115 }
1116 }
1117
on_batch_scan_disable_completebluetooth::hci::LeScanningManager::impl1118 void on_batch_scan_disable_complete(CommandCompleteView view) {
1119 ASSERT(view.IsValid());
1120 auto status_view = LeBatchScanCompleteView::Create(view);
1121 ASSERT(status_view.IsValid());
1122 auto complete_view = LeBatchScanSetScanParametersCompleteView::Create(status_view);
1123 ASSERT(complete_view.IsValid());
1124 ASSERT(status_view.GetStatus() == ErrorCode::SUCCESS);
1125 batch_scan_config_.current_state = BatchScanState::DISABLED_STATE;
1126 }
1127
on_batch_scan_read_result_completebluetooth::hci::LeScanningManager::impl1128 void on_batch_scan_read_result_complete(
1129 ScannerId scanner_id, uint16_t total_num_of_records, CommandCompleteView view) {
1130 ASSERT(view.IsValid());
1131 auto status_view = LeBatchScanCompleteView::Create(view);
1132 ASSERT(status_view.IsValid());
1133 auto complete_view = LeBatchScanReadResultParametersCompleteRawView::Create(status_view);
1134 ASSERT(complete_view.IsValid());
1135 if (complete_view.GetStatus() != ErrorCode::SUCCESS) {
1136 LOG_INFO("Got batch scan read result complete, status %s", ErrorCodeText(status_view.GetStatus()).c_str());
1137 }
1138 uint8_t num_of_records = complete_view.GetNumOfRecords();
1139 auto report_format = complete_view.GetBatchScanDataRead();
1140 if (num_of_records == 0) {
1141 scanning_callbacks_->OnBatchScanReports(
1142 scanner_id, 0x00, (int)report_format, total_num_of_records, batch_scan_result_cache_[scanner_id]);
1143 batch_scan_result_cache_.erase(scanner_id);
1144 } else {
1145 auto raw_data = complete_view.GetRawData();
1146 batch_scan_result_cache_[scanner_id].insert(
1147 batch_scan_result_cache_[scanner_id].end(), raw_data.begin(), raw_data.end());
1148 total_num_of_records += num_of_records;
1149 batch_scan_read_results(scanner_id, total_num_of_records, static_cast<BatchScanMode>(report_format));
1150 }
1151 }
1152
on_storage_threshold_breachbluetooth::hci::LeScanningManager::impl1153 void on_storage_threshold_breach(VendorSpecificEventView event) {
1154 if (batch_scan_config_.ref_value == kInvalidScannerId) {
1155 LOG_WARN("storage threshold was not set !!");
1156 return;
1157 }
1158 scanning_callbacks_->OnBatchScanThresholdCrossed(static_cast<int>(batch_scan_config_.ref_value));
1159 }
1160
on_advertisement_trackingbluetooth::hci::LeScanningManager::impl1161 void on_advertisement_tracking(VendorSpecificEventView event) {
1162 if (tracker_id == kInvalidScannerId) {
1163 LOG_WARN("Advertisement track is not register");
1164 return;
1165 }
1166 auto view = LEAdvertisementTrackingEventView::Create(event);
1167 ASSERT(view.IsValid());
1168 AdvertisingFilterOnFoundOnLostInfo on_found_on_lost_info = {};
1169 on_found_on_lost_info.scanner_id = tracker_id;
1170 on_found_on_lost_info.filter_index = view.GetApcfFilterIndex();
1171 on_found_on_lost_info.advertiser_state = view.GetAdvertiserState();
1172 on_found_on_lost_info.advertiser_address = view.GetAdvertiserAddress();
1173 on_found_on_lost_info.advertiser_address_type = view.GetAdvertiserAddressType();
1174 on_found_on_lost_info.advertiser_info_present = view.GetAdvtInfoPresent();
1175 /* Extract the adv info details */
1176 if (on_found_on_lost_info.advertiser_info_present == AdvtInfoPresent::ADVT_INFO_PRESENT) {
1177 auto info_view = LEAdvertisementTrackingWithInfoEventView::Create(view);
1178 ASSERT(info_view.IsValid());
1179 on_found_on_lost_info.tx_power = info_view.GetTxPower();
1180 on_found_on_lost_info.rssi = info_view.GetRssi();
1181 on_found_on_lost_info.time_stamp = info_view.GetTimestamp();
1182 auto adv_data = info_view.GetAdvPacket();
1183 on_found_on_lost_info.adv_packet.reserve(adv_data.size());
1184 on_found_on_lost_info.adv_packet.insert(on_found_on_lost_info.adv_packet.end(), adv_data.begin(), adv_data.end());
1185 auto scan_rsp_data = info_view.GetScanResponse();
1186 on_found_on_lost_info.scan_response.reserve(scan_rsp_data.size());
1187 on_found_on_lost_info.scan_response.insert(
1188 on_found_on_lost_info.scan_response.end(), scan_rsp_data.begin(), scan_rsp_data.end());
1189 }
1190 scanning_callbacks_->OnTrackAdvFoundLost(on_found_on_lost_info);
1191 }
1192
OnPausebluetooth::hci::LeScanningManager::impl1193 void OnPause() override {
1194 paused_ = true;
1195 scan_on_resume_ = is_scanning_;
1196 stop_scan();
1197 ack_pause();
1198 }
1199
ack_pausebluetooth::hci::LeScanningManager::impl1200 void ack_pause() {
1201 le_address_manager_->AckPause(this);
1202 }
1203
OnResumebluetooth::hci::LeScanningManager::impl1204 void OnResume() override {
1205 paused_ = false;
1206 if (scan_on_resume_ == true) {
1207 start_scan();
1208 }
1209 le_address_manager_->AckResume(this);
1210 }
1211
1212 ScanApiType api_type_;
1213
1214 Module* module_;
1215 os::Handler* module_handler_;
1216 hci::HciLayer* hci_layer_;
1217 hci::Controller* controller_;
1218 hci::VendorSpecificEventManager* vendor_specific_event_manager_;
1219 hci::LeScanningInterface* le_scanning_interface_;
1220 hci::LeAddressManager* le_address_manager_;
1221 bool address_manager_registered_ = false;
1222 NullScanningCallback null_scanning_callback_;
1223 ScanningCallback* scanning_callbacks_ = &null_scanning_callback_;
1224 std::vector<Scanner> scanners_;
1225 bool is_scanning_ = false;
1226 bool scan_on_resume_ = false;
1227 bool paused_ = false;
1228 AdvertisingCache advertising_cache_;
1229 bool is_filter_support_ = false;
1230 bool is_batch_scan_support_ = false;
1231
1232 LeScanType le_scan_type_ = LeScanType::ACTIVE;
1233 uint32_t interval_ms_{1000};
1234 uint16_t window_ms_{1000};
1235 OwnAddressType own_address_type_{OwnAddressType::PUBLIC_DEVICE_ADDRESS};
1236 LeScanningFilterPolicy filter_policy_{LeScanningFilterPolicy::ACCEPT_ALL};
1237 BatchScanConfig batch_scan_config_;
1238 std::map<ScannerId, std::vector<uint8_t>> batch_scan_result_cache_;
1239 ScannerId tracker_id = kInvalidScannerId;
1240
check_statusbluetooth::hci::LeScanningManager::impl1241 static void check_status(CommandCompleteView view) {
1242 switch (view.GetCommandOpCode()) {
1243 case (OpCode::LE_SET_SCAN_ENABLE): {
1244 auto status_view = LeSetScanEnableCompleteView::Create(view);
1245 ASSERT(status_view.IsValid());
1246 ASSERT(status_view.GetStatus() == ErrorCode::SUCCESS);
1247 } break;
1248 case (OpCode::LE_SET_EXTENDED_SCAN_ENABLE): {
1249 auto status_view = LeSetExtendedScanEnableCompleteView::Create(view);
1250 ASSERT(status_view.IsValid());
1251 ASSERT(status_view.GetStatus() == ErrorCode::SUCCESS);
1252 } break;
1253 case (OpCode::LE_SET_SCAN_PARAMETERS): {
1254 auto status_view = LeSetScanParametersCompleteView::Create(view);
1255 ASSERT(status_view.IsValid());
1256 ASSERT(status_view.GetStatus() == ErrorCode::SUCCESS);
1257 } break;
1258 case (OpCode::LE_EXTENDED_SCAN_PARAMS): {
1259 auto status_view = LeExtendedScanParamsCompleteView::Create(view);
1260 ASSERT(status_view.IsValid());
1261 ASSERT(status_view.GetStatus() == ErrorCode::SUCCESS);
1262 } break;
1263 case (OpCode::LE_SET_EXTENDED_SCAN_PARAMETERS): {
1264 auto status_view = LeSetExtendedScanParametersCompleteView::Create(view);
1265 ASSERT(status_view.IsValid());
1266 ASSERT(status_view.GetStatus() == ErrorCode::SUCCESS);
1267 } break;
1268 default:
1269 LOG_ALWAYS_FATAL("Unhandled event %s", OpCodeText(view.GetCommandOpCode()).c_str());
1270 }
1271 }
1272 };
1273
LeScanningManager()1274 LeScanningManager::LeScanningManager() {
1275 pimpl_ = std::make_unique<impl>(this);
1276 }
1277
ListDependencies(ModuleList * list)1278 void LeScanningManager::ListDependencies(ModuleList* list) {
1279 list->add<hci::HciLayer>();
1280 list->add<hci::VendorSpecificEventManager>();
1281 list->add<hci::Controller>();
1282 list->add<hci::AclManager>();
1283 }
1284
Start()1285 void LeScanningManager::Start() {
1286 pimpl_->start(
1287 GetHandler(),
1288 GetDependency<hci::HciLayer>(),
1289 GetDependency<hci::Controller>(),
1290 GetDependency<AclManager>(),
1291 GetDependency<VendorSpecificEventManager>());
1292 }
1293
Stop()1294 void LeScanningManager::Stop() {
1295 pimpl_->stop();
1296 pimpl_.reset();
1297 }
1298
ToString() const1299 std::string LeScanningManager::ToString() const {
1300 return "Le Scanning Manager";
1301 }
1302
RegisterScanner(Uuid app_uuid)1303 void LeScanningManager::RegisterScanner(Uuid app_uuid) {
1304 CallOn(pimpl_.get(), &impl::register_scanner, app_uuid);
1305 }
1306
Unregister(ScannerId scanner_id)1307 void LeScanningManager::Unregister(ScannerId scanner_id) {
1308 CallOn(pimpl_.get(), &impl::unregister_scanner, scanner_id);
1309 }
1310
Scan(bool start)1311 void LeScanningManager::Scan(bool start) {
1312 CallOn(pimpl_.get(), &impl::scan, start);
1313 }
1314
SetScanParameters(LeScanType scan_type,uint16_t scan_interval,uint16_t scan_window)1315 void LeScanningManager::SetScanParameters(LeScanType scan_type, uint16_t scan_interval, uint16_t scan_window) {
1316 CallOn(pimpl_.get(), &impl::set_scan_parameters, scan_type, scan_interval, scan_window);
1317 }
1318
ScanFilterEnable(bool enable)1319 void LeScanningManager::ScanFilterEnable(bool enable) {
1320 CallOn(pimpl_.get(), &impl::scan_filter_enable, enable);
1321 }
1322
ScanFilterParameterSetup(ApcfAction action,uint8_t filter_index,AdvertisingFilterParameter advertising_filter_parameter)1323 void LeScanningManager::ScanFilterParameterSetup(
1324 ApcfAction action, uint8_t filter_index, AdvertisingFilterParameter advertising_filter_parameter) {
1325 CallOn(pimpl_.get(), &impl::scan_filter_parameter_setup, action, filter_index, advertising_filter_parameter);
1326 }
1327
ScanFilterAdd(uint8_t filter_index,std::vector<AdvertisingPacketContentFilterCommand> filters)1328 void LeScanningManager::ScanFilterAdd(
1329 uint8_t filter_index, std::vector<AdvertisingPacketContentFilterCommand> filters) {
1330 CallOn(pimpl_.get(), &impl::scan_filter_add, filter_index, filters);
1331 }
1332
BatchScanConifgStorage(uint8_t batch_scan_full_max,uint8_t batch_scan_truncated_max,uint8_t batch_scan_notify_threshold,ScannerId scanner_id)1333 void LeScanningManager::BatchScanConifgStorage(
1334 uint8_t batch_scan_full_max,
1335 uint8_t batch_scan_truncated_max,
1336 uint8_t batch_scan_notify_threshold,
1337 ScannerId scanner_id) {
1338 CallOn(
1339 pimpl_.get(),
1340 &impl::batch_scan_set_storage_parameter,
1341 batch_scan_full_max,
1342 batch_scan_truncated_max,
1343 batch_scan_notify_threshold,
1344 scanner_id);
1345 }
1346
BatchScanEnable(BatchScanMode scan_mode,uint32_t duty_cycle_scan_window_slots,uint32_t duty_cycle_scan_interval_slots,BatchScanDiscardRule batch_scan_discard_rule)1347 void LeScanningManager::BatchScanEnable(
1348 BatchScanMode scan_mode,
1349 uint32_t duty_cycle_scan_window_slots,
1350 uint32_t duty_cycle_scan_interval_slots,
1351 BatchScanDiscardRule batch_scan_discard_rule) {
1352 CallOn(
1353 pimpl_.get(),
1354 &impl::batch_scan_enable,
1355 scan_mode,
1356 duty_cycle_scan_window_slots,
1357 duty_cycle_scan_interval_slots,
1358 batch_scan_discard_rule);
1359 }
1360
BatchScanDisable()1361 void LeScanningManager::BatchScanDisable() {
1362 CallOn(pimpl_.get(), &impl::batch_scan_disable);
1363 }
1364
BatchScanReadReport(ScannerId scanner_id,BatchScanMode scan_mode)1365 void LeScanningManager::BatchScanReadReport(ScannerId scanner_id, BatchScanMode scan_mode) {
1366 CallOn(pimpl_.get(), &impl::batch_scan_read_results, scanner_id, 0, scan_mode);
1367 }
1368
TrackAdvertiser(ScannerId scanner_id)1369 void LeScanningManager::TrackAdvertiser(ScannerId scanner_id) {
1370 CallOn(pimpl_.get(), &impl::track_advertiser, scanner_id);
1371 }
1372
RegisterScanningCallback(ScanningCallback * scanning_callback)1373 void LeScanningManager::RegisterScanningCallback(ScanningCallback* scanning_callback) {
1374 CallOn(pimpl_.get(), &impl::register_scanning_callback, scanning_callback);
1375 }
1376
1377 } // namespace hci
1378 } // namespace bluetooth
1379