| 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 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 : is_discovery_complete_(false), | 72 : is_discovery_complete_(false), |
| 73 discovery_pending_count_(0), | 73 discovery_pending_count_(0), |
| 74 gatt_service_(gatt_service), | 74 gatt_service_(gatt_service), |
| 75 cb_characteristic_(cb_characteristic, base::scoped_policy::RETAIN), | 75 cb_characteristic_(cb_characteristic, base::scoped_policy::RETAIN), |
| 76 weak_ptr_factory_(this) { | 76 weak_ptr_factory_(this) { |
| 77 uuid_ = BluetoothAdapterMac::BluetoothUUIDWithCBUUID( | 77 uuid_ = |
| 78 [cb_characteristic_.get() UUID]); | 78 BluetoothAdapterMac::BluetoothUUIDWithCBUUID([cb_characteristic_ UUID]); |
| 79 identifier_ = base::SysNSStringToUTF8( | 79 identifier_ = base::SysNSStringToUTF8( |
| 80 [NSString stringWithFormat:@"%s-%p", uuid_.canonical_value().c_str(), | 80 [NSString stringWithFormat:@"%s-%p", uuid_.canonical_value().c_str(), |
| 81 (void*)cb_characteristic_]); | 81 (void*)cb_characteristic_]); |
| 82 } | 82 } |
| 83 | 83 |
| 84 BluetoothRemoteGattCharacteristicMac::~BluetoothRemoteGattCharacteristicMac() { | 84 BluetoothRemoteGattCharacteristicMac::~BluetoothRemoteGattCharacteristicMac() { |
| 85 if (HasPendingRead()) { | 85 if (HasPendingRead()) { |
| 86 std::pair<ValueCallback, ErrorCallback> callbacks; | 86 std::pair<ValueCallback, ErrorCallback> callbacks; |
| 87 callbacks.swap(read_characteristic_value_callbacks_); | 87 callbacks.swap(read_characteristic_value_callbacks_); |
| 88 callbacks.second.Run(BluetoothGattService::GATT_ERROR_FAILED); | 88 callbacks.second.Run(BluetoothGattService::GATT_ERROR_FAILED); |
| 89 } | 89 } |
| 90 if (HasPendingWrite()) { | 90 if (HasPendingWrite()) { |
| 91 std::pair<base::Closure, ErrorCallback> callbacks; | 91 std::pair<base::Closure, ErrorCallback> callbacks; |
| 92 callbacks.swap(write_characteristic_value_callbacks_); | 92 callbacks.swap(write_characteristic_value_callbacks_); |
| 93 callbacks.second.Run(BluetoothGattService::GATT_ERROR_FAILED); | 93 callbacks.second.Run(BluetoothGattService::GATT_ERROR_FAILED); |
| 94 } | 94 } |
| 95 } | 95 } |
| 96 | 96 |
| 97 std::string BluetoothRemoteGattCharacteristicMac::GetIdentifier() const { | 97 std::string BluetoothRemoteGattCharacteristicMac::GetIdentifier() const { |
| 98 return identifier_; | 98 return identifier_; |
| 99 } | 99 } |
| 100 | 100 |
| 101 BluetoothUUID BluetoothRemoteGattCharacteristicMac::GetUUID() const { | 101 BluetoothUUID BluetoothRemoteGattCharacteristicMac::GetUUID() const { |
| 102 return uuid_; | 102 return uuid_; |
| 103 } | 103 } |
| 104 | 104 |
| 105 BluetoothGattCharacteristic::Properties | 105 BluetoothGattCharacteristic::Properties |
| 106 BluetoothRemoteGattCharacteristicMac::GetProperties() const { | 106 BluetoothRemoteGattCharacteristicMac::GetProperties() const { |
| 107 return ConvertProperties(cb_characteristic_.get().properties); | 107 return ConvertProperties([cb_characteristic_ properties]); |
| 108 } | 108 } |
| 109 | 109 |
| 110 BluetoothGattCharacteristic::Permissions | 110 BluetoothGattCharacteristic::Permissions |
| 111 BluetoothRemoteGattCharacteristicMac::GetPermissions() const { | 111 BluetoothRemoteGattCharacteristicMac::GetPermissions() const { |
| 112 // Not supported for remote characteristics for CoreBluetooth. | 112 // Not supported for remote characteristics for CoreBluetooth. |
| 113 NOTIMPLEMENTED(); | 113 NOTIMPLEMENTED(); |
| 114 return PERMISSION_NONE; | 114 return PERMISSION_NONE; |
| 115 } | 115 } |
| 116 | 116 |
| 117 const std::vector<uint8_t>& BluetoothRemoteGattCharacteristicMac::GetValue() | 117 const std::vector<uint8_t>& BluetoothRemoteGattCharacteristicMac::GetValue() |
| 118 const { | 118 const { |
| 119 return value_; | 119 return value_; |
| 120 } | 120 } |
| 121 | 121 |
| 122 BluetoothRemoteGattService* BluetoothRemoteGattCharacteristicMac::GetService() | 122 BluetoothRemoteGattService* BluetoothRemoteGattCharacteristicMac::GetService() |
| 123 const { | 123 const { |
| 124 return static_cast<BluetoothRemoteGattService*>(gatt_service_); | 124 return static_cast<BluetoothRemoteGattService*>(gatt_service_); |
| 125 } | 125 } |
| 126 | 126 |
| 127 bool BluetoothRemoteGattCharacteristicMac::IsNotifying() const { | 127 bool BluetoothRemoteGattCharacteristicMac::IsNotifying() const { |
| 128 return cb_characteristic_.get().isNotifying == YES; | 128 return [cb_characteristic_ isNotifying] == YES; |
| 129 } | 129 } |
| 130 | 130 |
| 131 std::vector<BluetoothRemoteGattDescriptor*> | 131 std::vector<BluetoothRemoteGattDescriptor*> |
| 132 BluetoothRemoteGattCharacteristicMac::GetDescriptors() const { | 132 BluetoothRemoteGattCharacteristicMac::GetDescriptors() const { |
| 133 std::vector<BluetoothRemoteGattDescriptor*> gatt_descriptors; | 133 std::vector<BluetoothRemoteGattDescriptor*> gatt_descriptors; |
| 134 for (const auto& iter : gatt_descriptor_macs_) { | 134 for (const auto& iter : gatt_descriptor_macs_) { |
| 135 BluetoothRemoteGattDescriptor* gatt_descriptor = | 135 BluetoothRemoteGattDescriptor* gatt_descriptor = |
| 136 static_cast<BluetoothRemoteGattDescriptor*>(iter.second.get()); | 136 static_cast<BluetoothRemoteGattDescriptor*>(iter.second.get()); |
| 137 gatt_descriptors.push_back(gatt_descriptor); | 137 gatt_descriptors.push_back(gatt_descriptor); |
| 138 } | 138 } |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 216 BluetoothRemoteGattDescriptor* ccc_descriptor, | 216 BluetoothRemoteGattDescriptor* ccc_descriptor, |
| 217 const base::Closure& callback, | 217 const base::Closure& callback, |
| 218 const ErrorCallback& error_callback) { | 218 const ErrorCallback& error_callback) { |
| 219 VLOG(1) << *this << ": Subscribe to characteristic."; | 219 VLOG(1) << *this << ": Subscribe to characteristic."; |
| 220 DCHECK(subscribe_to_notification_callbacks_.first.is_null()); | 220 DCHECK(subscribe_to_notification_callbacks_.first.is_null()); |
| 221 DCHECK(subscribe_to_notification_callbacks_.second.is_null()); | 221 DCHECK(subscribe_to_notification_callbacks_.second.is_null()); |
| 222 DCHECK(unsubscribe_from_notification_callbacks_.first.is_null()); | 222 DCHECK(unsubscribe_from_notification_callbacks_.first.is_null()); |
| 223 DCHECK(unsubscribe_from_notification_callbacks_.second.is_null()); | 223 DCHECK(unsubscribe_from_notification_callbacks_.second.is_null()); |
| 224 subscribe_to_notification_callbacks_ = | 224 subscribe_to_notification_callbacks_ = |
| 225 std::make_pair(callback, error_callback); | 225 std::make_pair(callback, error_callback); |
| 226 [GetCBPeripheral() setNotifyValue:YES | 226 [GetCBPeripheral() setNotifyValue:YES forCharacteristic:cb_characteristic_]; |
| 227 forCharacteristic:cb_characteristic_.get()]; | |
| 228 } | 227 } |
| 229 | 228 |
| 230 void BluetoothRemoteGattCharacteristicMac::UnsubscribeFromNotifications( | 229 void BluetoothRemoteGattCharacteristicMac::UnsubscribeFromNotifications( |
| 231 BluetoothRemoteGattDescriptor* ccc_descriptor, | 230 BluetoothRemoteGattDescriptor* ccc_descriptor, |
| 232 const base::Closure& callback, | 231 const base::Closure& callback, |
| 233 const ErrorCallback& error_callback) { | 232 const ErrorCallback& error_callback) { |
| 234 VLOG(1) << *this << ": Unsubscribe from characteristic."; | 233 VLOG(1) << *this << ": Unsubscribe from characteristic."; |
| 235 DCHECK(subscribe_to_notification_callbacks_.first.is_null()); | 234 DCHECK(subscribe_to_notification_callbacks_.first.is_null()); |
| 236 DCHECK(subscribe_to_notification_callbacks_.second.is_null()); | 235 DCHECK(subscribe_to_notification_callbacks_.second.is_null()); |
| 237 DCHECK(unsubscribe_from_notification_callbacks_.first.is_null()); | 236 DCHECK(unsubscribe_from_notification_callbacks_.first.is_null()); |
| 238 DCHECK(unsubscribe_from_notification_callbacks_.second.is_null()); | 237 DCHECK(unsubscribe_from_notification_callbacks_.second.is_null()); |
| 239 unsubscribe_from_notification_callbacks_ = | 238 unsubscribe_from_notification_callbacks_ = |
| 240 std::make_pair(callback, error_callback); | 239 std::make_pair(callback, error_callback); |
| 241 [GetCBPeripheral() setNotifyValue:NO | 240 [GetCBPeripheral() setNotifyValue:NO forCharacteristic:cb_characteristic_]; |
| 242 forCharacteristic:cb_characteristic_.get()]; | |
| 243 } | 241 } |
| 244 | 242 |
| 245 void BluetoothRemoteGattCharacteristicMac::DiscoverDescriptors() { | 243 void BluetoothRemoteGattCharacteristicMac::DiscoverDescriptors() { |
| 246 VLOG(1) << *this << ": Discover descriptors."; | 244 VLOG(1) << *this << ": Discover descriptors."; |
| 247 is_discovery_complete_ = false; | 245 is_discovery_complete_ = false; |
| 248 ++discovery_pending_count_; | 246 ++discovery_pending_count_; |
| 249 [GetCBPeripheral() | 247 [GetCBPeripheral() discoverDescriptorsForCharacteristic:cb_characteristic_]; |
| 250 discoverDescriptorsForCharacteristic:cb_characteristic_.get()]; | |
| 251 } | 248 } |
| 252 | 249 |
| 253 void BluetoothRemoteGattCharacteristicMac::DidUpdateValue(NSError* error) { | 250 void BluetoothRemoteGattCharacteristicMac::DidUpdateValue(NSError* error) { |
| 254 CHECK_EQ(GetCBPeripheral().state, CBPeripheralStateConnected); | 251 CHECK_EQ(GetCBPeripheral().state, CBPeripheralStateConnected); |
| 255 // This method is called when the characteristic is read and when a | 252 // This method is called when the characteristic is read and when a |
| 256 // notification is received. | 253 // notification is received. |
| 257 if (HasPendingRead()) { | 254 if (HasPendingRead()) { |
| 258 std::pair<ValueCallback, ErrorCallback> callbacks; | 255 std::pair<ValueCallback, ErrorCallback> callbacks; |
| 259 callbacks.swap(read_characteristic_value_callbacks_); | 256 callbacks.swap(read_characteristic_value_callbacks_); |
| 260 if (error) { | 257 if (error) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 279 // In case of buggy device, nothing should be done if receiving extra | 276 // In case of buggy device, nothing should be done if receiving extra |
| 280 // read confirmation. | 277 // read confirmation. |
| 281 VLOG(1) | 278 VLOG(1) |
| 282 << *this | 279 << *this |
| 283 << ": Characteristic value updated while having no pending read nor " | 280 << ": Characteristic value updated while having no pending read nor " |
| 284 "notification."; | 281 "notification."; |
| 285 } | 282 } |
| 286 } | 283 } |
| 287 | 284 |
| 288 void BluetoothRemoteGattCharacteristicMac::UpdateValue() { | 285 void BluetoothRemoteGattCharacteristicMac::UpdateValue() { |
| 289 NSData* nsdata_value = cb_characteristic_.get().value; | 286 NSData* nsdata_value = [cb_characteristic_ value]; |
| 290 const uint8_t* buffer = static_cast<const uint8_t*>(nsdata_value.bytes); | 287 const uint8_t* buffer = static_cast<const uint8_t*>(nsdata_value.bytes); |
| 291 value_.assign(buffer, buffer + nsdata_value.length); | 288 value_.assign(buffer, buffer + nsdata_value.length); |
| 292 } | 289 } |
| 293 | 290 |
| 294 void BluetoothRemoteGattCharacteristicMac::DidWriteValue(NSError* error) { | 291 void BluetoothRemoteGattCharacteristicMac::DidWriteValue(NSError* error) { |
| 295 // We could have called cancelPeripheralConnection, which causes | 292 // We could have called cancelPeripheralConnection, which causes |
| 296 // [CBPeripheral state] to be CBPeripheralStateDisconnected, before or during | 293 // [CBPeripheral state] to be CBPeripheralStateDisconnected, before or during |
| 297 // a write without response callback so we flush all pending writes. | 294 // a write without response callback so we flush all pending writes. |
| 298 // TODO(crbug.com/726534): Remove once we can avoid calling DidWriteValue | 295 // TODO(crbug.com/726534): Remove once we can avoid calling DidWriteValue |
| 299 // when we disconnect before or during a write without response call. | 296 // when we disconnect before or during a write without response call. |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 365 << ": Unmatch DiscoverDescriptors and DidDiscoverDescriptors."; | 362 << ": Unmatch DiscoverDescriptors and DidDiscoverDescriptors."; |
| 366 return; | 363 return; |
| 367 } | 364 } |
| 368 VLOG(1) << *this << ": Did discover descriptors."; | 365 VLOG(1) << *this << ": Did discover descriptors."; |
| 369 --discovery_pending_count_; | 366 --discovery_pending_count_; |
| 370 std::unordered_set<std::string> descriptor_identifier_to_remove; | 367 std::unordered_set<std::string> descriptor_identifier_to_remove; |
| 371 for (const auto& iter : gatt_descriptor_macs_) { | 368 for (const auto& iter : gatt_descriptor_macs_) { |
| 372 descriptor_identifier_to_remove.insert(iter.first); | 369 descriptor_identifier_to_remove.insert(iter.first); |
| 373 } | 370 } |
| 374 | 371 |
| 375 for (CBDescriptor* cb_descriptor in cb_characteristic_.get().descriptors) { | 372 for (CBDescriptor* cb_descriptor in [cb_characteristic_ descriptors]) { |
| 376 BluetoothRemoteGattDescriptorMac* gatt_descriptor_mac = | 373 BluetoothRemoteGattDescriptorMac* gatt_descriptor_mac = |
| 377 GetBluetoothRemoteGattDescriptorMac(cb_descriptor); | 374 GetBluetoothRemoteGattDescriptorMac(cb_descriptor); |
| 378 if (gatt_descriptor_mac) { | 375 if (gatt_descriptor_mac) { |
| 379 VLOG(1) << *gatt_descriptor_mac << ": Known descriptor."; | 376 VLOG(1) << *gatt_descriptor_mac << ": Known descriptor."; |
| 380 const std::string& identifier = gatt_descriptor_mac->GetIdentifier(); | 377 const std::string& identifier = gatt_descriptor_mac->GetIdentifier(); |
| 381 descriptor_identifier_to_remove.erase(identifier); | 378 descriptor_identifier_to_remove.erase(identifier); |
| 382 continue; | 379 continue; |
| 383 } | 380 } |
| 384 gatt_descriptor_mac = | 381 gatt_descriptor_mac = |
| 385 new BluetoothRemoteGattDescriptorMac(this, cb_descriptor); | 382 new BluetoothRemoteGattDescriptorMac(this, cb_descriptor); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 420 | 417 |
| 421 CBCharacteristicWriteType BluetoothRemoteGattCharacteristicMac::GetCBWriteType() | 418 CBCharacteristicWriteType BluetoothRemoteGattCharacteristicMac::GetCBWriteType() |
| 422 const { | 419 const { |
| 423 return (GetProperties() & BluetoothGattCharacteristic::PROPERTY_WRITE) | 420 return (GetProperties() & BluetoothGattCharacteristic::PROPERTY_WRITE) |
| 424 ? CBCharacteristicWriteWithResponse | 421 ? CBCharacteristicWriteWithResponse |
| 425 : CBCharacteristicWriteWithoutResponse; | 422 : CBCharacteristicWriteWithoutResponse; |
| 426 } | 423 } |
| 427 | 424 |
| 428 CBCharacteristic* BluetoothRemoteGattCharacteristicMac::GetCBCharacteristic() | 425 CBCharacteristic* BluetoothRemoteGattCharacteristicMac::GetCBCharacteristic() |
| 429 const { | 426 const { |
| 430 return cb_characteristic_.get(); | 427 return cb_characteristic_; |
| 431 } | 428 } |
| 432 | 429 |
| 433 BluetoothAdapterMac* BluetoothRemoteGattCharacteristicMac::GetMacAdapter() | 430 BluetoothAdapterMac* BluetoothRemoteGattCharacteristicMac::GetMacAdapter() |
| 434 const { | 431 const { |
| 435 return gatt_service_->GetMacAdapter(); | 432 return gatt_service_->GetMacAdapter(); |
| 436 } | 433 } |
| 437 | 434 |
| 438 CBPeripheral* BluetoothRemoteGattCharacteristicMac::GetCBPeripheral() const { | 435 CBPeripheral* BluetoothRemoteGattCharacteristicMac::GetCBPeripheral() const { |
| 439 return gatt_service_->GetCBPeripheral(); | 436 return gatt_service_->GetCBPeripheral(); |
| 440 } | 437 } |
| (...skipping 26 matching lines...) Expand all Loading... |
| 467 const BluetoothRemoteGattServiceMac* service_mac = | 464 const BluetoothRemoteGattServiceMac* service_mac = |
| 468 static_cast<const BluetoothRemoteGattServiceMac*>( | 465 static_cast<const BluetoothRemoteGattServiceMac*>( |
| 469 characteristic.GetService()); | 466 characteristic.GetService()); |
| 470 return out << "<BluetoothRemoteGattCharacteristicMac " | 467 return out << "<BluetoothRemoteGattCharacteristicMac " |
| 471 << characteristic.GetUUID().canonical_value() << "/" | 468 << characteristic.GetUUID().canonical_value() << "/" |
| 472 << &characteristic | 469 << &characteristic |
| 473 << ", service: " << service_mac->GetUUID().canonical_value() << "/" | 470 << ", service: " << service_mac->GetUUID().canonical_value() << "/" |
| 474 << service_mac << ">"; | 471 << service_mac << ">"; |
| 475 } | 472 } |
| 476 } // namespace device. | 473 } // namespace device. |
| OLD | NEW |