| 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 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/memory/ptr_util.h" | 8 #include "base/memory/ptr_util.h" |
| 9 #include "base/strings/sys_string_conversions.h" | 9 #include "base/strings/sys_string_conversions.h" |
| 10 #include "base/threading/thread_task_runner_handle.h" | 10 #include "base/threading/thread_task_runner_handle.h" |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 result |= BluetoothGattCharacteristic::PROPERTY_INDICATE; | 63 result |= BluetoothGattCharacteristic::PROPERTY_INDICATE; |
| 64 } | 64 } |
| 65 return result; | 65 return result; |
| 66 } | 66 } |
| 67 } // namespace | 67 } // namespace |
| 68 | 68 |
| 69 BluetoothRemoteGattCharacteristicMac::BluetoothRemoteGattCharacteristicMac( | 69 BluetoothRemoteGattCharacteristicMac::BluetoothRemoteGattCharacteristicMac( |
| 70 BluetoothRemoteGattServiceMac* gatt_service, | 70 BluetoothRemoteGattServiceMac* gatt_service, |
| 71 CBCharacteristic* cb_characteristic) | 71 CBCharacteristic* cb_characteristic) |
| 72 : gatt_service_(gatt_service), | 72 : gatt_service_(gatt_service), |
| 73 cb_characteristic_(cb_characteristic, base::scoped_policy::RETAIN), | 73 cb_characteristic_(cb_characteristic, base::scoped_policy::RETAIN) { |
| 74 characteristic_value_read_or_write_in_progress_(false) { | |
| 75 uuid_ = BluetoothAdapterMac::BluetoothUUIDWithCBUUID( | 74 uuid_ = BluetoothAdapterMac::BluetoothUUIDWithCBUUID( |
| 76 [cb_characteristic_.get() UUID]); | 75 [cb_characteristic_.get() UUID]); |
| 77 identifier_ = base::SysNSStringToUTF8( | 76 identifier_ = base::SysNSStringToUTF8( |
| 78 [NSString stringWithFormat:@"%s-%p", uuid_.canonical_value().c_str(), | 77 [NSString stringWithFormat:@"%s-%p", uuid_.canonical_value().c_str(), |
| 79 (void*)cb_characteristic_]); | 78 (void*)cb_characteristic_]); |
| 80 } | 79 } |
| 81 | 80 |
| 82 BluetoothRemoteGattCharacteristicMac::~BluetoothRemoteGattCharacteristicMac() { | 81 BluetoothRemoteGattCharacteristicMac::~BluetoothRemoteGattCharacteristicMac() { |
| 83 if (!read_characteristic_value_callbacks_.first.is_null()) { | 82 if (HasPendingRead()) { |
| 84 std::pair<ValueCallback, ErrorCallback> callbacks; | 83 std::pair<ValueCallback, ErrorCallback> callbacks; |
| 85 callbacks.swap(read_characteristic_value_callbacks_); | 84 callbacks.swap(read_characteristic_value_callbacks_); |
| 86 callbacks.second.Run(BluetoothGattService::GATT_ERROR_FAILED); | 85 callbacks.second.Run(BluetoothGattService::GATT_ERROR_FAILED); |
| 87 } | 86 } |
| 88 if (!write_characteristic_value_callbacks_.first.is_null()) { | 87 if (HasPendingWrite()) { |
| 89 std::pair<base::Closure, ErrorCallback> callbacks; | 88 std::pair<base::Closure, ErrorCallback> callbacks; |
| 90 callbacks.swap(write_characteristic_value_callbacks_); | 89 callbacks.swap(write_characteristic_value_callbacks_); |
| 91 callbacks.second.Run(BluetoothGattService::GATT_ERROR_FAILED); | 90 callbacks.second.Run(BluetoothGattService::GATT_ERROR_FAILED); |
| 92 } | 91 } |
| 93 } | 92 } |
| 94 | 93 |
| 95 std::string BluetoothRemoteGattCharacteristicMac::GetIdentifier() const { | 94 std::string BluetoothRemoteGattCharacteristicMac::GetIdentifier() const { |
| 96 return identifier_; | 95 return identifier_; |
| 97 } | 96 } |
| 98 | 97 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 152 const ValueCallback& callback, | 151 const ValueCallback& callback, |
| 153 const ErrorCallback& error_callback) { | 152 const ErrorCallback& error_callback) { |
| 154 if (!IsReadable()) { | 153 if (!IsReadable()) { |
| 155 VLOG(1) << *this << ": Characteristic not readable."; | 154 VLOG(1) << *this << ": Characteristic not readable."; |
| 156 base::ThreadTaskRunnerHandle::Get()->PostTask( | 155 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 157 FROM_HERE, | 156 FROM_HERE, |
| 158 base::Bind(error_callback, | 157 base::Bind(error_callback, |
| 159 BluetoothRemoteGattService::GATT_ERROR_NOT_SUPPORTED)); | 158 BluetoothRemoteGattService::GATT_ERROR_NOT_SUPPORTED)); |
| 160 return; | 159 return; |
| 161 } | 160 } |
| 162 if (characteristic_value_read_or_write_in_progress_) { | 161 if (HasPendingRead() || HasPendingWrite()) { |
| 163 VLOG(1) << *this << ": Characteristic read already in progress."; | 162 VLOG(1) << *this << ": Characteristic read already in progress."; |
| 164 base::ThreadTaskRunnerHandle::Get()->PostTask( | 163 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 165 FROM_HERE, | 164 FROM_HERE, |
| 166 base::Bind(error_callback, | 165 base::Bind(error_callback, |
| 167 BluetoothRemoteGattService::GATT_ERROR_IN_PROGRESS)); | 166 BluetoothRemoteGattService::GATT_ERROR_IN_PROGRESS)); |
| 168 return; | 167 return; |
| 169 } | 168 } |
| 170 VLOG(1) << *this << ": Read characteristic."; | 169 VLOG(1) << *this << ": Read characteristic."; |
| 171 characteristic_value_read_or_write_in_progress_ = true; | |
| 172 read_characteristic_value_callbacks_ = | 170 read_characteristic_value_callbacks_ = |
| 173 std::make_pair(callback, error_callback); | 171 std::make_pair(callback, error_callback); |
| 174 [GetCBPeripheral() readValueForCharacteristic:cb_characteristic_]; | 172 [GetCBPeripheral() readValueForCharacteristic:cb_characteristic_]; |
| 175 } | 173 } |
| 176 | 174 |
| 177 void BluetoothRemoteGattCharacteristicMac::WriteRemoteCharacteristic( | 175 void BluetoothRemoteGattCharacteristicMac::WriteRemoteCharacteristic( |
| 178 const std::vector<uint8_t>& value, | 176 const std::vector<uint8_t>& value, |
| 179 const base::Closure& callback, | 177 const base::Closure& callback, |
| 180 const ErrorCallback& error_callback) { | 178 const ErrorCallback& error_callback) { |
| 181 if (!IsWritable()) { | 179 if (!IsWritable()) { |
| 182 VLOG(1) << *this << ": Characteristic not writable."; | 180 VLOG(1) << *this << ": Characteristic not writable."; |
| 183 base::ThreadTaskRunnerHandle::Get()->PostTask( | 181 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 184 FROM_HERE, | 182 FROM_HERE, |
| 185 base::Bind(error_callback, | 183 base::Bind(error_callback, |
| 186 BluetoothRemoteGattService::GATT_ERROR_NOT_PERMITTED)); | 184 BluetoothRemoteGattService::GATT_ERROR_NOT_PERMITTED)); |
| 187 return; | 185 return; |
| 188 } | 186 } |
| 189 if (characteristic_value_read_or_write_in_progress_) { | 187 if (HasPendingRead() || HasPendingWrite()) { |
| 190 VLOG(1) << *this << ": Characteristic write already in progress."; | 188 VLOG(1) << *this << ": Characteristic write already in progress."; |
| 191 base::ThreadTaskRunnerHandle::Get()->PostTask( | 189 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 192 FROM_HERE, | 190 FROM_HERE, |
| 193 base::Bind(error_callback, | 191 base::Bind(error_callback, |
| 194 BluetoothRemoteGattService::GATT_ERROR_IN_PROGRESS)); | 192 BluetoothRemoteGattService::GATT_ERROR_IN_PROGRESS)); |
| 195 return; | 193 return; |
| 196 } | 194 } |
| 197 VLOG(1) << *this << ": Write characteristic."; | 195 VLOG(1) << *this << ": Write characteristic."; |
| 198 characteristic_value_read_or_write_in_progress_ = true; | |
| 199 write_characteristic_value_callbacks_ = | 196 write_characteristic_value_callbacks_ = |
| 200 std::make_pair(callback, error_callback); | 197 std::make_pair(callback, error_callback); |
| 201 base::scoped_nsobject<NSData> nsdata_value( | 198 base::scoped_nsobject<NSData> nsdata_value( |
| 202 [[NSData alloc] initWithBytes:value.data() length:value.size()]); | 199 [[NSData alloc] initWithBytes:value.data() length:value.size()]); |
| 203 CBCharacteristicWriteType write_type = GetCBWriteType(); | 200 CBCharacteristicWriteType write_type = GetCBWriteType(); |
| 204 [GetCBPeripheral() writeValue:nsdata_value | 201 [GetCBPeripheral() writeValue:nsdata_value |
| 205 forCharacteristic:cb_characteristic_ | 202 forCharacteristic:cb_characteristic_ |
| 206 type:write_type]; | 203 type:write_type]; |
| 207 if (write_type == CBCharacteristicWriteWithoutResponse) { | 204 if (write_type == CBCharacteristicWriteWithoutResponse) { |
| 208 base::ThreadTaskRunnerHandle::Get()->PostTask( | 205 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 VLOG(1) << *this << ": Discover descriptors."; | 243 VLOG(1) << *this << ": Discover descriptors."; |
| 247 is_discovery_complete_ = false; | 244 is_discovery_complete_ = false; |
| 248 [GetCBPeripheral() | 245 [GetCBPeripheral() |
| 249 discoverDescriptorsForCharacteristic:cb_characteristic_.get()]; | 246 discoverDescriptorsForCharacteristic:cb_characteristic_.get()]; |
| 250 } | 247 } |
| 251 | 248 |
| 252 void BluetoothRemoteGattCharacteristicMac::DidUpdateValue(NSError* error) { | 249 void BluetoothRemoteGattCharacteristicMac::DidUpdateValue(NSError* error) { |
| 253 CHECK_EQ(GetCBPeripheral().state, CBPeripheralStateConnected); | 250 CHECK_EQ(GetCBPeripheral().state, CBPeripheralStateConnected); |
| 254 // This method is called when the characteristic is read and when a | 251 // This method is called when the characteristic is read and when a |
| 255 // notification is received. | 252 // notification is received. |
| 256 if (characteristic_value_read_or_write_in_progress_) { | 253 if (HasPendingRead()) { |
| 257 std::pair<ValueCallback, ErrorCallback> callbacks; | 254 std::pair<ValueCallback, ErrorCallback> callbacks; |
| 258 callbacks.swap(read_characteristic_value_callbacks_); | 255 callbacks.swap(read_characteristic_value_callbacks_); |
| 259 characteristic_value_read_or_write_in_progress_ = false; | |
| 260 if (error) { | 256 if (error) { |
| 261 BluetoothGattService::GattErrorCode error_code = | 257 BluetoothGattService::GattErrorCode error_code = |
| 262 BluetoothDeviceMac::GetGattErrorCodeFromNSError(error); | 258 BluetoothDeviceMac::GetGattErrorCodeFromNSError(error); |
| 263 VLOG(1) << *this | 259 VLOG(1) << *this |
| 264 << ": Bluetooth error while reading for characteristic, domain: " | 260 << ": Bluetooth error while reading for characteristic, domain: " |
| 265 << BluetoothAdapterMac::String(error) | 261 << BluetoothAdapterMac::String(error) |
| 266 << ", error code: " << error_code; | 262 << ", error code: " << error_code; |
| 267 callbacks.second.Run(error_code); | 263 callbacks.second.Run(error_code); |
| 268 return; | 264 return; |
| 269 } | 265 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 286 } | 282 } |
| 287 | 283 |
| 288 void BluetoothRemoteGattCharacteristicMac::UpdateValue() { | 284 void BluetoothRemoteGattCharacteristicMac::UpdateValue() { |
| 289 NSData* nsdata_value = cb_characteristic_.get().value; | 285 NSData* nsdata_value = cb_characteristic_.get().value; |
| 290 const uint8_t* buffer = static_cast<const uint8_t*>(nsdata_value.bytes); | 286 const uint8_t* buffer = static_cast<const uint8_t*>(nsdata_value.bytes); |
| 291 value_.assign(buffer, buffer + nsdata_value.length); | 287 value_.assign(buffer, buffer + nsdata_value.length); |
| 292 } | 288 } |
| 293 | 289 |
| 294 void BluetoothRemoteGattCharacteristicMac::DidWriteValue(NSError* error) { | 290 void BluetoothRemoteGattCharacteristicMac::DidWriteValue(NSError* error) { |
| 295 CHECK_EQ(GetCBPeripheral().state, CBPeripheralStateConnected); | 291 CHECK_EQ(GetCBPeripheral().state, CBPeripheralStateConnected); |
| 296 if (!characteristic_value_read_or_write_in_progress_) { | 292 if (!HasPendingWrite()) { |
| 297 // In case of buggy device, nothing should be done if receiving extra | 293 // In case of buggy device, nothing should be done if receiving extra |
| 298 // write confirmation. | 294 // write confirmation. |
| 299 VLOG(1) << *this | 295 VLOG(1) << *this |
| 300 << ": Write notification while no write operation pending."; | 296 << ": Write notification while no write operation pending."; |
| 301 return; | 297 return; |
| 302 } | 298 } |
| 303 std::pair<base::Closure, ErrorCallback> callbacks; | 299 std::pair<base::Closure, ErrorCallback> callbacks; |
| 304 callbacks.swap(write_characteristic_value_callbacks_); | 300 callbacks.swap(write_characteristic_value_callbacks_); |
| 305 characteristic_value_read_or_write_in_progress_ = false; | |
| 306 if (error) { | 301 if (error) { |
| 307 BluetoothGattService::GattErrorCode error_code = | 302 BluetoothGattService::GattErrorCode error_code = |
| 308 BluetoothDeviceMac::GetGattErrorCodeFromNSError(error); | 303 BluetoothDeviceMac::GetGattErrorCodeFromNSError(error); |
| 309 VLOG(1) << *this | 304 VLOG(1) << *this |
| 310 << ": Bluetooth error while writing for characteristic, error: " | 305 << ": Bluetooth error while writing for characteristic, error: " |
| 311 << BluetoothAdapterMac::String(error) | 306 << BluetoothAdapterMac::String(error) |
| 312 << ", error code: " << error_code; | 307 << ", error code: " << error_code; |
| 313 callbacks.second.Run(error_code); | 308 callbacks.second.Run(error_code); |
| 314 return; | 309 return; |
| 315 } | 310 } |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 447 const BluetoothRemoteGattServiceMac* service_mac = | 442 const BluetoothRemoteGattServiceMac* service_mac = |
| 448 static_cast<const BluetoothRemoteGattServiceMac*>( | 443 static_cast<const BluetoothRemoteGattServiceMac*>( |
| 449 characteristic.GetService()); | 444 characteristic.GetService()); |
| 450 return out << "<BluetoothRemoteGattCharacteristicMac " | 445 return out << "<BluetoothRemoteGattCharacteristicMac " |
| 451 << characteristic.GetUUID().canonical_value() << "/" | 446 << characteristic.GetUUID().canonical_value() << "/" |
| 452 << &characteristic | 447 << &characteristic |
| 453 << ", service: " << service_mac->GetUUID().canonical_value() << "/" | 448 << ", service: " << service_mac->GetUUID().canonical_value() << "/" |
| 454 << service_mac << ">"; | 449 << service_mac << ">"; |
| 455 } | 450 } |
| 456 } // namespace device. | 451 } // namespace device. |
| OLD | NEW |