| OLD | NEW |
| 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" |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 #include "device/bluetooth/bluetooth_remote_gatt_service_mac.h" | 21 #include "device/bluetooth/bluetooth_remote_gatt_service_mac.h" |
| 22 | 22 |
| 23 using device::BluetoothDevice; | 23 using device::BluetoothDevice; |
| 24 using device::BluetoothLowEnergyDeviceMac; | 24 using device::BluetoothLowEnergyDeviceMac; |
| 25 | 25 |
| 26 BluetoothLowEnergyDeviceMac::BluetoothLowEnergyDeviceMac( | 26 BluetoothLowEnergyDeviceMac::BluetoothLowEnergyDeviceMac( |
| 27 BluetoothAdapterMac* adapter, | 27 BluetoothAdapterMac* adapter, |
| 28 CBPeripheral* peripheral) | 28 CBPeripheral* peripheral) |
| 29 : BluetoothDeviceMac(adapter), | 29 : BluetoothDeviceMac(adapter), |
| 30 peripheral_(peripheral, base::scoped_policy::RETAIN), | 30 peripheral_(peripheral, base::scoped_policy::RETAIN), |
| 31 connected_(false), |
| 31 discovery_pending_count_(0) { | 32 discovery_pending_count_(0) { |
| 32 DCHECK(BluetoothAdapterMac::IsLowEnergyAvailable()); | 33 DCHECK(BluetoothAdapterMac::IsLowEnergyAvailable()); |
| 33 DCHECK(peripheral_.get()); | 34 DCHECK(peripheral_.get()); |
| 34 peripheral_delegate_.reset([[BluetoothLowEnergyPeripheralDelegate alloc] | 35 peripheral_delegate_.reset([[BluetoothLowEnergyPeripheralDelegate alloc] |
| 35 initWithBluetoothLowEnergyDeviceMac:this]); | 36 initWithBluetoothLowEnergyDeviceMac:this]); |
| 36 [peripheral_ setDelegate:peripheral_delegate_]; | 37 [peripheral_ setDelegate:peripheral_delegate_]; |
| 37 identifier_ = GetPeripheralIdentifier(peripheral); | 38 identifier_ = GetPeripheralIdentifier(peripheral); |
| 38 hash_address_ = GetPeripheralHashAddress(peripheral); | 39 hash_address_ = GetPeripheralHashAddress(peripheral); |
| 39 UpdateTimestamp(); | 40 UpdateTimestamp(); |
| 40 } | 41 } |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 89 | 90 |
| 90 bool BluetoothLowEnergyDeviceMac::IsPaired() const { | 91 bool BluetoothLowEnergyDeviceMac::IsPaired() const { |
| 91 return false; | 92 return false; |
| 92 } | 93 } |
| 93 | 94 |
| 94 bool BluetoothLowEnergyDeviceMac::IsConnected() const { | 95 bool BluetoothLowEnergyDeviceMac::IsConnected() const { |
| 95 return IsGattConnected(); | 96 return IsGattConnected(); |
| 96 } | 97 } |
| 97 | 98 |
| 98 bool BluetoothLowEnergyDeviceMac::IsGattConnected() const { | 99 bool BluetoothLowEnergyDeviceMac::IsGattConnected() const { |
| 99 return ([peripheral_ state] == CBPeripheralStateConnected); | 100 // |connected_| can be false while |[peripheral_ state]| is |
| 101 // |CBPeripheralStateConnected|. This happens |
| 102 // BluetoothAdapterMac::DidConnectPeripheral() is called and |
| 103 // BluetoothLowEnergyDeviceMac::DidConnectGatt() has not been called yet. |
| 104 return connected_; |
| 100 } | 105 } |
| 101 | 106 |
| 102 bool BluetoothLowEnergyDeviceMac::IsConnectable() const { | 107 bool BluetoothLowEnergyDeviceMac::IsConnectable() const { |
| 103 // Only available for Chrome OS. | 108 // Only available for Chrome OS. |
| 104 NOTIMPLEMENTED(); | 109 NOTIMPLEMENTED(); |
| 105 return false; | 110 return false; |
| 106 } | 111 } |
| 107 | 112 |
| 108 bool BluetoothLowEnergyDeviceMac::IsConnecting() const { | 113 bool BluetoothLowEnergyDeviceMac::IsConnecting() const { |
| 109 return ([peripheral_ state] == CBPeripheralStateConnecting); | 114 return ([peripheral_ state] == CBPeripheralStateConnecting); |
| (...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 381 std::string BluetoothLowEnergyDeviceMac::GetPeripheralHashAddress( | 386 std::string BluetoothLowEnergyDeviceMac::GetPeripheralHashAddress( |
| 382 CBPeripheral* peripheral) { | 387 CBPeripheral* peripheral) { |
| 383 const size_t kCanonicalAddressNumberOfBytes = 6; | 388 const size_t kCanonicalAddressNumberOfBytes = 6; |
| 384 char raw[kCanonicalAddressNumberOfBytes]; | 389 char raw[kCanonicalAddressNumberOfBytes]; |
| 385 crypto::SHA256HashString(GetPeripheralIdentifier(peripheral), raw, | 390 crypto::SHA256HashString(GetPeripheralIdentifier(peripheral), raw, |
| 386 sizeof(raw)); | 391 sizeof(raw)); |
| 387 std::string hash = base::HexEncode(raw, sizeof(raw)); | 392 std::string hash = base::HexEncode(raw, sizeof(raw)); |
| 388 return BluetoothDevice::CanonicalizeAddress(hash); | 393 return BluetoothDevice::CanonicalizeAddress(hash); |
| 389 } | 394 } |
| 390 | 395 |
| 396 void BluetoothLowEnergyDeviceMac::DidConnectPeripheral() { |
| 397 VLOG(1) << *this << ": GATT connected."; |
| 398 if (!connected_) { |
| 399 connected_ = true; |
| 400 DidConnectGatt(); |
| 401 DiscoverPrimaryServices(); |
| 402 } else { |
| 403 // -[<CBCentralManagerDelegate> centralManager:didConnectPeripheral:] can be |
| 404 // called twice because of a macOS bug. This second call should be ignored. |
| 405 // See crbug.com/681414. |
| 406 VLOG(1) << *this << ": Already connected, ignoring event."; |
| 407 } |
| 408 } |
| 409 |
| 391 void BluetoothLowEnergyDeviceMac::DiscoverPrimaryServices() { | 410 void BluetoothLowEnergyDeviceMac::DiscoverPrimaryServices() { |
| 392 VLOG(1) << *this << ": DiscoverPrimaryServices, pending count " | 411 VLOG(1) << *this << ": DiscoverPrimaryServices, pending count " |
| 393 << discovery_pending_count_; | 412 << discovery_pending_count_; |
| 394 ++discovery_pending_count_; | 413 ++discovery_pending_count_; |
| 395 [GetPeripheral() discoverServices:nil]; | 414 [GetPeripheral() discoverServices:nil]; |
| 396 } | 415 } |
| 397 | 416 |
| 398 void BluetoothLowEnergyDeviceMac::SendNotificationIfDiscoveryComplete() { | 417 void BluetoothLowEnergyDeviceMac::SendNotificationIfDiscoveryComplete() { |
| 399 DCHECK(!IsGattServicesDiscoveryComplete()); | 418 DCHECK(!IsGattServicesDiscoveryComplete()); |
| 400 // Notify when all services have been discovered. | 419 // Notify when all services have been discovered. |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 445 GetBluetoothRemoteGattService(cb_characteristic.service); | 464 GetBluetoothRemoteGattService(cb_characteristic.service); |
| 446 DCHECK(gatt_service); | 465 DCHECK(gatt_service); |
| 447 device::BluetoothRemoteGattCharacteristicMac* gatt_characteristic = | 466 device::BluetoothRemoteGattCharacteristicMac* gatt_characteristic = |
| 448 gatt_service->GetBluetoothRemoteGattCharacteristicMac(cb_characteristic); | 467 gatt_service->GetBluetoothRemoteGattCharacteristicMac(cb_characteristic); |
| 449 DCHECK(gatt_characteristic); | 468 DCHECK(gatt_characteristic); |
| 450 return gatt_characteristic->GetBluetoothRemoteGattDescriptorMac( | 469 return gatt_characteristic->GetBluetoothRemoteGattDescriptorMac( |
| 451 cb_descriptor); | 470 cb_descriptor); |
| 452 } | 471 } |
| 453 | 472 |
| 454 void BluetoothLowEnergyDeviceMac::DidDisconnectPeripheral(NSError* error) { | 473 void BluetoothLowEnergyDeviceMac::DidDisconnectPeripheral(NSError* error) { |
| 474 connected_ = false; |
| 455 VLOG(1) << *this << ": Disconnected from peripheral."; | 475 VLOG(1) << *this << ": Disconnected from peripheral."; |
| 456 if (error) { | 476 if (error) { |
| 457 VLOG(1) << *this | 477 VLOG(1) << *this |
| 458 << ": Bluetooth error: " << BluetoothAdapterMac::String(error); | 478 << ": Bluetooth error: " << BluetoothAdapterMac::String(error); |
| 459 } | 479 } |
| 460 SetGattServicesDiscoveryComplete(false); | 480 SetGattServicesDiscoveryComplete(false); |
| 461 // Removing all services at once to ensure that calling GetGattService on | 481 // Removing all services at once to ensure that calling GetGattService on |
| 462 // removed service in GattServiceRemoved returns null. | 482 // removed service in GattServiceRemoved returns null. |
| 463 GattServiceMap gatt_services_swapped; | 483 GattServiceMap gatt_services_swapped; |
| 464 gatt_services_swapped.swap(gatt_services_); | 484 gatt_services_swapped.swap(gatt_services_); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 478 DidFailToConnectGatt(BluetoothDevice::ConnectErrorCode::ERROR_FAILED); | 498 DidFailToConnectGatt(BluetoothDevice::ConnectErrorCode::ERROR_FAILED); |
| 479 } | 499 } |
| 480 | 500 |
| 481 namespace device { | 501 namespace device { |
| 482 | 502 |
| 483 std::ostream& operator<<(std::ostream& out, | 503 std::ostream& operator<<(std::ostream& out, |
| 484 const BluetoothLowEnergyDeviceMac& device) { | 504 const BluetoothLowEnergyDeviceMac& device) { |
| 485 // TODO(crbug.com/703878): Should use | 505 // TODO(crbug.com/703878): Should use |
| 486 // BluetoothLowEnergyDeviceMac::GetNameForDisplay() instead. | 506 // BluetoothLowEnergyDeviceMac::GetNameForDisplay() instead. |
| 487 base::Optional<std::string> name = device.GetName(); | 507 base::Optional<std::string> name = device.GetName(); |
| 488 const char* name_cstr = name ? name->c_str() : ""; | 508 const char* is_gatt_connected = |
| 509 device.IsGattConnected() ? "GATT connected" : "GATT disconnected"; |
| 489 return out << "<BluetoothLowEnergyDeviceMac " << device.GetAddress() << "/" | 510 return out << "<BluetoothLowEnergyDeviceMac " << device.GetAddress() << "/" |
| 490 << &device << ", \"" << name_cstr << "\">"; | 511 << &device << ", " << is_gatt_connected << ", \"" |
| 512 << name.value_or("Unnamed device") << "\">"; |
| 491 } | 513 } |
| 492 } // namespace device | 514 } // namespace device |
| OLD | NEW |