| // Copyright 2017 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_GAP_DISCOVERY_FILTER_H_ |
| #define SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_GAP_DISCOVERY_FILTER_H_ |
| |
| #include <string> |
| #include <vector> |
| |
| #include "src/connectivity/bluetooth/core/bt-host/common/uuid.h" |
| #include "src/connectivity/bluetooth/core/bt-host/hci-spec/constants.h" |
| |
| namespace bt { |
| |
| class ByteBuffer; |
| |
| namespace gap { |
| |
| class Peer; |
| |
| // A DiscoveryFilter allows clients of discovery procedures to filter results |
| // based on certain parameters, such as service UUIDs that might be present in |
| // EIR or advertising data, or based on available proximity information, to name |
| // a few. |
| class DiscoveryFilter final { |
| public: |
| DiscoveryFilter() = default; |
| |
| // Discovery filter based on the "Flags" bit field in LE Advertising Data. If |
| // |require_all| is true, then The filter is considered satisifed if ALL of |
| // the bits set in |flags_bitfield| are present in the advertisement. |
| // Otherwise, the filter is considered satisfied as long as one of the bits |
| // set in |flags_bitfield| is present. |
| void set_flags(uint8_t flags_bitfield, bool require_all = false) { |
| flags_ = flags_bitfield; |
| all_flags_required_ = require_all; |
| } |
| |
| // Discovery filter based on whether or not a device is connectable. |
| void set_connectable(bool connectable) { connectable_ = connectable; } |
| std::optional<bool> connectable() const { return connectable_; } |
| |
| // Sets the service UUIDs that should be present in a scan result. A scan |
| // result satisfies this filter if it provides at least one of the provided |
| // UUIDs. |
| // |
| // Passing an empty value for |service_uuids| effectively disables this |
| // filter. |
| void set_service_uuids(const std::vector<UUID>& service_uuids) { service_uuids_ = service_uuids; } |
| const std::vector<UUID>& service_uuids() const { return service_uuids_; } |
| |
| // Filter on service data UUIDs. |
| // |
| // Passing an empty value for |service_data_uuids| effectively disables this |
| // filter. |
| void set_service_data_uuids(const std::vector<UUID>& service_data_uuids) { |
| service_data_uuids_ = service_data_uuids; |
| } |
| const std::vector<UUID>& service_data_uuids() const { return service_data_uuids_; } |
| |
| // Sets a string to be matched against the device name. A scan result |
| // satisfies this filter if part of the complete or shortened device name |
| // fields matches |name_substring|. |
| // |
| // Passing an empty value for |name_substring| effectively disables this |
| // filter. |
| void set_name_substring(const std::string& name_substring) { name_substring_ = name_substring; } |
| const std::string& name_substring() const { return name_substring_; } |
| |
| // Sets a device to be filtered by the pathloss (in dBm) of the radio wave. |
| // This value is calculated using the received signal strength (measured |
| // locally) and the transmission power of the signal (as reported by the |
| // remote): |
| // |
| // Path Loss = RSSI - Tx Power |
| // |
| // If this filter parameter has been set and the pathloss value calculated for |
| // a device greater than the provided |pathloss| value, then the scan result |
| // will fail to satisfy this filter. |
| // |
| // If this filter parameter has been set and the pathloss value cannot be |
| // calculated because the remote device did not report its transmission power, |
| // then the device will fail to satisfy this filter UNLESS an RSSI filter |
| // parameter has been set via SetRSSI() that is satisfied by the scan result. |
| void set_pathloss(int8_t pathloss) { pathloss_ = pathloss; } |
| std::optional<int8_t> pathloss() const { return pathloss_; } |
| |
| // Sets a device to be filtered by RSSI. While this can produce inaccurate |
| // results when used alone to approximate proximity, it can still be useful |
| // when the scan results do not provide the remote device's Transmission |
| // Power. |
| // |
| // A remote device is considered to satisfy this filter parameter if the RSSI |
| // of the received transmission is greater than or equal to |rssi|, except if |
| // a path loss filter was provided via SetPathLoss() which the remote device |
| // failed to satisfy (see comments on SetPathLoss()). |
| void set_rssi(int8_t rssi) { rssi_ = rssi; } |
| |
| // Sets a device to be filtered by manufacturer specific data. A scan result |
| // satisfies this filter if it advertises manufacturer specific data |
| // containing |manufacturer_code|. |
| void set_manufacturer_code(uint16_t manufacturer_code) { manufacturer_code_ = manufacturer_code; } |
| std::optional<uint16_t> manufacturer_code() const { return manufacturer_code_; } |
| |
| // Sets this filter up for the "General Discovery" procedure. |
| void SetGeneralDiscoveryFlags(); |
| |
| // Returns true, if the given LE scan result satisfies this filter. Otherwise |
| // returns false. |advertising_data| should include scan response data, if |
| // any. |
| bool MatchLowEnergyResult(const ByteBuffer& advertising_data, bool connectable, |
| int8_t rssi) const; |
| |
| // Clears all the fields of this filter. |
| void Reset(); |
| |
| private: |
| std::vector<UUID> service_uuids_; |
| std::vector<UUID> service_data_uuids_; |
| std::string name_substring_; |
| std::optional<uint8_t> flags_; |
| bool all_flags_required_; |
| std::optional<bool> connectable_; |
| std::optional<uint16_t> manufacturer_code_; |
| std::optional<int8_t> pathloss_; |
| std::optional<int8_t> rssi_; |
| }; |
| |
| } // namespace gap |
| } // namespace bt |
| |
| #endif // SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_GAP_DISCOVERY_FILTER_H_ |