| 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_service_mac.h" | 5 #include "device/bluetooth/bluetooth_remote_gatt_service_mac.h" |
| 6 | 6 |
| 7 #import <CoreBluetooth/CoreBluetooth.h> | 7 #import <CoreBluetooth/CoreBluetooth.h> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/memory/ptr_util.h" | 11 #include "base/memory/ptr_util.h" |
| 12 #include "device/bluetooth/bluetooth_adapter_mac.h" | 12 #include "device/bluetooth/bluetooth_adapter_mac.h" |
| 13 #include "device/bluetooth/bluetooth_low_energy_device_mac.h" | 13 #include "device/bluetooth/bluetooth_low_energy_device_mac.h" |
| 14 #include "device/bluetooth/bluetooth_remote_gatt_characteristic_mac.h" | 14 #include "device/bluetooth/bluetooth_remote_gatt_characteristic_mac.h" |
| 15 #include "device/bluetooth/bluetooth_uuid.h" | 15 #include "device/bluetooth/bluetooth_uuid.h" |
| 16 | 16 |
| 17 namespace device { | 17 namespace device { |
| 18 | 18 |
| 19 BluetoothRemoteGattServiceMac::BluetoothRemoteGattServiceMac( | 19 BluetoothRemoteGattServiceMac::BluetoothRemoteGattServiceMac( |
| 20 BluetoothLowEnergyDeviceMac* bluetooth_device_mac, | 20 BluetoothLowEnergyDeviceMac* bluetooth_device_mac, |
| 21 CBService* service, | 21 CBService* service, |
| 22 bool is_primary) | 22 bool is_primary) |
| 23 : bluetooth_device_mac_(bluetooth_device_mac), | 23 : bluetooth_device_mac_(bluetooth_device_mac), |
| 24 service_(service, base::scoped_policy::RETAIN), | 24 service_(service, base::scoped_policy::RETAIN), |
| 25 is_primary_(is_primary), | 25 is_primary_(is_primary), |
| 26 is_discovery_complete_(false) { | 26 is_discovery_complete_(false), |
| 27 discovery_pending_count_(0) { |
| 27 uuid_ = BluetoothAdapterMac::BluetoothUUIDWithCBUUID([service_.get() UUID]); | 28 uuid_ = BluetoothAdapterMac::BluetoothUUIDWithCBUUID([service_.get() UUID]); |
| 28 identifier_ = | 29 identifier_ = |
| 29 [NSString stringWithFormat:@"%s-%p", uuid_.canonical_value().c_str(), | 30 [NSString stringWithFormat:@"%s-%p", uuid_.canonical_value().c_str(), |
| 30 (void*)service_] | 31 (void*)service_] |
| 31 .UTF8String; | 32 .UTF8String; |
| 32 } | 33 } |
| 33 | 34 |
| 34 BluetoothRemoteGattServiceMac::~BluetoothRemoteGattServiceMac() {} | 35 BluetoothRemoteGattServiceMac::~BluetoothRemoteGattServiceMac() {} |
| 35 | 36 |
| 36 std::string BluetoothRemoteGattServiceMac::GetIdentifier() const { | 37 std::string BluetoothRemoteGattServiceMac::GetIdentifier() const { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 73 if (searched_pair == gatt_characteristic_macs_.end()) { | 74 if (searched_pair == gatt_characteristic_macs_.end()) { |
| 74 return nullptr; | 75 return nullptr; |
| 75 } | 76 } |
| 76 return static_cast<BluetoothRemoteGattCharacteristic*>( | 77 return static_cast<BluetoothRemoteGattCharacteristic*>( |
| 77 searched_pair->second.get()); | 78 searched_pair->second.get()); |
| 78 } | 79 } |
| 79 | 80 |
| 80 void BluetoothRemoteGattServiceMac::DiscoverCharacteristics() { | 81 void BluetoothRemoteGattServiceMac::DiscoverCharacteristics() { |
| 81 VLOG(1) << *this << ": DiscoverCharacteristics."; | 82 VLOG(1) << *this << ": DiscoverCharacteristics."; |
| 82 is_discovery_complete_ = false; | 83 is_discovery_complete_ = false; |
| 84 ++discovery_pending_count_; |
| 83 [GetCBPeripheral() discoverCharacteristics:nil forService:GetService()]; | 85 [GetCBPeripheral() discoverCharacteristics:nil forService:GetService()]; |
| 84 } | 86 } |
| 85 | 87 |
| 86 void BluetoothRemoteGattServiceMac::DidDiscoverCharacteristics() { | 88 void BluetoothRemoteGattServiceMac::DidDiscoverCharacteristics() { |
| 87 DCHECK(!is_discovery_complete_); | 89 if (is_discovery_complete_ || discovery_pending_count_ == 0) { |
| 90 // This should never happen, just in case it happens with a device, this |
| 91 // notification should be ignored. |
| 92 VLOG(1) |
| 93 << *this |
| 94 << ": Unmatch DiscoverCharacteristics and DidDiscoverCharacteristics."; |
| 95 return; |
| 96 } |
| 88 VLOG(1) << *this << ": DidDiscoverCharacteristics."; | 97 VLOG(1) << *this << ": DidDiscoverCharacteristics."; |
| 98 --discovery_pending_count_; |
| 89 std::unordered_set<std::string> characteristic_identifier_to_remove; | 99 std::unordered_set<std::string> characteristic_identifier_to_remove; |
| 90 for (const auto& iter : gatt_characteristic_macs_) { | 100 for (const auto& iter : gatt_characteristic_macs_) { |
| 91 characteristic_identifier_to_remove.insert(iter.first); | 101 characteristic_identifier_to_remove.insert(iter.first); |
| 92 } | 102 } |
| 93 | 103 |
| 94 for (CBCharacteristic* cb_characteristic in GetService().characteristics) { | 104 for (CBCharacteristic* cb_characteristic in GetService().characteristics) { |
| 95 BluetoothRemoteGattCharacteristicMac* gatt_characteristic_mac = | 105 BluetoothRemoteGattCharacteristicMac* gatt_characteristic_mac = |
| 96 GetBluetoothRemoteGattCharacteristicMac(cb_characteristic); | 106 GetBluetoothRemoteGattCharacteristicMac(cb_characteristic); |
| 97 if (gatt_characteristic_mac) { | 107 if (gatt_characteristic_mac) { |
| 98 VLOG(1) << *gatt_characteristic_mac | 108 VLOG(1) << *gatt_characteristic_mac |
| 99 << ": Known characteristic, properties " | 109 << ": Known characteristic, properties " |
| 100 << gatt_characteristic_mac->GetProperties(); | 110 << gatt_characteristic_mac->GetProperties(); |
| 101 const std::string& identifier = gatt_characteristic_mac->GetIdentifier(); | 111 const std::string& identifier = gatt_characteristic_mac->GetIdentifier(); |
| 102 characteristic_identifier_to_remove.erase(identifier); | 112 characteristic_identifier_to_remove.erase(identifier); |
| 103 gatt_characteristic_mac->DiscoverDescriptors(); | 113 gatt_characteristic_mac->DiscoverDescriptors(); |
| 104 continue; | 114 continue; |
| 105 } | 115 } |
| 106 gatt_characteristic_mac = | 116 gatt_characteristic_mac = |
| 107 new BluetoothRemoteGattCharacteristicMac(this, cb_characteristic); | 117 new BluetoothRemoteGattCharacteristicMac(this, cb_characteristic); |
| 108 const std::string& identifier = gatt_characteristic_mac->GetIdentifier(); | 118 const std::string& identifier = gatt_characteristic_mac->GetIdentifier(); |
| 109 auto result_iter = gatt_characteristic_macs_.insert( | 119 auto result_iter = gatt_characteristic_macs_.insert( |
| 110 {identifier, base::WrapUnique(gatt_characteristic_mac)}); | 120 {identifier, base::WrapUnique(gatt_characteristic_mac)}); |
| 111 DCHECK(result_iter.second); | 121 DCHECK(result_iter.second); |
| 112 VLOG(1) << *gatt_characteristic_mac << ": New characteristic, properties " | 122 VLOG(1) << *gatt_characteristic_mac << ": New characteristic, properties " |
| 113 << gatt_characteristic_mac->GetProperties(); | 123 << gatt_characteristic_mac->GetProperties(); |
| 114 gatt_characteristic_mac->DiscoverDescriptors(); | 124 if (discovery_pending_count_ == 0) { |
| 125 gatt_characteristic_mac->DiscoverDescriptors(); |
| 126 } |
| 115 GetMacAdapter()->NotifyGattCharacteristicAdded(gatt_characteristic_mac); | 127 GetMacAdapter()->NotifyGattCharacteristicAdded(gatt_characteristic_mac); |
| 116 } | 128 } |
| 117 | 129 |
| 118 for (const std::string& identifier : characteristic_identifier_to_remove) { | 130 for (const std::string& identifier : characteristic_identifier_to_remove) { |
| 119 auto pair_to_remove = gatt_characteristic_macs_.find(identifier); | 131 auto pair_to_remove = gatt_characteristic_macs_.find(identifier); |
| 120 std::unique_ptr<BluetoothRemoteGattCharacteristicMac> | 132 std::unique_ptr<BluetoothRemoteGattCharacteristicMac> |
| 121 characteristic_to_remove; | 133 characteristic_to_remove; |
| 122 pair_to_remove->second.swap(characteristic_to_remove); | 134 pair_to_remove->second.swap(characteristic_to_remove); |
| 123 VLOG(1) << *characteristic_to_remove << ": Removed characteristic."; | 135 VLOG(1) << *characteristic_to_remove << ": Removed characteristic."; |
| 124 gatt_characteristic_macs_.erase(pair_to_remove); | 136 gatt_characteristic_macs_.erase(pair_to_remove); |
| 125 GetMacAdapter()->NotifyGattCharacteristicRemoved( | 137 GetMacAdapter()->NotifyGattCharacteristicRemoved( |
| 126 characteristic_to_remove.get()); | 138 characteristic_to_remove.get()); |
| 127 } | 139 } |
| 128 SendNotificationIfComplete(); | 140 SendNotificationIfComplete(); |
| 129 } | 141 } |
| 130 | 142 |
| 131 void BluetoothRemoteGattServiceMac::DidDiscoverDescriptors( | 143 void BluetoothRemoteGattServiceMac::DidDiscoverDescriptors( |
| 132 CBCharacteristic* characteristic) { | 144 CBCharacteristic* characteristic) { |
| 133 DCHECK(!is_discovery_complete_); | 145 if (is_discovery_complete_) { |
| 146 // This should never happen, just in case it happens with a device, this |
| 147 // notification should be ignored. |
| 148 VLOG(1) << *this |
| 149 << ": Discovery complete, ignoring DidDiscoverDescriptors."; |
| 150 return; |
| 151 } |
| 134 BluetoothRemoteGattCharacteristicMac* gatt_characteristic = | 152 BluetoothRemoteGattCharacteristicMac* gatt_characteristic = |
| 135 GetBluetoothRemoteGattCharacteristicMac(characteristic); | 153 GetBluetoothRemoteGattCharacteristicMac(characteristic); |
| 136 DCHECK(gatt_characteristic); | 154 DCHECK(gatt_characteristic); |
| 137 gatt_characteristic->DidDiscoverDescriptors(); | 155 gatt_characteristic->DidDiscoverDescriptors(); |
| 138 SendNotificationIfComplete(); | 156 SendNotificationIfComplete(); |
| 139 } | 157 } |
| 140 | 158 |
| 141 void BluetoothRemoteGattServiceMac::SendNotificationIfComplete() { | 159 void BluetoothRemoteGattServiceMac::SendNotificationIfComplete() { |
| 142 DCHECK(!is_discovery_complete_); | 160 DCHECK(!is_discovery_complete_); |
| 143 // Notify when all characteristics have been fully discovered. | 161 // Notify when all characteristics have been fully discovered. |
| 144 is_discovery_complete_ = | 162 is_discovery_complete_ = |
| 163 discovery_pending_count_ == 0 && |
| 145 std::find_if_not( | 164 std::find_if_not( |
| 146 gatt_characteristic_macs_.begin(), gatt_characteristic_macs_.end(), | 165 gatt_characteristic_macs_.begin(), gatt_characteristic_macs_.end(), |
| 147 [](const std::pair< | 166 [](const std::pair< |
| 148 const std::string, | 167 const std::string, |
| 149 std::unique_ptr<BluetoothRemoteGattCharacteristicMac>>& pair) { | 168 std::unique_ptr<BluetoothRemoteGattCharacteristicMac>>& pair) { |
| 150 return pair.second->IsDiscoveryComplete(); | 169 return pair.second->IsDiscoveryComplete(); |
| 151 }) == gatt_characteristic_macs_.end(); | 170 }) == gatt_characteristic_macs_.end(); |
| 152 if (is_discovery_complete_) { | 171 if (is_discovery_complete_) { |
| 153 VLOG(1) << *this << ": Discovery complete."; | 172 VLOG(1) << *this << ": Discovery complete."; |
| 154 GetMacAdapter()->NotifyGattServiceChanged(this); | 173 GetMacAdapter()->NotifyGattServiceChanged(this); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 221 const BluetoothRemoteGattServiceMac& service) { | 240 const BluetoothRemoteGattServiceMac& service) { |
| 222 const BluetoothLowEnergyDeviceMac* bluetooth_device_mac_ = | 241 const BluetoothLowEnergyDeviceMac* bluetooth_device_mac_ = |
| 223 static_cast<const BluetoothLowEnergyDeviceMac*>(service.GetDevice()); | 242 static_cast<const BluetoothLowEnergyDeviceMac*>(service.GetDevice()); |
| 224 return out << "<BluetoothRemoteGattServiceMac " | 243 return out << "<BluetoothRemoteGattServiceMac " |
| 225 << service.GetUUID().canonical_value() << "/" << &service | 244 << service.GetUUID().canonical_value() << "/" << &service |
| 226 << ", device: " << bluetooth_device_mac_->GetAddress() << "/" | 245 << ", device: " << bluetooth_device_mac_->GetAddress() << "/" |
| 227 << bluetooth_device_mac_ << ">"; | 246 << bluetooth_device_mac_ << ">"; |
| 228 } | 247 } |
| 229 | 248 |
| 230 } // namespace device | 249 } // namespace device |
| OLD | NEW |