blob: 073dfb333b584250d9127bec73fe7ca76d4d97a4 [file] [log] [blame]
// 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; }
// 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; }
// Sets a string to be matched against the device name. A scan result
// satisifes 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; }
// 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; }
// 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; }
// 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::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_