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 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
62 DCHECK(false); | 62 DCHECK(false); |
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 : is_discovery_complete_(false), |
| 73 discovery_pending_count_(0), |
| 74 gatt_service_(gatt_service), |
73 cb_characteristic_(cb_characteristic, base::scoped_policy::RETAIN) { | 75 cb_characteristic_(cb_characteristic, base::scoped_policy::RETAIN) { |
74 uuid_ = BluetoothAdapterMac::BluetoothUUIDWithCBUUID( | 76 uuid_ = BluetoothAdapterMac::BluetoothUUIDWithCBUUID( |
75 [cb_characteristic_.get() UUID]); | 77 [cb_characteristic_.get() UUID]); |
76 identifier_ = base::SysNSStringToUTF8( | 78 identifier_ = base::SysNSStringToUTF8( |
77 [NSString stringWithFormat:@"%s-%p", uuid_.canonical_value().c_str(), | 79 [NSString stringWithFormat:@"%s-%p", uuid_.canonical_value().c_str(), |
78 (void*)cb_characteristic_]); | 80 (void*)cb_characteristic_]); |
79 } | 81 } |
80 | 82 |
81 BluetoothRemoteGattCharacteristicMac::~BluetoothRemoteGattCharacteristicMac() { | 83 BluetoothRemoteGattCharacteristicMac::~BluetoothRemoteGattCharacteristicMac() { |
82 if (HasPendingRead()) { | 84 if (HasPendingRead()) { |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
235 DCHECK(unsubscribe_from_notification_callbacks_.second.is_null()); | 237 DCHECK(unsubscribe_from_notification_callbacks_.second.is_null()); |
236 unsubscribe_from_notification_callbacks_ = | 238 unsubscribe_from_notification_callbacks_ = |
237 std::make_pair(callback, error_callback); | 239 std::make_pair(callback, error_callback); |
238 [GetCBPeripheral() setNotifyValue:NO | 240 [GetCBPeripheral() setNotifyValue:NO |
239 forCharacteristic:cb_characteristic_.get()]; | 241 forCharacteristic:cb_characteristic_.get()]; |
240 } | 242 } |
241 | 243 |
242 void BluetoothRemoteGattCharacteristicMac::DiscoverDescriptors() { | 244 void BluetoothRemoteGattCharacteristicMac::DiscoverDescriptors() { |
243 VLOG(1) << *this << ": Discover descriptors."; | 245 VLOG(1) << *this << ": Discover descriptors."; |
244 is_discovery_complete_ = false; | 246 is_discovery_complete_ = false; |
| 247 ++discovery_pending_count_; |
245 [GetCBPeripheral() | 248 [GetCBPeripheral() |
246 discoverDescriptorsForCharacteristic:cb_characteristic_.get()]; | 249 discoverDescriptorsForCharacteristic:cb_characteristic_.get()]; |
247 } | 250 } |
248 | 251 |
249 void BluetoothRemoteGattCharacteristicMac::DidUpdateValue(NSError* error) { | 252 void BluetoothRemoteGattCharacteristicMac::DidUpdateValue(NSError* error) { |
250 CHECK_EQ(GetCBPeripheral().state, CBPeripheralStateConnected); | 253 CHECK_EQ(GetCBPeripheral().state, CBPeripheralStateConnected); |
251 // This method is called when the characteristic is read and when a | 254 // This method is called when the characteristic is read and when a |
252 // notification is received. | 255 // notification is received. |
253 if (HasPendingRead()) { | 256 if (HasPendingRead()) { |
254 std::pair<ValueCallback, ErrorCallback> callbacks; | 257 std::pair<ValueCallback, ErrorCallback> callbacks; |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
333 "characteristic, error: " | 336 "characteristic, error: " |
334 << BluetoothAdapterMac::String(error) | 337 << BluetoothAdapterMac::String(error) |
335 << ", error code: " << error_code; | 338 << ", error code: " << error_code; |
336 reentrant_safe_callbacks.second.Run(error_code); | 339 reentrant_safe_callbacks.second.Run(error_code); |
337 return; | 340 return; |
338 } | 341 } |
339 reentrant_safe_callbacks.first.Run(); | 342 reentrant_safe_callbacks.first.Run(); |
340 } | 343 } |
341 | 344 |
342 void BluetoothRemoteGattCharacteristicMac::DidDiscoverDescriptors() { | 345 void BluetoothRemoteGattCharacteristicMac::DidDiscoverDescriptors() { |
343 DCHECK(!is_discovery_complete_); | 346 if (discovery_pending_count_ == 0) { |
| 347 // This should never happen, just in case it happens with a device, this |
| 348 // notification should be ignored. |
| 349 VLOG(1) << *this |
| 350 << ": Unmatch DiscoverDescriptors and DidDiscoverDescriptors."; |
| 351 return; |
| 352 } |
344 VLOG(1) << *this << ": Did discover descriptors."; | 353 VLOG(1) << *this << ": Did discover descriptors."; |
| 354 --discovery_pending_count_; |
345 std::unordered_set<std::string> descriptor_identifier_to_remove; | 355 std::unordered_set<std::string> descriptor_identifier_to_remove; |
346 for (const auto& iter : gatt_descriptor_macs_) { | 356 for (const auto& iter : gatt_descriptor_macs_) { |
347 descriptor_identifier_to_remove.insert(iter.first); | 357 descriptor_identifier_to_remove.insert(iter.first); |
348 } | 358 } |
349 | 359 |
350 for (CBDescriptor* cb_descriptor in cb_characteristic_.get().descriptors) { | 360 for (CBDescriptor* cb_descriptor in cb_characteristic_.get().descriptors) { |
351 BluetoothRemoteGattDescriptorMac* gatt_descriptor_mac = | 361 BluetoothRemoteGattDescriptorMac* gatt_descriptor_mac = |
352 GetBluetoothRemoteGattDescriptorMac(cb_descriptor); | 362 GetBluetoothRemoteGattDescriptorMac(cb_descriptor); |
353 if (gatt_descriptor_mac) { | 363 if (gatt_descriptor_mac) { |
354 VLOG(1) << *gatt_descriptor_mac << ": Known descriptor."; | 364 VLOG(1) << *gatt_descriptor_mac << ": Known descriptor."; |
(...skipping 12 matching lines...) Expand all Loading... |
367 } | 377 } |
368 | 378 |
369 for (const std::string& identifier : descriptor_identifier_to_remove) { | 379 for (const std::string& identifier : descriptor_identifier_to_remove) { |
370 auto pair_to_remove = gatt_descriptor_macs_.find(identifier); | 380 auto pair_to_remove = gatt_descriptor_macs_.find(identifier); |
371 std::unique_ptr<BluetoothRemoteGattDescriptorMac> descriptor_to_remove; | 381 std::unique_ptr<BluetoothRemoteGattDescriptorMac> descriptor_to_remove; |
372 VLOG(1) << *descriptor_to_remove << ": Removed descriptor."; | 382 VLOG(1) << *descriptor_to_remove << ": Removed descriptor."; |
373 pair_to_remove->second.swap(descriptor_to_remove); | 383 pair_to_remove->second.swap(descriptor_to_remove); |
374 gatt_descriptor_macs_.erase(pair_to_remove); | 384 gatt_descriptor_macs_.erase(pair_to_remove); |
375 GetMacAdapter()->NotifyGattDescriptorRemoved(descriptor_to_remove.get()); | 385 GetMacAdapter()->NotifyGattDescriptorRemoved(descriptor_to_remove.get()); |
376 } | 386 } |
377 is_discovery_complete_ = true; | 387 is_discovery_complete_ = discovery_pending_count_ == 0; |
378 } | 388 } |
379 | 389 |
380 bool BluetoothRemoteGattCharacteristicMac::IsReadable() const { | 390 bool BluetoothRemoteGattCharacteristicMac::IsReadable() const { |
381 return GetProperties() & BluetoothGattCharacteristic::PROPERTY_READ; | 391 return GetProperties() & BluetoothGattCharacteristic::PROPERTY_READ; |
382 } | 392 } |
383 | 393 |
384 bool BluetoothRemoteGattCharacteristicMac::IsWritable() const { | 394 bool BluetoothRemoteGattCharacteristicMac::IsWritable() const { |
385 BluetoothGattCharacteristic::Properties properties = GetProperties(); | 395 BluetoothGattCharacteristic::Properties properties = GetProperties(); |
386 return (properties & BluetoothGattCharacteristic::PROPERTY_WRITE) || | 396 return (properties & BluetoothGattCharacteristic::PROPERTY_WRITE) || |
387 (properties & PROPERTY_WRITE_WITHOUT_RESPONSE); | 397 (properties & PROPERTY_WRITE_WITHOUT_RESPONSE); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
442 const BluetoothRemoteGattServiceMac* service_mac = | 452 const BluetoothRemoteGattServiceMac* service_mac = |
443 static_cast<const BluetoothRemoteGattServiceMac*>( | 453 static_cast<const BluetoothRemoteGattServiceMac*>( |
444 characteristic.GetService()); | 454 characteristic.GetService()); |
445 return out << "<BluetoothRemoteGattCharacteristicMac " | 455 return out << "<BluetoothRemoteGattCharacteristicMac " |
446 << characteristic.GetUUID().canonical_value() << "/" | 456 << characteristic.GetUUID().canonical_value() << "/" |
447 << &characteristic | 457 << &characteristic |
448 << ", service: " << service_mac->GetUUID().canonical_value() << "/" | 458 << ", service: " << service_mac->GetUUID().canonical_value() << "/" |
449 << service_mac << ">"; | 459 << service_mac << ">"; |
450 } | 460 } |
451 } // namespace device. | 461 } // namespace device. |
OLD | NEW |