| 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 38fc4a164ef661ba56c0e7963406f892d1bc1871..d0f12892a7d734c484260c8a7f31cda7843db347 100644
|
| --- a/device/bluetooth/bluetooth_low_energy_win.cc
|
| +++ b/device/bluetooth/bluetooth_low_energy_win.cc
|
| @@ -4,6 +4,10 @@
|
|
|
| #include "device/bluetooth/bluetooth_low_energy_win.h"
|
|
|
| +#include <cfg.h>
|
| +#define INITGUID // For DEVPKEY_Xxxx guid/pid pairs
|
| +#include <devpkey.h>
|
| +
|
| #include "base/logging.h"
|
| #include "base/strings/sys_string_conversions.h"
|
| #include "base/win/windows_version.h"
|
| @@ -11,6 +15,7 @@
|
| namespace {
|
|
|
| using device::win::DeviceRegistryPropertyValue;
|
| +using device::win::DevicePropertyValue;
|
|
|
| const char kPlatformNotSupported[] =
|
| "Bluetooth Low energy is only supported on Windows 8 and later.";
|
| @@ -125,6 +130,47 @@ bool CheckExpectedLength(size_t actual_length,
|
| return true;
|
| }
|
|
|
| +bool CollectBluetoothLowEnergyDeviceProperty(
|
| + const ScopedDeviceInfoSetHandle& device_info_handle,
|
| + PSP_DEVINFO_DATA device_info_data,
|
| + const DEVPROPKEY& key,
|
| + scoped_ptr<DevicePropertyValue>* value,
|
| + std::string* error) {
|
| + DWORD required_length;
|
| + DEVPROPTYPE prop_type;
|
| + BOOL success = SetupDiGetDeviceProperty(device_info_handle,
|
| + device_info_data,
|
| + &key,
|
| + &prop_type,
|
| + NULL,
|
| + 0,
|
| + &required_length,
|
| + 0);
|
| + if (!CheckInsufficientBuffer(!!success, kDeviceInfoError, error))
|
| + return false;
|
| +
|
| + scoped_ptr<uint8_t[]> prop_value(new uint8_t[required_length]);
|
| + DWORD actual_length = required_length;
|
| + success = SetupDiGetDeviceProperty(device_info_handle,
|
| + device_info_data,
|
| + &key,
|
| + &prop_type,
|
| + prop_value.get(),
|
| + actual_length,
|
| + &required_length,
|
| + 0);
|
| + if (!CheckSuccess(!!success, kDeviceInfoError, error))
|
| + return false;
|
| + if (!CheckExpectedLength(
|
| + actual_length, required_length, kDeviceInfoError, error)) {
|
| + return false;
|
| + }
|
| +
|
| + (*value) = scoped_ptr<DevicePropertyValue>(
|
| + new DevicePropertyValue(prop_type, prop_value.Pass(), actual_length));
|
| + return true;
|
| +}
|
| +
|
| bool CollectBluetoothLowEnergyDeviceRegistryProperty(
|
| const ScopedDeviceInfoSetHandle& device_info_handle,
|
| PSP_DEVINFO_DATA device_info_data,
|
| @@ -142,7 +188,7 @@ bool CollectBluetoothLowEnergyDeviceRegistryProperty(
|
| if (!CheckInsufficientBuffer(!!success, kDeviceInfoError, error))
|
| return false;
|
|
|
| - scoped_ptr<UINT8[]> property_value(new UINT8[required_length]);
|
| + scoped_ptr<uint8_t[]> property_value(new uint8_t[required_length]);
|
| ULONG actual_length = required_length;
|
| DWORD property_type;
|
| success = SetupDiGetDeviceRegistryProperty(device_info_handle,
|
| @@ -155,8 +201,9 @@ bool CollectBluetoothLowEnergyDeviceRegistryProperty(
|
| if (!CheckSuccess(!!success, kDeviceInfoError, error))
|
| return false;
|
| if (!CheckExpectedLength(
|
| - actual_length, required_length, kDeviceInfoError, error))
|
| + actual_length, required_length, kDeviceInfoError, error)) {
|
| return false;
|
| + }
|
|
|
| (*value) = DeviceRegistryPropertyValue::Create(
|
| property_type, property_value.Pass(), actual_length).Pass();
|
| @@ -255,6 +302,29 @@ bool CollectBluetoothLowEnergyDeviceAddress(
|
| device_info->id, &device_info->address, error);
|
| }
|
|
|
| +bool CollectBluetoothLowEnergyDeviceStatus(
|
| + const ScopedDeviceInfoSetHandle& device_info_handle,
|
| + PSP_DEVINFO_DATA device_info_data,
|
| + scoped_ptr<device::win::BluetoothLowEnergyDeviceInfo>& device_info,
|
| + std::string* error) {
|
| + scoped_ptr<DevicePropertyValue> value;
|
| + if (!CollectBluetoothLowEnergyDeviceProperty(device_info_handle,
|
| + device_info_data,
|
| + DEVPKEY_Device_DevNodeStatus,
|
| + &value,
|
| + error)) {
|
| + return false;
|
| + }
|
| +
|
| + if (value->property_type() != DEVPROP_TYPE_UINT32) {
|
| + *error = kDeviceInfoError;
|
| + return false;
|
| + }
|
| +
|
| + device_info->connected = !(value->AsUint32() & DN_DEVICE_DISCONNECTED);
|
| + return true;
|
| +}
|
| +
|
| bool CollectBluetoothLowEnergyDeviceInfo(
|
| const ScopedDeviceInfoSetHandle& device_info_handle,
|
| PSP_DEVICE_INTERFACE_DATA device_interface_data,
|
| @@ -271,7 +341,7 @@ bool CollectBluetoothLowEnergyDeviceInfo(
|
| if (!CheckInsufficientBuffer(!!success, kDeviceInfoError, error))
|
| return false;
|
|
|
| - scoped_ptr<UINT8[]> interface_data(new UINT8[required_length]);
|
| + scoped_ptr<uint8_t[]> interface_data(new uint8_t[required_length]);
|
| ZeroMemory(interface_data.get(), required_length);
|
|
|
| PSP_DEVICE_INTERFACE_DETAIL_DATA device_interface_detail_data =
|
| @@ -292,8 +362,9 @@ bool CollectBluetoothLowEnergyDeviceInfo(
|
| if (!CheckSuccess(!!success, kDeviceInfoError, error))
|
| return false;
|
| if (!CheckExpectedLength(
|
| - actual_length, required_length, kDeviceInfoError, error))
|
| + actual_length, required_length, kDeviceInfoError, error)) {
|
| return false;
|
| + }
|
|
|
| scoped_ptr<device::win::BluetoothLowEnergyDeviceInfo> result(
|
| new device::win::BluetoothLowEnergyDeviceInfo());
|
| @@ -311,6 +382,10 @@ bool CollectBluetoothLowEnergyDeviceInfo(
|
| device_info_handle, &device_info_data, result, error)) {
|
| return false;
|
| }
|
| + if (!CollectBluetoothLowEnergyDeviceStatus(
|
| + device_info_handle, &device_info_data, result, error)) {
|
| + return false;
|
| + }
|
| (*device_info) = result.Pass();
|
| return true;
|
| }
|
| @@ -322,7 +397,7 @@ DeviceInfoResult EnumerateSingleBluetoothLowEnergyDevice(
|
| DWORD device_index,
|
| scoped_ptr<device::win::BluetoothLowEnergyDeviceInfo>* device_info,
|
| std::string* error) {
|
| - // Enumerate device of LE_DEVICE interface class
|
| + // Enumerate device of BLUETOOTHLE_DEVICE interface class
|
| GUID BluetoothInterfaceGUID = GUID_BLUETOOTHLE_DEVICE_INTERFACE;
|
| SP_DEVICE_INTERFACE_DATA device_interface_data = {0};
|
| device_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
|
| @@ -341,8 +416,9 @@ DeviceInfoResult EnumerateSingleBluetoothLowEnergyDevice(
|
| }
|
|
|
| if (!CollectBluetoothLowEnergyDeviceInfo(
|
| - device_info_handle, &device_interface_data, device_info, error))
|
| + device_info_handle, &device_interface_data, device_info, error)) {
|
| return kError;
|
| + }
|
|
|
| return kOk;
|
| }
|
| @@ -428,6 +504,28 @@ DWORD DeviceRegistryPropertyValue::AsDWORD() const {
|
| return *value;
|
| }
|
|
|
| +DevicePropertyValue::DevicePropertyValue(DEVPROPTYPE property_type,
|
| + scoped_ptr<uint8_t[]> value,
|
| + size_t value_size)
|
| + : property_type_(property_type),
|
| + value_(value.Pass()),
|
| + value_size_(value_size) {
|
| +}
|
| +
|
| +uint32_t DevicePropertyValue::AsUint32() const {
|
| + CHECK_EQ(property_type_, static_cast<DEVPROPTYPE>(DEVPROP_TYPE_UINT32));
|
| + CHECK_EQ(value_size_, sizeof(uint32_t));
|
| + return *reinterpret_cast<uint32_t*>(value_.get());
|
| +}
|
| +
|
| +BluetoothLowEnergyDeviceInfo::BluetoothLowEnergyDeviceInfo()
|
| + : connected(false) {
|
| + address.ullLong = BLUETOOTH_NULL_ADDRESS;
|
| +}
|
| +
|
| +BluetoothLowEnergyDeviceInfo::~BluetoothLowEnergyDeviceInfo() {
|
| +}
|
| +
|
| bool IsBluetoothLowEnergySupported() {
|
| return base::win::GetVersion() >= base::win::VERSION_WIN8;
|
| }
|
|
|