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 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 | |
| 178 start_notify_session_callbacks_.push_back( | |
| 179 std::make_pair(callback, error_callback)); | |
| 180 task_manager_->PostRegisterGattCharacteristicValueChangedEvent( | |
| 181 parent_service_->GetServicePath(), characteristic_info_.get(), | |
| 182 base::Bind( | |
| 183 &BluetoothRemoteGattCharacteristicWin::GattEventRegistrationCallback, | |
| 184 weak_ptr_factory_.GetWeakPtr()), | |
| 185 base::Bind(&BluetoothRemoteGattCharacteristicWin:: | |
| 186 OnGattCharacteristicValueChanged, | |
| 187 weak_ptr_factory_.GetWeakPtr())); | |
| 188 gatt_event_registeration_in_progress_ = true; | |
| 145 } | 189 } |
| 146 | 190 |
| 147 void BluetoothRemoteGattCharacteristicWin::ReadRemoteCharacteristic( | 191 void BluetoothRemoteGattCharacteristicWin::ReadRemoteCharacteristic( |
| 148 const ValueCallback& callback, | 192 const ValueCallback& callback, |
| 149 const ErrorCallback& error_callback) { | 193 const ErrorCallback& error_callback) { |
| 150 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 194 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| 151 | 195 |
| 152 if (!characteristic_info_.get()->IsReadable) { | 196 if (!characteristic_info_.get()->IsReadable) { |
| 153 error_callback.Run(BluetoothGattService::GATT_ERROR_NOT_PERMITTED); | 197 error_callback.Run(BluetoothGattService::GATT_ERROR_NOT_PERMITTED); |
| 154 return; | 198 return; |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 317 if (FAILED(hr)) { | 361 if (FAILED(hr)) { |
| 318 callbacks.second.Run(HRESULTToGattErrorCode(hr)); | 362 callbacks.second.Run(HRESULTToGattErrorCode(hr)); |
| 319 } else { | 363 } else { |
| 320 callbacks.first.Run(); | 364 callbacks.first.Run(); |
| 321 } | 365 } |
| 322 characteristic_value_read_or_write_in_progress_ = false; | 366 characteristic_value_read_or_write_in_progress_ = false; |
| 323 } | 367 } |
| 324 | 368 |
| 325 BluetoothGattService::GattErrorCode | 369 BluetoothGattService::GattErrorCode |
| 326 BluetoothRemoteGattCharacteristicWin::HRESULTToGattErrorCode(HRESULT hr) { | 370 BluetoothRemoteGattCharacteristicWin::HRESULTToGattErrorCode(HRESULT hr) { |
| 371 if (HRESULT_FROM_WIN32(ERROR_INVALID_USER_BUFFER) == hr) | |
| 372 return BluetoothGattService::GATT_ERROR_INVALID_LENGTH; | |
| 373 | |
| 327 switch (hr) { | 374 switch (hr) { |
| 328 case E_BLUETOOTH_ATT_READ_NOT_PERMITTED: | 375 case E_BLUETOOTH_ATT_READ_NOT_PERMITTED: |
| 329 case E_BLUETOOTH_ATT_WRITE_NOT_PERMITTED: | 376 case E_BLUETOOTH_ATT_WRITE_NOT_PERMITTED: |
| 330 return BluetoothGattService::GATT_ERROR_NOT_PERMITTED; | 377 return BluetoothGattService::GATT_ERROR_NOT_PERMITTED; |
| 331 case E_BLUETOOTH_ATT_UNKNOWN_ERROR: | 378 case E_BLUETOOTH_ATT_UNKNOWN_ERROR: |
| 332 return BluetoothGattService::GATT_ERROR_UNKNOWN; | 379 return BluetoothGattService::GATT_ERROR_UNKNOWN; |
| 333 case ERROR_INVALID_USER_BUFFER: | |
| 334 case E_BLUETOOTH_ATT_INVALID_ATTRIBUTE_VALUE_LENGTH: | 380 case E_BLUETOOTH_ATT_INVALID_ATTRIBUTE_VALUE_LENGTH: |
| 335 return BluetoothGattService::GATT_ERROR_INVALID_LENGTH; | 381 return BluetoothGattService::GATT_ERROR_INVALID_LENGTH; |
| 382 case E_BLUETOOTH_ATT_REQUEST_NOT_SUPPORTED: | |
| 383 return BluetoothGattService::GATT_ERROR_NOT_SUPPORTED; | |
| 336 default: | 384 default: |
| 337 return BluetoothGattService::GATT_ERROR_FAILED; | 385 return BluetoothGattService::GATT_ERROR_FAILED; |
| 338 } | 386 } |
| 339 } | 387 } |
| 340 | 388 |
| 389 void BluetoothRemoteGattCharacteristicWin::OnGattCharacteristicValueChanged( | |
| 390 scoped_ptr<std::vector<uint8_t>> new_value) { | |
| 391 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | |
| 392 | |
| 393 // Ignore notification if no active notify session exist. This could happen | |
| 394 // since PostUnregisterGattCharacteristicValueChangedEvent is asynchronous. | |
| 395 if (!IsNotifying()) | |
|
ortuno
2016/03/15 02:55:31
I don't think you need this. The only time gatt_ev
gogerald1
2016/03/15 18:28:22
Done. Residual of removing stop notify session.
| |
| 396 return; | |
| 397 characteristic_value_.assign(new_value->begin(), new_value->end()); | |
| 398 parent_service_->GetWinAdapter()->NotifyGattCharacteristicValueChanged( | |
| 399 this, characteristic_value_); | |
| 400 } | |
| 401 | |
| 402 void BluetoothRemoteGattCharacteristicWin::GattEventRegistrationCallback( | |
| 403 BLUETOOTH_GATT_EVENT_HANDLE event_handle, | |
| 404 HRESULT hr) { | |
| 405 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | |
| 406 | |
| 407 gatt_event_registeration_in_progress_ = false; | |
| 408 std::vector<std::pair<NotifySessionCallback, ErrorCallback>> callbacks; | |
| 409 callbacks.swap(start_notify_session_callbacks_); | |
| 410 if (SUCCEEDED(hr)) { | |
| 411 gatt_event_handle_ = event_handle; | |
| 412 for (const auto& callback : callbacks) { | |
| 413 callback.first.Run(make_scoped_ptr( | |
| 414 new BluetoothGattNotifySessionWin(weak_ptr_factory_.GetWeakPtr()))); | |
| 415 } | |
| 416 } else { | |
| 417 for (const auto& callback : callbacks) | |
| 418 callback.second.Run(HRESULTToGattErrorCode(hr)); | |
| 419 } | |
| 420 } | |
| 421 | |
| 341 } // namespace device. | 422 } // namespace device. |
| OLD | NEW |