Chromium Code Reviews| 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 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 323 | 323 |
| 324 if (transport & BLUETOOTH_TRANSPORT_CLASSIC) { | 324 if (transport & BLUETOOTH_TRANSPORT_CLASSIC) { |
| 325 if (!classic_discovery_manager_->StopDiscovery()) { | 325 if (!classic_discovery_manager_->StopDiscovery()) { |
| 326 DVLOG(1) << "Failed to stop classic discovery"; | 326 DVLOG(1) << "Failed to stop classic discovery"; |
| 327 // TODO: Provide a more precise error here. | 327 // TODO: Provide a more precise error here. |
| 328 error_callback.Run(UMABluetoothDiscoverySessionOutcome::UNKNOWN); | 328 error_callback.Run(UMABluetoothDiscoverySessionOutcome::UNKNOWN); |
| 329 return; | 329 return; |
| 330 } | 330 } |
| 331 } | 331 } |
| 332 if (transport & BLUETOOTH_TRANSPORT_LE) { | 332 if (transport & BLUETOOTH_TRANSPORT_LE) { |
| 333 if (IsLowEnergyAvailable()) | 333 if (IsLowEnergyAvailable()) { |
| 334 low_energy_discovery_manager_->StopDiscovery(); | 334 low_energy_discovery_manager_->StopDiscovery(); |
| 335 for (const auto& device_id_object_pair : devices_) { | |
| 336 device_id_object_pair.second->ClearAdvertisementData(); | |
| 337 } | |
| 338 } | |
| 335 } | 339 } |
| 336 | 340 |
| 337 DVLOG(1) << "Discovery stopped"; | 341 DVLOG(1) << "Discovery stopped"; |
| 338 num_discovery_sessions_--; | 342 num_discovery_sessions_--; |
| 339 callback.Run(); | 343 callback.Run(); |
| 340 } | 344 } |
| 341 | 345 |
| 342 void BluetoothAdapterMac::SetDiscoveryFilter( | 346 void BluetoothAdapterMac::SetDiscoveryFilter( |
| 343 std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter, | 347 std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter, |
| 344 const base::Closure& callback, | 348 const base::Closure& callback, |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 474 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, | 478 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, |
| 475 DeviceAdded(this, device_classic)); | 479 DeviceAdded(this, device_classic)); |
| 476 } | 480 } |
| 477 | 481 |
| 478 void BluetoothAdapterMac::LowEnergyDeviceUpdated( | 482 void BluetoothAdapterMac::LowEnergyDeviceUpdated( |
| 479 CBPeripheral* peripheral, | 483 CBPeripheral* peripheral, |
| 480 NSDictionary* advertisement_data, | 484 NSDictionary* advertisement_data, |
| 481 int rssi) { | 485 int rssi) { |
| 482 BluetoothLowEnergyDeviceMac* device_mac = | 486 BluetoothLowEnergyDeviceMac* device_mac = |
| 483 GetBluetoothLowEnergyDeviceMac(peripheral); | 487 GetBluetoothLowEnergyDeviceMac(peripheral); |
| 484 // if has no entry in the map, create new device and insert into |devices_|, | 488 // If has no entry in the map, create new device and insert into |devices_|, |
| 485 // otherwise update the existing device. | 489 // otherwise update the existing device. |
| 486 if (!device_mac) { | 490 bool is_new_device = device_mac == nullptr; |
|
Jeffrey Yasskin
2016/08/18 19:56:30
Consider making this const, so it's really clear i
ortuno
2016/08/19 20:50:33
Done.
| |
| 491 if (is_new_device) { | |
| 487 VLOG(1) << "LowEnergyDeviceUpdated new device"; | 492 VLOG(1) << "LowEnergyDeviceUpdated new device"; |
| 488 // A new device has been found. | 493 // A new device has been found. |
| 489 device_mac = new BluetoothLowEnergyDeviceMac(this, peripheral, | 494 device_mac = new BluetoothLowEnergyDeviceMac(this, peripheral); |
| 490 advertisement_data, rssi); | 495 } else { |
| 496 // Check that there are no collisions. | |
| 497 std::string stored_device_id = device_mac->GetIdentifier(); | |
| 498 std::string updated_device_id = | |
| 499 BluetoothLowEnergyDeviceMac::GetPeripheralIdentifier(peripheral); | |
| 500 if (stored_device_id != updated_device_id) { | |
| 501 VLOG(1) | |
| 502 << "LowEnergyDeviceUpdated stored_device_id != updated_device_id: " | |
| 503 << std::endl | |
| 504 << " " << stored_device_id << std::endl | |
| 505 << " " << updated_device_id; | |
| 506 // Collision, two identifiers map to the same hash address. With a 48 bit | |
| 507 // hash the probability of this occuring with 10,000 devices | |
| 508 // simultaneously present is 1e-6 (see | |
| 509 // https://en.wikipedia.org/wiki/Birthday_problem#Probability_table). We | |
| 510 // ignore the second device by returning. | |
| 511 return; | |
| 512 } | |
| 513 } | |
| 514 | |
| 515 DCHECK(device_mac); | |
| 516 | |
| 517 // Get Advertised UUIDs | |
| 518 std::vector<std::string> advertised_uuids; | |
| 519 NSArray* service_uuids = | |
| 520 [advertisement_data objectForKey:CBAdvertisementDataServiceUUIDsKey]; | |
| 521 for (CBUUID* uuid in service_uuids) { | |
| 522 advertised_uuids.push_back([[uuid UUIDString] UTF8String]); | |
| 523 } | |
| 524 NSArray* overflow_service_uuids = [advertisement_data | |
| 525 objectForKey:CBAdvertisementDataOverflowServiceUUIDsKey]; | |
| 526 for (CBUUID* uuid in overflow_service_uuids) { | |
| 527 advertised_uuids.push_back([[uuid UUIDString] UTF8String]); | |
| 528 } | |
| 529 | |
| 530 // Get Service Data. | |
| 531 std::unordered_map<std::string, std::vector<uint8_t>> service_data_map; | |
|
Jeffrey Yasskin
2016/08/18 19:56:30
Would it make sense to use a BluetoothUUID as the
ortuno
2016/08/19 20:50:33
Done.
| |
| 532 NSDictionary* service_data = | |
| 533 [advertisement_data objectForKey:CBAdvertisementDataServiceDataKey]; | |
| 534 for (CBUUID* uuid in service_data) { | |
| 535 NSData* data = [service_data objectForKey:uuid]; | |
| 536 const uint8_t* bytes = static_cast<const uint8_t*>([data bytes]); | |
| 537 size_t length = [data length]; | |
| 538 service_data_map.emplace( | |
| 539 std::piecewise_construct, | |
|
Jeffrey Yasskin
2016/08/18 16:04:33
I wouldn't bother with the complexity of piecewise
ortuno
2016/08/19 20:50:33
Done.
| |
| 540 std::forward_as_tuple([[uuid UUIDString] UTF8String]), | |
| 541 std::forward_as_tuple(bytes, bytes + length)); | |
| 542 } | |
| 543 | |
| 544 device_mac->UpdateAdvertisementData(std::move(advertised_uuids), | |
| 545 std::move(service_data_map)); | |
| 546 | |
| 547 if (is_new_device) { | |
| 491 std::string device_address = | 548 std::string device_address = |
| 492 BluetoothLowEnergyDeviceMac::GetPeripheralHashAddress(peripheral); | 549 BluetoothLowEnergyDeviceMac::GetPeripheralHashAddress(peripheral); |
| 493 devices_.add(device_address, std::unique_ptr<BluetoothDevice>(device_mac)); | 550 devices_.add(device_address, std::unique_ptr<BluetoothDevice>(device_mac)); |
| 494 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, | 551 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, |
| 495 DeviceAdded(this, device_mac)); | 552 DeviceAdded(this, device_mac)); |
| 496 return; | 553 } else { |
| 554 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, | |
| 555 DeviceChanged(this, device_mac)); | |
| 497 } | 556 } |
| 498 | |
| 499 std::string stored_device_id = device_mac->GetIdentifier(); | |
| 500 std::string updated_device_id = | |
| 501 BluetoothLowEnergyDeviceMac::GetPeripheralIdentifier(peripheral); | |
| 502 if (stored_device_id != updated_device_id) { | |
| 503 VLOG(1) << "LowEnergyDeviceUpdated stored_device_id != updated_device_id: " | |
| 504 << std::endl | |
| 505 << " " << stored_device_id << std::endl | |
| 506 << " " << updated_device_id; | |
| 507 // Collision, two identifiers map to the same hash address. With a 48 bit | |
| 508 // hash the probability of this occuring with 10,000 devices | |
| 509 // simultaneously present is 1e-6 (see | |
| 510 // https://en.wikipedia.org/wiki/Birthday_problem#Probability_table). We | |
| 511 // ignore the second device by returning. | |
| 512 return; | |
| 513 } | |
| 514 | |
| 515 // A device has an update. | |
| 516 VLOG(2) << "LowEnergyDeviceUpdated"; | |
| 517 device_mac->Update(advertisement_data, rssi); | |
| 518 | |
| 519 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, | |
| 520 DeviceChanged(this, device_mac)); | |
| 521 } | 557 } |
| 522 | 558 |
| 523 // TODO(krstnmnlsn): Implement. crbug.com/511025 | 559 // TODO(krstnmnlsn): Implement. crbug.com/511025 |
| 524 void BluetoothAdapterMac::LowEnergyCentralManagerUpdatedState() {} | 560 void BluetoothAdapterMac::LowEnergyCentralManagerUpdatedState() {} |
| 525 | 561 |
| 526 void BluetoothAdapterMac::AddPairedDevices() { | 562 void BluetoothAdapterMac::AddPairedDevices() { |
| 527 // Add any new paired devices. | 563 // Add any new paired devices. |
| 528 for (IOBluetoothDevice* device in [IOBluetoothDevice pairedDevices]) { | 564 for (IOBluetoothDevice* device in [IOBluetoothDevice pairedDevices]) { |
| 529 ClassicDeviceAdded(device); | 565 ClassicDeviceAdded(device); |
| 530 } | 566 } |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 591 std::string device_address = | 627 std::string device_address = |
| 592 BluetoothLowEnergyDeviceMac::GetPeripheralHashAddress(peripheral); | 628 BluetoothLowEnergyDeviceMac::GetPeripheralHashAddress(peripheral); |
| 593 DevicesMap::const_iterator iter = devices_.find(device_address); | 629 DevicesMap::const_iterator iter = devices_.find(device_address); |
| 594 if (iter == devices_.end()) { | 630 if (iter == devices_.end()) { |
| 595 return nil; | 631 return nil; |
| 596 } | 632 } |
| 597 return static_cast<BluetoothLowEnergyDeviceMac*>(iter->second); | 633 return static_cast<BluetoothLowEnergyDeviceMac*>(iter->second); |
| 598 } | 634 } |
| 599 | 635 |
| 600 } // namespace device | 636 } // namespace device |
| OLD | NEW |