OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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_characteristic_mac.h" | 5 #include "device/bluetooth/bluetooth_remote_gatt_characteristic_mac.h" |
6 | 6 |
7 #import <CoreBluetooth/CoreBluetooth.h> | |
8 | |
9 #include "base/bind.h" | 7 #include "base/bind.h" |
10 #include "base/threading/thread_task_runner_handle.h" | 8 #include "base/threading/thread_task_runner_handle.h" |
11 #include "device/bluetooth/bluetooth_adapter_mac.h" | 9 #include "device/bluetooth/bluetooth_adapter_mac.h" |
12 #include "device/bluetooth/bluetooth_device_mac.h" | 10 #include "device/bluetooth/bluetooth_device_mac.h" |
13 #include "device/bluetooth/bluetooth_remote_gatt_service_mac.h" | 11 #include "device/bluetooth/bluetooth_remote_gatt_service_mac.h" |
14 | 12 |
15 namespace device { | 13 namespace device { |
16 | 14 |
17 namespace { | 15 namespace { |
18 | 16 |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 read_characteristic_value_callbacks_ = | 153 read_characteristic_value_callbacks_ = |
156 std::make_pair(callback, error_callback); | 154 std::make_pair(callback, error_callback); |
157 [gatt_service_->GetCBPeripheral() | 155 [gatt_service_->GetCBPeripheral() |
158 readValueForCharacteristic:cb_characteristic_]; | 156 readValueForCharacteristic:cb_characteristic_]; |
159 } | 157 } |
160 | 158 |
161 void BluetoothRemoteGattCharacteristicMac::WriteRemoteCharacteristic( | 159 void BluetoothRemoteGattCharacteristicMac::WriteRemoteCharacteristic( |
162 const std::vector<uint8_t>& new_value, | 160 const std::vector<uint8_t>& new_value, |
163 const base::Closure& callback, | 161 const base::Closure& callback, |
164 const ErrorCallback& error_callback) { | 162 const ErrorCallback& error_callback) { |
165 NOTIMPLEMENTED(); | 163 if (!IsWritable()) { |
| 164 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 165 FROM_HERE, |
| 166 base::Bind(error_callback, |
| 167 BluetoothRemoteGattService::GATT_ERROR_NOT_PERMITTED)); |
| 168 return; |
| 169 } |
| 170 if (characteristic_value_read_or_write_in_progress_) { |
| 171 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 172 FROM_HERE, |
| 173 base::Bind(error_callback, |
| 174 BluetoothRemoteGattService::GATT_ERROR_IN_PROGRESS)); |
| 175 return; |
| 176 } |
| 177 characteristic_value_read_or_write_in_progress_ = true; |
| 178 write_characteristic_value_callbacks_ = |
| 179 std::make_pair(callback, error_callback); |
| 180 base::scoped_nsobject<NSData> nsdata_value( |
| 181 [[NSData alloc] initWithBytes:new_value.data() length:new_value.size()]); |
| 182 CBCharacteristicWriteType write_type = GetCBWriteType(); |
| 183 [gatt_service_->GetCBPeripheral() writeValue:nsdata_value |
| 184 forCharacteristic:cb_characteristic_ |
| 185 type:write_type]; |
| 186 if (write_type == CBCharacteristicWriteWithoutResponse) { |
| 187 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 188 FROM_HERE, |
| 189 base::Bind(&BluetoothRemoteGattCharacteristicMac::DidWriteValue, |
| 190 base::Unretained(this), nil)); |
| 191 } |
166 } | 192 } |
167 | 193 |
168 void BluetoothRemoteGattCharacteristicMac::DidUpdateValue(NSError* error) { | 194 void BluetoothRemoteGattCharacteristicMac::DidUpdateValue(NSError* error) { |
169 if (!characteristic_value_read_or_write_in_progress_) { | 195 if (!characteristic_value_read_or_write_in_progress_) { |
| 196 // In case of buggy device, nothing should be done if receiving extra |
| 197 // read confirmation. |
170 return; | 198 return; |
171 } | 199 } |
172 std::pair<ValueCallback, ErrorCallback> callbacks; | 200 std::pair<ValueCallback, ErrorCallback> callbacks; |
173 callbacks.swap(read_characteristic_value_callbacks_); | 201 callbacks.swap(read_characteristic_value_callbacks_); |
174 characteristic_value_read_or_write_in_progress_ = false; | 202 characteristic_value_read_or_write_in_progress_ = false; |
175 if (error) { | 203 if (error) { |
176 VLOG(1) << "Bluetooth error while reading for characteristic, domain: " | 204 VLOG(1) << "Bluetooth error while reading for characteristic, domain: " |
177 << error.domain.UTF8String << ", error code: " << error.code; | 205 << error.domain.UTF8String << ", error code: " << error.code; |
178 BluetoothGattService::GattErrorCode error_code = | 206 BluetoothGattService::GattErrorCode error_code = |
179 BluetoothDeviceMac::GetGattErrorCodeFromNSError(error); | 207 BluetoothDeviceMac::GetGattErrorCodeFromNSError(error); |
180 callbacks.second.Run(error_code); | 208 callbacks.second.Run(error_code); |
181 return; | 209 return; |
182 } | 210 } |
183 NSData* nsdata_value = cb_characteristic_.get().value; | 211 NSData* nsdata_value = cb_characteristic_.get().value; |
184 const uint8_t* buffer = static_cast<const uint8_t*>(nsdata_value.bytes); | 212 const uint8_t* buffer = static_cast<const uint8_t*>(nsdata_value.bytes); |
185 value_.assign(buffer, buffer + nsdata_value.length); | 213 value_.assign(buffer, buffer + nsdata_value.length); |
186 gatt_service_->GetMacAdapter()->NotifyGattCharacteristicValueChanged(this, | 214 gatt_service_->GetMacAdapter()->NotifyGattCharacteristicValueChanged(this, |
187 value_); | 215 value_); |
188 callbacks.first.Run(value_); | 216 callbacks.first.Run(value_); |
189 } | 217 } |
190 | 218 |
| 219 void BluetoothRemoteGattCharacteristicMac::DidWriteValue(NSError* error) { |
| 220 if (!characteristic_value_read_or_write_in_progress_) { |
| 221 // In case of buggy device, nothing should be done if receiving extra |
| 222 // write confirmation. |
| 223 return; |
| 224 } |
| 225 std::pair<base::Closure, ErrorCallback> callbacks; |
| 226 callbacks.swap(write_characteristic_value_callbacks_); |
| 227 characteristic_value_read_or_write_in_progress_ = false; |
| 228 if (error) { |
| 229 VLOG(1) << "Bluetooth error while writing for characteristic, domain: " |
| 230 << error.domain.UTF8String << ", error code: " << error.code; |
| 231 BluetoothGattService::GattErrorCode error_code = |
| 232 BluetoothDeviceMac::GetGattErrorCodeFromNSError(error); |
| 233 callbacks.second.Run(error_code); |
| 234 return; |
| 235 } |
| 236 NSData* nsdata_value = cb_characteristic_.get().value; |
| 237 const uint8_t* buffer = static_cast<const uint8_t*>(nsdata_value.bytes); |
| 238 std::vector<uint8_t> gatt_value(buffer, buffer + nsdata_value.length); |
| 239 gatt_service_->GetMacAdapter()->NotifyGattCharacteristicValueChanged(this, |
| 240 value_); |
| 241 callbacks.first.Run(); |
| 242 } |
| 243 |
191 bool BluetoothRemoteGattCharacteristicMac::IsReadable() const { | 244 bool BluetoothRemoteGattCharacteristicMac::IsReadable() const { |
192 return GetProperties() & BluetoothGattCharacteristic::PROPERTY_READ; | 245 return GetProperties() & BluetoothGattCharacteristic::PROPERTY_READ; |
193 } | 246 } |
194 | 247 |
| 248 bool BluetoothRemoteGattCharacteristicMac::IsWritable() const { |
| 249 BluetoothGattCharacteristic::Properties properties = GetProperties(); |
| 250 return (properties & BluetoothGattCharacteristic::PROPERTY_WRITE) || |
| 251 (properties & PROPERTY_WRITE_WITHOUT_RESPONSE); |
| 252 } |
| 253 |
| 254 CBCharacteristicWriteType BluetoothRemoteGattCharacteristicMac::GetCBWriteType() |
| 255 const { |
| 256 return (GetProperties() & BluetoothGattCharacteristic::PROPERTY_WRITE) |
| 257 ? CBCharacteristicWriteWithResponse |
| 258 : CBCharacteristicWriteWithoutResponse; |
| 259 } |
| 260 |
195 CBCharacteristic* BluetoothRemoteGattCharacteristicMac::GetCBCharacteristic() | 261 CBCharacteristic* BluetoothRemoteGattCharacteristicMac::GetCBCharacteristic() |
196 const { | 262 const { |
197 return cb_characteristic_.get(); | 263 return cb_characteristic_.get(); |
198 } | 264 } |
199 | |
200 } // namespace device. | 265 } // namespace device. |
OLD | NEW |