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

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

Issue 2767813002: Bluetooth: macOS: Implementing read/write for descriptors (Closed)
Patch Set: Removing CFNumberGetByteSize() 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 #import "base/mac/foundation_util.h"
7 #include "base/strings/sys_string_conversions.h" 9 #include "base/strings/sys_string_conversions.h"
8 #include "device/bluetooth/bluetooth_adapter_mac.h" 10 #include "base/threading/thread_task_runner_handle.h"
9 #include "device/bluetooth/bluetooth_remote_gatt_characteristic_mac.h" 11 #import "device/bluetooth/bluetooth_adapter_mac.h"
12 #import "device/bluetooth/bluetooth_remote_gatt_characteristic_mac.h"
13
14 using base::mac::ObjCCast;
10 15
11 namespace device { 16 namespace device {
12 17
18 std::vector<uint8_t> VectorValueFromObjC(id objc_value) {
19 // According to
20 // https://developer.apple.com/reference/corebluetooth/cbdescriptor some
21 // descriptor values can be NSData, NSString or NSNumber.
22 std::vector<uint8_t> value;
23 NSData* data = ObjCCast<NSData>(objc_value);
24 NSString* as_string = ObjCCast<NSString>(objc_value);
25 NSNumber* as_number = ObjCCast<NSNumber>(objc_value);
26
27 if (!data && !as_string && as_number) {
28 unsigned short descriptor = [as_number shortValue];
29 data = [NSData dataWithBytes:&descriptor length:sizeof(descriptor)];
30 }
31
32 if (!data && as_string)
33 data = [as_string dataUsingEncoding:NSUTF8StringEncoding];
34
35 DCHECK(data) << "Unexpected value: "
ortuno 2017/04/10 01:52:11 Can we log this?
ortuno 2017/04/10 23:36:39 DCHECK usually signals that that case will never h
jlebel 2017/04/11 18:48:18 Done.
36 << base::SysNSStringToUTF8([objc_value description]);
37 if (data) {
38 value.resize([data length]);
39 [data getBytes:value.data() length:value.size()];
40 }
41 return value;
42 }
43
13 BluetoothRemoteGattDescriptorMac::BluetoothRemoteGattDescriptorMac( 44 BluetoothRemoteGattDescriptorMac::BluetoothRemoteGattDescriptorMac(
14 BluetoothRemoteGattCharacteristicMac* characteristic, 45 BluetoothRemoteGattCharacteristicMac* characteristic,
15 CBDescriptor* descriptor) 46 CBDescriptor* descriptor)
16 : gatt_characteristic_(characteristic), 47 : gatt_characteristic_(characteristic),
17 cb_descriptor_(descriptor, base::scoped_policy::RETAIN) { 48 cb_descriptor_(descriptor, base::scoped_policy::RETAIN),
18 uuid_ = 49 value_read_or_write_in_progress_(false) {
19 BluetoothAdapterMac::BluetoothUUIDWithCBUUID([cb_descriptor_.get() UUID]); 50 uuid_ = BluetoothAdapterMac::BluetoothUUIDWithCBUUID([cb_descriptor_ UUID]);
20 identifier_ = base::SysNSStringToUTF8( 51 identifier_ = base::SysNSStringToUTF8(
21 [NSString stringWithFormat:@"%s-%p", uuid_.canonical_value().c_str(), 52 [NSString stringWithFormat:@"%s-%p", uuid_.canonical_value().c_str(),
22 (void*)cb_descriptor_]); 53 (void*)cb_descriptor_]);
23 } 54 }
24 55
25 std::string BluetoothRemoteGattDescriptorMac::GetIdentifier() const { 56 std::string BluetoothRemoteGattDescriptorMac::GetIdentifier() const {
26 return identifier_; 57 return identifier_;
27 } 58 }
28 59
29 BluetoothUUID BluetoothRemoteGattDescriptorMac::GetUUID() const { 60 BluetoothUUID BluetoothRemoteGattDescriptorMac::GetUUID() const {
30 return uuid_; 61 return uuid_;
31 } 62 }
32 63
33 BluetoothGattCharacteristic::Permissions 64 BluetoothGattCharacteristic::Permissions
34 BluetoothRemoteGattDescriptorMac::GetPermissions() const { 65 BluetoothRemoteGattDescriptorMac::GetPermissions() const {
35 NOTIMPLEMENTED(); 66 NOTIMPLEMENTED();
36 return BluetoothGattCharacteristic::PERMISSION_NONE; 67 return BluetoothGattCharacteristic::PERMISSION_NONE;
37 } 68 }
38 69
39 const std::vector<uint8_t>& BluetoothRemoteGattDescriptorMac::GetValue() const { 70 const std::vector<uint8_t>& BluetoothRemoteGattDescriptorMac::GetValue() const {
40 return value_; 71 return value_;
41 } 72 }
42 73
43 BluetoothRemoteGattDescriptorMac::~BluetoothRemoteGattDescriptorMac() {} 74 BluetoothRemoteGattDescriptorMac::~BluetoothRemoteGattDescriptorMac() {
75 if (!read_value_callbacks_.first.is_null()) {
76 std::pair<ValueCallback, ErrorCallback> callbacks;
77 callbacks.swap(read_value_callbacks_);
78 callbacks.second.Run(BluetoothGattService::GATT_ERROR_FAILED);
79 }
80 if (!write_value_callbacks_.first.is_null()) {
81 std::pair<base::Closure, ErrorCallback> callbacks;
82 callbacks.swap(write_value_callbacks_);
83 callbacks.second.Run(BluetoothGattService::GATT_ERROR_FAILED);
84 }
85 }
44 86
45 // Returns a pointer to the GATT characteristic that this characteristic
46 // descriptor belongs to.
47 BluetoothRemoteGattCharacteristic* 87 BluetoothRemoteGattCharacteristic*
48 BluetoothRemoteGattDescriptorMac::GetCharacteristic() const { 88 BluetoothRemoteGattDescriptorMac::GetCharacteristic() const {
49 return static_cast<BluetoothRemoteGattCharacteristic*>(gatt_characteristic_); 89 return static_cast<BluetoothRemoteGattCharacteristic*>(gatt_characteristic_);
50 } 90 }
51 91
52 // Sends a read request to a remote characteristic descriptor to read its 92 // 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 93 // value. |callback| is called to return the read value on success and
54 // |error_callback| is called for failures. 94 // |error_callback| is called for failures.
55 void BluetoothRemoteGattDescriptorMac::ReadRemoteDescriptor( 95 void BluetoothRemoteGattDescriptorMac::ReadRemoteDescriptor(
56 const ValueCallback& callback, 96 const ValueCallback& callback,
57 const ErrorCallback& error_callback) { 97 const ErrorCallback& error_callback) {
58 NOTIMPLEMENTED(); 98 if (value_read_or_write_in_progress_) {
99 VLOG(1) << *this << ": Read failed, already in progress.";
100 base::ThreadTaskRunnerHandle::Get()->PostTask(
101 FROM_HERE,
102 base::Bind(error_callback,
103 BluetoothRemoteGattService::GATT_ERROR_IN_PROGRESS));
104 return;
105 }
106 VLOG(1) << *this << ": Read value.";
107 value_read_or_write_in_progress_ = true;
108 read_value_callbacks_ = std::make_pair(callback, error_callback);
109 [GetCBPeripheral() readValueForDescriptor:cb_descriptor_];
59 } 110 }
60 111
61 // Sends a write request to a remote characteristic descriptor, to modify the
62 // value of the descriptor with the new value |new_value|. |callback| is
63 // called to signal success and |error_callback| for failures. This method
64 // only applies to remote descriptors and will fail for those that are locally
65 // hosted.
66 void BluetoothRemoteGattDescriptorMac::WriteRemoteDescriptor( 112 void BluetoothRemoteGattDescriptorMac::WriteRemoteDescriptor(
67 const std::vector<uint8_t>& new_value, 113 const std::vector<uint8_t>& value,
68 const base::Closure& callback, 114 const base::Closure& callback,
69 const ErrorCallback& error_callback) { 115 const ErrorCallback& error_callback) {
70 NOTIMPLEMENTED(); 116 if (value_read_or_write_in_progress_) {
117 VLOG(1) << *this << ": Write failed, already in progress.";
118 base::ThreadTaskRunnerHandle::Get()->PostTask(
119 FROM_HERE,
120 base::Bind(error_callback,
121 BluetoothRemoteGattService::GATT_ERROR_IN_PROGRESS));
122 return;
123 }
124 VLOG(1) << *this << ": Write value.";
125 value_read_or_write_in_progress_ = true;
126 write_value_callbacks_ = std::make_pair(callback, error_callback);
127 base::scoped_nsobject<NSData> nsdata_value(
128 [[NSData alloc] initWithBytes:value.data() length:value.size()]);
129 [GetCBPeripheral() writeValue:nsdata_value forDescriptor:GetCBDescriptor()];
130 }
131
132 void BluetoothRemoteGattDescriptorMac::DidUpdateValueForDescriptor(
133 NSError* error) {
134 if (!value_read_or_write_in_progress_) {
135 VLOG(1) << *this << ": Value updated, no read in progress.";
136 return;
137 }
138 std::pair<ValueCallback, ErrorCallback> callbacks;
139 callbacks.swap(read_value_callbacks_);
140 value_read_or_write_in_progress_ = false;
141 if (error) {
142 BluetoothGattService::GattErrorCode error_code =
143 BluetoothDeviceMac::GetGattErrorCodeFromNSError(error);
144 VLOG(1) << *this << ": Read value failed with error: "
145 << BluetoothAdapterMac::String(error)
146 << ", converted to error code: " << error_code;
147 callbacks.second.Run(error_code);
148 return;
149 }
150 VLOG(1) << *this << ": Value read.";
151 value_ = VectorValueFromObjC([cb_descriptor_ value]);
152 callbacks.first.Run(value_);
153 }
154
155 void BluetoothRemoteGattDescriptorMac::DidWriteValueForDescriptor(
156 NSError* error) {
157 if (!value_read_or_write_in_progress_) {
158 VLOG(1) << *this << ": Value written, no write in progress.";
159 return;
160 }
161 std::pair<base::Closure, ErrorCallback> callbacks;
162 callbacks.swap(write_value_callbacks_);
163 value_read_or_write_in_progress_ = false;
164 if (error) {
165 BluetoothGattService::GattErrorCode error_code =
166 BluetoothDeviceMac::GetGattErrorCodeFromNSError(error);
167 VLOG(1) << *this << ": Write value failed with error: "
168 << BluetoothAdapterMac::String(error)
169 << ", converted to error code: " << error_code;
170 callbacks.second.Run(error_code);
171 return;
172 }
173 VLOG(1) << *this << ": Value written.";
174 callbacks.first.Run();
175 }
176
177 CBPeripheral* BluetoothRemoteGattDescriptorMac::GetCBPeripheral() const {
178 return gatt_characteristic_->GetCBPeripheral();
71 } 179 }
72 180
73 CBDescriptor* BluetoothRemoteGattDescriptorMac::GetCBDescriptor() const { 181 CBDescriptor* BluetoothRemoteGattDescriptorMac::GetCBDescriptor() const {
74 return cb_descriptor_.get(); 182 return cb_descriptor_;
75 } 183 }
76 184
77 DEVICE_BLUETOOTH_EXPORT std::ostream& operator<<( 185 DEVICE_BLUETOOTH_EXPORT std::ostream& operator<<(
78 std::ostream& out, 186 std::ostream& out,
79 const BluetoothRemoteGattDescriptorMac& descriptor) { 187 const BluetoothRemoteGattDescriptorMac& descriptor) {
80 const BluetoothRemoteGattCharacteristicMac* characteristic_mac = 188 const BluetoothRemoteGattCharacteristicMac* characteristic_mac =
81 static_cast<const BluetoothRemoteGattCharacteristicMac*>( 189 static_cast<const BluetoothRemoteGattCharacteristicMac*>(
82 descriptor.GetCharacteristic()); 190 descriptor.GetCharacteristic());
83 return out << "<BluetoothRemoteGattServiceMac " 191 return out << "<BluetoothRemoteGattServiceMac "
84 << descriptor.GetUUID().canonical_value() << "/" << &descriptor 192 << descriptor.GetUUID().canonical_value() << "/" << &descriptor
85 << ", characteristic: " 193 << ", characteristic: "
86 << characteristic_mac->GetUUID().canonical_value() << "/" 194 << characteristic_mac->GetUUID().canonical_value() << "/"
87 << characteristic_mac << ">"; 195 << characteristic_mac << ">";
88 } 196 }
89 197
90 } // namespace device. 198 } // namespace device.
OLDNEW
« 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