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

Side by Side Diff: device/bluetooth/bluetooth_remote_gatt_descriptor_mac.mm

Issue 2767813002: Bluetooth: macOS: Implementing read/write for descriptors (Closed)
Patch Set: Adding NSError logs (and merge) 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 unified diff | Download patch
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 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_descriptor_mac.h" 5 #include "device/bluetooth/bluetooth_remote_gatt_descriptor_mac.h"
6 6
7 #include "base/bind.h"
8 #include "base/mac/foundation_util.h"
7 #include "base/strings/sys_string_conversions.h" 9 #include "base/strings/sys_string_conversions.h"
10 #include "base/threading/thread_task_runner_handle.h"
8 #include "device/bluetooth/bluetooth_adapter_mac.h" 11 #include "device/bluetooth/bluetooth_adapter_mac.h"
9 #include "device/bluetooth/bluetooth_remote_gatt_characteristic_mac.h" 12 #include "device/bluetooth/bluetooth_remote_gatt_characteristic_mac.h"
10 13
14 using base::mac::ObjCCast;
15
11 namespace device { 16 namespace device {
12 17
18 std::vector<uint8_t> VectorValueFromNSValue(id nsvalue) {
ortuno 2017/04/03 01:27:50 This name is pretty confusing since nsvalue is not
jlebel 2017/04/04 22:13:12 Done.
19 // According to
20 // https://developer.apple.com/reference/corebluetooth/cbdescriptor some of
ortuno 2017/04/03 01:27:50 We should handle all documented cases. It's certai
jlebel 2017/04/04 22:13:12 Done.
21 // the descriptor values should be NSNumber (like
22 // CBUUIDServerCharacteristicConfigurationString). But while testing, only
23 // NSString and NSData values were received.
24 std::vector<uint8_t> value;
25 if ([nsvalue isKindOfClass:[NSString class]]) {
26 NSString* string = ObjCCast<NSString>(nsvalue);
27 const uint8_t* buffer = (const uint8_t*)(string.UTF8String);
28 value.assign(buffer, buffer + string.length);
29 } else {
30 DCHECK([nsvalue isKindOfClass:[NSData class]]);
31 NSData* data = ObjCCast<NSData>(nsvalue);
32 const uint8_t* buffer = (const uint8_t*)(data.bytes);
33 value.assign(buffer, buffer + data.length);
34 }
ortuno 2017/04/03 01:27:50 Could we log the class if it's not one of the thre
jlebel 2017/04/04 22:13:12 Done.
35 return value;
36 }
37
13 BluetoothRemoteGattDescriptorMac::BluetoothRemoteGattDescriptorMac( 38 BluetoothRemoteGattDescriptorMac::BluetoothRemoteGattDescriptorMac(
14 BluetoothRemoteGattCharacteristicMac* characteristic, 39 BluetoothRemoteGattCharacteristicMac* characteristic,
15 CBDescriptor* descriptor) 40 CBDescriptor* descriptor)
16 : gatt_characteristic_(characteristic), 41 : gatt_characteristic_(characteristic),
17 cb_descriptor_(descriptor, base::scoped_policy::RETAIN) { 42 cb_descriptor_(descriptor, base::scoped_policy::RETAIN) {
18 uuid_ = 43 uuid_ =
19 BluetoothAdapterMac::BluetoothUUIDWithCBUUID([cb_descriptor_.get() UUID]); 44 BluetoothAdapterMac::BluetoothUUIDWithCBUUID([cb_descriptor_.get() UUID]);
20 identifier_ = base::SysNSStringToUTF8( 45 identifier_ = base::SysNSStringToUTF8(
21 [NSString stringWithFormat:@"%s-%p", uuid_.canonical_value().c_str(), 46 [NSString stringWithFormat:@"%s-%p", uuid_.canonical_value().c_str(),
22 (void*)cb_descriptor_]); 47 (void*)cb_descriptor_]);
(...skipping 10 matching lines...) Expand all
33 BluetoothGattCharacteristic::Permissions 58 BluetoothGattCharacteristic::Permissions
34 BluetoothRemoteGattDescriptorMac::GetPermissions() const { 59 BluetoothRemoteGattDescriptorMac::GetPermissions() const {
35 NOTIMPLEMENTED(); 60 NOTIMPLEMENTED();
36 return BluetoothGattCharacteristic::PERMISSION_NONE; 61 return BluetoothGattCharacteristic::PERMISSION_NONE;
37 } 62 }
38 63
39 const std::vector<uint8_t>& BluetoothRemoteGattDescriptorMac::GetValue() const { 64 const std::vector<uint8_t>& BluetoothRemoteGattDescriptorMac::GetValue() const {
40 return value_; 65 return value_;
41 } 66 }
42 67
43 BluetoothRemoteGattDescriptorMac::~BluetoothRemoteGattDescriptorMac() {} 68 BluetoothRemoteGattDescriptorMac::~BluetoothRemoteGattDescriptorMac() {}
ortuno 2017/04/03 04:51:46 We need to call pending error callbacks when the o
jlebel 2017/04/04 22:13:12 Done.
44 69
45 // Returns a pointer to the GATT characteristic that this characteristic 70 // Returns a pointer to the GATT characteristic that this characteristic
46 // descriptor belongs to. 71 // descriptor belongs to.
47 BluetoothRemoteGattCharacteristic* 72 BluetoothRemoteGattCharacteristic*
48 BluetoothRemoteGattDescriptorMac::GetCharacteristic() const { 73 BluetoothRemoteGattDescriptorMac::GetCharacteristic() const {
49 return static_cast<BluetoothRemoteGattCharacteristic*>(gatt_characteristic_); 74 return static_cast<BluetoothRemoteGattCharacteristic*>(gatt_characteristic_);
50 } 75 }
51 76
52 // Sends a read request to a remote characteristic descriptor to read its 77 // Sends a read request to a remote characteristic descriptor to read its
53 // value. |callback| is called to return the read value on success and 78 // value. |callback| is called to return the read value on success and
54 // |error_callback| is called for failures. 79 // |error_callback| is called for failures.
55 void BluetoothRemoteGattDescriptorMac::ReadRemoteDescriptor( 80 void BluetoothRemoteGattDescriptorMac::ReadRemoteDescriptor(
56 const ValueCallback& callback, 81 const ValueCallback& callback,
57 const ErrorCallback& error_callback) { 82 const ErrorCallback& error_callback) {
58 NOTIMPLEMENTED(); 83 if (value_read_or_write_in_progress_) {
84 VLOG(1) << *this << ": Read failed, already in progress.";
85 base::ThreadTaskRunnerHandle::Get()->PostTask(
86 FROM_HERE,
87 base::Bind(error_callback,
88 BluetoothRemoteGattService::GATT_ERROR_IN_PROGRESS));
89 return;
90 }
91 VLOG(1) << *this << ": Read value.";
92 value_read_or_write_in_progress_ = true;
93 read_value_callbacks_ = std::make_pair(callback, error_callback);
94 [GetCBPeripheral() readValueForDescriptor:cb_descriptor_];
59 } 95 }
60 96
61 // Sends a write request to a remote characteristic descriptor, to modify the 97 // Sends a write request to a remote characteristic descriptor, to modify the
ortuno 2017/04/03 01:27:50 Why do we need this comment?
jlebel 2017/04/04 22:13:12 Done.
62 // value of the descriptor with the new value |new_value|. |callback| is 98 // value of the descriptor with the new value |value|. |callback| is called to
63 // called to signal success and |error_callback| for failures. This method 99 // signal success and |error_callback| for failures. This method only applies to
64 // only applies to remote descriptors and will fail for those that are locally 100 // remote descriptors and will fail for those that are locally hosted.
65 // hosted.
66 void BluetoothRemoteGattDescriptorMac::WriteRemoteDescriptor( 101 void BluetoothRemoteGattDescriptorMac::WriteRemoteDescriptor(
67 const std::vector<uint8_t>& new_value, 102 const std::vector<uint8_t>& value,
68 const base::Closure& callback, 103 const base::Closure& callback,
69 const ErrorCallback& error_callback) { 104 const ErrorCallback& error_callback) {
70 NOTIMPLEMENTED(); 105 if (value_read_or_write_in_progress_) {
106 VLOG(1) << *this << ": Write failed, already in progress.";
107 base::ThreadTaskRunnerHandle::Get()->PostTask(
108 FROM_HERE,
109 base::Bind(error_callback,
110 BluetoothRemoteGattService::GATT_ERROR_IN_PROGRESS));
111 return;
112 }
113 VLOG(1) << *this << ": Write value.";
114 value_read_or_write_in_progress_ = true;
115 write_value_callbacks_ = std::make_pair(callback, error_callback);
116 base::scoped_nsobject<NSData> nsdata_value(
117 [[NSData alloc] initWithBytes:value.data() length:value.size()]);
118 [GetCBPeripheral() writeValue:nsdata_value forDescriptor:GetCBDescriptor()];
119 }
120
121 void BluetoothRemoteGattDescriptorMac::DidUpdateValueForDescriptor(
122 NSError* error) {
123 if (!value_read_or_write_in_progress_) {
124 VLOG(1) << *this << ": Value updated, no read in progress.";
125 return;
126 }
127 std::pair<ValueCallback, ErrorCallback> callbacks;
128 callbacks.swap(read_value_callbacks_);
129 value_read_or_write_in_progress_ = false;
130 if (error) {
131 BluetoothGattService::GattErrorCode error_code =
132 BluetoothDeviceMac::GetGattErrorCodeFromNSError(error);
133 VLOG(1) << *this << ": Read value failed with error: "
134 << BluetoothAdapterMac::String(error)
ortuno 2017/04/03 01:27:50 Didn't we have a patch to make it easier to print
jlebel 2017/04/04 22:13:12 I did that: crrev.com/2745323002 crrev.com/2784373
135 << ", converted to error code: " << error_code;
136 callbacks.second.Run(error_code);
137 return;
138 }
139 VLOG(1) << *this << ": Value updated.";
ortuno 2017/04/03 01:27:50 nit: Value read.
jlebel 2017/04/04 22:13:12 Done.
140 value_ = VectorValueFromNSValue(cb_descriptor_.get().value);
141 callbacks.first.Run(value_);
142 }
143
144 void BluetoothRemoteGattDescriptorMac::DidWriteValueForDescriptor(
145 NSError* error) {
146 if (!value_read_or_write_in_progress_) {
147 VLOG(1) << *this << ": Value written, no write in progress.";
148 return;
149 }
150 std::pair<base::Closure, ErrorCallback> callbacks;
151 callbacks.swap(write_value_callbacks_);
152 value_read_or_write_in_progress_ = false;
153 if (error) {
154 BluetoothGattService::GattErrorCode error_code =
155 BluetoothDeviceMac::GetGattErrorCodeFromNSError(error);
156 VLOG(1) << *this << ": Write value failed with error: "
157 << BluetoothAdapterMac::String(error)
158 << ", converted to error code: " << error_code;
159 callbacks.second.Run(error_code);
160 return;
161 }
162 VLOG(1) << *this << ": Value updated.";
ortuno 2017/04/03 01:27:50 nit: Value written.
jlebel 2017/04/04 22:13:12 Done.
163 callbacks.first.Run();
164 }
165
166 CBPeripheral* BluetoothRemoteGattDescriptorMac::GetCBPeripheral() const {
167 return gatt_characteristic_->GetCBPeripheral();
71 } 168 }
72 169
73 CBDescriptor* BluetoothRemoteGattDescriptorMac::GetCBDescriptor() const { 170 CBDescriptor* BluetoothRemoteGattDescriptorMac::GetCBDescriptor() const {
74 return cb_descriptor_.get(); 171 return cb_descriptor_.get();
75 } 172 }
76 173
77 DEVICE_BLUETOOTH_EXPORT std::ostream& operator<<( 174 DEVICE_BLUETOOTH_EXPORT std::ostream& operator<<(
78 std::ostream& out, 175 std::ostream& out,
79 const BluetoothRemoteGattDescriptorMac& descriptor) { 176 const BluetoothRemoteGattDescriptorMac& descriptor) {
80 const BluetoothRemoteGattCharacteristicMac* characteristic_mac = 177 const BluetoothRemoteGattCharacteristicMac* characteristic_mac =
81 static_cast<const BluetoothRemoteGattCharacteristicMac*>( 178 static_cast<const BluetoothRemoteGattCharacteristicMac*>(
82 descriptor.GetCharacteristic()); 179 descriptor.GetCharacteristic());
83 return out << "<BluetoothRemoteGattServiceMac " 180 return out << "<BluetoothRemoteGattServiceMac "
84 << descriptor.GetUUID().canonical_value() << "/" << &descriptor 181 << descriptor.GetUUID().canonical_value() << "/" << &descriptor
85 << ", characteristic: " 182 << ", characteristic: "
86 << characteristic_mac->GetUUID().canonical_value() << "/" 183 << characteristic_mac->GetUUID().canonical_value() << "/"
87 << characteristic_mac << ">"; 184 << characteristic_mac << ">";
88 } 185 }
89 186
90 } // namespace device. 187 } // namespace device.
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698