Chromium Code Reviews| 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 baf4a73467996ec9f7a2c7f90109cf8e859d1df0..d98c0ea8d2fcb7f5709672d03305dee3076abfe7 100644 |
| --- a/device/bluetooth/bluetooth_remote_gatt_characteristic_win.cc |
| +++ b/device/bluetooth/bluetooth_remote_gatt_characteristic_win.cc |
| @@ -20,6 +20,7 @@ BluetoothRemoteGattCharacteristicWin::BluetoothRemoteGattCharacteristicWin( |
| characteristic_info_(characteristic_info), |
| ui_task_runner_(ui_task_runner), |
| characteristic_added_notified_(false), |
| + characteristic_value_read_or_write_in_progress_(false), |
| weak_ptr_factory_(this) { |
| DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| DCHECK(parent_service_); |
| @@ -56,7 +57,6 @@ bool BluetoothRemoteGattCharacteristicWin::IsLocal() const { |
| } |
| std::vector<uint8_t>& BluetoothRemoteGattCharacteristicWin::GetValue() const { |
| - NOTIMPLEMENTED(); |
| return const_cast<std::vector<uint8_t>&>(characteristic_value_); |
| } |
| @@ -147,16 +147,52 @@ void BluetoothRemoteGattCharacteristicWin::StartNotifySession( |
| void BluetoothRemoteGattCharacteristicWin::ReadRemoteCharacteristic( |
| const ValueCallback& callback, |
| const ErrorCallback& error_callback) { |
| - NOTIMPLEMENTED(); |
| - error_callback.Run(BluetoothGattService::GATT_ERROR_NOT_SUPPORTED); |
| + DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| + |
| + if (!characteristic_info_.get()->IsReadable) { |
| + error_callback.Run(BluetoothGattService::GATT_ERROR_NOT_PERMITTED); |
| + return; |
| + } |
| + |
| + if (characteristic_value_read_or_write_in_progress_) { |
| + error_callback.Run(BluetoothGattService::GATT_ERROR_IN_PROGRESS); |
| + return; |
| + } |
| + |
| + characteristic_value_read_or_write_in_progress_ = true; |
| + read_characteristic_value_callbacks_ = |
| + std::make_pair(callback, error_callback); |
| + task_manager_->PostReadGattCharacteristicValue( |
| + parent_service_->GetServicePath(), characteristic_info_.get(), |
| + base::Bind(&BluetoothRemoteGattCharacteristicWin:: |
| + OnReadRemoteCharacteristicValueCallback, |
| + weak_ptr_factory_.GetWeakPtr())); |
| } |
| void BluetoothRemoteGattCharacteristicWin::WriteRemoteCharacteristic( |
| const std::vector<uint8_t>& new_value, |
| const base::Closure& callback, |
| const ErrorCallback& error_callback) { |
| - NOTIMPLEMENTED(); |
| - error_callback.Run(BluetoothGattService::GATT_ERROR_NOT_SUPPORTED); |
| + DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| + |
| + if (!characteristic_info_.get()->IsWritable) { |
| + error_callback.Run(BluetoothGattService::GATT_ERROR_NOT_PERMITTED); |
| + return; |
| + } |
| + |
| + if (characteristic_value_read_or_write_in_progress_) { |
| + error_callback.Run(BluetoothGattService::GATT_ERROR_IN_PROGRESS); |
| + return; |
| + } |
| + |
| + characteristic_value_read_or_write_in_progress_ = true; |
| + write_characteristic_value_callbacks_ = |
| + std::make_pair(callback, error_callback); |
| + task_manager_->PostWriteGattCharacteristicValue( |
| + parent_service_->GetServicePath(), characteristic_info_.get(), new_value, |
| + base::Bind(&BluetoothRemoteGattCharacteristicWin:: |
| + OnWriteRemoteCharacteristicValueCallback, |
| + weak_ptr_factory_.GetWeakPtr())); |
| } |
| void BluetoothRemoteGattCharacteristicWin::Update() { |
| @@ -253,4 +289,53 @@ bool BluetoothRemoteGattCharacteristicWin::DoesDescriptorExist( |
| return false; |
| } |
| +void BluetoothRemoteGattCharacteristicWin:: |
| + OnReadRemoteCharacteristicValueCallback( |
| + scoped_ptr<BTH_LE_GATT_CHARACTERISTIC_VALUE> value, |
| + HRESULT hr) { |
| + DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| + |
| + std::pair<ValueCallback, ErrorCallback> callbacks; |
| + callbacks.swap(read_characteristic_value_callbacks_); |
| + if (FAILED(hr)) { |
| + callbacks.second.Run(HRESULTToGattErrorCode(hr)); |
| + } else { |
| + characteristic_value_.clear(); |
| + for (ULONG i = 0; i < value->DataSize; i++) |
| + characteristic_value_.push_back(value->Data[i]); |
| + callbacks.first.Run(characteristic_value_); |
| + } |
| + characteristic_value_read_or_write_in_progress_ = false; |
| +} |
| + |
| +void BluetoothRemoteGattCharacteristicWin:: |
| + OnWriteRemoteCharacteristicValueCallback(HRESULT hr) { |
| + DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| + |
| + std::pair<base::Closure, ErrorCallback> callbacks; |
| + callbacks.swap(write_characteristic_value_callbacks_); |
| + if (FAILED(hr)) { |
| + callbacks.second.Run(HRESULTToGattErrorCode(hr)); |
| + } else { |
| + callbacks.first.Run(); |
| + } |
| + characteristic_value_read_or_write_in_progress_ = false; |
| +} |
| + |
| +BluetoothGattService::GattErrorCode |
| +BluetoothRemoteGattCharacteristicWin::HRESULTToGattErrorCode(HRESULT hr) { |
| + switch (hr) { |
| + case E_BLUETOOTH_ATT_READ_NOT_PERMITTED: |
| + case E_BLUETOOTH_ATT_WRITE_NOT_PERMITTED: |
| + return BluetoothGattService::GATT_ERROR_NOT_PERMITTED; |
| + case E_BLUETOOTH_ATT_UNKNOWN_ERROR: |
| + return BluetoothGattService::GATT_ERROR_UNKNOWN; |
| + case ERROR_INVALID_USER_BUFFER: |
|
brucedawson
2016/03/08 02:03:57
This is a semantically invalid case statement. I o
|
| + case E_BLUETOOTH_ATT_INVALID_ATTRIBUTE_VALUE_LENGTH: |
| + return BluetoothGattService::GATT_ERROR_INVALID_LENGTH; |
| + default: |
| + return BluetoothGattService::GATT_ERROR_FAILED; |
| + } |
| +} |
| + |
| } // namespace device. |