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

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

Issue 2339253002: bluetooth: mac: add connected LE devices to chooser (Closed)
Patch Set: Nit for the tests Created 4 years, 1 month 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 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 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 } 179 }
180 180
181 bool BluetoothAdapterMac::IsDiscovering() const { 181 bool BluetoothAdapterMac::IsDiscovering() const {
182 bool is_discovering = classic_discovery_manager_->IsDiscovering(); 182 bool is_discovering = classic_discovery_manager_->IsDiscovering();
183 if (IsLowEnergyAvailable()) 183 if (IsLowEnergyAvailable())
184 is_discovering = 184 is_discovering =
185 is_discovering || low_energy_discovery_manager_->IsDiscovering(); 185 is_discovering || low_energy_discovery_manager_->IsDiscovering();
186 return is_discovering; 186 return is_discovering;
187 } 187 }
188 188
189 std::unordered_map<BluetoothDevice*, BluetoothDevice::UUIDSet>
190 BluetoothAdapterMac::RetrieveGattConnectedDevicesWithDiscoveryFilter(
191 const BluetoothDiscoveryFilter& discovery_filter) {
192 std::unordered_map<BluetoothDevice*, BluetoothDevice::UUIDSet>
193 connected_devices;
194 std::set<device::BluetoothUUID> uuids;
195 discovery_filter.GetUUIDs(uuids);
196 if (uuids.empty()) {
197 for (BluetoothDevice* device :
198 RetrieveGattConnectedDevicesWithService(nullptr)) {
199 connected_devices[device] = BluetoothDevice::UUIDSet();
200 }
201 return connected_devices;
202 }
203 for (const BluetoothUUID& uuid : uuids) {
204 for (BluetoothDevice* device :
205 RetrieveGattConnectedDevicesWithService(&uuid)) {
206 connected_devices[device].insert(uuid);
207 }
208 }
209 return connected_devices;
210 }
211
189 BluetoothAdapter::UUIDList BluetoothAdapterMac::GetUUIDs() const { 212 BluetoothAdapter::UUIDList BluetoothAdapterMac::GetUUIDs() const {
190 NOTIMPLEMENTED(); 213 NOTIMPLEMENTED();
191 return UUIDList(); 214 return UUIDList();
192 } 215 }
193 216
194 void BluetoothAdapterMac::CreateRfcommService( 217 void BluetoothAdapterMac::CreateRfcommService(
195 const BluetoothUUID& uuid, 218 const BluetoothUUID& uuid,
196 const ServiceOptions& options, 219 const ServiceOptions& options,
197 const CreateServiceCallback& callback, 220 const CreateServiceCallback& callback,
198 const CreateServiceErrorCallback& error_callback) { 221 const CreateServiceErrorCallback& error_callback) {
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
492 int rssi) { 515 int rssi) {
493 BluetoothLowEnergyDeviceMac* device_mac = 516 BluetoothLowEnergyDeviceMac* device_mac =
494 GetBluetoothLowEnergyDeviceMac(peripheral); 517 GetBluetoothLowEnergyDeviceMac(peripheral);
495 // If has no entry in the map, create new device and insert into |devices_|, 518 // If has no entry in the map, create new device and insert into |devices_|,
496 // otherwise update the existing device. 519 // otherwise update the existing device.
497 const bool is_new_device = device_mac == nullptr; 520 const bool is_new_device = device_mac == nullptr;
498 if (is_new_device) { 521 if (is_new_device) {
499 VLOG(1) << "LowEnergyDeviceUpdated new device"; 522 VLOG(1) << "LowEnergyDeviceUpdated new device";
500 // A new device has been found. 523 // A new device has been found.
501 device_mac = new BluetoothLowEnergyDeviceMac(this, peripheral); 524 device_mac = new BluetoothLowEnergyDeviceMac(this, peripheral);
502 } else { 525 } else if (DoesCollideWithKnownDevice(peripheral, device_mac)) {
503 // Check that there are no collisions. 526 return;
504 std::string stored_device_id = device_mac->GetIdentifier();
505 std::string updated_device_id =
506 BluetoothLowEnergyDeviceMac::GetPeripheralIdentifier(peripheral);
507 if (stored_device_id != updated_device_id) {
508 VLOG(1)
509 << "LowEnergyDeviceUpdated stored_device_id != updated_device_id: "
510 << std::endl
511 << " " << stored_device_id << std::endl
512 << " " << updated_device_id;
513 // Collision, two identifiers map to the same hash address. With a 48 bit
514 // hash the probability of this occuring with 10,000 devices
515 // simultaneously present is 1e-6 (see
516 // https://en.wikipedia.org/wiki/Birthday_problem#Probability_table). We
517 // ignore the second device by returning.
518 return;
519 }
520 } 527 }
521 528
522 DCHECK(device_mac); 529 DCHECK(device_mac);
523 530
524 // Get Advertised UUIDs 531 // Get Advertised UUIDs
525 BluetoothDevice::UUIDList advertised_uuids; 532 BluetoothDevice::UUIDList advertised_uuids;
526 NSArray* service_uuids = 533 NSArray* service_uuids =
527 [advertisement_data objectForKey:CBAdvertisementDataServiceUUIDsKey]; 534 [advertisement_data objectForKey:CBAdvertisementDataServiceUUIDsKey];
528 for (CBUUID* uuid in service_uuids) { 535 for (CBUUID* uuid in service_uuids) {
529 advertised_uuids.push_back(BluetoothUUID([[uuid UUIDString] UTF8String])); 536 advertised_uuids.push_back(BluetoothUUID([[uuid UUIDString] UTF8String]));
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
575 // Add any new paired devices. 582 // Add any new paired devices.
576 for (IOBluetoothDevice* device in [IOBluetoothDevice pairedDevices]) { 583 for (IOBluetoothDevice* device in [IOBluetoothDevice pairedDevices]) {
577 // pairedDevices sometimes includes unknown devices that are not paired. 584 // pairedDevices sometimes includes unknown devices that are not paired.
578 // Radar issue with id 2282763004 has been filed about it. 585 // Radar issue with id 2282763004 has been filed about it.
579 if ([device isPaired]) { 586 if ([device isPaired]) {
580 ClassicDeviceAdded(device); 587 ClassicDeviceAdded(device);
581 } 588 }
582 } 589 }
583 } 590 }
584 591
592 std::vector<BluetoothDevice*>
593 BluetoothAdapterMac::RetrieveGattConnectedDevicesWithService(
594 const BluetoothUUID* uuid) {
595 NSArray* cbUUIDs = nil;
596 if (!uuid) {
597 // It is not possible to ask for all connected peripherals with
598 // -[CBCentralManager retrieveConnectedPeripheralsWithServices:] by passing
599 // nil. To try to get most of the peripherals, the search is done with
600 // Generic Access service.
601 CBUUID* genericAccessServiceUUID = [CBUUID UUIDWithString:@"1800"];
602 cbUUIDs = @[ genericAccessServiceUUID ];
603 } else {
604 NSString* uuidString =
605 base::SysUTF8ToNSString(uuid->canonical_value().c_str());
606 cbUUIDs = @[ [CBUUID UUIDWithString:uuidString] ];
607 }
608 NSArray* peripherals = [low_energy_central_manager_
609 retrieveConnectedPeripheralsWithServices:cbUUIDs];
610 std::vector<BluetoothDevice*> connected_devices;
611 for (CBPeripheral* peripheral in peripherals) {
612 BluetoothLowEnergyDeviceMac* device_mac =
613 GetBluetoothLowEnergyDeviceMac(peripheral);
614 const bool is_new_device = device_mac == nullptr;
615
616 if (!is_new_device && DoesCollideWithKnownDevice(peripheral, device_mac)) {
617 continue;
618 }
619 if (is_new_device) {
620 device_mac = new BluetoothLowEnergyDeviceMac(this, peripheral);
621 std::string device_address =
622 BluetoothLowEnergyDeviceMac::GetPeripheralHashAddress(peripheral);
623 devices_.add(device_address,
624 std::unique_ptr<BluetoothDevice>(device_mac));
625 for (auto& observer : observers_) {
626 observer.DeviceAdded(this, device_mac);
627 }
628 }
629 connected_devices.push_back(device_mac);
630 }
631 return connected_devices;
632 }
633
585 void BluetoothAdapterMac::CreateGattConnection( 634 void BluetoothAdapterMac::CreateGattConnection(
586 BluetoothLowEnergyDeviceMac* device_mac) { 635 BluetoothLowEnergyDeviceMac* device_mac) {
587 [low_energy_central_manager_ connectPeripheral:device_mac->peripheral_ 636 [low_energy_central_manager_ connectPeripheral:device_mac->peripheral_
588 options:nil]; 637 options:nil];
589 } 638 }
590 639
591 void BluetoothAdapterMac::DisconnectGatt( 640 void BluetoothAdapterMac::DisconnectGatt(
592 BluetoothLowEnergyDeviceMac* device_mac) { 641 BluetoothLowEnergyDeviceMac* device_mac) {
593 [low_energy_central_manager_ 642 [low_energy_central_manager_
594 cancelPeripheralConnection:device_mac->peripheral_]; 643 cancelPeripheralConnection:device_mac->peripheral_];
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
645 BluetoothAdapterMac::GetBluetoothLowEnergyDeviceMac(CBPeripheral* peripheral) { 694 BluetoothAdapterMac::GetBluetoothLowEnergyDeviceMac(CBPeripheral* peripheral) {
646 std::string device_address = 695 std::string device_address =
647 BluetoothLowEnergyDeviceMac::GetPeripheralHashAddress(peripheral); 696 BluetoothLowEnergyDeviceMac::GetPeripheralHashAddress(peripheral);
648 DevicesMap::const_iterator iter = devices_.find(device_address); 697 DevicesMap::const_iterator iter = devices_.find(device_address);
649 if (iter == devices_.end()) { 698 if (iter == devices_.end()) {
650 return nil; 699 return nil;
651 } 700 }
652 return static_cast<BluetoothLowEnergyDeviceMac*>(iter->second); 701 return static_cast<BluetoothLowEnergyDeviceMac*>(iter->second);
653 } 702 }
654 703
704 bool BluetoothAdapterMac::DoesCollideWithKnownDevice(
705 CBPeripheral* peripheral,
706 BluetoothLowEnergyDeviceMac* device_mac) {
707 // Check that there are no collisions.
708 std::string stored_device_id = device_mac->GetIdentifier();
709 std::string updated_device_id =
710 BluetoothLowEnergyDeviceMac::GetPeripheralIdentifier(peripheral);
711 if (stored_device_id != updated_device_id) {
712 VLOG(1) << "LowEnergyDeviceUpdated stored_device_id != updated_device_id: "
713 << std::endl
714 << " " << stored_device_id << std::endl
715 << " " << updated_device_id;
716 // Collision, two identifiers map to the same hash address. With a 48 bit
717 // hash the probability of this occuring with 10,000 devices
718 // simultaneously present is 1e-6 (see
719 // https://en.wikipedia.org/wiki/Birthday_problem#Probability_table). We
720 // ignore the second device by returning.
721 return true;
722 }
723 return false;
724 }
725
655 } // namespace device 726 } // namespace device
OLDNEW
« no previous file with comments | « device/bluetooth/bluetooth_adapter_mac.h ('k') | device/bluetooth/bluetooth_adapter_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698