| Index: device/bluetooth/bluetooth_remote_gatt_characteristic_win.cc
|
| diff --git a/device/bluetooth/bluetooth_remote_gatt_characteristic_win.cc b/device/bluetooth/bluetooth_remote_gatt_characteristic_win.cc
|
| index 8f2a6d89303d0c73953674eab9b8c5cc06a01925..baf4a73467996ec9f7a2c7f90109cf8e859d1df0 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.
|
|
|