| 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 const bool is_new_device = device_mac == nullptr; |
| 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 BluetoothDevice::UUIDList advertised_uuids; |
| 519 NSArray* service_uuids = |
| 520 [advertisement_data objectForKey:CBAdvertisementDataServiceUUIDsKey]; |
| 521 for (CBUUID* uuid in service_uuids) { |
| 522 advertised_uuids.push_back(BluetoothUUID([[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(BluetoothUUID([[uuid UUIDString] UTF8String])); |
| 528 } |
| 529 |
| 530 // Get Service Data. |
| 531 BluetoothDevice::ServiceDataMap service_data_map; |
| 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(BluetoothUUID([[uuid UUIDString] UTF8String]), |
| 539 std::vector<uint8_t>(bytes, bytes + length)); |
| 540 } |
| 541 |
| 542 device_mac->UpdateAdvertisementData(std::move(advertised_uuids), |
| 543 std::move(service_data_map)); |
| 544 |
| 545 if (is_new_device) { |
| 491 std::string device_address = | 546 std::string device_address = |
| 492 BluetoothLowEnergyDeviceMac::GetPeripheralHashAddress(peripheral); | 547 BluetoothLowEnergyDeviceMac::GetPeripheralHashAddress(peripheral); |
| 493 devices_.add(device_address, std::unique_ptr<BluetoothDevice>(device_mac)); | 548 devices_.add(device_address, std::unique_ptr<BluetoothDevice>(device_mac)); |
| 494 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, | 549 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, |
| 495 DeviceAdded(this, device_mac)); | 550 DeviceAdded(this, device_mac)); |
| 496 return; | 551 } else { |
| 552 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, |
| 553 DeviceChanged(this, device_mac)); |
| 497 } | 554 } |
| 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 } | 555 } |
| 522 | 556 |
| 523 // TODO(krstnmnlsn): Implement. crbug.com/511025 | 557 // TODO(krstnmnlsn): Implement. crbug.com/511025 |
| 524 void BluetoothAdapterMac::LowEnergyCentralManagerUpdatedState() {} | 558 void BluetoothAdapterMac::LowEnergyCentralManagerUpdatedState() {} |
| 525 | 559 |
| 526 void BluetoothAdapterMac::AddPairedDevices() { | 560 void BluetoothAdapterMac::AddPairedDevices() { |
| 527 // Add any new paired devices. | 561 // Add any new paired devices. |
| 528 for (IOBluetoothDevice* device in [IOBluetoothDevice pairedDevices]) { | 562 for (IOBluetoothDevice* device in [IOBluetoothDevice pairedDevices]) { |
| 529 ClassicDeviceAdded(device); | 563 ClassicDeviceAdded(device); |
| 530 } | 564 } |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 591 std::string device_address = | 625 std::string device_address = |
| 592 BluetoothLowEnergyDeviceMac::GetPeripheralHashAddress(peripheral); | 626 BluetoothLowEnergyDeviceMac::GetPeripheralHashAddress(peripheral); |
| 593 DevicesMap::const_iterator iter = devices_.find(device_address); | 627 DevicesMap::const_iterator iter = devices_.find(device_address); |
| 594 if (iter == devices_.end()) { | 628 if (iter == devices_.end()) { |
| 595 return nil; | 629 return nil; |
| 596 } | 630 } |
| 597 return static_cast<BluetoothLowEnergyDeviceMac*>(iter->second); | 631 return static_cast<BluetoothLowEnergyDeviceMac*>(iter->second); |
| 598 } | 632 } |
| 599 | 633 |
| 600 } // namespace device | 634 } // namespace device |
| OLD | NEW |