Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(341)

Side by Side Diff: device/bluetooth/bluetooth_low_energy_device_mac.mm

Issue 2641133003: Bluetooth: macOS: Adding counter for service discovery callbacks. (Closed)
Patch Set: Adding comment Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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_low_energy_device_mac.h" 5 #include "device/bluetooth/bluetooth_low_energy_device_mac.h"
6 6
7 #import <CoreFoundation/CoreFoundation.h> 7 #import <CoreFoundation/CoreFoundation.h>
8 #include <stddef.h> 8 #include <stddef.h>
9 9
10 #include "base/mac/mac_util.h" 10 #include "base/mac/mac_util.h"
11 #include "base/mac/scoped_cftyperef.h" 11 #include "base/mac/scoped_cftyperef.h"
12 #include "base/mac/sdk_forward_declarations.h" 12 #include "base/mac/sdk_forward_declarations.h"
13 #include "base/memory/ptr_util.h" 13 #include "base/memory/ptr_util.h"
14 #include "base/strings/string_number_conversions.h" 14 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/sys_string_conversions.h" 15 #include "base/strings/sys_string_conversions.h"
16 #include "device/bluetooth/bluetooth_adapter_mac.h" 16 #include "device/bluetooth/bluetooth_adapter_mac.h"
17 #include "device/bluetooth/bluetooth_device.h" 17 #include "device/bluetooth/bluetooth_device.h"
18 #include "device/bluetooth/bluetooth_low_energy_peripheral_delegate.h" 18 #include "device/bluetooth/bluetooth_low_energy_peripheral_delegate.h"
19 #include "device/bluetooth/bluetooth_remote_gatt_service_mac.h" 19 #include "device/bluetooth/bluetooth_remote_gatt_service_mac.h"
20 20
21 using device::BluetoothDevice; 21 using device::BluetoothDevice;
22 using device::BluetoothLowEnergyDeviceMac; 22 using device::BluetoothLowEnergyDeviceMac;
23 23
24 BluetoothLowEnergyDeviceMac::BluetoothLowEnergyDeviceMac( 24 BluetoothLowEnergyDeviceMac::BluetoothLowEnergyDeviceMac(
25 BluetoothAdapterMac* adapter, 25 BluetoothAdapterMac* adapter,
26 CBPeripheral* peripheral) 26 CBPeripheral* peripheral)
27 : BluetoothDeviceMac(adapter), 27 : BluetoothDeviceMac(adapter),
28 peripheral_(peripheral, base::scoped_policy::RETAIN) { 28 peripheral_(peripheral, base::scoped_policy::RETAIN),
29 discovery_pending_count_(0) {
29 DCHECK(BluetoothAdapterMac::IsLowEnergyAvailable()); 30 DCHECK(BluetoothAdapterMac::IsLowEnergyAvailable());
30 DCHECK(peripheral_.get()); 31 DCHECK(peripheral_.get());
31 peripheral_delegate_.reset([[BluetoothLowEnergyPeripheralDelegate alloc] 32 peripheral_delegate_.reset([[BluetoothLowEnergyPeripheralDelegate alloc]
32 initWithBluetoothLowEnergyDeviceMac:this]); 33 initWithBluetoothLowEnergyDeviceMac:this]);
33 [peripheral_ setDelegate:peripheral_delegate_]; 34 [peripheral_ setDelegate:peripheral_delegate_];
34 identifier_ = GetPeripheralIdentifier(peripheral); 35 identifier_ = GetPeripheralIdentifier(peripheral);
35 hash_address_ = GetPeripheralHashAddress(peripheral); 36 hash_address_ = GetPeripheralHashAddress(peripheral);
36 UpdateTimestamp(); 37 UpdateTimestamp();
37 } 38 }
38 39
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 if (!IsGattConnected()) { 178 if (!IsGattConnected()) {
178 GetMacAdapter()->CreateGattConnection(this); 179 GetMacAdapter()->CreateGattConnection(this);
179 } 180 }
180 } 181 }
181 182
182 void BluetoothLowEnergyDeviceMac::DisconnectGatt() { 183 void BluetoothLowEnergyDeviceMac::DisconnectGatt() {
183 GetMacAdapter()->DisconnectGatt(this); 184 GetMacAdapter()->DisconnectGatt(this);
184 } 185 }
185 186
186 void BluetoothLowEnergyDeviceMac::DidDiscoverPrimaryServices(NSError* error) { 187 void BluetoothLowEnergyDeviceMac::DidDiscoverPrimaryServices(NSError* error) {
188 --discovery_pending_count_;
189 if (discovery_pending_count_ < 0) {
190 // This should never happens, just in case it happens with a device,
191 // discovery_pending_count_ is set back to 0.
192 VLOG(1) << GetName()->c_str()
193 << ": BluetoothLowEnergyDeviceMac::discovery_pending_count_ "
194 << discovery_pending_count_;
195 discovery_pending_count_ = 0;
196 return;
197 }
187 if (error) { 198 if (error) {
188 // TODO(http://crbug.com/609320): Need to pass the error. 199 // TODO(http://crbug.com/609320): Need to pass the error.
189 // TODO(http://crbug.com/609844): Decide what to do if discover failed 200 // TODO(http://crbug.com/609844): Decide what to do if discover failed
190 // a device services. 201 // a device services.
191 VLOG(1) << "Can't discover primary services: " 202 VLOG(1) << "Can't discover primary services: "
192 << error.localizedDescription.UTF8String << " (" << error.domain 203 << error.localizedDescription.UTF8String << " (" << error.domain
193 << ": " << error.code << ")"; 204 << ": " << error.code << ")";
194 return; 205 return;
195 } 206 }
196 VLOG(1) << "DidDiscoverPrimaryServices."; 207 VLOG(1) << "DidDiscoverPrimaryServices, pending count: "
208 << discovery_pending_count_;
197 209
198 if (!IsGattConnected()) { 210 if (!IsGattConnected()) {
199 // Don't create services if the device disconnected. 211 // Don't create services if the device disconnected.
200 return; 212 return;
201 } 213 }
202 214
203 for (CBService* cb_service in GetPeripheral().services) { 215 for (CBService* cb_service in GetPeripheral().services) {
204 BluetoothRemoteGattServiceMac* gatt_service = 216 BluetoothRemoteGattServiceMac* gatt_service =
205 GetBluetoothRemoteGattService(cb_service); 217 GetBluetoothRemoteGattService(cb_service);
206 if (!gatt_service) { 218 if (!gatt_service) {
207 gatt_service = new BluetoothRemoteGattServiceMac(this, cb_service, 219 gatt_service = new BluetoothRemoteGattServiceMac(this, cb_service,
208 true /* is_primary */); 220 true /* is_primary */);
209 auto result_iter = gatt_services_.insert(std::make_pair( 221 auto result_iter = gatt_services_.insert(std::make_pair(
210 gatt_service->GetIdentifier(), base::WrapUnique(gatt_service))); 222 gatt_service->GetIdentifier(), base::WrapUnique(gatt_service)));
211 DCHECK(result_iter.second); 223 DCHECK(result_iter.second);
212 adapter_->NotifyGattServiceAdded(gatt_service); 224 adapter_->NotifyGattServiceAdded(gatt_service);
213 } 225 }
214 } 226 }
215 for (auto it = gatt_services_.begin(); it != gatt_services_.end(); ++it) { 227 if (discovery_pending_count_ == 0) {
216 device::BluetoothRemoteGattService* gatt_service = it->second.get(); 228 for (auto it = gatt_services_.begin(); it != gatt_services_.end(); ++it) {
217 device::BluetoothRemoteGattServiceMac* gatt_service_mac = 229 device::BluetoothRemoteGattService* gatt_service = it->second.get();
218 static_cast<BluetoothRemoteGattServiceMac*>(gatt_service); 230 device::BluetoothRemoteGattServiceMac* gatt_service_mac =
219 gatt_service_mac->DiscoverCharacteristics(); 231 static_cast<BluetoothRemoteGattServiceMac*>(gatt_service);
232 gatt_service_mac->DiscoverCharacteristics();
233 }
234 SendNotificationIfDiscoveryComplete();
220 } 235 }
221 } 236 }
222 237
223 void BluetoothLowEnergyDeviceMac::DidDiscoverCharacteristics( 238 void BluetoothLowEnergyDeviceMac::DidDiscoverCharacteristics(
224 CBService* cb_service, 239 CBService* cb_service,
225 NSError* error) { 240 NSError* error) {
226 if (error) { 241 if (error) {
227 // TODO(http://crbug.com/609320): Need to pass the error. 242 // TODO(http://crbug.com/609320): Need to pass the error.
228 // TODO(http://crbug.com/609844): Decide what to do if discover failed 243 // TODO(http://crbug.com/609844): Decide what to do if discover failed
229 VLOG(1) << "Can't discover characteristics: " 244 VLOG(1) << "Can't discover characteristics: "
(...skipping 24 matching lines...) Expand all
254 DCHECK(gatt_service); 269 DCHECK(gatt_service);
255 VLOG(1) << gatt_service->GetUUID().canonical_value(); 270 VLOG(1) << gatt_service->GetUUID().canonical_value();
256 std::unique_ptr<BluetoothRemoteGattService> scoped_service = 271 std::unique_ptr<BluetoothRemoteGattService> scoped_service =
257 std::move(gatt_services_[gatt_service->GetIdentifier()]); 272 std::move(gatt_services_[gatt_service->GetIdentifier()]);
258 gatt_services_.erase(gatt_service->GetIdentifier()); 273 gatt_services_.erase(gatt_service->GetIdentifier());
259 adapter_->NotifyGattServiceRemoved(scoped_service.get()); 274 adapter_->NotifyGattServiceRemoved(scoped_service.get());
260 } 275 }
261 device_uuids_.ClearServiceUUIDs(); 276 device_uuids_.ClearServiceUUIDs();
262 SetGattServicesDiscoveryComplete(false); 277 SetGattServicesDiscoveryComplete(false);
263 adapter_->NotifyDeviceChanged(this); 278 adapter_->NotifyDeviceChanged(this);
264 [GetPeripheral() discoverServices:nil]; 279 DiscoverPrimaryServices();
265 } 280 }
266 281
267 void BluetoothLowEnergyDeviceMac::DidUpdateValue( 282 void BluetoothLowEnergyDeviceMac::DidUpdateValue(
268 CBCharacteristic* characteristic, 283 CBCharacteristic* characteristic,
269 NSError* error) { 284 NSError* error) {
270 VLOG(1) << "DidUpdateValue."; 285 VLOG(1) << "DidUpdateValue.";
271 BluetoothRemoteGattServiceMac* gatt_service = 286 BluetoothRemoteGattServiceMac* gatt_service =
272 GetBluetoothRemoteGattService(characteristic.service); 287 GetBluetoothRemoteGattService(characteristic.service);
273 DCHECK(gatt_service); 288 DCHECK(gatt_service);
274 gatt_service->DidUpdateValue(characteristic, error); 289 gatt_service->DidUpdateValue(characteristic, error);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 std::string BluetoothLowEnergyDeviceMac::GetPeripheralHashAddress( 345 std::string BluetoothLowEnergyDeviceMac::GetPeripheralHashAddress(
331 CBPeripheral* peripheral) { 346 CBPeripheral* peripheral) {
332 const size_t kCanonicalAddressNumberOfBytes = 6; 347 const size_t kCanonicalAddressNumberOfBytes = 6;
333 char raw[kCanonicalAddressNumberOfBytes]; 348 char raw[kCanonicalAddressNumberOfBytes];
334 crypto::SHA256HashString(GetPeripheralIdentifier(peripheral), raw, 349 crypto::SHA256HashString(GetPeripheralIdentifier(peripheral), raw,
335 sizeof(raw)); 350 sizeof(raw));
336 std::string hash = base::HexEncode(raw, sizeof(raw)); 351 std::string hash = base::HexEncode(raw, sizeof(raw));
337 return BluetoothDevice::CanonicalizeAddress(hash); 352 return BluetoothDevice::CanonicalizeAddress(hash);
338 } 353 }
339 354
355 void BluetoothLowEnergyDeviceMac::DiscoverPrimaryServices() {
356 VLOG(1) << "DidDiscoverDescriptors pending count" << discovery_pending_count_;
357 ++discovery_pending_count_;
358 [GetPeripheral() discoverServices:nil];
359 }
360
340 void BluetoothLowEnergyDeviceMac::SendNotificationIfDiscoveryComplete() { 361 void BluetoothLowEnergyDeviceMac::SendNotificationIfDiscoveryComplete() {
341 // Notify when all services have been discovered. 362 // Notify when all services have been discovered.
342 bool discovery_complete = 363 bool discovery_complete =
364 discovery_pending_count_ == 0 &&
343 std::find_if_not( 365 std::find_if_not(
344 gatt_services_.begin(), gatt_services_.end(), 366 gatt_services_.begin(),
345 [](GattServiceMap::value_type& pair) { 367 gatt_services_.end(), [](GattServiceMap::value_type & pair) {
346 BluetoothRemoteGattService* gatt_service = pair.second.get(); 368 BluetoothRemoteGattService* gatt_service = pair.second.get();
347 return static_cast<BluetoothRemoteGattServiceMac*>(gatt_service) 369 return static_cast<BluetoothRemoteGattServiceMac*>(gatt_service)
348 ->IsDiscoveryComplete(); 370 ->IsDiscoveryComplete();
349 }) == gatt_services_.end(); 371 }) == gatt_services_.end();
350 if (discovery_complete) { 372 if (discovery_complete) {
351 device_uuids_.ReplaceServiceUUIDs(gatt_services_); 373 device_uuids_.ReplaceServiceUUIDs(gatt_services_);
352 SetGattServicesDiscoveryComplete(true); 374 SetGattServicesDiscoveryComplete(true);
353 adapter_->NotifyGattServicesDiscovered(this); 375 adapter_->NotifyGattServicesDiscovered(this);
354 adapter_->NotifyDeviceChanged(this); 376 adapter_->NotifyDeviceChanged(this);
355 } 377 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 // 2. When we cancel a pending connection request. 412 // 2. When we cancel a pending connection request.
391 if (create_gatt_connection_error_callbacks_.empty()) { 413 if (create_gatt_connection_error_callbacks_.empty()) {
392 // If there are no pending callbacks then the connection broke (#1). 414 // If there are no pending callbacks then the connection broke (#1).
393 DidDisconnectGatt(true /* notifyDeviceChanged */); 415 DidDisconnectGatt(true /* notifyDeviceChanged */);
394 return; 416 return;
395 } 417 }
396 // Else we canceled the connection request (#2). 418 // Else we canceled the connection request (#2).
397 // TODO(http://crbug.com/585897): Need to pass the error. 419 // TODO(http://crbug.com/585897): Need to pass the error.
398 DidFailToConnectGatt(BluetoothDevice::ConnectErrorCode::ERROR_FAILED); 420 DidFailToConnectGatt(BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
399 } 421 }
OLDNEW
« no previous file with comments | « device/bluetooth/bluetooth_low_energy_device_mac.h ('k') | device/bluetooth/test/bluetooth_test_mac.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698