File: floss_lescan_client.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (236 lines) | stat: -rw-r--r-- 7,830 bytes parent folder | download | duplicates (6)
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_