summaryrefslogtreecommitdiffstats
path: root/device
diff options
context:
space:
mode:
authorgogerald <gogerald@chromium.org>2016-03-01 12:45:36 -0800
committerCommit bot <commit-bot@chromium.org>2016-03-01 20:47:06 +0000
commit74459acf6390eed6009b8bf5edad68d7e03bf008 (patch)
tree4187f9836cb9e7992835eae39101a45f465fdb1b /device
parent0a8abd1cd85e42b969740ca38e01df01ff244743 (diff)
downloadchromium_src-74459acf6390eed6009b8bf5edad68d7e03bf008.zip
chromium_src-74459acf6390eed6009b8bf5edad68d7e03bf008.tar.gz
chromium_src-74459acf6390eed6009b8bf5edad68d7e03bf008.tar.bz2
Implement BluetoothRemoteGattCharacteristicWin::GetDescriptors
This CL implements GetDescriptors() in BluetoothRemoteGattCharacteristicWin. It also optimized previous codes by renaming interfaces, data structures and so on. BUG=579202 Review URL: https://codereview.chromium.org/1728163006 Cr-Commit-Position: refs/heads/master@{#378552}
Diffstat (limited to 'device')
-rw-r--r--device/bluetooth/BUILD.gn2
-rw-r--r--device/bluetooth/bluetooth.gyp2
-rw-r--r--device/bluetooth/bluetooth_adapter_win.cc2
-rw-r--r--device/bluetooth/bluetooth_gatt_characteristic_unittest.cc28
-rw-r--r--device/bluetooth/bluetooth_low_energy_win.cc56
-rw-r--r--device/bluetooth/bluetooth_low_energy_win.h9
-rw-r--r--device/bluetooth/bluetooth_low_energy_win_fake.cc117
-rw-r--r--device/bluetooth/bluetooth_low_energy_win_fake.h92
-rw-r--r--device/bluetooth/bluetooth_remote_gatt_characteristic_win.cc116
-rw-r--r--device/bluetooth/bluetooth_remote_gatt_characteristic_win.h33
-rw-r--r--device/bluetooth/bluetooth_remote_gatt_descriptor_win.cc99
-rw-r--r--device/bluetooth/bluetooth_remote_gatt_descriptor_win.h60
-rw-r--r--device/bluetooth/bluetooth_remote_gatt_service_win.h2
-rw-r--r--device/bluetooth/bluetooth_task_manager_win.cc33
-rw-r--r--device/bluetooth/bluetooth_task_manager_win.h15
-rw-r--r--device/bluetooth/test/bluetooth_test_win.cc113
-rw-r--r--device/bluetooth/test/bluetooth_test_win.h9
17 files changed, 648 insertions, 140 deletions
diff --git a/device/bluetooth/BUILD.gn b/device/bluetooth/BUILD.gn
index 167fe30..b3394b9 100644
--- a/device/bluetooth/BUILD.gn
+++ b/device/bluetooth/BUILD.gn
@@ -93,6 +93,8 @@ component("bluetooth") {
"bluetooth_remote_gatt_characteristic_win.h",
"bluetooth_remote_gatt_descriptor_android.cc",
"bluetooth_remote_gatt_descriptor_android.h",
+ "bluetooth_remote_gatt_descriptor_win.cc",
+ "bluetooth_remote_gatt_descriptor_win.h",
"bluetooth_remote_gatt_service_android.cc",
"bluetooth_remote_gatt_service_android.h",
"bluetooth_remote_gatt_service_win.cc",
diff --git a/device/bluetooth/bluetooth.gyp b/device/bluetooth/bluetooth.gyp
index 59eacfd..d46a243 100644
--- a/device/bluetooth/bluetooth.gyp
+++ b/device/bluetooth/bluetooth.gyp
@@ -95,6 +95,8 @@
'bluetooth_remote_gatt_characteristic_win.h',
'bluetooth_remote_gatt_descriptor_android.cc',
'bluetooth_remote_gatt_descriptor_android.h',
+ 'bluetooth_remote_gatt_descriptor_win.cc',
+ 'bluetooth_remote_gatt_descriptor_win.h',
'bluetooth_remote_gatt_service_android.cc',
'bluetooth_remote_gatt_service_android.h',
'bluetooth_remote_gatt_service_win.cc',
diff --git a/device/bluetooth/bluetooth_adapter_win.cc b/device/bluetooth/bluetooth_adapter_win.cc
index 8206c91..c946091 100644
--- a/device/bluetooth/bluetooth_adapter_win.cc
+++ b/device/bluetooth/bluetooth_adapter_win.cc
@@ -346,6 +346,8 @@ void BluetoothAdapterWin::InitForTest(
scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
scoped_refptr<base::SequencedTaskRunner> bluetooth_task_runner) {
ui_task_runner_ = ui_task_runner;
+ if (ui_task_runner_ == nullptr)
+ ui_task_runner_ = base::ThreadTaskRunnerHandle::Get();
task_manager_ =
new BluetoothTaskManagerWin(ui_task_runner_);
task_manager_->AddObserver(this);
diff --git a/device/bluetooth/bluetooth_gatt_characteristic_unittest.cc b/device/bluetooth/bluetooth_gatt_characteristic_unittest.cc
index e8cfe87..96e3f52 100644
--- a/device/bluetooth/bluetooth_gatt_characteristic_unittest.cc
+++ b/device/bluetooth/bluetooth_gatt_characteristic_unittest.cc
@@ -17,11 +17,13 @@
#include "device/bluetooth/test/bluetooth_test_android.h"
#elif defined(OS_MACOSX)
#include "device/bluetooth/test/bluetooth_test_mac.h"
+#elif defined(OS_WIN)
+#include "device/bluetooth/test/bluetooth_test_win.h"
#endif
namespace device {
-#if defined(OS_ANDROID) || defined(OS_MACOSX)
+#if defined(OS_ANDROID) || defined(OS_MACOSX) || defined(OS_WIN)
class BluetoothGattCharacteristicTest : public BluetoothTest {
public:
// Creates adapter_, device_, service_, characteristic1_, & characteristic2_.
@@ -123,7 +125,7 @@ class BluetoothGattCharacteristicTest : public BluetoothTest {
};
#endif
-#if defined(OS_ANDROID)
+#if defined(OS_ANDROID) || defined(OS_WIN)
TEST_F(BluetoothGattCharacteristicTest, GetIdentifier) {
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
@@ -184,9 +186,9 @@ TEST_F(BluetoothGattCharacteristicTest, GetIdentifier) {
EXPECT_NE(char5->GetIdentifier(), char6->GetIdentifier());
}
-#endif // defined(OS_ANDROID)
+#endif // defined(OS_ANDROID) || defined(OS_WIN)
-#if defined(OS_ANDROID)
+#if defined(OS_ANDROID) || defined(OS_WIN)
TEST_F(BluetoothGattCharacteristicTest, GetUUID) {
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
@@ -222,9 +224,9 @@ TEST_F(BluetoothGattCharacteristicTest, GetUUID) {
EXPECT_EQ(uuid2, char2->GetUUID());
EXPECT_EQ(uuid2, char3->GetUUID());
}
-#endif // defined(OS_ANDROID)
+#endif // defined(OS_ANDROID) || defined(OS_WIN)
-#if defined(OS_ANDROID)
+#if defined(OS_ANDROID) || defined(OS_WIN)
TEST_F(BluetoothGattCharacteristicTest, GetProperties) {
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
@@ -250,9 +252,9 @@ TEST_F(BluetoothGattCharacteristicTest, GetProperties) {
EXPECT_EQ(0, properties1);
EXPECT_EQ(7, properties2);
}
-#endif // defined(OS_ANDROID)
+#endif // defined(OS_ANDROID) || defined(OS_WIN)
-#if defined(OS_ANDROID)
+#if defined(OS_ANDROID) || defined(OS_WIN)
// Tests GetService.
TEST_F(BluetoothGattCharacteristicTest, GetService) {
ASSERT_NO_FATAL_FAILURE(FakeCharacteristicBoilerplate());
@@ -260,7 +262,7 @@ TEST_F(BluetoothGattCharacteristicTest, GetService) {
EXPECT_EQ(service_, characteristic1_->GetService());
EXPECT_EQ(service_, characteristic2_->GetService());
}
-#endif // defined(OS_ANDROID)
+#endif // defined(OS_ANDROID) || defined(OS_WIN)
#if defined(OS_ANDROID)
// Tests ReadRemoteCharacteristic and GetValue with empty value buffer.
@@ -898,15 +900,15 @@ TEST_F(BluetoothGattCharacteristicTest, StartNotifySession_Multiple) {
}
#endif // defined(OS_ANDROID)
-#if defined(OS_ANDROID)
+#if defined(OS_ANDROID) || defined(OS_WIN)
TEST_F(BluetoothGattCharacteristicTest, GetDescriptors_FindNone) {
ASSERT_NO_FATAL_FAILURE(FakeCharacteristicBoilerplate());
EXPECT_EQ(0u, characteristic1_->GetDescriptors().size());
}
-#endif // defined(OS_ANDROID)
+#endif // defined(OS_ANDROID) || defined(OS_WIN)
-#if defined(OS_ANDROID)
+#if defined(OS_ANDROID) || defined(OS_WIN)
TEST_F(BluetoothGattCharacteristicTest, GetDescriptors_and_GetDescriptor) {
ASSERT_NO_FATAL_FAILURE(FakeCharacteristicBoilerplate());
@@ -949,6 +951,6 @@ TEST_F(BluetoothGattCharacteristicTest, GetDescriptors_and_GetDescriptor) {
// ... but not uuid 3
EXPECT_FALSE(c1_uuid1 == uuid3 || c1_uuid2 == uuid3);
}
-#endif // defined(OS_ANDROID)
+#endif // defined(OS_ANDROID) || defined(OS_WIN)
} // namespace device
diff --git a/device/bluetooth/bluetooth_low_energy_win.cc b/device/bluetooth/bluetooth_low_energy_win.cc
index 1e985b5..4d88565 100644
--- a/device/bluetooth/bluetooth_low_energy_win.cc
+++ b/device/bluetooth/bluetooth_low_energy_win.cc
@@ -728,27 +728,25 @@ HRESULT BluetoothLowEnergyWrapper::ReadCharacteristicsOfAService(
if (!file.IsValid())
return HRESULT_FROM_WIN32(ERROR_OPEN_FAILED);
- USHORT required_length = 0;
+ USHORT allocated_length = 0;
HRESULT hr = BluetoothGATTGetCharacteristics(file.GetPlatformFile(), service,
- 0, NULL, &required_length,
+ 0, NULL, &allocated_length,
BLUETOOTH_GATT_FLAG_NONE);
if (hr != HRESULT_FROM_WIN32(ERROR_MORE_DATA))
return hr;
out_included_characteristics->reset(
- new BTH_LE_GATT_CHARACTERISTIC[required_length]);
- USHORT actual_length = required_length;
- hr = BluetoothGATTGetCharacteristics(
- file.GetPlatformFile(), service, actual_length,
- out_included_characteristics->get(), &required_length,
- BLUETOOTH_GATT_FLAG_NONE);
- if (SUCCEEDED(hr) && required_length != actual_length) {
+ new BTH_LE_GATT_CHARACTERISTIC[allocated_length]);
+ hr = BluetoothGATTGetCharacteristics(file.GetPlatformFile(), service,
+ allocated_length,
+ out_included_characteristics->get(),
+ out_counts, BLUETOOTH_GATT_FLAG_NONE);
+ if (SUCCEEDED(hr) && allocated_length != *out_counts) {
LOG(ERROR) << "Retrieved charactersitics is not equal to expected"
- << " actual_length " << actual_length << " required_length "
- << required_length;
+ << " allocated_length " << allocated_length << " got "
+ << *out_counts;
hr = HRESULT_FROM_WIN32(ERROR_INVALID_USER_BUFFER);
}
- *out_counts = actual_length;
if (FAILED(hr)) {
out_included_characteristics->reset(nullptr);
@@ -757,5 +755,39 @@ HRESULT BluetoothLowEnergyWrapper::ReadCharacteristicsOfAService(
return hr;
}
+HRESULT BluetoothLowEnergyWrapper::ReadDescriptorsOfACharacteristic(
+ base::FilePath& service_path,
+ const PBTH_LE_GATT_CHARACTERISTIC characteristic,
+ scoped_ptr<BTH_LE_GATT_DESCRIPTOR>* out_included_descriptors,
+ USHORT* out_counts) {
+ base::File file(service_path, base::File::FLAG_OPEN | base::File::FLAG_READ);
+ if (!file.IsValid())
+ return HRESULT_FROM_WIN32(ERROR_OPEN_FAILED);
+
+ USHORT allocated_length = 0;
+ HRESULT hr = BluetoothGATTGetDescriptors(
+ file.GetPlatformFile(), characteristic, 0, NULL, &allocated_length,
+ BLUETOOTH_GATT_FLAG_NONE);
+ if (hr != HRESULT_FROM_WIN32(ERROR_MORE_DATA))
+ return hr;
+
+ out_included_descriptors->reset(new BTH_LE_GATT_DESCRIPTOR[allocated_length]);
+ hr = BluetoothGATTGetDescriptors(
+ file.GetPlatformFile(), characteristic, allocated_length,
+ out_included_descriptors->get(), out_counts, BLUETOOTH_GATT_FLAG_NONE);
+ if (SUCCEEDED(hr) && allocated_length != *out_counts) {
+ LOG(ERROR) << "Retrieved descriptors is not equal to expected"
+ << " allocated_length " << allocated_length << " got "
+ << *out_counts;
+ hr = HRESULT_FROM_WIN32(ERROR_INVALID_USER_BUFFER);
+ }
+
+ if (FAILED(hr)) {
+ out_included_descriptors->reset(nullptr);
+ *out_counts = 0;
+ }
+ return hr;
+}
+
} // namespace win
} // namespace device
diff --git a/device/bluetooth/bluetooth_low_energy_win.h b/device/bluetooth/bluetooth_low_energy_win.h
index a2bae9e..b7d378a 100644
--- a/device/bluetooth/bluetooth_low_energy_win.h
+++ b/device/bluetooth/bluetooth_low_energy_win.h
@@ -153,6 +153,15 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothLowEnergyWrapper {
scoped_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,
+ scoped_ptr<BTH_LE_GATT_DESCRIPTOR>* out_included_descriptors,
+ USHORT* out_counts);
+
protected:
BluetoothLowEnergyWrapper();
virtual ~BluetoothLowEnergyWrapper();
diff --git a/device/bluetooth/bluetooth_low_energy_win_fake.cc b/device/bluetooth/bluetooth_low_energy_win_fake.cc
index bc1d2b5..d6fb5f0 100644
--- a/device/bluetooth/bluetooth_low_energy_win_fake.cc
+++ b/device/bluetooth/bluetooth_low_energy_win_fake.cc
@@ -18,14 +18,14 @@ namespace win {
BLEDevice::BLEDevice() {}
BLEDevice::~BLEDevice() {}
-BLEGattService::BLEGattService() {}
-BLEGattService::~BLEGattService() {}
+GattService::GattService() {}
+GattService::~GattService() {}
-BLEGattCharacteristic::BLEGattCharacteristic() {}
-BLEGattCharacteristic::~BLEGattCharacteristic() {}
+GattCharacteristic::GattCharacteristic() {}
+GattCharacteristic::~GattCharacteristic() {}
-BLEGattDescriptor::BLEGattDescriptor() {}
-BLEGattDescriptor::~BLEGattDescriptor() {}
+GattDescriptor::GattDescriptor() {}
+GattDescriptor::~GattDescriptor() {}
BluetoothLowEnergyWrapperFake::BluetoothLowEnergyWrapperFake() {}
BluetoothLowEnergyWrapperFake::~BluetoothLowEnergyWrapperFake() {}
@@ -65,7 +65,7 @@ bool BluetoothLowEnergyWrapperFake::
BluetoothLowEnergyDeviceInfo* device_info =
new BluetoothLowEnergyDeviceInfo();
*device_info = *(device.second->device_info);
- base::string16 path = GenerateBLEGattServiceDevicePath(
+ base::string16 path = GenerateGattServiceDevicePath(
device.second->device_info->path.value(),
service.second->service_info->AttributeHandle);
device_info->path = base::FilePath(path);
@@ -107,7 +107,7 @@ bool BluetoothLowEnergyWrapperFake::EnumerateKnownBluetoothLowEnergyServices(
}
} else {
// Return corresponding GATT service for BLE GATT service device.
- BLEGattService* target_service =
+ GattService* target_service =
GetSimulatedGattService(it_d->second.get(), service_attribute_handles);
BluetoothLowEnergyServiceInfo* service_info =
new BluetoothLowEnergyServiceInfo();
@@ -129,7 +129,7 @@ HRESULT BluetoothLowEnergyWrapperFake::ReadCharacteristicsOfAService(
ExtractDeviceAddressFromDevicePath(service_path.value());
const std::vector<std::string> service_att_handles =
ExtractServiceAttributeHandlesFromDevicePath(service_path.value());
- BLEGattService* target_service = GetSimulatedGattService(
+ GattService* target_service = GetSimulatedGattService(
GetSimulatedBLEDevice(
std::string(device_address.begin(), device_address.end())),
service_att_handles);
@@ -153,6 +153,30 @@ HRESULT BluetoothLowEnergyWrapperFake::ReadCharacteristicsOfAService(
return HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS);
}
+HRESULT BluetoothLowEnergyWrapperFake::ReadDescriptorsOfACharacteristic(
+ base::FilePath& service_path,
+ const PBTH_LE_GATT_CHARACTERISTIC characteristic,
+ scoped_ptr<BTH_LE_GATT_DESCRIPTOR>* out_included_descriptors,
+ USHORT* out_counts) {
+ GattCharacteristic* target_characteristic =
+ GetSimulatedGattCharacteristic(service_path, characteristic);
+ if (target_characteristic == nullptr)
+ return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
+
+ std::size_t number_of_included_descriptors =
+ target_characteristic->included_descriptors.size();
+ PBTH_LE_GATT_DESCRIPTOR win_descriptors_info =
+ new BTH_LE_GATT_DESCRIPTOR[number_of_included_descriptors];
+ *out_counts = USHORT(number_of_included_descriptors);
+ std::size_t i = 0;
+ for (const auto& d : target_characteristic->included_descriptors) {
+ win_descriptors_info[i] = *(d.second->descriptor_info);
+ i++;
+ }
+ out_included_descriptors->reset(win_descriptors_info);
+ return S_OK;
+}
+
BLEDevice* BluetoothLowEnergyWrapperFake::SimulateBLEDevice(
std::string device_name,
BLUETOOTH_ADDRESS device_address) {
@@ -178,13 +202,13 @@ BLEDevice* BluetoothLowEnergyWrapperFake::GetSimulatedBLEDevice(
return it_d->second.get();
}
-BLEGattService* BluetoothLowEnergyWrapperFake::SimulateBLEGattService(
+GattService* BluetoothLowEnergyWrapperFake::SimulateGattService(
BLEDevice* device,
- BLEGattService* parent_service,
+ GattService* parent_service,
const BTH_LE_UUID& uuid) {
CHECK(device);
- BLEGattService* service = new BLEGattService();
+ GattService* service = new GattService();
PBTH_LE_GATT_SERVICE service_info = new BTH_LE_GATT_SERVICE[1];
std::string string_device_address =
BluetoothAddressToCanonicalString(device->device_info->address);
@@ -204,9 +228,9 @@ BLEGattService* BluetoothLowEnergyWrapperFake::SimulateBLEGattService(
return service;
}
-void BluetoothLowEnergyWrapperFake::SimulateBLEGattServiceRemoved(
+void BluetoothLowEnergyWrapperFake::SimulateGattServiceRemoved(
BLEDevice* device,
- BLEGattService* parent_service,
+ GattService* parent_service,
std::string attribute_handle) {
if (parent_service) {
parent_service->included_services.erase(attribute_handle);
@@ -215,11 +239,11 @@ void BluetoothLowEnergyWrapperFake::SimulateBLEGattServiceRemoved(
}
}
-BLEGattService* BluetoothLowEnergyWrapperFake::GetSimulatedGattService(
+GattService* BluetoothLowEnergyWrapperFake::GetSimulatedGattService(
BLEDevice* device,
const std::vector<std::string>& chain_of_att_handle) {
// First, find the root primary service.
- BLEGattServicesMap::iterator it_s =
+ GattServicesMap::iterator it_s =
device->primary_services.find(chain_of_att_handle[0]);
if (it_s == device->primary_services.end())
return nullptr;
@@ -229,7 +253,7 @@ BLEGattService* BluetoothLowEnergyWrapperFake::GetSimulatedGattService(
for (std::size_t i = 1; i < chain_of_att_handle.size(); i++) {
std::string included_att_handle = std::string(
chain_of_att_handle[i].begin(), chain_of_att_handle[i].end());
- BLEGattServicesMap::iterator it_i =
+ GattServicesMap::iterator it_i =
it_s->second->included_services.find(included_att_handle);
if (it_i == it_s->second->included_services.end())
return nullptr;
@@ -238,14 +262,13 @@ BLEGattService* BluetoothLowEnergyWrapperFake::GetSimulatedGattService(
return it_s->second.get();
}
-BLEGattCharacteristic*
-BluetoothLowEnergyWrapperFake::SimulateBLEGattCharacterisc(
+GattCharacteristic* BluetoothLowEnergyWrapperFake::SimulateGattCharacterisc(
std::string device_address,
- BLEGattService* parent_service,
+ GattService* parent_service,
const BTH_LE_GATT_CHARACTERISTIC& characteristic) {
CHECK(parent_service);
- BLEGattCharacteristic* win_characteristic = new BLEGattCharacteristic();
+ GattCharacteristic* win_characteristic = new GattCharacteristic();
PBTH_LE_GATT_CHARACTERISTIC win_characteristic_info =
new BTH_LE_GATT_CHARACTERISTIC[1];
*win_characteristic_info = characteristic;
@@ -258,13 +281,59 @@ BluetoothLowEnergyWrapperFake::SimulateBLEGattCharacterisc(
return win_characteristic;
}
-void BluetoothLowEnergyWrapperFake::SimulateBLEGattCharacteriscRemove(
- BLEGattService* parent_service,
+void BluetoothLowEnergyWrapperFake::SimulateGattCharacteriscRemove(
+ GattService* parent_service,
std::string attribute_handle) {
CHECK(parent_service);
parent_service->included_characteristics.erase(attribute_handle);
}
+GattCharacteristic*
+BluetoothLowEnergyWrapperFake::GetSimulatedGattCharacteristic(
+ GattService* parent_service,
+ std::string attribute_handle) {
+ CHECK(parent_service);
+ GattCharacteristicsMap::iterator it =
+ parent_service->included_characteristics.find(attribute_handle);
+ if (it != parent_service->included_characteristics.end())
+ return it->second.get();
+ return nullptr;
+}
+
+void BluetoothLowEnergyWrapperFake::SimulateGattDescriptor(
+ std::string device_address,
+ GattCharacteristic* characteristic,
+ const BTH_LE_UUID& uuid) {
+ scoped_ptr<GattDescriptor> descriptor(new GattDescriptor());
+ descriptor->descriptor_info.reset(new BTH_LE_GATT_DESCRIPTOR[1]);
+ descriptor->descriptor_info->DescriptorUuid = uuid;
+ descriptor->descriptor_info->AttributeHandle =
+ GenerateAUniqueAttributeHandle(device_address);
+ characteristic->included_descriptors[std::to_string(
+ descriptor->descriptor_info->AttributeHandle)] = std::move(descriptor);
+}
+
+GattCharacteristic*
+BluetoothLowEnergyWrapperFake::GetSimulatedGattCharacteristic(
+ base::FilePath& service_path,
+ const PBTH_LE_GATT_CHARACTERISTIC characteristic) {
+ base::string16 device_address =
+ ExtractDeviceAddressFromDevicePath(service_path.value());
+ BLEDevice* target_device = GetSimulatedBLEDevice(
+ std::string(device_address.begin(), device_address.end()));
+ if (target_device == nullptr)
+ return nullptr;
+ const std::vector<std::string> service_att_handles =
+ ExtractServiceAttributeHandlesFromDevicePath(service_path.value());
+ GattService* target_service =
+ GetSimulatedGattService(target_device, service_att_handles);
+ if (target_service == nullptr)
+ return nullptr;
+ GattCharacteristic* target_characteristic = GetSimulatedGattCharacteristic(
+ target_service, std::to_string(characteristic->AttributeHandle));
+ return target_characteristic;
+}
+
USHORT BluetoothLowEnergyWrapperFake::GenerateAUniqueAttributeHandle(
std::string device_address) {
scoped_ptr<std::set<USHORT>>& set_of_ushort =
@@ -300,7 +369,7 @@ base::string16 BluetoothLowEnergyWrapperFake::GenerateBLEDevicePath(
return base::string16(device_address.begin(), device_address.end());
}
-base::string16 BluetoothLowEnergyWrapperFake::GenerateBLEGattServiceDevicePath(
+base::string16 BluetoothLowEnergyWrapperFake::GenerateGattServiceDevicePath(
base::string16 resident_device_path,
USHORT service_attribute_handle) {
std::string sub_path = std::to_string(service_attribute_handle);
diff --git a/device/bluetooth/bluetooth_low_energy_win_fake.h b/device/bluetooth/bluetooth_low_energy_win_fake.h
index b069daa..f21fa5a 100644
--- a/device/bluetooth/bluetooth_low_energy_win_fake.h
+++ b/device/bluetooth/bluetooth_low_energy_win_fake.h
@@ -14,20 +14,20 @@ namespace device {
namespace win {
struct BLEDevice;
-struct BLEGattService;
-struct BLEGattCharacteristic;
-struct BLEGattDescriptor;
+struct GattService;
+struct GattCharacteristic;
+struct GattDescriptor;
// The key of BLEDevicesMap is the string of the BLE device address.
typedef std::unordered_map<std::string, scoped_ptr<BLEDevice>> BLEDevicesMap;
-// The key of BLEGattServicesMap, BLEGattCharacteristicsMap and
-// BLEGattDescriptorsMap is the string of the attribute handle.
-typedef std::unordered_map<std::string, scoped_ptr<BLEGattService>>
- BLEGattServicesMap;
-typedef std::unordered_map<std::string, scoped_ptr<BLEGattCharacteristic>>
- BLEGattCharacteristicsMap;
-typedef std::unordered_map<std::string, scoped_ptr<BLEGattDescriptor>>
- BLEGattDescriptorsMap;
+// The key of GattServicesMap, GattCharacteristicsMap and GattDescriptorsMap is
+// the string of the attribute handle.
+typedef std::unordered_map<std::string, scoped_ptr<GattService>>
+ GattServicesMap;
+typedef std::unordered_map<std::string, scoped_ptr<GattCharacteristic>>
+ GattCharacteristicsMap;
+typedef std::unordered_map<std::string, scoped_ptr<GattDescriptor>>
+ GattDescriptorsMap;
// The key of BLEAttributeHandleTable is the string of the BLE device address.
typedef std::unordered_map<std::string, scoped_ptr<std::set<USHORT>>>
BLEAttributeHandleTable;
@@ -36,28 +36,28 @@ struct BLEDevice {
BLEDevice();
~BLEDevice();
scoped_ptr<BluetoothLowEnergyDeviceInfo> device_info;
- BLEGattServicesMap primary_services;
+ GattServicesMap primary_services;
};
-struct BLEGattService {
- BLEGattService();
- ~BLEGattService();
+struct GattService {
+ GattService();
+ ~GattService();
scoped_ptr<BTH_LE_GATT_SERVICE> service_info;
- BLEGattServicesMap included_services;
- BLEGattCharacteristicsMap included_characteristics;
+ GattServicesMap included_services;
+ GattCharacteristicsMap included_characteristics;
};
-struct BLEGattCharacteristic {
- BLEGattCharacteristic();
- ~BLEGattCharacteristic();
+struct GattCharacteristic {
+ GattCharacteristic();
+ ~GattCharacteristic();
scoped_ptr<BTH_LE_GATT_CHARACTERISTIC> characteristic_info;
scoped_ptr<BTH_LE_GATT_CHARACTERISTIC_VALUE> value;
- BLEGattDescriptorsMap included_descriptors;
+ GattDescriptorsMap included_descriptors;
};
-struct BLEGattDescriptor {
- BLEGattDescriptor();
- ~BLEGattDescriptor();
+struct GattDescriptor {
+ GattDescriptor();
+ ~GattDescriptor();
scoped_ptr<BTH_LE_GATT_DESCRIPTOR> descriptor_info;
scoped_ptr<BTH_LE_GATT_DESCRIPTOR_VALUE> value;
};
@@ -84,35 +84,51 @@ class BluetoothLowEnergyWrapperFake : public BluetoothLowEnergyWrapper {
const PBTH_LE_GATT_SERVICE service,
scoped_ptr<BTH_LE_GATT_CHARACTERISTIC>* out_included_characteristics,
USHORT* out_counts) override;
+ HRESULT ReadDescriptorsOfACharacteristic(
+ base::FilePath& service_path,
+ const PBTH_LE_GATT_CHARACTERISTIC characteristic,
+ scoped_ptr<BTH_LE_GATT_DESCRIPTOR>* out_included_descriptors,
+ USHORT* out_counts) override;
BLEDevice* SimulateBLEDevice(std::string device_name,
BLUETOOTH_ADDRESS device_address);
BLEDevice* GetSimulatedBLEDevice(std::string device_address);
// Note: |parent_service| may be nullptr to indicate a primary service.
- BLEGattService* SimulateBLEGattService(BLEDevice* device,
- BLEGattService* parent_service,
- const BTH_LE_UUID& uuid);
+ GattService* SimulateGattService(BLEDevice* device,
+ GattService* parent_service,
+ const BTH_LE_UUID& uuid);
// Note: |parent_service| may be nullptr to indicate a primary service.
- void SimulateBLEGattServiceRemoved(BLEDevice* device,
- BLEGattService* parent_service,
- std::string attribute_handle);
+ void SimulateGattServiceRemoved(BLEDevice* device,
+ GattService* parent_service,
+ std::string attribute_handle);
// Note: |chain_of_att_handle| contains the attribute handles of the services
// in order from primary service to target service. The last item in
// |chain_of_att_handle| is the target service's attribute handle.
- BLEGattService* GetSimulatedGattService(
+ GattService* GetSimulatedGattService(
BLEDevice* device,
const std::vector<std::string>& chain_of_att_handle);
- BLEGattCharacteristic* SimulateBLEGattCharacterisc(
+ GattCharacteristic* SimulateGattCharacterisc(
std::string device_address,
- BLEGattService* parent_service,
+ GattService* parent_service,
const BTH_LE_GATT_CHARACTERISTIC& characteristic);
- void SimulateBLEGattCharacteriscRemove(BLEGattService* parent_service,
- std::string attribute_handle);
+ void SimulateGattCharacteriscRemove(GattService* parent_service,
+ std::string attribute_handle);
+ GattCharacteristic* GetSimulatedGattCharacteristic(
+ GattService* parent_service,
+ std::string attribute_handle);
+ void SimulateGattDescriptor(std::string device_address,
+ GattCharacteristic* characteristic,
+ const BTH_LE_UUID& uuid);
private:
+ // Get simulated characteristic by |service_path| and |characteristic| info.
+ GattCharacteristic* GetSimulatedGattCharacteristic(
+ base::FilePath& service_path,
+ const PBTH_LE_GATT_CHARACTERISTIC characteristic);
+
// Generate an unique attribute handle on |device_address|.
USHORT GenerateAUniqueAttributeHandle(std::string device_address);
@@ -122,16 +138,16 @@ class BluetoothLowEnergyWrapperFake : public BluetoothLowEnergyWrapper {
// Generate GATT service device path of the service with
// |service_attribute_handle|. |resident_device_path| is the BLE device this
// GATT service belongs to.
- base::string16 GenerateBLEGattServiceDevicePath(
+ base::string16 GenerateGattServiceDevicePath(
base::string16 resident_device_path,
USHORT service_attribute_handle);
// Extract device address from the device |path| generated by
- // GenerateBLEDevicePath or GenerateBLEGattServiceDevicePath.
+ // GenerateBLEDevicePath or GenerateGattServiceDevicePath.
base::string16 ExtractDeviceAddressFromDevicePath(base::string16 path);
// Extract service attribute handles from the |path| generated by
- // GenerateBLEGattServiceDevicePath.
+ // GenerateGattServiceDevicePath.
std::vector<std::string> ExtractServiceAttributeHandlesFromDevicePath(
base::string16 path);
diff --git a/device/bluetooth/bluetooth_remote_gatt_characteristic_win.cc b/device/bluetooth/bluetooth_remote_gatt_characteristic_win.cc
index 8f2a6d8..baf4a73 100644
--- a/device/bluetooth/bluetooth_remote_gatt_characteristic_win.cc
+++ b/device/bluetooth/bluetooth_remote_gatt_characteristic_win.cc
@@ -4,7 +4,9 @@
#include "device/bluetooth/bluetooth_remote_gatt_characteristic_win.h"
+#include "base/bind.h"
#include "device/bluetooth/bluetooth_adapter_win.h"
+#include "device/bluetooth/bluetooth_remote_gatt_descriptor_win.h"
#include "device/bluetooth/bluetooth_remote_gatt_service_win.h"
#include "device/bluetooth/bluetooth_task_manager_win.h"
@@ -17,21 +19,20 @@ BluetoothRemoteGattCharacteristicWin::BluetoothRemoteGattCharacteristicWin(
: parent_service_(parent_service),
characteristic_info_(characteristic_info),
ui_task_runner_(ui_task_runner),
+ characteristic_added_notified_(false),
weak_ptr_factory_(this) {
DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
DCHECK(parent_service_);
DCHECK(characteristic_info_);
- adapter_ = static_cast<BluetoothAdapterWin*>(
- parent_service_->GetDevice()->GetAdapter());
- DCHECK(adapter_);
- task_manager_ = adapter_->GetWinBluetoothTaskManager();
+ task_manager_ =
+ parent_service_->GetWinAdapter()->GetWinBluetoothTaskManager();
DCHECK(task_manager_);
-
- characteristic_uuid_ = task_manager_->BluetoothLowEnergyUuidToBluetoothUuid(
- characteristic_info_->CharacteristicUuid);
+ characteristic_uuid_ =
+ BluetoothTaskManagerWin::BluetoothLowEnergyUuidToBluetoothUuid(
+ characteristic_info_->CharacteristicUuid);
characteristic_identifier_ =
- parent_service_->GetIdentifier() +
+ parent_service_->GetIdentifier() + "_" +
std::to_string(characteristic_info_->AttributeHandle);
Update();
}
@@ -39,7 +40,7 @@ BluetoothRemoteGattCharacteristicWin::BluetoothRemoteGattCharacteristicWin(
BluetoothRemoteGattCharacteristicWin::~BluetoothRemoteGattCharacteristicWin() {
DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
- adapter_->NotifyGattCharacteristicRemoved(this);
+ parent_service_->GetWinAdapter()->NotifyGattCharacteristicRemoved(this);
}
std::string BluetoothRemoteGattCharacteristicWin::GetIdentifier() const {
@@ -110,13 +111,17 @@ bool BluetoothRemoteGattCharacteristicWin::IsNotifying() const {
std::vector<BluetoothGattDescriptor*>
BluetoothRemoteGattCharacteristicWin::GetDescriptors() const {
- NOTIMPLEMENTED();
- return std::vector<BluetoothGattDescriptor*>();
+ std::vector<BluetoothGattDescriptor*> descriptors;
+ for (const auto& descriptor : included_descriptors_)
+ descriptors.push_back(descriptor.second.get());
+ return descriptors;
}
BluetoothGattDescriptor* BluetoothRemoteGattCharacteristicWin::GetDescriptor(
const std::string& identifier) const {
- NOTIMPLEMENTED();
+ GattDescriptorMap::const_iterator it = included_descriptors_.find(identifier);
+ if (it != included_descriptors_.end())
+ return it->second.get();
return nullptr;
}
@@ -156,11 +161,96 @@ void BluetoothRemoteGattCharacteristicWin::WriteRemoteCharacteristic(
void BluetoothRemoteGattCharacteristicWin::Update() {
DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
- NOTIMPLEMENTED();
+
+ task_manager_->PostGetGattIncludedDescriptors(
+ parent_service_->GetServicePath(), characteristic_info_.get(),
+ base::Bind(&BluetoothRemoteGattCharacteristicWin::
+ OnGetIncludedDescriptorsCallback,
+ weak_ptr_factory_.GetWeakPtr()));
}
uint16_t BluetoothRemoteGattCharacteristicWin::GetAttributeHandle() const {
return characteristic_info_->AttributeHandle;
}
+void BluetoothRemoteGattCharacteristicWin::OnGetIncludedDescriptorsCallback(
+ scoped_ptr<BTH_LE_GATT_DESCRIPTOR> descriptors,
+ uint16_t num,
+ HRESULT hr) {
+ DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
+
+ UpdateIncludedDescriptors(descriptors.get(), num);
+ if (!characteristic_added_notified_) {
+ characteristic_added_notified_ = true;
+ parent_service_->GetWinAdapter()->NotifyGattCharacteristicAdded(this);
+ }
+}
+
+void BluetoothRemoteGattCharacteristicWin::UpdateIncludedDescriptors(
+ PBTH_LE_GATT_DESCRIPTOR descriptors,
+ uint16_t num) {
+ if (num == 0) {
+ included_descriptors_.clear();
+ return;
+ }
+
+ // First, remove descriptors that no longer exist.
+ std::vector<std::string> to_be_removed;
+ for (const auto& d : included_descriptors_) {
+ if (!DoesDescriptorExist(descriptors, num, d.second.get()))
+ to_be_removed.push_back(d.second->GetIdentifier());
+ }
+ for (auto id : to_be_removed)
+ included_descriptors_.erase(id);
+
+ // Return if no new descriptors have been added.
+ if (included_descriptors_.size() == num)
+ return;
+
+ // Add new descriptors.
+ for (uint16_t i = 0; i < num; i++) {
+ if (!IsDescriptorDiscovered(descriptors[i].DescriptorUuid,
+ descriptors[i].AttributeHandle)) {
+ PBTH_LE_GATT_DESCRIPTOR win_descriptor_info =
+ new BTH_LE_GATT_DESCRIPTOR();
+ *win_descriptor_info = descriptors[i];
+ BluetoothRemoteGattDescriptorWin* descriptor =
+ new BluetoothRemoteGattDescriptorWin(this, win_descriptor_info,
+ ui_task_runner_);
+ included_descriptors_[descriptor->GetIdentifier()] =
+ make_scoped_ptr(descriptor);
+ }
+ }
+}
+
+bool BluetoothRemoteGattCharacteristicWin::IsDescriptorDiscovered(
+ BTH_LE_UUID& uuid,
+ uint16_t attribute_handle) {
+ BluetoothUUID bt_uuid =
+ BluetoothTaskManagerWin::BluetoothLowEnergyUuidToBluetoothUuid(uuid);
+ for (const auto& d : included_descriptors_) {
+ if (bt_uuid == d.second->GetUUID() &&
+ attribute_handle == d.second->GetAttributeHandle()) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool BluetoothRemoteGattCharacteristicWin::DoesDescriptorExist(
+ PBTH_LE_GATT_DESCRIPTOR descriptors,
+ uint16_t num,
+ BluetoothRemoteGattDescriptorWin* descriptor) {
+ for (uint16_t i = 0; i < num; i++) {
+ BluetoothUUID uuid =
+ BluetoothTaskManagerWin::BluetoothLowEnergyUuidToBluetoothUuid(
+ descriptors[i].DescriptorUuid);
+ if (descriptor->GetUUID() == uuid &&
+ descriptor->GetAttributeHandle() == descriptors[i].AttributeHandle) {
+ return true;
+ }
+ }
+ return false;
+}
+
} // namespace device.
diff --git a/device/bluetooth/bluetooth_remote_gatt_characteristic_win.h b/device/bluetooth/bluetooth_remote_gatt_characteristic_win.h
index f397363..9860116 100644
--- a/device/bluetooth/bluetooth_remote_gatt_characteristic_win.h
+++ b/device/bluetooth/bluetooth_remote_gatt_characteristic_win.h
@@ -5,6 +5,8 @@
#ifndef DEVICE_BLUETOOTH_BLUETOOTH_REMOTE_GATT_CHARACTERISTIC_WIN_H_
#define DEVICE_BLUETOOTH_BLUETOOTH_REMOTE_GATT_CHARACTERISTIC_WIN_H_
+#include <unordered_map>
+
#include "base/memory/weak_ptr.h"
#include "base/sequenced_task_runner.h"
#include "device/bluetooth/bluetooth_gatt_characteristic.h"
@@ -13,6 +15,7 @@
namespace device {
class BluetoothAdapterWin;
+class BluetoothRemoteGattDescriptorWin;
class BluetoothRemoteGattServiceWin;
class BluetoothTaskManagerWin;
@@ -52,9 +55,26 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothRemoteGattCharacteristicWin
// Update included descriptors.
void Update();
uint16_t GetAttributeHandle() const;
+ BluetoothRemoteGattServiceWin* GetWinService() { return parent_service_; }
private:
- BluetoothAdapterWin* adapter_;
+ void OnGetIncludedDescriptorsCallback(
+ scoped_ptr<BTH_LE_GATT_DESCRIPTOR> descriptors,
+ uint16_t num,
+ HRESULT hr);
+ void UpdateIncludedDescriptors(PBTH_LE_GATT_DESCRIPTOR descriptors,
+ uint16_t num);
+
+ // Checks if the descriptor with |uuid| and |attribute_handle| has already
+ // been discovered as included descriptor.
+ bool IsDescriptorDiscovered(BTH_LE_UUID& uuid, uint16_t attribute_handle);
+
+ // Checks if |descriptor| still exists in this characteristic according to
+ // newly discovered |num| of |descriptors|.
+ static bool DoesDescriptorExist(PBTH_LE_GATT_DESCRIPTOR descriptors,
+ uint16_t num,
+ BluetoothRemoteGattDescriptorWin* descriptor);
+
BluetoothRemoteGattServiceWin* parent_service_;
scoped_refptr<BluetoothTaskManagerWin> task_manager_;
@@ -65,6 +85,17 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothRemoteGattCharacteristicWin
std::vector<uint8_t> characteristic_value_;
std::string characteristic_identifier_;
+ // The key of GattDescriptorMap is the identitfier of
+ // BluetoothRemoteGattDescriptorWin instance.
+ typedef std::unordered_map<std::string,
+ scoped_ptr<BluetoothRemoteGattDescriptorWin>>
+ GattDescriptorMap;
+ GattDescriptorMap included_descriptors_;
+
+ // Flag indicates if characteristic added notification of this characteristic
+ // has been sent out to avoid duplicate notification.
+ bool characteristic_added_notified_;
+
base::WeakPtrFactory<BluetoothRemoteGattCharacteristicWin> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(BluetoothRemoteGattCharacteristicWin);
};
diff --git a/device/bluetooth/bluetooth_remote_gatt_descriptor_win.cc b/device/bluetooth/bluetooth_remote_gatt_descriptor_win.cc
new file mode 100644
index 0000000..3610af0
--- /dev/null
+++ b/device/bluetooth/bluetooth_remote_gatt_descriptor_win.cc
@@ -0,0 +1,99 @@
+// Copyright 2016 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.
+
+#include "device/bluetooth/bluetooth_remote_gatt_descriptor_win.h"
+
+#include "base/bind.h"
+#include "device/bluetooth/bluetooth_adapter_win.h"
+#include "device/bluetooth/bluetooth_remote_gatt_characteristic_win.h"
+#include "device/bluetooth/bluetooth_remote_gatt_service_win.h"
+
+namespace device {
+
+BluetoothRemoteGattDescriptorWin::BluetoothRemoteGattDescriptorWin(
+ BluetoothRemoteGattCharacteristicWin* parent_characteristic,
+ BTH_LE_GATT_DESCRIPTOR* descriptor_info,
+ scoped_refptr<base::SequencedTaskRunner>& ui_task_runner)
+ : parent_characteristic_(parent_characteristic),
+ descriptor_info_(descriptor_info),
+ ui_task_runner_(ui_task_runner),
+ weak_ptr_factory_(this) {
+ DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
+ DCHECK(parent_characteristic_);
+ DCHECK(descriptor_info_.get());
+
+ task_manager_ = parent_characteristic_->GetWinService()
+ ->GetWinAdapter()
+ ->GetWinBluetoothTaskManager();
+ DCHECK(task_manager_);
+ service_path_ = parent_characteristic_->GetWinService()->GetServicePath();
+ DCHECK(!service_path_.empty());
+ descriptor_uuid_ =
+ BluetoothTaskManagerWin::BluetoothLowEnergyUuidToBluetoothUuid(
+ descriptor_info_.get()->DescriptorUuid);
+ DCHECK(descriptor_uuid_.IsValid());
+ descriptor_identifier_ = parent_characteristic_->GetIdentifier() + "_" +
+ std::to_string(descriptor_info_->AttributeHandle);
+}
+
+BluetoothRemoteGattDescriptorWin::~BluetoothRemoteGattDescriptorWin() {
+ DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
+
+ parent_characteristic_->GetWinService()
+ ->GetWinAdapter()
+ ->NotifyGattDescriptorRemoved(this);
+}
+
+std::string BluetoothRemoteGattDescriptorWin::GetIdentifier() const {
+ return descriptor_identifier_;
+}
+
+BluetoothUUID BluetoothRemoteGattDescriptorWin::GetUUID() const {
+ return descriptor_uuid_;
+}
+
+bool BluetoothRemoteGattDescriptorWin::IsLocal() const {
+ return false;
+}
+
+std::vector<uint8_t>& BluetoothRemoteGattDescriptorWin::GetValue() const {
+ NOTIMPLEMENTED();
+ return const_cast<std::vector<uint8_t>&>(descriptor_value_);
+}
+
+BluetoothGattCharacteristic*
+BluetoothRemoteGattDescriptorWin::GetCharacteristic() const {
+ return parent_characteristic_;
+}
+
+BluetoothGattCharacteristic::Permissions
+BluetoothRemoteGattDescriptorWin::GetPermissions() const {
+ NOTIMPLEMENTED();
+ return descriptor_permissions_;
+}
+
+void BluetoothRemoteGattDescriptorWin::ReadRemoteDescriptor(
+ const ValueCallback& callback,
+ const ErrorCallback& error_callback) {
+ DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
+
+ NOTIMPLEMENTED();
+ error_callback.Run(BluetoothGattService::GATT_ERROR_NOT_SUPPORTED);
+}
+
+void BluetoothRemoteGattDescriptorWin::WriteRemoteDescriptor(
+ const std::vector<uint8_t>& new_value,
+ const base::Closure& callback,
+ const ErrorCallback& error_callback) {
+ DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
+
+ NOTIMPLEMENTED();
+ error_callback.Run(BluetoothGattService::GATT_ERROR_NOT_SUPPORTED);
+}
+
+uint16_t BluetoothRemoteGattDescriptorWin::GetAttributeHandle() const {
+ return descriptor_info_->AttributeHandle;
+}
+
+} // namespace device.
diff --git a/device/bluetooth/bluetooth_remote_gatt_descriptor_win.h b/device/bluetooth/bluetooth_remote_gatt_descriptor_win.h
new file mode 100644
index 0000000..b042b1c
--- /dev/null
+++ b/device/bluetooth/bluetooth_remote_gatt_descriptor_win.h
@@ -0,0 +1,60 @@
+// Copyright 2016 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_REMOTE_GATT_DESCRIPTOR_WIN_H_
+#define DEVICE_BLUETOOTH_BLUETOOTH_REMOTE_GATT_DESCRIPTOR_WIN_H_
+
+#include "base/files/file_path.h"
+#include "base/memory/weak_ptr.h"
+#include "device/bluetooth/bluetooth_gatt_descriptor.h"
+#include "device/bluetooth/bluetooth_low_energy_defs_win.h"
+
+namespace device {
+
+class BluetoothAdapterWin;
+class BluetoothRemoteGattCharacteristicWin;
+class BluetoothTaskManagerWin;
+
+class DEVICE_BLUETOOTH_EXPORT BluetoothRemoteGattDescriptorWin
+ : public BluetoothGattDescriptor {
+ public:
+ BluetoothRemoteGattDescriptorWin(
+ BluetoothRemoteGattCharacteristicWin* parent_characteristic,
+ BTH_LE_GATT_DESCRIPTOR* descriptor_info,
+ scoped_refptr<base::SequencedTaskRunner>& ui_task_runner);
+ ~BluetoothRemoteGattDescriptorWin();
+
+ // Override BluetoothGattDescriptor interfaces.
+ std::string GetIdentifier() const override;
+ BluetoothUUID GetUUID() const override;
+ bool IsLocal() const override;
+ std::vector<uint8_t>& GetValue() const override;
+ BluetoothGattCharacteristic* GetCharacteristic() const override;
+ BluetoothGattCharacteristic::Permissions GetPermissions() const override;
+ void ReadRemoteDescriptor(const ValueCallback& callback,
+ const ErrorCallback& error_callback) override;
+ void WriteRemoteDescriptor(const std::vector<uint8_t>& new_value,
+ const base::Closure& callback,
+ const ErrorCallback& error_callback) override;
+
+ uint16_t GetAttributeHandle() const;
+
+ private:
+ BluetoothRemoteGattCharacteristicWin* parent_characteristic_;
+ scoped_ptr<BTH_LE_GATT_DESCRIPTOR> descriptor_info_;
+ scoped_refptr<base::SequencedTaskRunner> ui_task_runner_;
+
+ base::FilePath service_path_;
+ scoped_refptr<BluetoothTaskManagerWin> task_manager_;
+ BluetoothGattCharacteristic::Permissions descriptor_permissions_;
+ BluetoothUUID descriptor_uuid_;
+ std::string descriptor_identifier_;
+ std::vector<uint8_t> descriptor_value_;
+
+ base::WeakPtrFactory<BluetoothRemoteGattDescriptorWin> weak_ptr_factory_;
+ DISALLOW_COPY_AND_ASSIGN(BluetoothRemoteGattDescriptorWin);
+};
+
+} // namespace device.
+#endif // DEVICE_BLUETOOTH_BLUETOOTH_REMOTE_GATT_DESCRIPTOR_WIN_H_
diff --git a/device/bluetooth/bluetooth_remote_gatt_service_win.h b/device/bluetooth/bluetooth_remote_gatt_service_win.h
index ada0c83d..2ffa0f5 100644
--- a/device/bluetooth/bluetooth_remote_gatt_service_win.h
+++ b/device/bluetooth/bluetooth_remote_gatt_service_win.h
@@ -60,6 +60,8 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothRemoteGattServiceWin
// Update included services and characteristics.
void Update();
uint16_t GetAttributeHandle() const { return service_attribute_handle_; }
+ base::FilePath GetServicePath() { return service_path_; }
+ BluetoothAdapterWin* GetWinAdapter() { return adapter_; }
private:
void OnGetIncludedCharacteristics(
diff --git a/device/bluetooth/bluetooth_task_manager_win.cc b/device/bluetooth/bluetooth_task_manager_win.cc
index 1ccc013..c45f022 100644
--- a/device/bluetooth/bluetooth_task_manager_win.cc
+++ b/device/bluetooth/bluetooth_task_manager_win.cc
@@ -58,14 +58,14 @@ bool BluetoothUUIDToWinBLEUUID(const device::BluetoothUUID& uuid,
return false;
if (uuid.format() == device::BluetoothUUID::kFormat16Bit) {
- out_win_uuid->IsShortUuid = true;
+ out_win_uuid->IsShortUuid = TRUE;
unsigned int data = 0;
int result = sscanf_s(uuid.value().c_str(), "%04x", &data);
if (result != 1)
return false;
out_win_uuid->Value.ShortUuid = data;
} else {
- out_win_uuid->IsShortUuid = false;
+ out_win_uuid->IsShortUuid = FALSE;
unsigned int data[11];
int result =
sscanf_s(uuid.value().c_str(),
@@ -791,6 +791,24 @@ void BluetoothTaskManagerWin::GetGattIncludedCharacteristics(
number_of_charateristics, hr));
}
+void BluetoothTaskManagerWin::GetGattIncludedDescriptors(
+ base::FilePath service_path,
+ BTH_LE_GATT_CHARACTERISTIC characteristic,
+ const GetGattIncludedDescriptorsCallback& callback) {
+ scoped_ptr<BTH_LE_GATT_DESCRIPTOR> win_descriptors_info;
+ uint16_t number_of_descriptors = 0;
+
+ HRESULT hr =
+ win::BluetoothLowEnergyWrapper::GetInstance()
+ ->ReadDescriptorsOfACharacteristic(
+ service_path, (PBTH_LE_GATT_CHARACTERISTIC)(&characteristic),
+ &win_descriptors_info, &number_of_descriptors);
+
+ ui_task_runner_->PostTask(
+ FROM_HERE, base::Bind(callback, base::Passed(&win_descriptors_info),
+ number_of_descriptors, hr));
+}
+
void BluetoothTaskManagerWin::PostGetGattIncludedCharacteristics(
const base::FilePath& service_path,
const BluetoothUUID& uuid,
@@ -803,4 +821,15 @@ void BluetoothTaskManagerWin::PostGetGattIncludedCharacteristics(
service_path, uuid, attribute_handle, callback));
}
+void BluetoothTaskManagerWin::PostGetGattIncludedDescriptors(
+ const base::FilePath& service_path,
+ const PBTH_LE_GATT_CHARACTERISTIC characteristic,
+ const GetGattIncludedDescriptorsCallback& callback) {
+ DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
+ bluetooth_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&BluetoothTaskManagerWin::GetGattIncludedDescriptors, this,
+ service_path, *characteristic, callback));
+}
+
} // namespace device
diff --git a/device/bluetooth/bluetooth_task_manager_win.h b/device/bluetooth/bluetooth_task_manager_win.h
index 354a579..35d22cd 100644
--- a/device/bluetooth/bluetooth_task_manager_win.h
+++ b/device/bluetooth/bluetooth_task_manager_win.h
@@ -126,6 +126,9 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothTaskManagerWin
typedef base::Callback<
void(scoped_ptr<BTH_LE_GATT_CHARACTERISTIC>, uint16_t, HRESULT)>
GetGattIncludedCharacteristicsCallback;
+ typedef base::Callback<
+ void(scoped_ptr<BTH_LE_GATT_DESCRIPTOR>, uint16_t, HRESULT)>
+ GetGattIncludedDescriptorsCallback;
// Get all included characteristics of a given service. The service is
// uniquely identified by its |uuid| and |attribute_handle| with service
@@ -137,6 +140,14 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothTaskManagerWin
uint16_t attribute_handle,
const GetGattIncludedCharacteristicsCallback& callback);
+ // Get all included descriptors of a given |characterisitc| in service
+ // with |service_path|. The result is returned asynchronously through
+ // |callback|.
+ void PostGetGattIncludedDescriptors(
+ const base::FilePath& service_path,
+ const PBTH_LE_GATT_CHARACTERISTIC characteristic,
+ const GetGattIncludedDescriptorsCallback& callback);
+
private:
friend class base::RefCountedThreadSafe<BluetoothTaskManagerWin>;
friend class BluetoothTaskManagerWinTest;
@@ -233,6 +244,10 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothTaskManagerWin
BluetoothUUID uuid,
uint16_t attribute_handle,
const GetGattIncludedCharacteristicsCallback& callback);
+ void GetGattIncludedDescriptors(
+ base::FilePath service_path,
+ BTH_LE_GATT_CHARACTERISTIC characteristic,
+ const GetGattIncludedDescriptorsCallback& callback);
// UI task runner reference.
scoped_refptr<base::SequencedTaskRunner> ui_task_runner_;
diff --git a/device/bluetooth/test/bluetooth_test_win.cc b/device/bluetooth/test/bluetooth_test_win.cc
index b9cbe48..68af547 100644
--- a/device/bluetooth/test/bluetooth_test_win.cc
+++ b/device/bluetooth/test/bluetooth_test_win.cc
@@ -5,6 +5,7 @@
#include "device/bluetooth/test/bluetooth_test_win.h"
#include "base/bind.h"
+#include "base/run_loop.h"
#include "base/strings/sys_string_conversions.h"
#include "device/bluetooth/bluetooth_adapter_win.h"
#include "device/bluetooth/bluetooth_low_energy_win.h"
@@ -107,9 +108,8 @@ void BluetoothTestWin::InitWithFakeAdapter() {
adapter_ = new BluetoothAdapterWin(base::Bind(
&BluetoothTestWin::AdapterInitCallback, base::Unretained(this)));
adapter_win_ = static_cast<BluetoothAdapterWin*>(adapter_.get());
- adapter_win_->InitForTest(ui_task_runner_, bluetooth_task_runner_);
- bluetooth_task_runner_->RunPendingTasks();
- ui_task_runner_->RunPendingTasks();
+ adapter_win_->InitForTest(nullptr, bluetooth_task_runner_);
+ FinishPendingTasks();
}
bool BluetoothTestWin::DenyPermission() {
@@ -118,8 +118,7 @@ bool BluetoothTestWin::DenyPermission() {
void BluetoothTestWin::StartLowEnergyDiscoverySession() {
__super ::StartLowEnergyDiscoverySession();
- bluetooth_task_runner_->RunPendingTasks();
- ui_task_runner_->RunPendingTasks();
+ FinishPendingTasks();
}
BluetoothDevice* BluetoothTestWin::DiscoverLowEnergyDevice(int device_ordinal) {
@@ -153,18 +152,17 @@ BluetoothDevice* BluetoothTestWin::DiscoverLowEnergyDevice(int device_ordinal) {
device_name, CanonicalStringToBLUETOOTH_ADDRESS(device_address));
if (simulated_device != nullptr) {
if (!service_uuid_1.empty()) {
- fake_bt_le_wrapper_->SimulateBLEGattService(
+ fake_bt_le_wrapper_->SimulateGattService(
simulated_device, nullptr,
CanonicalStringToBTH_LE_UUID(service_uuid_1));
}
if (!service_uuid_2.empty()) {
- fake_bt_le_wrapper_->SimulateBLEGattService(
+ fake_bt_le_wrapper_->SimulateGattService(
simulated_device, nullptr,
CanonicalStringToBTH_LE_UUID(service_uuid_2));
}
}
- bluetooth_task_runner_->RunPendingTasks();
- ui_task_runner_->RunPendingTasks();
+ FinishPendingTasks();
std::vector<BluetoothDevice*> devices = adapter_win_->GetDevices();
for (auto device : devices) {
@@ -176,8 +174,7 @@ BluetoothDevice* BluetoothTestWin::DiscoverLowEnergyDevice(int device_ordinal) {
}
void BluetoothTestWin::SimulateGattConnection(BluetoothDevice* device) {
- bluetooth_task_runner_->RunPendingTasks();
- ui_task_runner_->RunPendingTasks();
+ FinishPendingTasks();
// Clear records caused by CreateGattConnection since we do not support it on
// Windows.
@@ -194,12 +191,11 @@ void BluetoothTestWin::SimulateGattServicesDiscovered(
CHECK(simulated_device);
for (auto uuid : uuids) {
- fake_bt_le_wrapper_->SimulateBLEGattService(
+ fake_bt_le_wrapper_->SimulateGattService(
simulated_device, nullptr, CanonicalStringToBTH_LE_UUID(uuid));
}
- bluetooth_task_runner_->RunPendingTasks();
- ui_task_runner_->RunPendingTasks();
+ FinishPendingTasks();
}
void BluetoothTestWin::SimulateGattServiceRemoved(
@@ -213,8 +209,8 @@ void BluetoothTestWin::SimulateGattServiceRemoved(
static_cast<BluetoothRemoteGattServiceWin*>(service);
std::string service_att_handle =
std::to_string(win_service->GetAttributeHandle());
- fake_bt_le_wrapper_->SimulateBLEGattServiceRemoved(target_device, nullptr,
- service_att_handle);
+ fake_bt_le_wrapper_->SimulateGattServiceRemoved(target_device, nullptr,
+ service_att_handle);
ForceRefreshDevice();
}
@@ -226,31 +222,42 @@ void BluetoothTestWin::SimulateGattCharacteristic(BluetoothGattService* service,
win::BLEDevice* target_device =
fake_bt_le_wrapper_->GetSimulatedBLEDevice(device_address);
CHECK(target_device);
- win::BLEGattService* target_service =
+ win::GattService* target_service =
GetSimulatedService(target_device, service);
CHECK(target_service);
- BTH_LE_GATT_CHARACTERISTIC win_cha_info;
- win_cha_info.CharacteristicUuid = CanonicalStringToBTH_LE_UUID(uuid);
+ BTH_LE_GATT_CHARACTERISTIC win_characteristic_info;
+ win_characteristic_info.CharacteristicUuid =
+ CanonicalStringToBTH_LE_UUID(uuid);
+ win_characteristic_info.IsBroadcastable = FALSE;
+ win_characteristic_info.IsReadable = FALSE;
+ win_characteristic_info.IsWritableWithoutResponse = FALSE;
+ win_characteristic_info.IsWritable = FALSE;
+ win_characteristic_info.IsNotifiable = FALSE;
+ win_characteristic_info.IsIndicatable = FALSE;
+ win_characteristic_info.IsSignedWritable = FALSE;
+ win_characteristic_info.HasExtendedProperties = FALSE;
if (properties & BluetoothGattCharacteristic::PROPERTY_BROADCAST)
- win_cha_info.IsBroadcastable = TRUE;
+ win_characteristic_info.IsBroadcastable = TRUE;
if (properties & BluetoothGattCharacteristic::PROPERTY_READ)
- win_cha_info.IsReadable = TRUE;
+ win_characteristic_info.IsReadable = TRUE;
if (properties & BluetoothGattCharacteristic::PROPERTY_WRITE_WITHOUT_RESPONSE)
- win_cha_info.IsWritableWithoutResponse = TRUE;
+ win_characteristic_info.IsWritableWithoutResponse = TRUE;
if (properties & BluetoothGattCharacteristic::PROPERTY_WRITE)
- win_cha_info.IsWritable = TRUE;
+ win_characteristic_info.IsWritable = TRUE;
if (properties & BluetoothGattCharacteristic::PROPERTY_NOTIFY)
- win_cha_info.IsNotifiable = TRUE;
+ win_characteristic_info.IsNotifiable = TRUE;
if (properties & BluetoothGattCharacteristic::PROPERTY_INDICATE)
- win_cha_info.IsIndicatable = TRUE;
+ win_characteristic_info.IsIndicatable = TRUE;
if (properties &
- BluetoothGattCharacteristic::PROPERTY_AUTHENTICATED_SIGNED_WRITES)
- win_cha_info.IsSignedWritable = TRUE;
+ BluetoothGattCharacteristic::PROPERTY_AUTHENTICATED_SIGNED_WRITES) {
+ win_characteristic_info.IsSignedWritable = TRUE;
+ }
if (properties & BluetoothGattCharacteristic::PROPERTY_EXTENDED_PROPERTIES)
- win_cha_info.HasExtendedProperties = TRUE;
- fake_bt_le_wrapper_->SimulateBLEGattCharacterisc(
- device_address, target_service, win_cha_info);
+ win_characteristic_info.HasExtendedProperties = TRUE;
+
+ fake_bt_le_wrapper_->SimulateGattCharacterisc(device_address, target_service,
+ win_characteristic_info);
ForceRefreshDevice();
}
@@ -262,20 +269,32 @@ void BluetoothTestWin::SimulateGattCharacteristicRemoved(
CHECK(characteristic);
std::string device_address = service->GetDevice()->GetAddress();
- win::BLEGattService* target_service = GetSimulatedService(
+ win::GattService* target_service = GetSimulatedService(
fake_bt_le_wrapper_->GetSimulatedBLEDevice(device_address), service);
CHECK(target_service);
std::string characteristic_att_handle = std::to_string(
static_cast<BluetoothRemoteGattCharacteristicWin*>(characteristic)
->GetAttributeHandle());
- fake_bt_le_wrapper_->SimulateBLEGattCharacteriscRemove(
+ fake_bt_le_wrapper_->SimulateGattCharacteriscRemove(
target_service, characteristic_att_handle);
ForceRefreshDevice();
}
-win::BLEGattService* BluetoothTestWin::GetSimulatedService(
+void BluetoothTestWin::SimulateGattDescriptor(
+ BluetoothGattCharacteristic* characteristic,
+ const std::string& uuid) {
+ win::GattCharacteristic* target_characteristic =
+ GetSimulatedCharacteristic(characteristic);
+ CHECK(target_characteristic);
+ fake_bt_le_wrapper_->SimulateGattDescriptor(
+ characteristic->GetService()->GetDevice()->GetAddress(),
+ target_characteristic, CanonicalStringToBTH_LE_UUID(uuid));
+ ForceRefreshDevice();
+}
+
+win::GattService* BluetoothTestWin::GetSimulatedService(
win::BLEDevice* device,
BluetoothGattService* service) {
CHECK(device);
@@ -287,16 +306,40 @@ win::BLEGattService* BluetoothTestWin::GetSimulatedService(
chain_of_att_handles.insert(
chain_of_att_handles.begin(),
std::to_string(win_service->GetAttributeHandle()));
- win::BLEGattService* simulated_service =
+ win::GattService* simulated_service =
fake_bt_le_wrapper_->GetSimulatedGattService(device,
chain_of_att_handles);
CHECK(simulated_service);
return simulated_service;
}
+win::GattCharacteristic* BluetoothTestWin::GetSimulatedCharacteristic(
+ BluetoothGattCharacteristic* characteristic) {
+ CHECK(characteristic);
+ BluetoothRemoteGattCharacteristicWin* win_characteristic =
+ static_cast<BluetoothRemoteGattCharacteristicWin*>(characteristic);
+
+ std::string device_address =
+ win_characteristic->GetService()->GetDevice()->GetAddress();
+ win::BLEDevice* target_device =
+ fake_bt_le_wrapper_->GetSimulatedBLEDevice(device_address);
+ if (target_device == nullptr)
+ return nullptr;
+ win::GattService* target_service =
+ GetSimulatedService(target_device, win_characteristic->GetService());
+ if (target_service == nullptr)
+ return nullptr;
+ return fake_bt_le_wrapper_->GetSimulatedGattCharacteristic(
+ target_service, std::to_string(win_characteristic->GetAttributeHandle()));
+}
+
void BluetoothTestWin::ForceRefreshDevice() {
adapter_win_->force_update_device_for_test_ = true;
+ FinishPendingTasks();
+}
+
+void BluetoothTestWin::FinishPendingTasks() {
bluetooth_task_runner_->RunPendingTasks();
- ui_task_runner_->RunPendingTasks();
+ base::RunLoop().RunUntilIdle();
}
}
diff --git a/device/bluetooth/test/bluetooth_test_win.h b/device/bluetooth/test/bluetooth_test_win.h
index f159235..d87bacc 100644
--- a/device/bluetooth/test/bluetooth_test_win.h
+++ b/device/bluetooth/test/bluetooth_test_win.h
@@ -41,6 +41,8 @@ class BluetoothTestWin : public BluetoothTestBase {
void SimulateGattCharacteristicRemoved(
BluetoothGattService* service,
BluetoothGattCharacteristic* characteristic) override;
+ void SimulateGattDescriptor(BluetoothGattCharacteristic* characteristic,
+ const std::string& uuid) override;
private:
scoped_refptr<base::TestSimpleTaskRunner> ui_task_runner_;
@@ -51,9 +53,12 @@ class BluetoothTestWin : public BluetoothTestBase {
win::BluetoothLowEnergyWrapperFake* fake_bt_le_wrapper_;
void AdapterInitCallback();
- win::BLEGattService* GetSimulatedService(win::BLEDevice* device,
- BluetoothGattService* service);
+ win::GattService* GetSimulatedService(win::BLEDevice* device,
+ BluetoothGattService* service);
+ win::GattCharacteristic* GetSimulatedCharacteristic(
+ BluetoothGattCharacteristic* characteristic);
void ForceRefreshDevice();
+ void FinishPendingTasks();
};
// Defines common test fixture name. Use TEST_F(BluetoothTest, YourTestName).