OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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_adapter_mac.h" | 5 #include "device/bluetooth/bluetooth_adapter_mac.h" |
6 | 6 |
7 #import <IOBluetooth/objc/IOBluetoothDevice.h> | 7 #import <IOBluetooth/objc/IOBluetoothDevice.h> |
8 #import <IOBluetooth/objc/IOBluetoothHostController.h> | 8 #import <IOBluetooth/objc/IOBluetoothHostController.h> |
9 #include <stddef.h> | 9 #include <stddef.h> |
10 | 10 |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 low_energy_central_manager_.reset([[CBCentralManager alloc] | 85 low_energy_central_manager_.reset([[CBCentralManager alloc] |
86 initWithDelegate:low_energy_central_manager_delegate_.get() | 86 initWithDelegate:low_energy_central_manager_delegate_.get() |
87 queue:dispatch_get_main_queue()]); | 87 queue:dispatch_get_main_queue()]); |
88 low_energy_discovery_manager_->SetCentralManager( | 88 low_energy_discovery_manager_->SetCentralManager( |
89 low_energy_central_manager_.get()); | 89 low_energy_central_manager_.get()); |
90 } | 90 } |
91 DCHECK(classic_discovery_manager_.get()); | 91 DCHECK(classic_discovery_manager_.get()); |
92 } | 92 } |
93 | 93 |
94 BluetoothAdapterMac::~BluetoothAdapterMac() { | 94 BluetoothAdapterMac::~BluetoothAdapterMac() { |
| 95 // When devices will be destroyed, they will need this current instance to |
| 96 // disconnect the gatt connection. To make sure they don't use the mac |
| 97 // adapter, they should be explicitly destroyed here. |
| 98 devices_.clear(); |
| 99 // Set low_energy_central_manager_ to nil so no devices will try to use it |
| 100 // while being destroyed after this method. |devices_| is owned by |
| 101 // BluetoothAdapter. |
| 102 low_energy_central_manager_.reset(); |
95 } | 103 } |
96 | 104 |
97 std::string BluetoothAdapterMac::GetAddress() const { | 105 std::string BluetoothAdapterMac::GetAddress() const { |
98 return address_; | 106 return address_; |
99 } | 107 } |
100 | 108 |
101 std::string BluetoothAdapterMac::GetName() const { | 109 std::string BluetoothAdapterMac::GetName() const { |
102 return name_; | 110 return name_; |
103 } | 111 } |
104 | 112 |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
214 DVLOG(1) << "Adapter registered a new connection from device with address: " | 222 DVLOG(1) << "Adapter registered a new connection from device with address: " |
215 << BluetoothClassicDeviceMac::GetDeviceAddress(device); | 223 << BluetoothClassicDeviceMac::GetDeviceAddress(device); |
216 ClassicDeviceAdded(device); | 224 ClassicDeviceAdded(device); |
217 } | 225 } |
218 | 226 |
219 // static | 227 // static |
220 bool BluetoothAdapterMac::IsLowEnergyAvailable() { | 228 bool BluetoothAdapterMac::IsLowEnergyAvailable() { |
221 return base::mac::IsOSYosemiteOrLater(); | 229 return base::mac::IsOSYosemiteOrLater(); |
222 } | 230 } |
223 | 231 |
| 232 void BluetoothAdapterMac::RemovePairingDelegateInternal( |
| 233 BluetoothDevice::PairingDelegate* pairing_delegate) {} |
| 234 |
224 void BluetoothAdapterMac::SetCentralManagerForTesting( | 235 void BluetoothAdapterMac::SetCentralManagerForTesting( |
225 CBCentralManager* central_manager) { | 236 CBCentralManager* central_manager) { |
226 CHECK(BluetoothAdapterMac::IsLowEnergyAvailable()); | 237 CHECK(BluetoothAdapterMac::IsLowEnergyAvailable()); |
227 central_manager.delegate = low_energy_central_manager_delegate_; | 238 central_manager.delegate = low_energy_central_manager_delegate_; |
228 low_energy_central_manager_.reset(central_manager); | 239 low_energy_central_manager_.reset(central_manager, |
| 240 base::scoped_policy::RETAIN); |
229 low_energy_discovery_manager_->SetCentralManager( | 241 low_energy_discovery_manager_->SetCentralManager( |
230 low_energy_central_manager_.get()); | 242 low_energy_central_manager_.get()); |
231 } | 243 } |
232 | 244 |
233 void BluetoothAdapterMac::RemovePairingDelegateInternal( | 245 CBCentralManager* BluetoothAdapterMac::GetCentralManagerForTesting() { |
234 BluetoothDevice::PairingDelegate* pairing_delegate) { | 246 return low_energy_central_manager_; |
235 } | 247 } |
236 | 248 |
237 void BluetoothAdapterMac::AddDiscoverySession( | 249 void BluetoothAdapterMac::AddDiscoverySession( |
238 BluetoothDiscoveryFilter* discovery_filter, | 250 BluetoothDiscoveryFilter* discovery_filter, |
239 const base::Closure& callback, | 251 const base::Closure& callback, |
240 const DiscoverySessionErrorCallback& error_callback) { | 252 const DiscoverySessionErrorCallback& error_callback) { |
241 DVLOG(1) << __func__; | 253 DVLOG(1) << __func__; |
242 if (num_discovery_sessions_ > 0) { | 254 if (num_discovery_sessions_ > 0) { |
243 DCHECK(IsDiscovering()); | 255 DCHECK(IsDiscovering()); |
244 num_discovery_sessions_++; | 256 num_discovery_sessions_++; |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
447 BluetoothDevice* device_classic = new BluetoothClassicDeviceMac(this, device); | 459 BluetoothDevice* device_classic = new BluetoothClassicDeviceMac(this, device); |
448 devices_.set(device_address, make_scoped_ptr(device_classic)); | 460 devices_.set(device_address, make_scoped_ptr(device_classic)); |
449 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, | 461 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, |
450 DeviceAdded(this, device_classic)); | 462 DeviceAdded(this, device_classic)); |
451 } | 463 } |
452 | 464 |
453 void BluetoothAdapterMac::LowEnergyDeviceUpdated( | 465 void BluetoothAdapterMac::LowEnergyDeviceUpdated( |
454 CBPeripheral* peripheral, | 466 CBPeripheral* peripheral, |
455 NSDictionary* advertisement_data, | 467 NSDictionary* advertisement_data, |
456 int rssi) { | 468 int rssi) { |
457 std::string device_address = | 469 BluetoothLowEnergyDeviceMac* device_mac = |
458 BluetoothLowEnergyDeviceMac::GetPeripheralHashAddress(peripheral); | 470 GetBluetoothLowEnergyDeviceMac(peripheral); |
459 // Try to find device from |devices_| with key |device_address|, | |
460 // if has no entry in the map, create new device and insert into |devices_|, | 471 // if has no entry in the map, create new device and insert into |devices_|, |
461 // otherwise update the existing device. | 472 // otherwise update the existing device. |
462 DevicesMap::const_iterator iter = devices_.find(device_address); | 473 if (!device_mac) { |
463 if (iter == devices_.end()) { | |
464 VLOG(1) << "LowEnergyDeviceUpdated new device"; | 474 VLOG(1) << "LowEnergyDeviceUpdated new device"; |
465 // A new device has been found. | 475 // A new device has been found. |
466 BluetoothLowEnergyDeviceMac* device_mac = new BluetoothLowEnergyDeviceMac( | 476 device_mac = new BluetoothLowEnergyDeviceMac(this, peripheral, |
467 this, peripheral, advertisement_data, rssi); | 477 advertisement_data, rssi); |
| 478 std::string device_address = |
| 479 BluetoothLowEnergyDeviceMac::GetPeripheralHashAddress(peripheral); |
468 devices_.add(device_address, scoped_ptr<BluetoothDevice>(device_mac)); | 480 devices_.add(device_address, scoped_ptr<BluetoothDevice>(device_mac)); |
469 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, | 481 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, |
470 DeviceAdded(this, device_mac)); | 482 DeviceAdded(this, device_mac)); |
471 return; | 483 return; |
472 } | 484 } |
473 | 485 |
474 BluetoothLowEnergyDeviceMac* device_mac = | |
475 static_cast<BluetoothLowEnergyDeviceMac*>(iter->second); | |
476 std::string stored_device_id = device_mac->GetIdentifier(); | 486 std::string stored_device_id = device_mac->GetIdentifier(); |
477 std::string updated_device_id = | 487 std::string updated_device_id = |
478 BluetoothLowEnergyDeviceMac::GetPeripheralIdentifier(peripheral); | 488 BluetoothLowEnergyDeviceMac::GetPeripheralIdentifier(peripheral); |
479 if (stored_device_id != updated_device_id) { | 489 if (stored_device_id != updated_device_id) { |
480 VLOG(1) << "LowEnergyDeviceUpdated stored_device_id != updated_device_id: " | 490 VLOG(1) << "LowEnergyDeviceUpdated stored_device_id != updated_device_id: " |
481 << std::endl | 491 << std::endl |
482 << " " << stored_device_id << std::endl | 492 << " " << stored_device_id << std::endl |
483 << " " << updated_device_id; | 493 << " " << updated_device_id; |
484 // Collision, two identifiers map to the same hash address. With a 48 bit | 494 // Collision, two identifiers map to the same hash address. With a 48 bit |
485 // hash the probability of this occuring with 10,000 devices | 495 // hash the probability of this occuring with 10,000 devices |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
528 } | 538 } |
529 } | 539 } |
530 | 540 |
531 void BluetoothAdapterMac::AddPairedDevices() { | 541 void BluetoothAdapterMac::AddPairedDevices() { |
532 // Add any new paired devices. | 542 // Add any new paired devices. |
533 for (IOBluetoothDevice* device in [IOBluetoothDevice pairedDevices]) { | 543 for (IOBluetoothDevice* device in [IOBluetoothDevice pairedDevices]) { |
534 ClassicDeviceAdded(device); | 544 ClassicDeviceAdded(device); |
535 } | 545 } |
536 } | 546 } |
537 | 547 |
| 548 void BluetoothAdapterMac::CreateGattConnection( |
| 549 BluetoothLowEnergyDeviceMac* device_mac) { |
| 550 [low_energy_central_manager_ connectPeripheral:device_mac->peripheral_ |
| 551 options:nil]; |
| 552 } |
| 553 |
| 554 void BluetoothAdapterMac::DisconnectGatt( |
| 555 BluetoothLowEnergyDeviceMac* device_mac) { |
| 556 [low_energy_central_manager_ |
| 557 cancelPeripheralConnection:device_mac->peripheral_]; |
| 558 } |
| 559 |
| 560 void BluetoothAdapterMac::DidConnectPeripheral(CBPeripheral* peripheral) { |
| 561 BluetoothLowEnergyDeviceMac* device_mac = |
| 562 GetBluetoothLowEnergyDeviceMac(peripheral); |
| 563 if (!device_mac) { |
| 564 [low_energy_central_manager_ cancelPeripheralConnection:peripheral]; |
| 565 return; |
| 566 } |
| 567 device_mac->DidConnectGatt(); |
| 568 } |
| 569 |
| 570 void BluetoothAdapterMac::DidFailToConnectPeripheral(CBPeripheral* peripheral, |
| 571 NSError* error) { |
| 572 BluetoothLowEnergyDeviceMac* device_mac = |
| 573 GetBluetoothLowEnergyDeviceMac(peripheral); |
| 574 if (!device_mac) { |
| 575 [low_energy_central_manager_ cancelPeripheralConnection:peripheral]; |
| 576 return; |
| 577 } |
| 578 VLOG(1) << "Bluetooth error, domain: " << error.domain.UTF8String |
| 579 << ", error code: " << error.code; |
| 580 // TODO(http://crbug.com/585894): Need to convert the error. |
| 581 device_mac->DidFailToConnectGatt(BluetoothClassicDeviceMac::ERROR_UNKNOWN); |
| 582 } |
| 583 |
| 584 void BluetoothAdapterMac::DidDisconnectPeripheral(CBPeripheral* peripheral, |
| 585 NSError* error) { |
| 586 BluetoothLowEnergyDeviceMac* device_mac = |
| 587 GetBluetoothLowEnergyDeviceMac(peripheral); |
| 588 if (!device_mac) { |
| 589 [low_energy_central_manager_ cancelPeripheralConnection:peripheral]; |
| 590 return; |
| 591 } |
| 592 // TODO(http://crbug.com/585897): Need to pass the error. |
| 593 device_mac->DidDisconnectPeripheral(); |
| 594 } |
| 595 |
| 596 BluetoothLowEnergyDeviceMac* |
| 597 BluetoothAdapterMac::GetBluetoothLowEnergyDeviceMac(CBPeripheral* peripheral) { |
| 598 std::string device_address = |
| 599 BluetoothLowEnergyDeviceMac::GetPeripheralHashAddress(peripheral); |
| 600 DevicesMap::const_iterator iter = devices_.find(device_address); |
| 601 if (iter == devices_.end()) { |
| 602 return nil; |
| 603 } |
| 604 return static_cast<BluetoothLowEnergyDeviceMac*>(iter->second); |
| 605 } |
| 606 |
538 } // namespace device | 607 } // namespace device |
OLD | NEW |