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 #pragma once 17 18 #include <gtest/gtest_prod.h> 19 20 #include <cstdint> 21 #include <list> 22 #include <optional> 23 #include <vector> 24 25 #include "hci/address_with_type.h" 26 #include "hci/hci_packets.h" 27 28 namespace bluetooth::hci { 29 30 /// The LE Scanning reassembler is responsible for defragmenting 31 /// LE advertising reports that are too large to fit inside an HCI event 32 /// and were fragmented by the compiler. 33 /// The reassembler also joins scan response data with the 34 /// matching advertising data. 35 36 class LeScanningReassembler { 37 public: LeScanningReassembler()38 LeScanningReassembler(){}; 39 LeScanningReassembler(const LeScanningReassembler&) = delete; 40 LeScanningReassembler& operator=(const LeScanningReassembler&) = delete; 41 42 /// Process an incoming advertsing report, extracted from any of the 43 /// HCI LE Advertising Report or the HCI LE Extended Advertising Report 44 /// events. 45 /// Returns the completed advertising data if the event was complete, or the 46 /// completion of a fragmented advertising event. 47 std::optional<std::vector<uint8_t>> ProcessAdvertisingReport( 48 uint16_t event_type, 49 uint8_t address_type, 50 Address address, 51 uint8_t advertising_sid, 52 const std::vector<uint8_t>& advertising_data); 53 54 /// Configure the scan response filter. 55 /// If true all scan responses are ignored. SetIgnoreScanResponses(bool ignore_scan_responses)56 void SetIgnoreScanResponses(bool ignore_scan_responses) { 57 ignore_scan_responses_ = ignore_scan_responses; 58 } 59 60 private: 61 /// Determine if scan responses should be processed or ignored. 62 bool ignore_scan_responses_{false}; 63 64 /// Constants for parsing event_type. 65 static constexpr uint8_t kScannableBit = 1; 66 static constexpr uint8_t kDirectedBit = 2; 67 static constexpr uint8_t kScanResponseBit = 3; 68 static constexpr uint8_t kLegacyBit = 4; 69 static constexpr uint8_t kDataStatusBits = 5; 70 71 /// Packs the information necessary to disambiguate advertising events: 72 /// - For legacy advertising events, the advertising address and 73 /// advertising address type are used to disambiguate advertisers. 74 /// - For extended advertising events, the SID is optionally used to 75 /// differentiate between advertising sets of the same advertiser. 76 /// The advertiser can also be anonymous in which case 77 /// the address is not provided. In this case, and when the SID 78 /// is missing, we trust the controller to send fragments of the same 79 /// advertisement together and not interleaved with that of other 80 /// advertisers. 81 struct AdvertisingKey { 82 std::optional<AddressWithType> address; 83 std::optional<uint8_t> sid; 84 85 AdvertisingKey(Address address, DirectAdvertisingAddressType address_type, uint8_t sid); 86 bool operator==(const AdvertisingKey& other); 87 }; 88 89 /// Packs incomplete advertising data. 90 struct AdvertisingFragment { 91 AdvertisingKey key; 92 std::vector<uint8_t> data; 93 AdvertisingFragmentAdvertisingFragment94 AdvertisingFragment(const AdvertisingKey& key, const std::vector<uint8_t>& data) 95 : key(key), data(data.begin(), data.end()) {} 96 }; 97 98 /// Advertising cache for de-fragmenting extended advertising reports, 99 /// and joining advertising reports with the matching scan response when 100 /// applicable. 101 /// The cached advertising data is removed as soon as the complete 102 /// advertisement is got (including the scan response). 103 static constexpr size_t kMaximumCacheSize = 16; 104 std::list<AdvertisingFragment> cache_; 105 106 /// Advertising cache management methods. 107 std::list<AdvertisingFragment>::iterator AppendFragment( 108 const AdvertisingKey& key, const std::vector<uint8_t>& data); 109 void RemoveFragment(const AdvertisingKey& key); 110 bool ContainsFragment(const AdvertisingKey& key); 111 std::list<AdvertisingFragment>::iterator FindFragment(const AdvertisingKey& key); 112 113 /// Trim the advertising data by removing empty or overflowing 114 /// GAP Data entries. 115 static std::vector<uint8_t> TrimAdvertisingData(const std::vector<uint8_t>& advertising_data); 116 117 FRIEND_TEST(LeScanningReassemblerTest, trim_advertising_data); 118 }; 119 120 } // namespace bluetooth::hci 121