1 // Copyright 2023 The Pigweed Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 // use this file except in compliance with the License. You may obtain a copy of 5 // the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations under 13 // the License. 14 15 #pragma once 16 #include <string> 17 #include <vector> 18 19 #include "pw_bluetooth_sapphire/internal/host/common/uuid.h" 20 #include "pw_bluetooth_sapphire/internal/host/hci-spec/constants.h" 21 22 namespace bt { 23 24 class ByteBuffer; 25 26 namespace gap { 27 28 class Peer; 29 30 // A DiscoveryFilter allows clients of discovery procedures to filter results 31 // based on certain parameters, such as service UUIDs that might be present in 32 // EIR or advertising data, or based on available proximity information, to name 33 // a few. 34 class DiscoveryFilter final { 35 public: 36 DiscoveryFilter() = default; 37 38 // Discovery filter based on the "Flags" bit field in LE Advertising Data. If 39 // |require_all| is true, then The filter is considered satisifed if ALL of 40 // the bits set in |flags_bitfield| are present in the advertisement. 41 // Otherwise, the filter is considered satisfied as long as one of the bits 42 // set in |flags_bitfield| is present. 43 void set_flags(uint8_t flags_bitfield, bool require_all = false) { 44 flags_ = flags_bitfield; 45 all_flags_required_ = require_all; 46 } 47 48 // Discovery filter based on whether or not a device is connectable. set_connectable(bool connectable)49 void set_connectable(bool connectable) { connectable_ = connectable; } connectable()50 std::optional<bool> connectable() const { return connectable_; } 51 52 // Sets the service UUIDs that should be present in a scan result. A scan 53 // result satisfies this filter if it provides at least one of the provided 54 // UUIDs. 55 // 56 // Passing an empty value for |service_uuids| effectively disables this 57 // filter. set_service_uuids(const std::vector<UUID> & service_uuids)58 void set_service_uuids(const std::vector<UUID>& service_uuids) { 59 service_uuids_ = service_uuids; 60 } service_uuids()61 const std::vector<UUID>& service_uuids() const { return service_uuids_; } 62 63 // Filter on service data UUIDs. 64 // 65 // Passing an empty value for |service_data_uuids| effectively disables this 66 // filter. set_service_data_uuids(const std::vector<UUID> & service_data_uuids)67 void set_service_data_uuids(const std::vector<UUID>& service_data_uuids) { 68 service_data_uuids_ = service_data_uuids; 69 } service_data_uuids()70 const std::vector<UUID>& service_data_uuids() const { 71 return service_data_uuids_; 72 } 73 74 // Sets a string to be matched against the device name. A scan result 75 // satisfies this filter if part of the complete or shortened device name 76 // fields matches |name_substring|. 77 // 78 // Passing an empty value for |name_substring| effectively disables this 79 // filter. set_name_substring(const std::string & name_substring)80 void set_name_substring(const std::string& name_substring) { 81 name_substring_ = name_substring; 82 } name_substring()83 const std::string& name_substring() const { return name_substring_; } 84 85 // Sets a device to be filtered by the pathloss (in dBm) of the radio wave. 86 // This value is calculated using the received signal strength (measured 87 // locally) and the transmission power of the signal (as reported by the 88 // remote): 89 // 90 // Path Loss = RSSI - Tx Power 91 // 92 // If this filter parameter has been set and the pathloss value calculated for 93 // a device greater than the provided |pathloss| value, then the scan result 94 // will fail to satisfy this filter. 95 // 96 // If this filter parameter has been set and the pathloss value cannot be 97 // calculated because the remote device did not report its transmission power, 98 // then the device will fail to satisfy this filter UNLESS an RSSI filter 99 // parameter has been set via SetRSSI() that is satisfied by the scan result. set_pathloss(int8_t pathloss)100 void set_pathloss(int8_t pathloss) { pathloss_ = pathloss; } pathloss()101 std::optional<int8_t> pathloss() const { return pathloss_; } 102 103 // Sets a device to be filtered by RSSI. While this can produce inaccurate 104 // results when used alone to approximate proximity, it can still be useful 105 // when the scan results do not provide the remote device's Transmission 106 // Power. 107 // 108 // A remote device is considered to satisfy this filter parameter if the RSSI 109 // of the received transmission is greater than or equal to |rssi|, except if 110 // a path loss filter was provided via SetPathLoss() which the remote device 111 // failed to satisfy (see comments on SetPathLoss()). set_rssi(int8_t rssi)112 void set_rssi(int8_t rssi) { rssi_ = rssi; } 113 114 // Sets a device to be filtered by manufacturer specific data. A scan result 115 // satisfies this filter if it advertises manufacturer specific data 116 // containing |manufacturer_code|. set_manufacturer_code(uint16_t manufacturer_code)117 void set_manufacturer_code(uint16_t manufacturer_code) { 118 manufacturer_code_ = manufacturer_code; 119 } manufacturer_code()120 std::optional<uint16_t> manufacturer_code() const { 121 return manufacturer_code_; 122 } 123 124 // Sets this filter up for the "General Discovery" procedure. 125 void SetGeneralDiscoveryFlags(); 126 127 // Returns true, if the given LE scan result satisfies this filter. Otherwise 128 // returns false. |advertising_data| should include scan response data, if 129 // any. 130 bool MatchLowEnergyResult( 131 const std::optional<std::reference_wrapper<const AdvertisingData>> 132 advertising_data, 133 bool connectable, 134 int8_t rssi) const; 135 136 // Clears all the fields of this filter. 137 void Reset(); 138 139 private: 140 std::vector<UUID> service_uuids_; 141 std::vector<UUID> service_data_uuids_; 142 std::string name_substring_; 143 std::optional<uint8_t> flags_; 144 bool all_flags_required_; 145 std::optional<bool> connectable_; 146 std::optional<uint16_t> manufacturer_code_; 147 std::optional<int8_t> pathloss_; 148 std::optional<int8_t> rssi_; 149 }; 150 151 } // namespace gap 152 } // namespace bt 153