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