| Index: device/bluetooth/bluetooth_low_energy_win.cc
|
| diff --git a/device/bluetooth/bluetooth_low_energy_win.cc b/device/bluetooth/bluetooth_low_energy_win.cc
|
| index 21f4ecfa7967f0deadf266ec30b1a5f9007af989..b47bc9af0137afd94144d327fe2035b90f89689a 100644
|
| --- a/device/bluetooth/bluetooth_low_energy_win.cc
|
| +++ b/device/bluetooth/bluetooth_low_energy_win.cc
|
| @@ -4,18 +4,18 @@
|
|
|
| #include "device/bluetooth/bluetooth_low_energy_win.h"
|
|
|
| -#include <cfg.h>
|
| -#define INITGUID // For DEVPKEY_Xxxx guid/pid pairs
|
| -#include <devpkey.h>
|
| -
|
| +#include "base/files/file.h"
|
| #include "base/logging.h"
|
| #include "base/strings/sys_string_conversions.h"
|
| +#include "base/win/scoped_handle.h"
|
| #include "base/win/windows_version.h"
|
|
|
| namespace {
|
|
|
| using device::win::DeviceRegistryPropertyValue;
|
| using device::win::DevicePropertyValue;
|
| +using device::win::BluetoothLowEnergyDeviceInfo;
|
| +using device::win::BluetoothLowEnergyServiceInfo;
|
|
|
| const char kPlatformNotSupported[] =
|
| "Bluetooth Low energy is only supported on Windows 8 and later.";
|
| @@ -109,7 +109,7 @@ bool CheckInsufficientBuffer(bool success,
|
| return true;
|
| }
|
|
|
| -bool CheckSuccess(HRESULT hr, const char* message, std::string* error) {
|
| +bool CheckHResult(HRESULT hr, const char* message, std::string* error) {
|
| if (FAILED(hr)) {
|
| *error = FormatBluetoothError(message, hr);
|
| return false;
|
| @@ -118,6 +118,39 @@ bool CheckSuccess(HRESULT hr, const char* message, std::string* error) {
|
| return true;
|
| }
|
|
|
| +bool CheckSuccess(bool success, const char* message, std::string* error) {
|
| + if (!success) {
|
| + CheckHResult(HRESULT_FROM_WIN32(GetLastError()), message, error);
|
| + return false;
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| +bool CheckNoData(HRESULT hr, size_t length) {
|
| + if (hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND))
|
| + return true;
|
| +
|
| + if (SUCCEEDED(hr) && length == 0)
|
| + return true;
|
| +
|
| + return false;
|
| +}
|
| +
|
| +bool CheckMoreData(HRESULT hr, const char* message, std::string* error) {
|
| + if (SUCCEEDED(hr)) {
|
| + *error = FormatBluetoothError(message, hr);
|
| + return false;
|
| + }
|
| +
|
| + if (hr != HRESULT_FROM_WIN32(ERROR_MORE_DATA)) {
|
| + *error = FormatBluetoothError(message, hr);
|
| + return false;
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| bool CheckExpectedLength(size_t actual_length,
|
| size_t expected_length,
|
| const char* message,
|
| @@ -243,7 +276,7 @@ bool CollectBluetoothLowEnergyDeviceInstanceId(
|
| return true;
|
| }
|
|
|
| -bool CollectDeviceFriendlyName(
|
| +bool CollectBluetoothLowEnergyDeviceFriendlyName(
|
| const ScopedDeviceInfoSetHandle& device_info_handle,
|
| PSP_DEVINFO_DATA device_info_data,
|
| scoped_ptr<device::win::BluetoothLowEnergyDeviceInfo>& device_info,
|
| @@ -330,6 +363,53 @@ bool CollectBluetoothLowEnergyDeviceStatus(
|
| return true;
|
| }
|
|
|
| +bool CollectBluetoothLowEnergyDeviceServices(
|
| + const base::FilePath& device_path,
|
| + ScopedVector<BluetoothLowEnergyServiceInfo>* services,
|
| + std::string* error) {
|
| + base::File file(device_path, base::File::FLAG_OPEN | base::File::FLAG_READ);
|
| + if (!file.IsValid()) {
|
| + *error = file.ErrorToString(file.error_details());
|
| + return false;
|
| + }
|
| +
|
| + USHORT required_length;
|
| + HRESULT hr = BluetoothGATTGetServices(file.GetPlatformFile(),
|
| + 0,
|
| + NULL,
|
| + &required_length,
|
| + BLUETOOTH_GATT_FLAG_NONE);
|
| + if (CheckNoData(hr, required_length))
|
| + return true;
|
| + if (!CheckMoreData(hr, kDeviceInfoError, error))
|
| + return false;
|
| +
|
| + scoped_ptr<BTH_LE_GATT_SERVICE[]> gatt_services(
|
| + new BTH_LE_GATT_SERVICE[required_length]);
|
| + USHORT actual_length = required_length;
|
| + hr = BluetoothGATTGetServices(file.GetPlatformFile(),
|
| + actual_length,
|
| + gatt_services.get(),
|
| + &required_length,
|
| + BLUETOOTH_GATT_FLAG_NONE);
|
| + if (!CheckHResult(hr, kDeviceInfoError, error))
|
| + return false;
|
| + if (!CheckExpectedLength(
|
| + actual_length, required_length, kDeviceInfoError, error)) {
|
| + return false;
|
| + }
|
| +
|
| + for (USHORT i = 0; i < actual_length; ++i) {
|
| + BTH_LE_GATT_SERVICE& gatt_service(gatt_services.get()[i]);
|
| + BluetoothLowEnergyServiceInfo* service_info =
|
| + new BluetoothLowEnergyServiceInfo();
|
| + service_info->uuid = gatt_service.ServiceUuid;
|
| + services->push_back(service_info);
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| bool CollectBluetoothLowEnergyDeviceInfo(
|
| const ScopedDeviceInfoSetHandle& device_info_handle,
|
| PSP_DEVICE_INTERFACE_DATA device_interface_data,
|
| @@ -379,7 +459,7 @@ bool CollectBluetoothLowEnergyDeviceInfo(
|
| device_info_handle, &device_info_data, result, error)) {
|
| return false;
|
| }
|
| - if (!CollectDeviceFriendlyName(
|
| + if (!CollectBluetoothLowEnergyDeviceFriendlyName(
|
| device_info_handle, &device_info_data, result, error)) {
|
| return false;
|
| }
|
| @@ -523,6 +603,12 @@ uint32_t DevicePropertyValue::AsUint32() const {
|
| return *reinterpret_cast<uint32_t*>(value_.get());
|
| }
|
|
|
| +BluetoothLowEnergyServiceInfo::BluetoothLowEnergyServiceInfo() {
|
| +}
|
| +
|
| +BluetoothLowEnergyServiceInfo::~BluetoothLowEnergyServiceInfo() {
|
| +}
|
| +
|
| BluetoothLowEnergyDeviceInfo::BluetoothLowEnergyDeviceInfo()
|
| : visible(false), authenticated(false), connected(false) {
|
| address.ullLong = BLUETOOTH_NULL_ADDRESS;
|
| @@ -565,6 +651,14 @@ bool EnumerateKnownBluetoothLowEnergyDevices(
|
| }
|
| }
|
|
|
| +bool EnumerateKnownBluetoothLowEnergyServices(
|
| + BluetoothLowEnergyDeviceInfo* device_info,
|
| + ScopedVector<BluetoothLowEnergyServiceInfo>* services,
|
| + std::string* error) {
|
| + return CollectBluetoothLowEnergyDeviceServices(
|
| + device_info->path, services, error);
|
| +}
|
| +
|
| bool ExtractBluetoothAddressFromDeviceInstanceIdForTesting(
|
| const std::string& instance_id,
|
| BLUETOOTH_ADDRESS* btha,
|
|
|