1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236
|
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef DEVICE_BLUETOOTH_FLOSS_FLOSS_LESCAN_CLIENT_H_
#define DEVICE_BLUETOOTH_FLOSS_FLOSS_LESCAN_CLIENT_H_
#include <memory>
#include <string>
#include "base/containers/queue.h"
#include "base/functional/callback.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "dbus/exported_object.h"
#include "dbus/object_path.h"
#include "device/bluetooth/bluetooth_device.h"
#include "device/bluetooth/bluetooth_export.h"
#include "device/bluetooth/floss/exported_callback_manager.h"
#include "device/bluetooth/floss/floss_dbus_client.h"
#include "device/bluetooth/floss/floss_gatt_manager_client.h"
namespace dbus {
class ObjectPath;
} // namespace dbus
namespace floss {
const char kScannerCallbackPath[] =
"/org/chromium/bluetooth/scanner/callback";
const char kScannerCallbackInterfaceName[] =
"org.chromium.bluetooth.ScannerCallback";
const char kEmptyUuidStr[] = "00000000-0000-0000-0000-000000000000";
// Represents type of a scan.
enum class ScanType {
kActive = 0,
kPassive = 1,
};
// Represents scanning configurations.
struct ScanSettings {
int32_t interval;
int32_t window;
ScanType scan_type;
};
struct DEVICE_BLUETOOTH_EXPORT ScanFilterPattern {
// Specifies the starting byte position of the pattern immediately following
// AD Type.
uint8_t start_position = 0;
// Advertising Data type (https://www.bluetooth.com/specifications/assigned-numbers/).
uint8_t ad_type = 0;
// The pattern to be matched for the specified AD Type within the
// advertisement packet from the specified starting byte.
std::vector<uint8_t> content;
ScanFilterPattern();
ScanFilterPattern(const ScanFilterPattern&);
~ScanFilterPattern();
};
struct DEVICE_BLUETOOTH_EXPORT ScanFilterCondition {
// Match by pattern anywhere in the advertisement data. Multiple patterns are
// "OR"-ed.
std::vector<ScanFilterPattern> patterns;
ScanFilterCondition();
ScanFilterCondition(const ScanFilterCondition&);
~ScanFilterCondition();
};
// Modeled based on MSFT HCI extension spec:
// https://learn.microsoft.com/en-us/windows-hardware/drivers/bluetooth/microsoft-defined-bluetooth-hci-commands-and-events#command_parameters-1
struct DEVICE_BLUETOOTH_EXPORT ScanFilter {
// Advertisements with RSSI above or equal this value is considered "found".
uint8_t rssi_high_threshold = 0;
// Advertisements with RSSI below or equal this value (for a period of
// rssi_low_timeout) is considered "lost".
uint8_t rssi_low_threshold = 0;
// Time in seconds over which the RSSI value should be below
// rssi_low_threshold before being considered "lost".
uint8_t rssi_low_timeout = 0;
// Sampling interval in 100 milliseconds.
// i.e. The real sampling period in ms = rssi_sampling_period * 100.
uint8_t rssi_sampling_period = 0;
//The condition to match advertisements with.
ScanFilterCondition condition;
ScanFilter();
ScanFilter(const ScanFilter&);
~ScanFilter();
};
struct DEVICE_BLUETOOTH_EXPORT ScanResult {
std::string name;
std::string address;
uint8_t addr_type = 0;
uint16_t event_type = 0;
uint8_t primary_phy = 0;
uint8_t secondary_phy = 0;
uint8_t advertising_sid = 0;
int8_t tx_power = 0;
int8_t rssi = 0;
uint16_t periodic_adv_int = 0;
uint8_t flags = 0;
std::vector<device::BluetoothUUID> service_uuids;
std::map<std::string, std::vector<uint8_t>> service_data;
std::map<uint16_t, std::vector<uint8_t>> manufacturer_data;
std::vector<uint8_t> adv_data;
ScanResult();
ScanResult(const ScanResult&);
~ScanResult();
};
class ScannerClientObserver : public base::CheckedObserver {
public:
ScannerClientObserver() = default;
~ScannerClientObserver() override = default;
// A scanner has been registered
virtual void ScannerRegistered(device::BluetoothUUID uuid,
uint8_t scanner_id,
GattStatus status) {}
// A scan result has been received
virtual void ScanResultReceived(ScanResult scan_result) {}
// An advertisement has been found
virtual void AdvertisementFound(uint8_t scanner_id, ScanResult scan_result) {}
// A scan result has been lost
virtual void AdvertisementLost(uint8_t scanner_id, ScanResult scan_result) {}
};
// Low-level interface to Floss's LE Scan API.
class DEVICE_BLUETOOTH_EXPORT FlossLEScanClient : public FlossDBusClient,
public ScannerClientObserver {
public:
// Error: No such adapter.
static const char kErrorUnknownAdapter[];
// Creates the instance.
static std::unique_ptr<FlossLEScanClient> Create();
FlossLEScanClient(const FlossLEScanClient&) = delete;
FlossLEScanClient& operator=(const FlossLEScanClient&) = delete;
FlossLEScanClient();
~FlossLEScanClient() override;
// Manage observers.
void AddObserver(ScannerClientObserver* observer);
void RemoveObserver(ScannerClientObserver* observer);
// Initialize the LE Scan client.
void Init(dbus::Bus* bus,
const std::string& service_name,
const int adapter_index,
base::Version version,
base::OnceClosure on_ready) override;
virtual void RegisterScanner(
ResponseCallback<device::BluetoothUUID> callback);
virtual void UnregisterScanner(ResponseCallback<bool> callback,
uint8_t scanner_id);
virtual void StartScan(ResponseCallback<BtifStatus> callback,
uint8_t scanner_id,
const std::optional<ScanSettings>& scan_settings,
const std::optional<ScanFilter>& filter);
virtual void StopScan(ResponseCallback<BtifStatus> callback,
uint8_t scanner_id);
protected:
// ScannerClientObserver overrides
void ScannerRegistered(device::BluetoothUUID uuid,
uint8_t scanner_id,
GattStatus status) override;
void ScanResultReceived(ScanResult scan_result) override;
void AdvertisementFound(uint8_t scanner_id, ScanResult scan_result) override;
void AdvertisementLost(uint8_t scanner_id, ScanResult scan_result) override;
// Managed by FlossDBusManager - we keep local pointer to access object proxy.
raw_ptr<dbus::Bus> bus_ = nullptr;
// Adapter managed by this client.
dbus::ObjectPath object_path_;
// List of observers interested in event notifications from this client.
base::ObserverList<ScannerClientObserver> observers_;
// Service which implements the adapter interface.
std::string service_name_;
private:
std::optional<uint32_t> le_scan_callback_id_;
ExportedCallbackManager<ScannerClientObserver>
exported_scanner_callback_manager_{kScannerCallbackInterfaceName};
// List of callbacks to register a scanner for once |RegisterScannerCallback|
// completes.
base::queue<ResponseCallback<device::BluetoothUUID>>
pending_register_scanners_;
void RegisterScannerCallback();
void OnRegisterScannerCallback(DBusResult<uint32_t> ret);
void OnUnregisterScannerCallback(DBusResult<bool> ret);
template <typename R, typename... Args>
void CallLEScanMethod(ResponseCallback<R> callback,
const char* member,
Args... args) {
CallMethod(std::move(callback), bus_, service_name_, kGattInterface,
object_path_, member, args...);
}
// Signal that the client is ready to be used.
base::OnceClosure on_ready_;
base::WeakPtrFactory<FlossLEScanClient> weak_ptr_factory_{this};
};
} // namespace floss
#endif // DEVICE_BLUETOOTH_FLOSS_FLOSS_LESCAN_CLIENT_H_
|