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. |