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

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

Issue 2339253002: bluetooth: mac: add connected LE devices to chooser (Closed)
Patch Set: Better implementation Created 4 years, 2 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 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 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 } 163 }
164 164
165 bool BluetoothAdapterMac::IsDiscovering() const { 165 bool BluetoothAdapterMac::IsDiscovering() const {
166 bool is_discovering = classic_discovery_manager_->IsDiscovering(); 166 bool is_discovering = classic_discovery_manager_->IsDiscovering();
167 if (IsLowEnergyAvailable()) 167 if (IsLowEnergyAvailable())
168 is_discovering = 168 is_discovering =
169 is_discovering || low_energy_discovery_manager_->IsDiscovering(); 169 is_discovering || low_energy_discovery_manager_->IsDiscovering();
170 return is_discovering; 170 return is_discovering;
171 } 171 }
172 172
173 void BluetoothAdapterMac::RetrieveUnknownGattConnectedDevices() {
174 // It is not possible to ask for all connected peripherals with
175 // -[CBCentralManager retrieveConnectedPeripheralsWithServices:] by passing
176 // nil. To try to get most of the peripherals, the search is done with
177 // Generic Access service.
178 CBUUID* genericAccessServiceUUID = [CBUUID UUIDWithString:@"1800"];
179 NSArray* connectedServices = @[ genericAccessServiceUUID ];
180 #pragma clang diagnostic push
181 #pragma clang diagnostic ignored "-Wpartial-availability"
182 // Can remove ignore -Wpartial-availability when 10.8 will not be supported
183 // anymore.
184 // TODO(crbug.com/653056)
185 NSArray* peripherals = [low_energy_central_manager_
186 retrieveConnectedPeripheralsWithServices:connectedServices];
187 #pragma clang diagnostic pop
188 for (CBPeripheral* peripheral in peripherals) {
189 BluetoothLowEnergyDeviceMac* device_mac =
190 GetBluetoothLowEnergyDeviceMac(peripheral);
191 const bool is_new_device = device_mac == nullptr;
192
193 if (!is_new_device) {
194 DoesCollideWithKnownDevice(peripheral, device_mac);
195 return;
196 }
197
198 device_mac = new BluetoothLowEnergyDeviceMac(this, peripheral);
199 std::string device_address =
200 BluetoothLowEnergyDeviceMac::GetPeripheralHashAddress(peripheral);
201 devices_.add(device_address, std::unique_ptr<BluetoothDevice>(device_mac));
202 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
203 DeviceAdded(this, device_mac));
204 }
205 }
206
173 BluetoothAdapter::UUIDList BluetoothAdapterMac::GetUUIDs() const { 207 BluetoothAdapter::UUIDList BluetoothAdapterMac::GetUUIDs() const {
174 NOTIMPLEMENTED(); 208 NOTIMPLEMENTED();
175 return UUIDList(); 209 return UUIDList();
176 } 210 }
177 211
178 void BluetoothAdapterMac::CreateRfcommService( 212 void BluetoothAdapterMac::CreateRfcommService(
179 const BluetoothUUID& uuid, 213 const BluetoothUUID& uuid,
180 const ServiceOptions& options, 214 const ServiceOptions& options,
181 const CreateServiceCallback& callback, 215 const CreateServiceCallback& callback,
182 const CreateServiceErrorCallback& error_callback) { 216 const CreateServiceErrorCallback& error_callback) {
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 int rssi) { 518 int rssi) {
485 BluetoothLowEnergyDeviceMac* device_mac = 519 BluetoothLowEnergyDeviceMac* device_mac =
486 GetBluetoothLowEnergyDeviceMac(peripheral); 520 GetBluetoothLowEnergyDeviceMac(peripheral);
487 // If has no entry in the map, create new device and insert into |devices_|, 521 // If has no entry in the map, create new device and insert into |devices_|,
488 // otherwise update the existing device. 522 // otherwise update the existing device.
489 const bool is_new_device = device_mac == nullptr; 523 const bool is_new_device = device_mac == nullptr;
490 if (is_new_device) { 524 if (is_new_device) {
491 VLOG(1) << "LowEnergyDeviceUpdated new device"; 525 VLOG(1) << "LowEnergyDeviceUpdated new device";
492 // A new device has been found. 526 // A new device has been found.
493 device_mac = new BluetoothLowEnergyDeviceMac(this, peripheral); 527 device_mac = new BluetoothLowEnergyDeviceMac(this, peripheral);
494 } else { 528 } else if (DoesCollideWithKnownDevice(peripheral, device_mac)) {
495 // Check that there are no collisions. 529 return;
496 std::string stored_device_id = device_mac->GetIdentifier();
497 std::string updated_device_id =
498 BluetoothLowEnergyDeviceMac::GetPeripheralIdentifier(peripheral);
499 if (stored_device_id != updated_device_id) {
500 VLOG(1)
501 << "LowEnergyDeviceUpdated stored_device_id != updated_device_id: "
502 << std::endl
503 << " " << stored_device_id << std::endl
504 << " " << updated_device_id;
505 // Collision, two identifiers map to the same hash address. With a 48 bit
506 // hash the probability of this occuring with 10,000 devices
507 // simultaneously present is 1e-6 (see
508 // https://en.wikipedia.org/wiki/Birthday_problem#Probability_table). We
509 // ignore the second device by returning.
510 return;
511 }
512 } 530 }
513 531
514 DCHECK(device_mac); 532 DCHECK(device_mac);
515 533
516 // Get Advertised UUIDs 534 if (advertisement_data) {
ortuno 2016/10/14 03:03:03 I might be missing something but I don't think you
517 BluetoothDevice::UUIDList advertised_uuids; 535 // Get Advertised UUIDs
518 NSArray* service_uuids = 536 BluetoothDevice::UUIDList advertised_uuids;
519 [advertisement_data objectForKey:CBAdvertisementDataServiceUUIDsKey]; 537 NSArray* service_uuids =
520 for (CBUUID* uuid in service_uuids) { 538 [advertisement_data objectForKey:CBAdvertisementDataServiceUUIDsKey];
521 advertised_uuids.push_back(BluetoothUUID([[uuid UUIDString] UTF8String])); 539 for (CBUUID* uuid in service_uuids) {
540 advertised_uuids.push_back(BluetoothUUID([[uuid UUIDString] UTF8String]));
541 }
542 NSArray* overflow_service_uuids = [advertisement_data
543 objectForKey:CBAdvertisementDataOverflowServiceUUIDsKey];
544 for (CBUUID* uuid in overflow_service_uuids) {
545 advertised_uuids.push_back(BluetoothUUID([[uuid UUIDString] UTF8String]));
546 }
547
548 // Get Service Data.
549 BluetoothDevice::ServiceDataMap service_data_map;
550 NSDictionary* service_data =
551 [advertisement_data objectForKey:CBAdvertisementDataServiceDataKey];
552 for (CBUUID* uuid in service_data) {
553 NSData* data = [service_data objectForKey:uuid];
554 const uint8_t* bytes = static_cast<const uint8_t*>([data bytes]);
555 size_t length = [data length];
556 service_data_map.emplace(BluetoothUUID([[uuid UUIDString] UTF8String]),
557 std::vector<uint8_t>(bytes, bytes + length));
558 }
559
560 // Get Tx Power.
561 NSNumber* tx_power =
562 [advertisement_data objectForKey:CBAdvertisementDataTxPowerLevelKey];
563 int8_t clamped_tx_power = BluetoothDevice::ClampPower([tx_power intValue]);
564
565 device_mac->UpdateAdvertisementData(
566 BluetoothDevice::ClampPower(rssi), std::move(advertised_uuids),
567 std::move(service_data_map),
568 tx_power == nil ? nullptr : &clamped_tx_power);
522 } 569 }
523 NSArray* overflow_service_uuids = [advertisement_data
524 objectForKey:CBAdvertisementDataOverflowServiceUUIDsKey];
525 for (CBUUID* uuid in overflow_service_uuids) {
526 advertised_uuids.push_back(BluetoothUUID([[uuid UUIDString] UTF8String]));
527 }
528
529 // Get Service Data.
530 BluetoothDevice::ServiceDataMap service_data_map;
531 NSDictionary* service_data =
532 [advertisement_data objectForKey:CBAdvertisementDataServiceDataKey];
533 for (CBUUID* uuid in service_data) {
534 NSData* data = [service_data objectForKey:uuid];
535 const uint8_t* bytes = static_cast<const uint8_t*>([data bytes]);
536 size_t length = [data length];
537 service_data_map.emplace(BluetoothUUID([[uuid UUIDString] UTF8String]),
538 std::vector<uint8_t>(bytes, bytes + length));
539 }
540
541 // Get Tx Power.
542 NSNumber* tx_power =
543 [advertisement_data objectForKey:CBAdvertisementDataTxPowerLevelKey];
544 int8_t clamped_tx_power = BluetoothDevice::ClampPower([tx_power intValue]);
545
546 device_mac->UpdateAdvertisementData(
547 BluetoothDevice::ClampPower(rssi), std::move(advertised_uuids),
548 std::move(service_data_map),
549 tx_power == nil ? nullptr : &clamped_tx_power);
550 570
551 if (is_new_device) { 571 if (is_new_device) {
552 std::string device_address = 572 std::string device_address =
553 BluetoothLowEnergyDeviceMac::GetPeripheralHashAddress(peripheral); 573 BluetoothLowEnergyDeviceMac::GetPeripheralHashAddress(peripheral);
554 devices_.add(device_address, std::unique_ptr<BluetoothDevice>(device_mac)); 574 devices_.add(device_address, std::unique_ptr<BluetoothDevice>(device_mac));
555 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, 575 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
556 DeviceAdded(this, device_mac)); 576 DeviceAdded(this, device_mac));
557 } else { 577 } else {
558 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, 578 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
559 DeviceChanged(this, device_mac)); 579 DeviceChanged(this, device_mac));
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
637 BluetoothAdapterMac::GetBluetoothLowEnergyDeviceMac(CBPeripheral* peripheral) { 657 BluetoothAdapterMac::GetBluetoothLowEnergyDeviceMac(CBPeripheral* peripheral) {
638 std::string device_address = 658 std::string device_address =
639 BluetoothLowEnergyDeviceMac::GetPeripheralHashAddress(peripheral); 659 BluetoothLowEnergyDeviceMac::GetPeripheralHashAddress(peripheral);
640 DevicesMap::const_iterator iter = devices_.find(device_address); 660 DevicesMap::const_iterator iter = devices_.find(device_address);
641 if (iter == devices_.end()) { 661 if (iter == devices_.end()) {
642 return nil; 662 return nil;
643 } 663 }
644 return static_cast<BluetoothLowEnergyDeviceMac*>(iter->second); 664 return static_cast<BluetoothLowEnergyDeviceMac*>(iter->second);
645 } 665 }
646 666
667 bool BluetoothAdapterMac::DoesCollideWithKnownDevice(
668 CBPeripheral* peripheral,
669 BluetoothLowEnergyDeviceMac* device_mac) {
670 // Check that there are no collisions.
671 std::string stored_device_id = device_mac->GetIdentifier();
672 std::string updated_device_id =
673 BluetoothLowEnergyDeviceMac::GetPeripheralIdentifier(peripheral);
674 if (stored_device_id != updated_device_id) {
675 VLOG(1) << "LowEnergyDeviceUpdated stored_device_id != updated_device_id: "
676 << std::endl
677 << " " << stored_device_id << std::endl
678 << " " << updated_device_id;
679 // Collision, two identifiers map to the same hash address. With a 48 bit
680 // hash the probability of this occuring with 10,000 devices
681 // simultaneously present is 1e-6 (see
682 // https://en.wikipedia.org/wiki/Birthday_problem#Probability_table). We
683 // ignore the second device by returning.
684 return true;
685 }
686 return false;
687 }
688
647 } // namespace device 689 } // 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