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

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: Splitting test 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;
ortuno 2017/02/28 02:06:50 I think just return. I don't think we want to star
jlebel 2017/02/28 23:16:18 ok.
196 }
187 if (error) { 197 if (error) {
188 // TODO(http://crbug.com/609320): Need to pass the error. 198 // TODO(http://crbug.com/609320): Need to pass the error.
189 // TODO(http://crbug.com/609844): Decide what to do if discover failed 199 // TODO(http://crbug.com/609844): Decide what to do if discover failed
190 // a device services. 200 // a device services.
191 VLOG(1) << "Can't discover primary services: " 201 VLOG(1) << "Can't discover primary services: "
192 << error.localizedDescription.UTF8String << " (" << error.domain 202 << error.localizedDescription.UTF8String << " (" << error.domain
193 << ": " << error.code << ")"; 203 << ": " << error.code << ")";
194 return; 204 return;
195 } 205 }
196 VLOG(1) << "DidDiscoverPrimaryServices."; 206 VLOG(1) << "DidDiscoverPrimaryServices, pending count: "
207 << discovery_pending_count_;
197 208
198 if (!IsGattConnected()) { 209 if (!IsGattConnected()) {
199 // Don't create services if the device disconnected. 210 // Don't create services if the device disconnected.
200 return; 211 return;
201 } 212 }
202 213
203 for (CBService* cb_service in GetPeripheral().services) { 214 for (CBService* cb_service in GetPeripheral().services) {
204 BluetoothRemoteGattServiceMac* gatt_service = 215 BluetoothRemoteGattServiceMac* gatt_service =
205 GetBluetoothRemoteGattService(cb_service); 216 GetBluetoothRemoteGattService(cb_service);
206 if (!gatt_service) { 217 if (!gatt_service) {
207 gatt_service = new BluetoothRemoteGattServiceMac(this, cb_service, 218 gatt_service = new BluetoothRemoteGattServiceMac(this, cb_service,
208 true /* is_primary */); 219 true /* is_primary */);
209 auto result_iter = gatt_services_.insert(std::make_pair( 220 auto result_iter = gatt_services_.insert(std::make_pair(
210 gatt_service->GetIdentifier(), base::WrapUnique(gatt_service))); 221 gatt_service->GetIdentifier(), base::WrapUnique(gatt_service)));
211 DCHECK(result_iter.second); 222 DCHECK(result_iter.second);
212 adapter_->NotifyGattServiceAdded(gatt_service); 223 adapter_->NotifyGattServiceAdded(gatt_service);
213 } 224 }
214 } 225 }
215 for (auto it = gatt_services_.begin(); it != gatt_services_.end(); ++it) { 226 if (discovery_pending_count_ == 0) {
216 device::BluetoothRemoteGattService* gatt_service = it->second.get(); 227 for (auto it = gatt_services_.begin(); it != gatt_services_.end(); ++it) {
217 device::BluetoothRemoteGattServiceMac* gatt_service_mac = 228 device::BluetoothRemoteGattService* gatt_service = it->second.get();
218 static_cast<BluetoothRemoteGattServiceMac*>(gatt_service); 229 device::BluetoothRemoteGattServiceMac* gatt_service_mac =
219 gatt_service_mac->DiscoverCharacteristics(); 230 static_cast<BluetoothRemoteGattServiceMac*>(gatt_service);
231 gatt_service_mac->DiscoverCharacteristics();
232 }
233 SendNotificationIfDiscoveryComplete();
220 } 234 }
221 } 235 }
222 236
223 void BluetoothLowEnergyDeviceMac::DidDiscoverCharacteristics( 237 void BluetoothLowEnergyDeviceMac::DidDiscoverCharacteristics(
224 CBService* cb_service, 238 CBService* cb_service,
225 NSError* error) { 239 NSError* error) {
226 if (error) { 240 if (error) {
227 // TODO(http://crbug.com/609320): Need to pass the error. 241 // TODO(http://crbug.com/609320): Need to pass the error.
228 // TODO(http://crbug.com/609844): Decide what to do if discover failed 242 // TODO(http://crbug.com/609844): Decide what to do if discover failed
229 VLOG(1) << "Can't discover characteristics: " 243 VLOG(1) << "Can't discover characteristics: "
(...skipping 24 matching lines...) Expand all
254 DCHECK(gatt_service); 268 DCHECK(gatt_service);
255 VLOG(1) << gatt_service->GetUUID().canonical_value(); 269 VLOG(1) << gatt_service->GetUUID().canonical_value();
256 std::unique_ptr<BluetoothRemoteGattService> scoped_service = 270 std::unique_ptr<BluetoothRemoteGattService> scoped_service =
257 std::move(gatt_services_[gatt_service->GetIdentifier()]); 271 std::move(gatt_services_[gatt_service->GetIdentifier()]);
258 gatt_services_.erase(gatt_service->GetIdentifier()); 272 gatt_services_.erase(gatt_service->GetIdentifier());
259 adapter_->NotifyGattServiceRemoved(scoped_service.get()); 273 adapter_->NotifyGattServiceRemoved(scoped_service.get());
260 } 274 }
261 device_uuids_.ClearServiceUUIDs(); 275 device_uuids_.ClearServiceUUIDs();
262 SetGattServicesDiscoveryComplete(false); 276 SetGattServicesDiscoveryComplete(false);
263 adapter_->NotifyDeviceChanged(this); 277 adapter_->NotifyDeviceChanged(this);
264 [GetPeripheral() discoverServices:nil]; 278 DiscoverPrimaryServices();
265 } 279 }
266 280
267 void BluetoothLowEnergyDeviceMac::DidUpdateValue( 281 void BluetoothLowEnergyDeviceMac::DidUpdateValue(
268 CBCharacteristic* characteristic, 282 CBCharacteristic* characteristic,
269 NSError* error) { 283 NSError* error) {
270 VLOG(1) << "DidUpdateValue."; 284 VLOG(1) << "DidUpdateValue.";
271 BluetoothRemoteGattServiceMac* gatt_service = 285 BluetoothRemoteGattServiceMac* gatt_service =
272 GetBluetoothRemoteGattService(characteristic.service); 286 GetBluetoothRemoteGattService(characteristic.service);
273 DCHECK(gatt_service); 287 DCHECK(gatt_service);
274 gatt_service->DidUpdateValue(characteristic, error); 288 gatt_service->DidUpdateValue(characteristic, error);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 std::string BluetoothLowEnergyDeviceMac::GetPeripheralHashAddress( 344 std::string BluetoothLowEnergyDeviceMac::GetPeripheralHashAddress(
331 CBPeripheral* peripheral) { 345 CBPeripheral* peripheral) {
332 const size_t kCanonicalAddressNumberOfBytes = 6; 346 const size_t kCanonicalAddressNumberOfBytes = 6;
333 char raw[kCanonicalAddressNumberOfBytes]; 347 char raw[kCanonicalAddressNumberOfBytes];
334 crypto::SHA256HashString(GetPeripheralIdentifier(peripheral), raw, 348 crypto::SHA256HashString(GetPeripheralIdentifier(peripheral), raw,
335 sizeof(raw)); 349 sizeof(raw));
336 std::string hash = base::HexEncode(raw, sizeof(raw)); 350 std::string hash = base::HexEncode(raw, sizeof(raw));
337 return BluetoothDevice::CanonicalizeAddress(hash); 351 return BluetoothDevice::CanonicalizeAddress(hash);
338 } 352 }
339 353
354 void BluetoothLowEnergyDeviceMac::DiscoverPrimaryServices() {
355 VLOG(1) << "DidDiscoverDescriptors pending count" << discovery_pending_count_;
356 ++discovery_pending_count_;
357 [GetPeripheral() discoverServices:nil];
358 }
359
340 void BluetoothLowEnergyDeviceMac::SendNotificationIfDiscoveryComplete() { 360 void BluetoothLowEnergyDeviceMac::SendNotificationIfDiscoveryComplete() {
341 // Notify when all services have been discovered. 361 // Notify when all services have been discovered.
342 bool discovery_complete = 362 bool discovery_complete =
363 discovery_pending_count_ == 0 &&
343 std::find_if_not( 364 std::find_if_not(
344 gatt_services_.begin(), gatt_services_.end(), 365 gatt_services_.begin(),
345 [](GattServiceMap::value_type& pair) { 366 gatt_services_.end(), [](GattServiceMap::value_type & pair) {
346 BluetoothRemoteGattService* gatt_service = pair.second.get(); 367 BluetoothRemoteGattService* gatt_service = pair.second.get();
347 return static_cast<BluetoothRemoteGattServiceMac*>(gatt_service) 368 return static_cast<BluetoothRemoteGattServiceMac*>(gatt_service)
348 ->IsDiscoveryComplete(); 369 ->IsDiscoveryComplete();
349 }) == gatt_services_.end(); 370 }) == gatt_services_.end();
350 if (discovery_complete) { 371 if (discovery_complete) {
351 device_uuids_.ReplaceServiceUUIDs(gatt_services_); 372 device_uuids_.ReplaceServiceUUIDs(gatt_services_);
352 SetGattServicesDiscoveryComplete(true); 373 SetGattServicesDiscoveryComplete(true);
353 adapter_->NotifyGattServicesDiscovered(this); 374 adapter_->NotifyGattServicesDiscovered(this);
354 adapter_->NotifyDeviceChanged(this); 375 adapter_->NotifyDeviceChanged(this);
355 } 376 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 // 2. When we cancel a pending connection request. 411 // 2. When we cancel a pending connection request.
391 if (create_gatt_connection_error_callbacks_.empty()) { 412 if (create_gatt_connection_error_callbacks_.empty()) {
392 // If there are no pending callbacks then the connection broke (#1). 413 // If there are no pending callbacks then the connection broke (#1).
393 DidDisconnectGatt(true /* notifyDeviceChanged */); 414 DidDisconnectGatt(true /* notifyDeviceChanged */);
394 return; 415 return;
395 } 416 }
396 // Else we canceled the connection request (#2). 417 // Else we canceled the connection request (#2).
397 // TODO(http://crbug.com/585897): Need to pass the error. 418 // TODO(http://crbug.com/585897): Need to pass the error.
398 DidFailToConnectGatt(BluetoothDevice::ConnectErrorCode::ERROR_FAILED); 419 DidFailToConnectGatt(BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
399 } 420 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698