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 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |