Implement read & write remote GATT characteristic value for Windows
This CL implements read & write remote GATT characteristic value for Windows and related unit tests.
BUG=579202
Review URL: https://codereview.chromium.org/1739383002
Cr-Commit-Position: refs/heads/master@{#379103}
diff --git a/device/bluetooth/bluetooth_remote_gatt_characteristic_win.cc b/device/bluetooth/bluetooth_remote_gatt_characteristic_win.cc
index baf4a73..d98c0ea 100644
--- a/device/bluetooth/bluetooth_remote_gatt_characteristic_win.cc
+++ b/device/bluetooth/bluetooth_remote_gatt_characteristic_win.cc
@@ -20,6 +20,7 @@
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 @@
}
std::vector<uint8_t>& BluetoothRemoteGattCharacteristicWin::GetValue() const {
- NOTIMPLEMENTED();
return const_cast<std::vector<uint8_t>&>(characteristic_value_);
}
@@ -147,16 +147,52 @@
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 @@
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:
+ case E_BLUETOOTH_ATT_INVALID_ATTRIBUTE_VALUE_LENGTH:
+ return BluetoothGattService::GATT_ERROR_INVALID_LENGTH;
+ default:
+ return BluetoothGattService::GATT_ERROR_FAILED;
+ }
+}
+
} // namespace device.