From: Chienyuan Date: Mon, 11 Jan 2021 14:25:11 +0000 (+0800) Subject: gd: Handle scan response X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=cfb5f5e585141cb3b22456fc2df410ad404d2fd2;p=android-x86%2Fsystem-bt.git gd: Handle scan response Tag: #gd-refactor Bug: 177044452 Test: gd/cert/run --host Change-Id: Ia710365dba1901803fd8c85d3cecb27f22d25bc5 --- diff --git a/gd/hci/le_scanning_manager.cc b/gd/hci/le_scanning_manager.cc index c7981a011..b49430d8f 100644 --- a/gd/hci/le_scanning_manager.cc +++ b/gd/hci/le_scanning_manager.cc @@ -33,6 +33,12 @@ namespace hci { constexpr uint16_t kDefaultLeScanWindow = 4800; constexpr uint16_t kDefaultLeScanInterval = 4800; +constexpr uint8_t kScannableBit = 1; +constexpr uint8_t kDirectedBit = 2; +constexpr uint8_t kScanResponseBit = 3; +constexpr uint8_t kLegacyBit = 4; +constexpr uint8_t kDataStatusBits = 5; + const ModuleFactory LeScanningManager::Factory = ModuleFactory([]() { return new LeScanningManager(); }); enum class ScanApiType { @@ -46,6 +52,79 @@ struct Scanner { bool in_use; }; +class AdvertisingCache { + public: + const std::vector& Set(const AddressWithType& address_with_type, std::vector data) { + auto it = Find(address_with_type); + if (it != items.end()) { + it->data = std::move(data); + } + + if (items.size() > cache_max) { + items.pop_back(); + } + + items.emplace_front(address_with_type, std::move(data)); + return items.front().data; + } + + bool Exist(const AddressWithType& address_with_type) { + auto it = Find(address_with_type); + if (it == items.end()) { + return false; + } + return true; + } + + const std::vector& Append(const AddressWithType& address_with_type, std::vector data) { + auto it = Find(address_with_type); + if (it != items.end()) { + it->data.insert(it->data.end(), data.begin(), data.end()); + return it->data; + } + + if (items.size() > cache_max) { + items.pop_back(); + } + + items.emplace_front(address_with_type, std::move(data)); + return items.front().data; + } + + /* Clear data for device |addr_type, addr| */ + void Clear(AddressWithType address_with_type) { + auto it = Find(address_with_type); + if (it != items.end()) { + items.erase(it); + } + } + + void ClearAll() { + items.clear(); + } + + struct Item { + AddressWithType address_with_type; + std::vector data; + + Item(const AddressWithType& address_with_type, std::vector data) + : address_with_type(address_with_type), data(data) {} + }; + + std::list::iterator Find(const AddressWithType& address_with_type) { + for (auto it = items.begin(); it != items.end(); it++) { + if (it->address_with_type == address_with_type) { + return it; + } + } + return items.end(); + } + + /* we keep maximum 7 devices in the cache */ + const size_t cache_max = 1000; + std::list items; +}; + struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback { impl(Module* module) : module_(module), le_scanning_interface_(nullptr) {} @@ -132,7 +211,6 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback return; } - // TODO: handle AdvertisingCache for scan response for (LeAdvertisingReport report : reports) { uint16_t extended_event_type = 0; switch (report.event_type_) { @@ -159,8 +237,8 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback return; } - scanning_callbacks_->OnScanResult( - (uint16_t)report.event_type_, + process_advertising_package_content( + extended_event_type, (uint8_t)report.address_type_, report.address_, (uint8_t)PrimaryPhyType::LE_1M, @@ -207,11 +285,11 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback return; } - // TODO: handle AdvertisingCache for scan response for (LeExtendedAdvertisingReport report : reports) { - uint16_t event_type = report.connectable_ | (report.scannable_ << 1) | (report.directed_ << 2) | - (report.scan_response_ << 3) | (report.legacy_ << 4) | ((uint16_t)report.data_status_ << 5); - scanning_callbacks_->OnScanResult( + uint16_t event_type = report.connectable_ | (report.scannable_ << kScannableBit) | + (report.directed_ << kDirectedBit) | (report.scan_response_ << kScanResponseBit) | + (report.legacy_ << kLegacyBit) | ((uint16_t)report.data_status_ << kDataStatusBits); + process_advertising_package_content( event_type, (uint8_t)report.address_type_, report.address_, @@ -225,6 +303,54 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback } } + void process_advertising_package_content( + 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 advertising_data) { + bool is_scannable = event_type & (1 << kScannableBit); + bool is_scan_response = event_type & (1 << kScanResponseBit); + bool is_legacy = event_type & (1 << kLegacyBit); + // TODO handle anonymous advertisement (0xFF) + AddressWithType address_with_type(address, (AddressType)address_type); + + if (is_legacy && is_scan_response && !advertising_cache_.Exist(address_with_type)) { + return; + } + + bool is_start = is_legacy && is_scannable && !is_scan_response; + + std::vector const& adv_data = is_start ? advertising_cache_.Set(address_with_type, advertising_data) + : advertising_cache_.Append(address_with_type, advertising_data); + + // TODO: handle data status + + if (is_scannable && !is_scan_response) { + // Waiting for scan response + return; + } + + scanning_callbacks_->OnScanResult( + event_type, + address_type, + address, + primary_phy, + secondary_phy, + advertising_sid, + tx_power, + rssi, + periodic_advertising_interval, + adv_data); + + advertising_cache_.Clear(address_with_type); + } + void configure_scan() { std::vector parameter_vector; PhyScanParameters phy_scan_parameters; @@ -389,6 +515,7 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback bool is_scanning_ = false; bool scan_on_resume_ = false; bool paused_ = false; + AdvertisingCache advertising_cache_; uint32_t interval_ms_{1000}; uint16_t window_ms_{1000}; diff --git a/gd/hci/le_scanning_manager_test.cc b/gd/hci/le_scanning_manager_test.cc index a39b86a1b..a9b37380f 100644 --- a/gd/hci/le_scanning_manager_test.cc +++ b/gd/hci/le_scanning_manager_test.cc @@ -334,7 +334,7 @@ TEST_F(LeScanningManagerTest, start_scan_test) { test_hci_layer_->IncomingEvent(LeSetScanEnableCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS)); LeAdvertisingReport report{}; - report.event_type_ = AdvertisingEventType::ADV_IND; + report.event_type_ = AdvertisingEventType::ADV_DIRECT_IND; report.address_type_ = AddressType::PUBLIC_DEVICE_ADDRESS; Address::FromString("12:34:56:78:9a:bc", report.address_); std::vector gap_data{}; @@ -361,7 +361,7 @@ TEST_F(LeAndroidHciScanningManagerTest, start_scan_test) { test_hci_layer_->IncomingEvent(LeSetScanEnableCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS)); LeAdvertisingReport report{}; - report.event_type_ = AdvertisingEventType::ADV_IND; + report.event_type_ = AdvertisingEventType::ADV_DIRECT_IND; report.address_type_ = AddressType::PUBLIC_DEVICE_ADDRESS; Address::FromString("12:34:56:78:9a:bc", report.address_); std::vector gap_data{}; @@ -391,7 +391,7 @@ TEST_F(LeExtendedScanningManagerTest, start_scan_test) { LeExtendedAdvertisingReport report{}; report.connectable_ = 1; - report.scannable_ = 1; + report.scannable_ = 0; report.address_type_ = DirectAdvertisingAddressType::PUBLIC_DEVICE_ADDRESS; Address::FromString("12:34:56:78:9a:bc", report.address_); std::vector gap_data{};