| 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 if (gatt_event_handle_ != nullptr) { |
| 48 task_manager_->PostUnregisterGattCharacteristicValueChangedEvent( |
| 49 gatt_event_handle_); |
| 50 gatt_event_handle_ = nullptr; |
| 51 } |
| 44 parent_service_->GetWinAdapter()->NotifyGattCharacteristicRemoved(this); | 52 parent_service_->GetWinAdapter()->NotifyGattCharacteristicRemoved(this); |
| 45 } | 53 } |
| 46 | 54 |
| 47 std::string BluetoothRemoteGattCharacteristicWin::GetIdentifier() const { | 55 std::string BluetoothRemoteGattCharacteristicWin::GetIdentifier() const { |
| 48 return characteristic_identifier_; | 56 return characteristic_identifier_; |
| 49 } | 57 } |
| 50 | 58 |
| 51 BluetoothUUID BluetoothRemoteGattCharacteristicWin::GetUUID() const { | 59 BluetoothUUID BluetoothRemoteGattCharacteristicWin::GetUUID() const { |
| 52 return characteristic_uuid_; | 60 return characteristic_uuid_; |
| 53 } | 61 } |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 98 | 106 |
| 99 if (characteristic_info_->IsReadable) | 107 if (characteristic_info_->IsReadable) |
| 100 permissions = permissions | PERMISSION_READ; | 108 permissions = permissions | PERMISSION_READ; |
| 101 if (characteristic_info_->IsWritable) | 109 if (characteristic_info_->IsWritable) |
| 102 permissions = permissions | PERMISSION_WRITE; | 110 permissions = permissions | PERMISSION_WRITE; |
| 103 | 111 |
| 104 return permissions; | 112 return permissions; |
| 105 } | 113 } |
| 106 | 114 |
| 107 bool BluetoothRemoteGattCharacteristicWin::IsNotifying() const { | 115 bool BluetoothRemoteGattCharacteristicWin::IsNotifying() const { |
| 108 NOTIMPLEMENTED(); | 116 return gatt_event_handle_ != nullptr; |
| 109 return false; | |
| 110 } | 117 } |
| 111 | 118 |
| 112 std::vector<BluetoothGattDescriptor*> | 119 std::vector<BluetoothGattDescriptor*> |
| 113 BluetoothRemoteGattCharacteristicWin::GetDescriptors() const { | 120 BluetoothRemoteGattCharacteristicWin::GetDescriptors() const { |
| 114 std::vector<BluetoothGattDescriptor*> descriptors; | 121 std::vector<BluetoothGattDescriptor*> descriptors; |
| 115 for (const auto& descriptor : included_descriptors_) | 122 for (const auto& descriptor : included_descriptors_) |
| 116 descriptors.push_back(descriptor.second.get()); | 123 descriptors.push_back(descriptor.second.get()); |
| 117 return descriptors; | 124 return descriptors; |
| 118 } | 125 } |
| 119 | 126 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 133 | 140 |
| 134 bool BluetoothRemoteGattCharacteristicWin::UpdateValue( | 141 bool BluetoothRemoteGattCharacteristicWin::UpdateValue( |
| 135 const std::vector<uint8_t>& value) { | 142 const std::vector<uint8_t>& value) { |
| 136 NOTIMPLEMENTED(); | 143 NOTIMPLEMENTED(); |
| 137 return false; | 144 return false; |
| 138 } | 145 } |
| 139 | 146 |
| 140 void BluetoothRemoteGattCharacteristicWin::StartNotifySession( | 147 void BluetoothRemoteGattCharacteristicWin::StartNotifySession( |
| 141 const NotifySessionCallback& callback, | 148 const NotifySessionCallback& callback, |
| 142 const ErrorCallback& error_callback) { | 149 const ErrorCallback& error_callback) { |
| 143 NOTIMPLEMENTED(); | 150 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| 144 error_callback.Run(BluetoothGattService::GATT_ERROR_NOT_SUPPORTED); | 151 |
| 152 if (IsNotifying()) { |
| 153 scoped_ptr<BluetoothGattNotifySessionWin> notify_session( |
| 154 new BluetoothGattNotifySessionWin(weak_ptr_factory_.GetWeakPtr())); |
| 155 ui_task_runner_->PostTask( |
| 156 FROM_HERE, |
| 157 base::Bind(callback, base::Passed(std::move(notify_session)))); |
| 158 return; |
| 159 } |
| 160 |
| 161 if (gatt_event_registeration_in_progress_) { |
| 162 start_notify_session_callbacks_.push_back( |
| 163 std::make_pair(callback, error_callback)); |
| 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 // TODO(crbug.com/594697): Check the existence of client characteristic |
| 176 // configuration descriptor. |
| 177 // Note: No need to write client characteristic configuration descriptor |
| 178 // explicitly to start notifications on Windows. |
| 179 |
| 180 start_notify_session_callbacks_.push_back( |
| 181 std::make_pair(callback, error_callback)); |
| 182 task_manager_->PostRegisterGattCharacteristicValueChangedEvent( |
| 183 parent_service_->GetServicePath(), characteristic_info_.get(), |
| 184 base::Bind( |
| 185 &BluetoothRemoteGattCharacteristicWin::GattEventRegistrationCallback, |
| 186 weak_ptr_factory_.GetWeakPtr()), |
| 187 base::Bind(&BluetoothRemoteGattCharacteristicWin:: |
| 188 OnGattCharacteristicValueChanged, |
| 189 weak_ptr_factory_.GetWeakPtr())); |
| 190 gatt_event_registeration_in_progress_ = true; |
| 145 } | 191 } |
| 146 | 192 |
| 147 void BluetoothRemoteGattCharacteristicWin::ReadRemoteCharacteristic( | 193 void BluetoothRemoteGattCharacteristicWin::ReadRemoteCharacteristic( |
| 148 const ValueCallback& callback, | 194 const ValueCallback& callback, |
| 149 const ErrorCallback& error_callback) { | 195 const ErrorCallback& error_callback) { |
| 150 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 196 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| 151 | 197 |
| 152 if (!characteristic_info_.get()->IsReadable) { | 198 if (!characteristic_info_.get()->IsReadable) { |
| 153 error_callback.Run(BluetoothGattService::GATT_ERROR_NOT_PERMITTED); | 199 error_callback.Run(BluetoothGattService::GATT_ERROR_NOT_PERMITTED); |
| 154 return; | 200 return; |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 317 if (FAILED(hr)) { | 363 if (FAILED(hr)) { |
| 318 callbacks.second.Run(HRESULTToGattErrorCode(hr)); | 364 callbacks.second.Run(HRESULTToGattErrorCode(hr)); |
| 319 } else { | 365 } else { |
| 320 callbacks.first.Run(); | 366 callbacks.first.Run(); |
| 321 } | 367 } |
| 322 characteristic_value_read_or_write_in_progress_ = false; | 368 characteristic_value_read_or_write_in_progress_ = false; |
| 323 } | 369 } |
| 324 | 370 |
| 325 BluetoothGattService::GattErrorCode | 371 BluetoothGattService::GattErrorCode |
| 326 BluetoothRemoteGattCharacteristicWin::HRESULTToGattErrorCode(HRESULT hr) { | 372 BluetoothRemoteGattCharacteristicWin::HRESULTToGattErrorCode(HRESULT hr) { |
| 373 if (HRESULT_FROM_WIN32(ERROR_INVALID_USER_BUFFER) == hr) |
| 374 return BluetoothGattService::GATT_ERROR_INVALID_LENGTH; |
| 375 |
| 327 switch (hr) { | 376 switch (hr) { |
| 328 case E_BLUETOOTH_ATT_READ_NOT_PERMITTED: | 377 case E_BLUETOOTH_ATT_READ_NOT_PERMITTED: |
| 329 case E_BLUETOOTH_ATT_WRITE_NOT_PERMITTED: | 378 case E_BLUETOOTH_ATT_WRITE_NOT_PERMITTED: |
| 330 return BluetoothGattService::GATT_ERROR_NOT_PERMITTED; | 379 return BluetoothGattService::GATT_ERROR_NOT_PERMITTED; |
| 331 case E_BLUETOOTH_ATT_UNKNOWN_ERROR: | 380 case E_BLUETOOTH_ATT_UNKNOWN_ERROR: |
| 332 return BluetoothGattService::GATT_ERROR_UNKNOWN; | 381 return BluetoothGattService::GATT_ERROR_UNKNOWN; |
| 333 case ERROR_INVALID_USER_BUFFER: | |
| 334 case E_BLUETOOTH_ATT_INVALID_ATTRIBUTE_VALUE_LENGTH: | 382 case E_BLUETOOTH_ATT_INVALID_ATTRIBUTE_VALUE_LENGTH: |
| 335 return BluetoothGattService::GATT_ERROR_INVALID_LENGTH; | 383 return BluetoothGattService::GATT_ERROR_INVALID_LENGTH; |
| 384 case E_BLUETOOTH_ATT_REQUEST_NOT_SUPPORTED: |
| 385 return BluetoothGattService::GATT_ERROR_NOT_SUPPORTED; |
| 336 default: | 386 default: |
| 337 return BluetoothGattService::GATT_ERROR_FAILED; | 387 return BluetoothGattService::GATT_ERROR_FAILED; |
| 338 } | 388 } |
| 339 } | 389 } |
| 340 | 390 |
| 391 void BluetoothRemoteGattCharacteristicWin::OnGattCharacteristicValueChanged( |
| 392 scoped_ptr<std::vector<uint8_t>> new_value) { |
| 393 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| 394 |
| 395 characteristic_value_.assign(new_value->begin(), new_value->end()); |
| 396 parent_service_->GetWinAdapter()->NotifyGattCharacteristicValueChanged( |
| 397 this, characteristic_value_); |
| 398 } |
| 399 |
| 400 void BluetoothRemoteGattCharacteristicWin::GattEventRegistrationCallback( |
| 401 BLUETOOTH_GATT_EVENT_HANDLE event_handle, |
| 402 HRESULT hr) { |
| 403 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| 404 |
| 405 gatt_event_registeration_in_progress_ = false; |
| 406 std::vector<std::pair<NotifySessionCallback, ErrorCallback>> callbacks; |
| 407 callbacks.swap(start_notify_session_callbacks_); |
| 408 if (SUCCEEDED(hr)) { |
| 409 gatt_event_handle_ = event_handle; |
| 410 for (const auto& callback : callbacks) { |
| 411 callback.first.Run(make_scoped_ptr( |
| 412 new BluetoothGattNotifySessionWin(weak_ptr_factory_.GetWeakPtr()))); |
| 413 } |
| 414 } else { |
| 415 for (const auto& callback : callbacks) |
| 416 callback.second.Run(HRESULTToGattErrorCode(hr)); |
| 417 } |
| 418 } |
| 419 |
| 341 } // namespace device. | 420 } // namespace device. |
| OLD | NEW |