diff options
Diffstat (limited to 'device/bluetooth/bluetooth_remote_gatt_characteristic_win.cc')
-rw-r--r-- | device/bluetooth/bluetooth_remote_gatt_characteristic_win.cc | 116 |
1 files changed, 103 insertions, 13 deletions
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. |