Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(225)

Unified Diff: device/bluetooth/bluetooth_remote_gatt_descriptor_mac.mm

Issue 2767813002: Bluetooth: macOS: Implementing read/write for descriptors (Closed)
Patch Set: . Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: device/bluetooth/bluetooth_remote_gatt_descriptor_mac.mm
diff --git a/device/bluetooth/bluetooth_remote_gatt_descriptor_mac.mm b/device/bluetooth/bluetooth_remote_gatt_descriptor_mac.mm
index 76cda0c349c19726f6917e40af48db3fd210a4a2..d7c5d6c79dcb403460c5868a6de1a14279e319de 100644
--- a/device/bluetooth/bluetooth_remote_gatt_descriptor_mac.mm
+++ b/device/bluetooth/bluetooth_remote_gatt_descriptor_mac.mm
@@ -4,19 +4,51 @@
#include "device/bluetooth/bluetooth_remote_gatt_descriptor_mac.h"
+#include "base/bind.h"
+#import "base/mac/foundation_util.h"
#include "base/strings/sys_string_conversions.h"
-#include "device/bluetooth/bluetooth_adapter_mac.h"
-#include "device/bluetooth/bluetooth_remote_gatt_characteristic_mac.h"
+#include "base/threading/thread_task_runner_handle.h"
+#import "device/bluetooth/bluetooth_adapter_mac.h"
+#import "device/bluetooth/bluetooth_remote_gatt_characteristic_mac.h"
+
+using base::mac::ObjCCast;
namespace device {
+std::vector<uint8_t> VectorValueFromObjC(id objc_value) {
+ // According to
+ // https://developer.apple.com/reference/corebluetooth/cbdescriptor some
+ // descriptor values can be NSData, NSString or NSNumber.
+ std::vector<uint8_t> value;
+ NSData* data = ObjCCast<NSData>(objc_value);
+ NSString* as_string = ObjCCast<NSString>(objc_value);
+ NSNumber* as_number = ObjCCast<NSNumber>(objc_value);
+
+ if (!data && !as_string && as_number) {
+ unsigned short descriptor = [as_number shortValue];
+ data = [NSData dataWithBytes:&descriptor length:sizeof(descriptor)];
+ }
+
+ if (!data && as_string)
+ data = [as_string dataUsingEncoding:NSUTF8StringEncoding];
+
+ if (data) {
+ value.resize([data length]);
+ [data getBytes:value.data() length:value.size()];
+ } else {
+ LOG(WARNING) << "Unexpected value: "
+ << base::SysNSStringToUTF8([objc_value description]);
+ }
+ return value;
+}
+
BluetoothRemoteGattDescriptorMac::BluetoothRemoteGattDescriptorMac(
BluetoothRemoteGattCharacteristicMac* characteristic,
CBDescriptor* descriptor)
: gatt_characteristic_(characteristic),
- cb_descriptor_(descriptor, base::scoped_policy::RETAIN) {
- uuid_ =
- BluetoothAdapterMac::BluetoothUUIDWithCBUUID([cb_descriptor_.get() UUID]);
+ cb_descriptor_(descriptor, base::scoped_policy::RETAIN),
+ value_read_or_write_in_progress_(false) {
+ uuid_ = BluetoothAdapterMac::BluetoothUUIDWithCBUUID([cb_descriptor_ UUID]);
identifier_ = base::SysNSStringToUTF8(
[NSString stringWithFormat:@"%s-%p", uuid_.canonical_value().c_str(),
(void*)cb_descriptor_]);
@@ -40,10 +72,19 @@ const std::vector<uint8_t>& BluetoothRemoteGattDescriptorMac::GetValue() const {
return value_;
}
-BluetoothRemoteGattDescriptorMac::~BluetoothRemoteGattDescriptorMac() {}
+BluetoothRemoteGattDescriptorMac::~BluetoothRemoteGattDescriptorMac() {
+ if (!read_value_callbacks_.first.is_null()) {
+ std::pair<ValueCallback, ErrorCallback> callbacks;
+ callbacks.swap(read_value_callbacks_);
+ callbacks.second.Run(BluetoothGattService::GATT_ERROR_FAILED);
+ }
+ if (!write_value_callbacks_.first.is_null()) {
+ std::pair<base::Closure, ErrorCallback> callbacks;
+ callbacks.swap(write_value_callbacks_);
+ callbacks.second.Run(BluetoothGattService::GATT_ERROR_FAILED);
+ }
+}
-// Returns a pointer to the GATT characteristic that this characteristic
-// descriptor belongs to.
BluetoothRemoteGattCharacteristic*
BluetoothRemoteGattDescriptorMac::GetCharacteristic() const {
return static_cast<BluetoothRemoteGattCharacteristic*>(gatt_characteristic_);
@@ -55,23 +96,91 @@ BluetoothRemoteGattDescriptorMac::GetCharacteristic() const {
void BluetoothRemoteGattDescriptorMac::ReadRemoteDescriptor(
const ValueCallback& callback,
const ErrorCallback& error_callback) {
- NOTIMPLEMENTED();
+ if (value_read_or_write_in_progress_) {
+ VLOG(1) << *this << ": Read failed, already in progress.";
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(error_callback,
+ BluetoothRemoteGattService::GATT_ERROR_IN_PROGRESS));
+ return;
+ }
+ VLOG(1) << *this << ": Read value.";
+ value_read_or_write_in_progress_ = true;
+ read_value_callbacks_ = std::make_pair(callback, error_callback);
+ [GetCBPeripheral() readValueForDescriptor:cb_descriptor_];
}
-// Sends a write request to a remote characteristic descriptor, to modify the
-// value of the descriptor with the new value |new_value|. |callback| is
-// called to signal success and |error_callback| for failures. This method
-// only applies to remote descriptors and will fail for those that are locally
-// hosted.
void BluetoothRemoteGattDescriptorMac::WriteRemoteDescriptor(
- const std::vector<uint8_t>& new_value,
+ const std::vector<uint8_t>& value,
const base::Closure& callback,
const ErrorCallback& error_callback) {
- NOTIMPLEMENTED();
+ if (value_read_or_write_in_progress_) {
+ VLOG(1) << *this << ": Write failed, already in progress.";
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(error_callback,
+ BluetoothRemoteGattService::GATT_ERROR_IN_PROGRESS));
+ return;
+ }
+ VLOG(1) << *this << ": Write value.";
+ value_read_or_write_in_progress_ = true;
+ write_value_callbacks_ = std::make_pair(callback, error_callback);
+ base::scoped_nsobject<NSData> nsdata_value(
+ [[NSData alloc] initWithBytes:value.data() length:value.size()]);
+ [GetCBPeripheral() writeValue:nsdata_value forDescriptor:GetCBDescriptor()];
+}
+
+void BluetoothRemoteGattDescriptorMac::DidUpdateValueForDescriptor(
+ NSError* error) {
+ if (!value_read_or_write_in_progress_) {
+ VLOG(1) << *this << ": Value updated, no read in progress.";
+ return;
+ }
+ std::pair<ValueCallback, ErrorCallback> callbacks;
+ callbacks.swap(read_value_callbacks_);
+ value_read_or_write_in_progress_ = false;
+ if (error) {
+ BluetoothGattService::GattErrorCode error_code =
+ BluetoothDeviceMac::GetGattErrorCodeFromNSError(error);
+ VLOG(1) << *this << ": Read value failed with error: "
+ << BluetoothAdapterMac::String(error)
+ << ", converted to error code: " << error_code;
+ callbacks.second.Run(error_code);
+ return;
+ }
+ VLOG(1) << *this << ": Value read.";
+ value_ = VectorValueFromObjC([cb_descriptor_ value]);
+ callbacks.first.Run(value_);
+}
+
+void BluetoothRemoteGattDescriptorMac::DidWriteValueForDescriptor(
+ NSError* error) {
+ if (!value_read_or_write_in_progress_) {
+ VLOG(1) << *this << ": Value written, no write in progress.";
+ return;
+ }
+ std::pair<base::Closure, ErrorCallback> callbacks;
+ callbacks.swap(write_value_callbacks_);
+ value_read_or_write_in_progress_ = false;
+ if (error) {
+ BluetoothGattService::GattErrorCode error_code =
+ BluetoothDeviceMac::GetGattErrorCodeFromNSError(error);
+ VLOG(1) << *this << ": Write value failed with error: "
+ << BluetoothAdapterMac::String(error)
+ << ", converted to error code: " << error_code;
+ callbacks.second.Run(error_code);
+ return;
+ }
+ VLOG(1) << *this << ": Value written.";
+ callbacks.first.Run();
+}
+
+CBPeripheral* BluetoothRemoteGattDescriptorMac::GetCBPeripheral() const {
+ return gatt_characteristic_->GetCBPeripheral();
}
CBDescriptor* BluetoothRemoteGattDescriptorMac::GetCBDescriptor() const {
- return cb_descriptor_.get();
+ return cb_descriptor_;
}
DEVICE_BLUETOOTH_EXPORT std::ostream& operator<<(
« no previous file with comments | « device/bluetooth/bluetooth_remote_gatt_descriptor_mac.h ('k') | device/bluetooth/bluetooth_remote_gatt_descriptor_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698