Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "device/bluetooth/bluetooth_remote_gatt_characteristic_win.h" | 5 #include "device/bluetooth/bluetooth_remote_gatt_characteristic_win.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "device/bluetooth/bluetooth_adapter_win.h" | 8 #include "device/bluetooth/bluetooth_adapter_win.h" |
| 9 #include "device/bluetooth/bluetooth_gatt_notify_session_win.h" | |
| 9 #include "device/bluetooth/bluetooth_remote_gatt_descriptor_win.h" | 10 #include "device/bluetooth/bluetooth_remote_gatt_descriptor_win.h" |
| 10 #include "device/bluetooth/bluetooth_remote_gatt_service_win.h" | 11 #include "device/bluetooth/bluetooth_remote_gatt_service_win.h" |
| 11 #include "device/bluetooth/bluetooth_task_manager_win.h" | 12 #include "device/bluetooth/bluetooth_task_manager_win.h" |
| 12 | 13 |
| 13 namespace device { | 14 namespace device { |
| 14 | 15 |
| 15 BluetoothRemoteGattCharacteristicWin::BluetoothRemoteGattCharacteristicWin( | 16 BluetoothRemoteGattCharacteristicWin::BluetoothRemoteGattCharacteristicWin( |
| 16 BluetoothRemoteGattServiceWin* parent_service, | 17 BluetoothRemoteGattServiceWin* parent_service, |
| 17 BTH_LE_GATT_CHARACTERISTIC* characteristic_info, | 18 BTH_LE_GATT_CHARACTERISTIC* characteristic_info, |
| 18 scoped_refptr<base::SequencedTaskRunner>& ui_task_runner) | 19 scoped_refptr<base::SequencedTaskRunner>& ui_task_runner) |
| 19 : parent_service_(parent_service), | 20 : parent_service_(parent_service), |
| 20 characteristic_info_(characteristic_info), | 21 characteristic_info_(characteristic_info), |
| 21 ui_task_runner_(ui_task_runner), | 22 ui_task_runner_(ui_task_runner), |
| 22 characteristic_added_notified_(false), | 23 characteristic_added_notified_(false), |
| 23 characteristic_value_read_or_write_in_progress_(false), | 24 characteristic_value_read_or_write_in_progress_(false), |
| 25 gatt_event_registeration_in_progress_(false), | |
| 26 gatt_event_handle_(nullptr), | |
| 24 weak_ptr_factory_(this) { | 27 weak_ptr_factory_(this) { |
| 25 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 28 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| 26 DCHECK(parent_service_); | 29 DCHECK(parent_service_); |
| 27 DCHECK(characteristic_info_); | 30 DCHECK(characteristic_info_); |
| 28 | 31 |
| 29 task_manager_ = | 32 task_manager_ = |
| 30 parent_service_->GetWinAdapter()->GetWinBluetoothTaskManager(); | 33 parent_service_->GetWinAdapter()->GetWinBluetoothTaskManager(); |
| 31 DCHECK(task_manager_); | 34 DCHECK(task_manager_); |
| 32 characteristic_uuid_ = | 35 characteristic_uuid_ = |
| 33 BluetoothTaskManagerWin::BluetoothLowEnergyUuidToBluetoothUuid( | 36 BluetoothTaskManagerWin::BluetoothLowEnergyUuidToBluetoothUuid( |
| 34 characteristic_info_->CharacteristicUuid); | 37 characteristic_info_->CharacteristicUuid); |
| 35 characteristic_identifier_ = | 38 characteristic_identifier_ = |
| 36 parent_service_->GetIdentifier() + "_" + | 39 parent_service_->GetIdentifier() + "_" + |
| 37 std::to_string(characteristic_info_->AttributeHandle); | 40 std::to_string(characteristic_info_->AttributeHandle); |
| 38 Update(); | 41 Update(); |
| 39 } | 42 } |
| 40 | 43 |
| 41 BluetoothRemoteGattCharacteristicWin::~BluetoothRemoteGattCharacteristicWin() { | 44 BluetoothRemoteGattCharacteristicWin::~BluetoothRemoteGattCharacteristicWin() { |
| 42 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 45 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| 43 | 46 |
| 47 ClearIncludedDescriptors(); | |
| 48 | |
| 49 if (gatt_event_handle_ != nullptr) { | |
| 50 task_manager_->PostUnregisterGattCharacteristicValueChangedEvent( | |
| 51 gatt_event_handle_); | |
| 52 gatt_event_handle_ = nullptr; | |
| 53 } | |
| 44 parent_service_->GetWinAdapter()->NotifyGattCharacteristicRemoved(this); | 54 parent_service_->GetWinAdapter()->NotifyGattCharacteristicRemoved(this); |
| 55 | |
| 56 // Clear pending StartNotifySession callbacks. | |
| 57 for (const auto& callback : start_notify_session_callbacks_) | |
| 58 callback.second.Run(BluetoothGattService::GATT_ERROR_FAILED); | |
| 45 } | 59 } |
| 46 | 60 |
| 47 std::string BluetoothRemoteGattCharacteristicWin::GetIdentifier() const { | 61 std::string BluetoothRemoteGattCharacteristicWin::GetIdentifier() const { |
| 48 return characteristic_identifier_; | 62 return characteristic_identifier_; |
| 49 } | 63 } |
| 50 | 64 |
| 51 BluetoothUUID BluetoothRemoteGattCharacteristicWin::GetUUID() const { | 65 BluetoothUUID BluetoothRemoteGattCharacteristicWin::GetUUID() const { |
| 52 return characteristic_uuid_; | 66 return characteristic_uuid_; |
| 53 } | 67 } |
| 54 | 68 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 98 | 112 |
| 99 if (characteristic_info_->IsReadable) | 113 if (characteristic_info_->IsReadable) |
| 100 permissions = permissions | PERMISSION_READ; | 114 permissions = permissions | PERMISSION_READ; |
| 101 if (characteristic_info_->IsWritable) | 115 if (characteristic_info_->IsWritable) |
| 102 permissions = permissions | PERMISSION_WRITE; | 116 permissions = permissions | PERMISSION_WRITE; |
| 103 | 117 |
| 104 return permissions; | 118 return permissions; |
| 105 } | 119 } |
| 106 | 120 |
| 107 bool BluetoothRemoteGattCharacteristicWin::IsNotifying() const { | 121 bool BluetoothRemoteGattCharacteristicWin::IsNotifying() const { |
| 108 NOTIMPLEMENTED(); | 122 return gatt_event_handle_ != nullptr; |
| 109 return false; | |
| 110 } | 123 } |
| 111 | 124 |
| 112 std::vector<BluetoothGattDescriptor*> | 125 std::vector<BluetoothGattDescriptor*> |
| 113 BluetoothRemoteGattCharacteristicWin::GetDescriptors() const { | 126 BluetoothRemoteGattCharacteristicWin::GetDescriptors() const { |
| 114 std::vector<BluetoothGattDescriptor*> descriptors; | 127 std::vector<BluetoothGattDescriptor*> descriptors; |
| 115 for (const auto& descriptor : included_descriptors_) | 128 for (const auto& descriptor : included_descriptors_) |
| 116 descriptors.push_back(descriptor.second.get()); | 129 descriptors.push_back(descriptor.second.get()); |
| 117 return descriptors; | 130 return descriptors; |
| 118 } | 131 } |
| 119 | 132 |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 133 | 146 |
| 134 bool BluetoothRemoteGattCharacteristicWin::UpdateValue( | 147 bool BluetoothRemoteGattCharacteristicWin::UpdateValue( |
| 135 const std::vector<uint8_t>& value) { | 148 const std::vector<uint8_t>& value) { |
| 136 NOTIMPLEMENTED(); | 149 NOTIMPLEMENTED(); |
| 137 return false; | 150 return false; |
| 138 } | 151 } |
| 139 | 152 |
| 140 void BluetoothRemoteGattCharacteristicWin::StartNotifySession( | 153 void BluetoothRemoteGattCharacteristicWin::StartNotifySession( |
| 141 const NotifySessionCallback& callback, | 154 const NotifySessionCallback& callback, |
| 142 const ErrorCallback& error_callback) { | 155 const ErrorCallback& error_callback) { |
| 143 NOTIMPLEMENTED(); | 156 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| 144 error_callback.Run(BluetoothGattService::GATT_ERROR_NOT_SUPPORTED); | 157 |
| 158 if (IsNotifying()) { | |
| 159 scoped_ptr<BluetoothGattNotifySessionWin> notify_session( | |
| 160 new BluetoothGattNotifySessionWin(weak_ptr_factory_.GetWeakPtr())); | |
| 161 ui_task_runner_->PostTask( | |
| 162 FROM_HERE, | |
| 163 base::Bind(callback, base::Passed(std::move(notify_session)))); | |
| 164 return; | |
| 165 } | |
| 166 | |
| 167 if (!characteristic_info_->IsNotifiable && | |
| 168 !characteristic_info_->IsIndicatable) { | |
| 169 ui_task_runner_->PostTask( | |
| 170 FROM_HERE, base::Bind(error_callback, | |
| 171 BluetoothGattService::GATT_ERROR_NOT_SUPPORTED)); | |
| 172 return; | |
| 173 } | |
| 174 | |
| 175 std::vector<BluetoothGattDescriptor*> ccc_descriptors = GetDescriptorsByUUID( | |
| 176 BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid()); | |
| 177 if (ccc_descriptors.size() < 1) { | |
| 178 ui_task_runner_->PostTask( | |
| 179 FROM_HERE, base::Bind(error_callback, | |
| 180 BluetoothGattService::GATT_ERROR_NOT_SUPPORTED)); | |
| 181 return; | |
| 182 } | |
| 183 if (ccc_descriptors.size() > 1) { | |
| 184 ui_task_runner_->PostTask( | |
| 185 FROM_HERE, | |
| 186 base::Bind(error_callback, BluetoothGattService::GATT_ERROR_FAILED)); | |
| 187 return; | |
| 188 } | |
| 189 | |
| 190 start_notify_session_callbacks_.push_back( | |
| 191 std::make_pair(callback, error_callback)); | |
| 192 if (gatt_event_registeration_in_progress_) | |
| 193 return; | |
| 194 | |
| 195 task_manager_->PostRegisterGattCharacteristicValueChangedEvent( | |
| 196 parent_service_->GetServicePath(), characteristic_info_.get(), | |
| 197 ((BluetoothRemoteGattDescriptorWin*)ccc_descriptors[0]) | |
|
ortuno
2016/03/31 18:09:19
static_cast<BluetoothRemoteGattDescriptorWin*>(ccc
gogerald1
2016/04/04 23:34:00
Done.
| |
| 198 ->GetWinDescriptorInfo(), | |
| 199 base::Bind( | |
| 200 &BluetoothRemoteGattCharacteristicWin::GattEventRegistrationCallback, | |
| 201 weak_ptr_factory_.GetWeakPtr()), | |
| 202 base::Bind(&BluetoothRemoteGattCharacteristicWin:: | |
| 203 OnGattCharacteristicValueChanged, | |
| 204 weak_ptr_factory_.GetWeakPtr())); | |
| 205 gatt_event_registeration_in_progress_ = true; | |
| 145 } | 206 } |
| 146 | 207 |
| 147 void BluetoothRemoteGattCharacteristicWin::ReadRemoteCharacteristic( | 208 void BluetoothRemoteGattCharacteristicWin::ReadRemoteCharacteristic( |
| 148 const ValueCallback& callback, | 209 const ValueCallback& callback, |
| 149 const ErrorCallback& error_callback) { | 210 const ErrorCallback& error_callback) { |
| 150 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 211 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| 151 | 212 |
| 152 if (!characteristic_info_.get()->IsReadable) { | 213 if (!characteristic_info_.get()->IsReadable) { |
| 153 error_callback.Run(BluetoothGattService::GATT_ERROR_NOT_PERMITTED); | 214 error_callback.Run(BluetoothGattService::GATT_ERROR_NOT_PERMITTED); |
| 154 return; | 215 return; |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 229 included_descriptors_.clear(); | 290 included_descriptors_.clear(); |
| 230 return; | 291 return; |
| 231 } | 292 } |
| 232 | 293 |
| 233 // First, remove descriptors that no longer exist. | 294 // First, remove descriptors that no longer exist. |
| 234 std::vector<std::string> to_be_removed; | 295 std::vector<std::string> to_be_removed; |
| 235 for (const auto& d : included_descriptors_) { | 296 for (const auto& d : included_descriptors_) { |
| 236 if (!DoesDescriptorExist(descriptors, num, d.second.get())) | 297 if (!DoesDescriptorExist(descriptors, num, d.second.get())) |
| 237 to_be_removed.push_back(d.second->GetIdentifier()); | 298 to_be_removed.push_back(d.second->GetIdentifier()); |
| 238 } | 299 } |
| 239 for (auto id : to_be_removed) | 300 for (auto id : to_be_removed) { |
| 301 included_descriptors_[id].reset(); | |
| 240 included_descriptors_.erase(id); | 302 included_descriptors_.erase(id); |
| 303 } | |
| 241 | 304 |
| 242 // Return if no new descriptors have been added. | 305 // Return if no new descriptors have been added. |
| 243 if (included_descriptors_.size() == num) | 306 if (included_descriptors_.size() == num) |
| 244 return; | 307 return; |
| 245 | 308 |
| 246 // Add new descriptors. | 309 // Add new descriptors. |
| 247 for (uint16_t i = 0; i < num; i++) { | 310 for (uint16_t i = 0; i < num; i++) { |
| 248 if (!IsDescriptorDiscovered(descriptors[i].DescriptorUuid, | 311 if (!IsDescriptorDiscovered(descriptors[i].DescriptorUuid, |
| 249 descriptors[i].AttributeHandle)) { | 312 descriptors[i].AttributeHandle)) { |
| 250 PBTH_LE_GATT_DESCRIPTOR win_descriptor_info = | 313 PBTH_LE_GATT_DESCRIPTOR win_descriptor_info = |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 317 if (FAILED(hr)) { | 380 if (FAILED(hr)) { |
| 318 callbacks.second.Run(HRESULTToGattErrorCode(hr)); | 381 callbacks.second.Run(HRESULTToGattErrorCode(hr)); |
| 319 } else { | 382 } else { |
| 320 callbacks.first.Run(); | 383 callbacks.first.Run(); |
| 321 } | 384 } |
| 322 characteristic_value_read_or_write_in_progress_ = false; | 385 characteristic_value_read_or_write_in_progress_ = false; |
| 323 } | 386 } |
| 324 | 387 |
| 325 BluetoothGattService::GattErrorCode | 388 BluetoothGattService::GattErrorCode |
| 326 BluetoothRemoteGattCharacteristicWin::HRESULTToGattErrorCode(HRESULT hr) { | 389 BluetoothRemoteGattCharacteristicWin::HRESULTToGattErrorCode(HRESULT hr) { |
| 390 if (HRESULT_FROM_WIN32(ERROR_INVALID_USER_BUFFER) == hr) | |
| 391 return BluetoothGattService::GATT_ERROR_INVALID_LENGTH; | |
| 392 | |
| 327 switch (hr) { | 393 switch (hr) { |
| 328 case E_BLUETOOTH_ATT_READ_NOT_PERMITTED: | 394 case E_BLUETOOTH_ATT_READ_NOT_PERMITTED: |
| 329 case E_BLUETOOTH_ATT_WRITE_NOT_PERMITTED: | 395 case E_BLUETOOTH_ATT_WRITE_NOT_PERMITTED: |
| 330 return BluetoothGattService::GATT_ERROR_NOT_PERMITTED; | 396 return BluetoothGattService::GATT_ERROR_NOT_PERMITTED; |
| 331 case E_BLUETOOTH_ATT_UNKNOWN_ERROR: | 397 case E_BLUETOOTH_ATT_UNKNOWN_ERROR: |
| 332 return BluetoothGattService::GATT_ERROR_UNKNOWN; | 398 return BluetoothGattService::GATT_ERROR_UNKNOWN; |
| 333 case ERROR_INVALID_USER_BUFFER: | |
| 334 case E_BLUETOOTH_ATT_INVALID_ATTRIBUTE_VALUE_LENGTH: | 399 case E_BLUETOOTH_ATT_INVALID_ATTRIBUTE_VALUE_LENGTH: |
| 335 return BluetoothGattService::GATT_ERROR_INVALID_LENGTH; | 400 return BluetoothGattService::GATT_ERROR_INVALID_LENGTH; |
| 401 case E_BLUETOOTH_ATT_REQUEST_NOT_SUPPORTED: | |
| 402 return BluetoothGattService::GATT_ERROR_NOT_SUPPORTED; | |
| 336 default: | 403 default: |
| 337 return BluetoothGattService::GATT_ERROR_FAILED; | 404 return BluetoothGattService::GATT_ERROR_FAILED; |
| 338 } | 405 } |
| 339 } | 406 } |
| 340 | 407 |
| 408 void BluetoothRemoteGattCharacteristicWin::OnGattCharacteristicValueChanged( | |
| 409 scoped_ptr<std::vector<uint8_t>> new_value) { | |
| 410 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | |
| 411 | |
| 412 characteristic_value_.assign(new_value->begin(), new_value->end()); | |
| 413 parent_service_->GetWinAdapter()->NotifyGattCharacteristicValueChanged( | |
| 414 this, characteristic_value_); | |
| 415 } | |
| 416 | |
| 417 void BluetoothRemoteGattCharacteristicWin::GattEventRegistrationCallback( | |
| 418 BLUETOOTH_GATT_EVENT_HANDLE event_handle, | |
| 419 HRESULT hr) { | |
| 420 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | |
| 421 | |
| 422 gatt_event_registeration_in_progress_ = false; | |
| 423 std::vector<std::pair<NotifySessionCallback, ErrorCallback>> callbacks; | |
| 424 callbacks.swap(start_notify_session_callbacks_); | |
| 425 if (SUCCEEDED(hr)) { | |
| 426 gatt_event_handle_ = event_handle; | |
| 427 for (const auto& callback : callbacks) { | |
| 428 callback.first.Run(make_scoped_ptr( | |
| 429 new BluetoothGattNotifySessionWin(weak_ptr_factory_.GetWeakPtr()))); | |
| 430 } | |
| 431 } else { | |
| 432 for (const auto& callback : callbacks) | |
| 433 callback.second.Run(HRESULTToGattErrorCode(hr)); | |
| 434 } | |
| 435 } | |
| 436 | |
| 437 void BluetoothRemoteGattCharacteristicWin::ClearIncludedDescriptors() { | |
| 438 // Explicitly reset to null to ensure that calling GetDescriptor() on the | |
| 439 // removed descriptor in GattDescriptorRemoved() returns null. | |
| 440 for (auto& entry : included_descriptors_) | |
| 441 entry.second.reset(); | |
| 442 included_descriptors_.clear(); | |
| 443 } | |
| 444 | |
| 341 } // namespace device. | 445 } // namespace device. |
| OLD | NEW |