summaryrefslogtreecommitdiff
path: root/chromium/device/bluetooth/bluetooth_low_energy_win.h
blob: e582d4cbaa85b3f058eca08172693d0ff33161be (plain)
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
// Copyright 2014 The Chromium 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 DEVICE_BLUETOOTH_BLUETOOTH_LOW_ENERGY_WIN_H_
#define DEVICE_BLUETOOTH_BLUETOOTH_LOW_ENERGY_WIN_H_

#include <stddef.h>
#include <stdint.h>

#include <memory>
#include <vector>

#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/optional.h"
#include "device/bluetooth/bluetooth_export.h"
#include "device/bluetooth/bluetooth_low_energy_defs_win.h"

namespace device {
namespace win {

//
// Callback function signature for Bluetooth GATT events. This fixes a bug in
// this typedef in the Windows 10.0.10586 SDK which is missing the CALLBACK
// modifier. This corrected typedef should be used throughout Chromium except
// when casting to the 'official' definition when calling Microsoft functions.
// This allows Chromium to build with 10.0.14393 or later SDKs (which have the
// fixed typedef) while doing the correct thing even when built with 10.0.10586.
// The CALLBACK modifier affects how function parameters are cleaned up from the
// stack and having a mismatch can lead to misalignment of the stack pointer.
//
typedef VOID(CALLBACK* PFNBLUETOOTH_GATT_EVENT_CALLBACK_CORRECTED)(
    _In_ BTH_LE_GATT_EVENT_TYPE EventType,
    _In_ PVOID EventOutParameter,
    _In_opt_ PVOID Context);

// Represents a device registry property value
class DEVICE_BLUETOOTH_EXPORT DeviceRegistryPropertyValue {
 public:
  // Creates a property value instance, where |property_type| is one of REG_xxx
  // registry value type (e.g. REG_SZ, REG_DWORD), |value| is a byte array
  // containing the property value and |value_size| is the number of bytes in
  // |value|. Note the returned instance takes ownership of the bytes in
  // |value|.
  static std::unique_ptr<DeviceRegistryPropertyValue> Create(
      DWORD property_type,
      std::unique_ptr<uint8_t[]> value,
      size_t value_size);
  ~DeviceRegistryPropertyValue();

  // Returns the vaue type a REG_xxx value (e.g. REG_SZ, REG_DWORD, ...)
  DWORD property_type() const { return property_type_; }

  std::string AsString() const;
  DWORD AsDWORD() const;

 private:
  DeviceRegistryPropertyValue(DWORD property_type,
                              std::unique_ptr<uint8_t[]> value);

  DWORD property_type_;
  std::unique_ptr<uint8_t[]> value_;

  DISALLOW_COPY_AND_ASSIGN(DeviceRegistryPropertyValue);
};

// Represents the value associated to a DEVPROPKEY.
class DEVICE_BLUETOOTH_EXPORT DevicePropertyValue {
 public:
  // Creates a property value instance, where |property_type| is one of
  // DEVPROP_TYPE_xxx value type , |value| is a byte array containing the
  // property value and |value_size| is the number of bytes in |value|. Note the
  // returned instance takes ownership of the bytes in |value|.
  DevicePropertyValue(DEVPROPTYPE property_type,
                      std::unique_ptr<uint8_t[]> value,
                      size_t value_size);
  ~DevicePropertyValue();

  DEVPROPTYPE property_type() const { return property_type_; }

  uint32_t AsUint32() const;

 private:
  DEVPROPTYPE property_type_;
  std::unique_ptr<uint8_t[]> value_;
  size_t value_size_;

  DISALLOW_COPY_AND_ASSIGN(DevicePropertyValue);
};

struct DEVICE_BLUETOOTH_EXPORT BluetoothLowEnergyServiceInfo {
  BluetoothLowEnergyServiceInfo();
  ~BluetoothLowEnergyServiceInfo();

  BTH_LE_UUID uuid;
  // Attribute handle uniquely identifies this service on the device.
  USHORT attribute_handle = 0;
};

struct DEVICE_BLUETOOTH_EXPORT BluetoothLowEnergyDeviceInfo {
  BluetoothLowEnergyDeviceInfo();
  ~BluetoothLowEnergyDeviceInfo();

  base::FilePath path;
  std::string id;
  base::Optional<std::string> friendly_name;
  BLUETOOTH_ADDRESS address;
  bool visible;
  bool authenticated;
  bool connected;
};

bool DEVICE_BLUETOOTH_EXPORT
ExtractBluetoothAddressFromDeviceInstanceIdForTesting(
    const std::string& instance_id,
    BLUETOOTH_ADDRESS* btha,
    std::string* error);

// Wraps Windows APIs used to access Bluetooth Low Energy devices, providing an
// interface that can be replaced with fakes in tests.
class DEVICE_BLUETOOTH_EXPORT BluetoothLowEnergyWrapper {
 public:
  BluetoothLowEnergyWrapper();
  virtual ~BluetoothLowEnergyWrapper();

  // Returns true only on Windows platforms supporting Bluetooth Low Energy.
  virtual bool IsBluetoothLowEnergySupported();

  // Enumerates the list of known (i.e. already paired) Bluetooth LE devices on
  // this machine. In case of error, returns false and sets |error| with an
  // error message describing the problem.
  // Note: This function returns an error if Bluetooth Low Energy is not
  // supported on this Windows platform.
  virtual bool EnumerateKnownBluetoothLowEnergyDevices(
      std::vector<std::unique_ptr<BluetoothLowEnergyDeviceInfo>>* devices,
      std::string* error);

  // Enumerates the list of known Bluetooth LE GATT service devices on this
  // machine (a Bluetooth LE device usually has more than one GATT
  // services that each of them has a device interface on the machine). In case
  // of error, returns false and sets |error| with an error message describing
  // the problem.
  // Note: This function returns an error if Bluetooth Low Energy is not
  // supported on this Windows platform.
  virtual bool EnumerateKnownBluetoothLowEnergyGattServiceDevices(
      std::vector<std::unique_ptr<BluetoothLowEnergyDeviceInfo>>* devices,
      std::string* error);

  // Enumerates the list of known (i.e. cached) GATT services for a given
  // Bluetooth LE device |device_path| into |services|. In case of error,
  // returns false and sets |error| with an error message describing the
  // problem.
  // Note: This function returns an error if Bluetooth Low Energy is not
  // supported on this Windows platform.
  virtual bool EnumerateKnownBluetoothLowEnergyServices(
      const base::FilePath& device_path,
      std::vector<std::unique_ptr<BluetoothLowEnergyServiceInfo>>* services,
      std::string* error);

  // Reads characteristics of |service| with service device path |service_path|.
  // The result will be stored in |*out_included_characteristics| and
  // |*out_counts|.
  virtual HRESULT ReadCharacteristicsOfAService(
      base::FilePath& service_path,
      const PBTH_LE_GATT_SERVICE service,
      std::unique_ptr<BTH_LE_GATT_CHARACTERISTIC>* out_included_characteristics,
      USHORT* out_counts);

  // Reads included descriptors of |characteristic| in service with service
  // device path |service_path|. The result will be stored in
  // |*out_included_descriptors| and |*out_counts|.
  virtual HRESULT ReadDescriptorsOfACharacteristic(
      base::FilePath& service_path,
      const PBTH_LE_GATT_CHARACTERISTIC characteristic,
      std::unique_ptr<BTH_LE_GATT_DESCRIPTOR>* out_included_descriptors,
      USHORT* out_counts);

  // Reads |characteristic| value in service with service device path
  // |service_path|. The result will be stored in |*out_value|.
  virtual HRESULT ReadCharacteristicValue(
      base::FilePath& service_path,
      const PBTH_LE_GATT_CHARACTERISTIC characteristic,
      std::unique_ptr<BTH_LE_GATT_CHARACTERISTIC_VALUE>* out_value);

  // Writes |characteristic| value in service with service device path
  // |service_path| to |*new_value|.
  virtual HRESULT WriteCharacteristicValue(
      base::FilePath& service_path,
      const PBTH_LE_GATT_CHARACTERISTIC characteristic,
      PBTH_LE_GATT_CHARACTERISTIC_VALUE new_value);

  // Register GATT events of |event_type| in the service with service device
  // path |service_path|. |event_parameter| is the event's parameter. |callback|
  // is the function to be invoked if the event happened. |context| is the input
  // parameter to be given back through |callback|. |*out_handle| stores the
  // unique handle in OS for this registration.
  virtual HRESULT RegisterGattEvents(
      base::FilePath& service_path,
      BTH_LE_GATT_EVENT_TYPE event_type,
      PVOID event_parameter,
      PFNBLUETOOTH_GATT_EVENT_CALLBACK_CORRECTED callback,
      PVOID context,
      BLUETOOTH_GATT_EVENT_HANDLE* out_handle);
  virtual HRESULT UnregisterGattEvent(BLUETOOTH_GATT_EVENT_HANDLE event_handle);

  // Writes |descriptor| value in service with service device path
  // |service_path| to |*new_value|.
  virtual HRESULT WriteDescriptorValue(base::FilePath& service_path,
                                       const PBTH_LE_GATT_DESCRIPTOR descriptor,
                                       PBTH_LE_GATT_DESCRIPTOR_VALUE new_value);
};

}  // namespace win
}  // namespace device

#endif  // DEVICE_BLUETOOTH_BLUETOOTH_LOW_ENERGY_WIN_H_