From 5a0eceb28201302bcb45621015119bd73351d659 Mon Sep 17 00:00:00 2001 From: krstnmnlsn Date: Fri, 31 Jul 2015 13:15:14 -0700 Subject: [PATCH] Modified BluetoothTestMac to support device discovery tests. Also implemented utility function FindCBUUIDForHashTarget() to find relatively simple CBUUIDs mapping (under SHA256 plus truncating) to a 6 byte address with the first 3 bytes specified. Used to choose CBUUID / bluetooth address pairs for testing. BUG=511008 Review URL: https://codereview.chromium.org/1246913006 Cr-Commit-Position: refs/heads/master@{#341400} --- device/bluetooth/bluetooth_adapter_mac.h | 1 + device/bluetooth/bluetooth_adapter_unittest.cc | 61 +++++--- device/bluetooth/bluetooth_device_unittest.cc | 2 +- device/bluetooth/bluetooth_low_energy_device_mac.h | 7 +- .../bluetooth/bluetooth_low_energy_device_mac.mm | 34 +++-- .../src/org/chromium/device/bluetooth/Fakes.java | 8 +- device/bluetooth/test/bluetooth_test.cc | 11 ++ device/bluetooth/test/bluetooth_test.h | 28 +++- device/bluetooth/test/bluetooth_test_android.cc | 4 + device/bluetooth/test/bluetooth_test_android.h | 1 + device/bluetooth/test/bluetooth_test_mac.h | 8 ++ device/bluetooth/test/bluetooth_test_mac.mm | 159 +++++++++++++++++++++ 12 files changed, 280 insertions(+), 44 deletions(-) diff --git a/device/bluetooth/bluetooth_adapter_mac.h b/device/bluetooth/bluetooth_adapter_mac.h index 2a5c1191f0ff..1c4f56cb13d4 100644 --- a/device/bluetooth/bluetooth_adapter_mac.h +++ b/device/bluetooth/bluetooth_adapter_mac.h @@ -112,6 +112,7 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterMac // Energy) before a discovered device is considered to be no longer available. const static NSTimeInterval kDiscoveryTimeoutSec; + friend class BluetoothTestMac; friend class BluetoothAdapterMacTest; friend class BluetoothLowEnergyCentralManagerBridge; diff --git a/device/bluetooth/bluetooth_adapter_unittest.cc b/device/bluetooth/bluetooth_adapter_unittest.cc index 2316ee5ac90b..7f380ab384a8 100644 --- a/device/bluetooth/bluetooth_adapter_unittest.cc +++ b/device/bluetooth/bluetooth_adapter_unittest.cc @@ -472,15 +472,23 @@ TEST_F(BluetoothTest, DiscoverySession) { } #endif // defined(OS_ANDROID) -#if defined(OS_ANDROID) +#if defined(OS_ANDROID) || defined(OS_MACOSX) // Discovers a device. -TEST_F(BluetoothTest, DiscoverDevice) { +TEST_F(BluetoothTest, DiscoverLowEnergyDevice) { + if (!PlatformSupportsLowEnergy()) { + LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test."; + return; + } InitWithFakeAdapter(); TestBluetoothAdapterObserver observer(adapter_); // Start discovery and find a device. - adapter_->StartDiscoverySession(GetDiscoverySessionCallback(), - GetErrorCallback()); + scoped_ptr discovery_filter( + new BluetoothDiscoveryFilter( + BluetoothDiscoveryFilter::Transport::TRANSPORT_LE)); + adapter_->StartDiscoverySessionWithFilter(discovery_filter.Pass(), + GetDiscoverySessionCallback(), + GetErrorCallback()); base::RunLoop().RunUntilIdle(); DiscoverLowEnergyDevice(1); base::RunLoop().RunUntilIdle(); @@ -488,11 +496,15 @@ TEST_F(BluetoothTest, DiscoverDevice) { BluetoothDevice* device = adapter_->GetDevice(observer.last_device_address()); EXPECT_TRUE(device); } -#endif // defined(OS_ANDROID) +#endif // defined(OS_ANDROID) || defined(OS_MACOSX) -#if defined(OS_ANDROID) +#if defined(OS_ANDROID) || defined(OS_MACOSX) // Discovers the same device multiple times. -TEST_F(BluetoothTest, DiscoverDeviceTwice) { +TEST_F(BluetoothTest, DiscoverLowEnergyDeviceTwice) { + if (!PlatformSupportsLowEnergy()) { + LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test."; + return; + } InitWithFakeAdapter(); TestBluetoothAdapterObserver observer(adapter_); @@ -511,14 +523,17 @@ TEST_F(BluetoothTest, DiscoverDeviceTwice) { DiscoverLowEnergyDevice(1); base::RunLoop().RunUntilIdle(); EXPECT_EQ(0, observer.device_added_count()); - EXPECT_EQ(0, observer.device_changed_count()); EXPECT_EQ(1u, adapter_->GetDevices().size()); } -#endif // defined(OS_ANDROID) +#endif // defined(OS_ANDROID) || defined(OS_MACOSX) -#if defined(OS_ANDROID) +#if defined(OS_ANDROID) || defined(OS_MACOSX) // Discovers a device, and then again with new Service UUIDs. -TEST_F(BluetoothTest, DiscoverDeviceWithUpdatedUUIDs) { +TEST_F(BluetoothTest, DiscoverLowEnergyDeviceWithUpdatedUUIDs) { + if (!PlatformSupportsLowEnergy()) { + LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test."; + return; + } InitWithFakeAdapter(); TestBluetoothAdapterObserver observer(adapter_); @@ -531,8 +546,10 @@ TEST_F(BluetoothTest, DiscoverDeviceWithUpdatedUUIDs) { BluetoothDevice* device = observer.last_device(); // Check the initial UUIDs: - EXPECT_TRUE(ContainsValue(device->GetUUIDs(), BluetoothUUID("1800"))); - EXPECT_FALSE(ContainsValue(device->GetUUIDs(), BluetoothUUID("1802"))); + EXPECT_TRUE( + ContainsValue(device->GetUUIDs(), BluetoothUUID(kTestUUIDGenericAccess))); + EXPECT_FALSE(ContainsValue(device->GetUUIDs(), + BluetoothUUID(kTestUUIDImmediateAlert))); // Discover same device again with updated UUIDs: observer.Reset(); @@ -544,8 +561,10 @@ TEST_F(BluetoothTest, DiscoverDeviceWithUpdatedUUIDs) { EXPECT_EQ(device, observer.last_device()); // Expect new UUIDs: - EXPECT_FALSE(ContainsValue(device->GetUUIDs(), BluetoothUUID("1800"))); - EXPECT_TRUE(ContainsValue(device->GetUUIDs(), BluetoothUUID("1802"))); + EXPECT_FALSE( + ContainsValue(device->GetUUIDs(), BluetoothUUID(kTestUUIDGenericAccess))); + EXPECT_TRUE(ContainsValue(device->GetUUIDs(), + BluetoothUUID(kTestUUIDImmediateAlert))); // Discover same device again with empty UUIDs: observer.Reset(); @@ -559,11 +578,15 @@ TEST_F(BluetoothTest, DiscoverDeviceWithUpdatedUUIDs) { // Expect empty UUIDs: EXPECT_EQ(0u, device->GetUUIDs().size()); } -#endif // defined(OS_ANDROID) +#endif // defined(OS_ANDROID) || defined(OS_MACOSX) -#if defined(OS_ANDROID) +#if defined(OS_ANDROID) || defined(OS_MACOSX) // Discovers multiple devices when addresses vary. -TEST_F(BluetoothTest, DiscoverMultipleDevices) { +TEST_F(BluetoothTest, DiscoverMultipleLowEnergyDevices) { + if (!PlatformSupportsLowEnergy()) { + LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test."; + return; + } InitWithFakeAdapter(); TestBluetoothAdapterObserver observer(adapter_); @@ -577,6 +600,6 @@ TEST_F(BluetoothTest, DiscoverMultipleDevices) { EXPECT_EQ(2, observer.device_added_count()); EXPECT_EQ(2u, adapter_->GetDevices().size()); } -#endif // defined(OS_ANDROID) +#endif // defined(OS_ANDROID) || defined(OS_MACOSX) } // namespace device diff --git a/device/bluetooth/bluetooth_device_unittest.cc b/device/bluetooth/bluetooth_device_unittest.cc index c92392d1327d..3e8d264efee8 100644 --- a/device/bluetooth/bluetooth_device_unittest.cc +++ b/device/bluetooth/bluetooth_device_unittest.cc @@ -77,7 +77,7 @@ TEST_F(BluetoothTest, DeviceProperties) { BluetoothDevice* device = observer.last_device(); ASSERT_TRUE(device); EXPECT_EQ(0x1F00u, device->GetBluetoothClass()); - EXPECT_EQ("AA:00:00:00:00:01", device->GetAddress()); + EXPECT_EQ(kTestDeviceAddress1, device->GetAddress()); EXPECT_EQ(BluetoothDevice::VENDOR_ID_UNKNOWN, device->GetVendorIDSource()); EXPECT_EQ(0, device->GetVendorID()); EXPECT_EQ(0, device->GetProductID()); diff --git a/device/bluetooth/bluetooth_low_energy_device_mac.h b/device/bluetooth/bluetooth_low_energy_device_mac.h index 502e082a185b..ed1684602ef1 100644 --- a/device/bluetooth/bluetooth_low_energy_device_mac.h +++ b/device/bluetooth/bluetooth_low_energy_device_mac.h @@ -24,7 +24,7 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothLowEnergyDeviceMac : public BluetoothDeviceMac { public: BluetoothLowEnergyDeviceMac(CBPeripheral* peripheral, - NSDictionary* advertisementData, + NSDictionary* advertisement_data, int rssi); ~BluetoothLowEnergyDeviceMac() override; @@ -81,7 +81,7 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothLowEnergyDeviceMac // Updates information about the device. virtual void Update(CBPeripheral* peripheral, - NSDictionary* advertisementData, + NSDictionary* advertisement_data, int rssi); static std::string GetPeripheralIdentifier(CBPeripheral* peripheral); @@ -118,6 +118,9 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothLowEnergyDeviceMac // Stores the time of the most recent call to Update(). base::scoped_nsobject last_update_time_; + // The services (identified by UUIDs) that this device provides. + UUIDList advertised_uuids_; + DISALLOW_COPY_AND_ASSIGN(BluetoothLowEnergyDeviceMac); }; diff --git a/device/bluetooth/bluetooth_low_energy_device_mac.mm b/device/bluetooth/bluetooth_low_energy_device_mac.mm index 4e4ca6431beb..875ab196b176 100644 --- a/device/bluetooth/bluetooth_low_energy_device_mac.mm +++ b/device/bluetooth/bluetooth_low_energy_device_mac.mm @@ -31,33 +31,41 @@ device::BluetoothUUID BluetoothUUIDWithCBUUID(CBUUID* uuid) { BluetoothLowEnergyDeviceMac::BluetoothLowEnergyDeviceMac( CBPeripheral* peripheral, - NSDictionary* advertisementData, + NSDictionary* advertisement_data, int rssi) { DCHECK(BluetoothAdapterMac::IsLowEnergyAvailable()); identifier_ = GetPeripheralIdentifier(peripheral); hash_address_ = GetPeripheralHashAddress(peripheral); - Update(peripheral, advertisementData, rssi); + Update(peripheral, advertisement_data, rssi); } BluetoothLowEnergyDeviceMac::~BluetoothLowEnergyDeviceMac() { } void BluetoothLowEnergyDeviceMac::Update(CBPeripheral* peripheral, - NSDictionary* advertisementData, + NSDictionary* advertisement_data, int rssi) { last_update_time_.reset([[NSDate date] retain]); peripheral_.reset([peripheral retain]); rssi_ = rssi; + NSNumber* connectable = + [advertisement_data objectForKey:CBAdvertisementDataIsConnectable]; + connectable_ = [connectable boolValue]; ClearServiceData(); - NSNumber* nbConnectable = - [advertisementData objectForKey:CBAdvertisementDataIsConnectable]; - connectable_ = [nbConnectable boolValue]; - NSDictionary* serviceData = - [advertisementData objectForKey:CBAdvertisementDataServiceDataKey]; - for (CBUUID* uuid in serviceData) { - NSData* data = [serviceData objectForKey:uuid]; - BluetoothUUID serviceUUID = BluetoothUUIDWithCBUUID(uuid); - SetServiceData(serviceUUID, (const char*)[data bytes], [data length]); + NSDictionary* service_data = + [advertisement_data objectForKey:@"CBAdvertisementDataServiceDataKey"]; + for (CBUUID* uuid in service_data) { + NSData* data = [service_data objectForKey:uuid]; + BluetoothUUID service_uuid = BluetoothUUIDWithCBUUID(uuid); + SetServiceData(service_uuid, static_cast([data bytes]), + [data length]); + } + advertised_uuids_.clear(); + NSArray* service_uuids = + [advertisement_data objectForKey:@"CBAdvertisementDataServiceUUIDsKey"]; + for (CBUUID* uuid in service_uuids) { + advertised_uuids_.push_back( + BluetoothUUID(std::string([[uuid UUIDString] UTF8String]))); } } @@ -111,7 +119,7 @@ bool BluetoothLowEnergyDeviceMac::IsConnecting() const { } BluetoothDevice::UUIDList BluetoothLowEnergyDeviceMac::GetUUIDs() const { - return std::vector(); + return advertised_uuids_; } int16 BluetoothLowEnergyDeviceMac::GetInquiryRSSI() const { diff --git a/device/bluetooth/test/android/java/src/org/chromium/device/bluetooth/Fakes.java b/device/bluetooth/test/android/java/src/org/chromium/device/bluetooth/Fakes.java index 6efafeccb25d..18a4683e1a64 100644 --- a/device/bluetooth/test/android/java/src/org/chromium/device/bluetooth/Fakes.java +++ b/device/bluetooth/test/android/java/src/org/chromium/device/bluetooth/Fakes.java @@ -57,7 +57,7 @@ class Fakes { mFakeScanner.mCallback.onScanResult(ScanSettings.CALLBACK_TYPE_ALL_MATCHES, new FakeScanResult(new FakeBluetoothDevice( - "AA:00:00:00:00:01", "FakeBluetoothDevice"), + "01:00:00:90:1E:BE", "FakeBluetoothDevice"), uuids)); break; } @@ -68,14 +68,14 @@ class Fakes { mFakeScanner.mCallback.onScanResult(ScanSettings.CALLBACK_TYPE_ALL_MATCHES, new FakeScanResult(new FakeBluetoothDevice( - "AA:00:00:00:00:01", "FakeBluetoothDevice"), + "01:00:00:90:1E:BE", "FakeBluetoothDevice"), uuids)); break; } case 3: { ArrayList uuids = null; mFakeScanner.mCallback.onScanResult(ScanSettings.CALLBACK_TYPE_ALL_MATCHES, - new FakeScanResult(new FakeBluetoothDevice("AA:00:00:00:00:01", ""), + new FakeScanResult(new FakeBluetoothDevice("01:00:00:90:1E:BE", ""), uuids)); break; @@ -83,7 +83,7 @@ class Fakes { case 4: { ArrayList uuids = null; mFakeScanner.mCallback.onScanResult(ScanSettings.CALLBACK_TYPE_ALL_MATCHES, - new FakeScanResult(new FakeBluetoothDevice("BB:00:00:00:00:02", ""), + new FakeScanResult(new FakeBluetoothDevice("02:00:00:8B:74:63", ""), uuids)); break; diff --git a/device/bluetooth/test/bluetooth_test.cc b/device/bluetooth/test/bluetooth_test.cc index 6f66b7341651..45425fa2ccb4 100644 --- a/device/bluetooth/test/bluetooth_test.cc +++ b/device/bluetooth/test/bluetooth_test.cc @@ -14,6 +14,17 @@ namespace device { const std::string BluetoothTestBase::kTestAdapterName = "FakeBluetoothAdapter"; const std::string BluetoothTestBase::kTestAdapterAddress = "A1:B2:C3:D4:E5:F6"; +const std::string BluetoothTestBase::kTestDeviceName = "FakeBluetoothDevice"; +const std::string BluetoothTestBase::kTestDeviceNameEmpty = ""; + +const std::string BluetoothTestBase::kTestDeviceAddress1 = "01:00:00:90:1E:BE"; +const std::string BluetoothTestBase::kTestDeviceAddress2 = "02:00:00:8B:74:63"; + +const std::string BluetoothTestBase::kTestUUIDGenericAccess = "1800"; +const std::string BluetoothTestBase::kTestUUIDGenericAttribute = "1801"; +const std::string BluetoothTestBase::kTestUUIDImmediateAlert = "1802"; +const std::string BluetoothTestBase::kTestUUIDLinkLoss = "1803"; + BluetoothTestBase::BluetoothTestBase() { } diff --git a/device/bluetooth/test/bluetooth_test.h b/device/bluetooth/test/bluetooth_test.h index a45373b0cfa7..7a0ed0e29f4d 100644 --- a/device/bluetooth/test/bluetooth_test.h +++ b/device/bluetooth/test/bluetooth_test.h @@ -25,9 +25,23 @@ class BluetoothTestBase : public testing::Test { static const std::string kTestAdapterName; static const std::string kTestAdapterAddress; + static const std::string kTestDeviceName; + static const std::string kTestDeviceNameEmpty; + + static const std::string kTestDeviceAddress1; + static const std::string kTestDeviceAddress2; + + static const std::string kTestUUIDGenericAccess; + static const std::string kTestUUIDGenericAttribute; + static const std::string kTestUUIDImmediateAlert; + static const std::string kTestUUIDLinkLoss; + BluetoothTestBase(); ~BluetoothTestBase() override; + // Check if Low Energy is available. On Mac, we require OS X >= 10.10. + virtual bool PlatformSupportsLowEnergy() = 0; + // Initializes the BluetoothAdapter |adapter_| with the system adapter. virtual void InitWithDefaultAdapter(){}; @@ -41,11 +55,15 @@ class BluetoothTestBase : public testing::Test { virtual void InitWithFakeAdapter(){}; // Create a fake Low Energy device and discover it. - // |device_ordinal| selects between multiple fake device data sets to produce. - // 1: AA:00:00:00:00:01 with simple default values. - // 2: AA:00:00:00:00:01 with different advertised Service UUIDs vs 1. - // 3: AA:00:00:00:00:01 with empty name, empty UUIDs. - // 4: BB:00:00:00:00:02 with empty name, empty UUIDs. + // |device_ordinal| selects between multiple fake device data sets to produce: + // 1: kTestDeviceName with advertised UUIDs kTestUUIDGenericAccess, + // kTestUUIDGenericAttribute and address kTestDeviceAddress1. + // 2: kTestDeviceName with advertised UUIDs kTestUUIDImmediateAlert, + // kTestUUIDLinkLoss and address kTestDeviceAddress1. + // 3: kTestDeviceNameEmpty with no advertised UUIDs and address + // kTestDeviceAddress1. + // 4: kTestDeviceNameEmpty with no advertised UUIDs and address + // kTestDeviceAddress2. virtual void DiscoverLowEnergyDevice(int device_ordinal){}; // Callbacks that increment |callback_count_|, |error_callback_count_|: diff --git a/device/bluetooth/test/bluetooth_test_android.cc b/device/bluetooth/test/bluetooth_test_android.cc index b7bf980655c2..1be588d51643 100644 --- a/device/bluetooth/test/bluetooth_test_android.cc +++ b/device/bluetooth/test/bluetooth_test_android.cc @@ -25,6 +25,10 @@ void BluetoothTestAndroid::SetUp() { ASSERT_TRUE(RegisterNativesImpl(AttachCurrentThread())); } +bool BluetoothTestAndroid::PlatformSupportsLowEnergy() { + return true; +} + void BluetoothTestAndroid::InitWithDefaultAdapter() { adapter_ = BluetoothAdapterAndroid::Create( diff --git a/device/bluetooth/test/bluetooth_test_android.h b/device/bluetooth/test/bluetooth_test_android.h index 0a87e7936136..63e8f9fa8253 100644 --- a/device/bluetooth/test/bluetooth_test_android.h +++ b/device/bluetooth/test/bluetooth_test_android.h @@ -22,6 +22,7 @@ class BluetoothTestAndroid : public BluetoothTestBase { void SetUp() override; // BluetoothTestBase overrides: + bool PlatformSupportsLowEnergy() override; void InitWithDefaultAdapter() override; void InitWithoutDefaultAdapter() override; void InitWithFakeAdapter() override; diff --git a/device/bluetooth/test/bluetooth_test_mac.h b/device/bluetooth/test/bluetooth_test_mac.h index b6d15385ad33..0e44ff999435 100644 --- a/device/bluetooth/test/bluetooth_test_mac.h +++ b/device/bluetooth/test/bluetooth_test_mac.h @@ -15,6 +15,9 @@ class BluetoothAdapterMac; // Mac implementation of BluetoothTestBase. class BluetoothTestMac : public BluetoothTestBase { public: + static const std::string kTestPeripheralUUID1; + static const std::string kTestPeripheralUUID2; + BluetoothTestMac(); ~BluetoothTestMac() override; @@ -22,11 +25,16 @@ class BluetoothTestMac : public BluetoothTestBase { void SetUp() override; // BluetoothTestBase overrides: + bool PlatformSupportsLowEnergy() override; void InitWithDefaultAdapter() override; void InitWithoutDefaultAdapter() override; void InitWithFakeAdapter() override; + void DiscoverLowEnergyDevice(int device_ordinal) override; protected: + // Utility function for finding CBUUIDs with relatively nice SHA256 hashes. + std::string FindCBUUIDForHashTarget(); + BluetoothAdapterMac* adapter_mac_ = NULL; }; diff --git a/device/bluetooth/test/bluetooth_test_mac.mm b/device/bluetooth/test/bluetooth_test_mac.mm index 3f9f72f833a7..fc1c81fc78d3 100644 --- a/device/bluetooth/test/bluetooth_test_mac.mm +++ b/device/bluetooth/test/bluetooth_test_mac.mm @@ -2,18 +2,69 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/strings/string_number_conversions.h" #include "device/bluetooth/bluetooth_adapter_mac.h" #include "device/bluetooth/test/bluetooth_test_mac.h" #include "device/bluetooth/test/mock_bluetooth_central_manager_mac.h" +#include "third_party/ocmock/OCMock/OCMock.h" + +#if defined(OS_IOS) +#import +#else // !defined(OS_IOS) +#import +#endif // defined(OS_IOS) namespace device { +namespace { + +CBPeripheral* CreateMockPeripheral(NSString* identifier) { + Class peripheral_class = NSClassFromString(@"CBPeripheral"); + id mock_peripheral = [OCMockObject mockForClass:[peripheral_class class]]; + [static_cast( + [[mock_peripheral stub] andReturnValue:@(CBPeripheralStateDisconnected)]) + performSelector:@selector(state)]; + [[[mock_peripheral stub] andReturn:[NSString string]] name]; + Class uuid_class = NSClassFromString(@"NSUUID"); + [[[mock_peripheral stub] + andReturn:[[uuid_class performSelector:@selector(UUID)] + performSelector:@selector(initWithUUIDString:) + withObject:identifier]] identifier]; + + return mock_peripheral; +} + +NSDictionary* CreateAdvertisementData(NSString* name, NSArray* uuids) { + NSMutableDictionary* advertisement_data = + [NSMutableDictionary dictionaryWithDictionary:@{ + @"CBAdvertisementDataLocalNameKey" : name, + @"CBAdvertisementDataServiceDataKey" : [NSDictionary dictionary], + @"CBAdvertisementDataIsConnectable" : @(YES), + }]; + if (uuids) + [advertisement_data setObject:uuids + forKey:@"CBAdvertisementDataServiceUUIDsKey"]; + return advertisement_data; +} + +} // namespace + +// UUID1 hashes to kTestDeviceAddress1, and UUID2 to kTestDeviceAddress2. +const std::string BluetoothTestMac::kTestPeripheralUUID1 = + "34045B00-0000-0000-0000-000000000000"; +const std::string BluetoothTestMac::kTestPeripheralUUID2 = + "EC1B8F00-0000-0000-0000-000000000000"; + BluetoothTestMac::BluetoothTestMac() {} BluetoothTestMac::~BluetoothTestMac() {} void BluetoothTestMac::SetUp() {} +bool BluetoothTestMac::PlatformSupportsLowEnergy() { + return BluetoothAdapterMac::IsLowEnergyAvailable(); +} + void BluetoothTestMac::InitWithDefaultAdapter() { adapter_mac_ = BluetoothAdapterMac::CreateAdapter().get(); adapter_ = adapter_mac_; @@ -46,4 +97,112 @@ void BluetoothTestMac::InitWithFakeAdapter() { } } +void BluetoothTestMac::DiscoverLowEnergyDevice(int device_ordinal) { + CBCentralManager* central_manager = adapter_mac_->low_energy_central_manager_; + BluetoothLowEnergyCentralManagerDelegate* central_manager_delegate = + adapter_mac_->low_energy_central_manager_delegate_; + switch (device_ordinal) { + case 1: { + CBPeripheral* peripheral = CreateMockPeripheral( + [NSString stringWithUTF8String:kTestPeripheralUUID1.c_str()]); + NSString* name = [NSString stringWithUTF8String:kTestDeviceName.c_str()]; + NSArray* uuids = @[ + [CBUUID + UUIDWithString:[NSString stringWithUTF8String:kTestUUIDGenericAccess + .c_str()]], + [CBUUID + UUIDWithString:[NSString + stringWithUTF8String:kTestUUIDGenericAttribute + .c_str()]] + ]; + NSDictionary* advertisement_data = CreateAdvertisementData(name, uuids); + [central_manager_delegate centralManager:central_manager + didDiscoverPeripheral:peripheral + advertisementData:advertisement_data + RSSI:0]; + break; + } + case 2: { + CBPeripheral* peripheral = CreateMockPeripheral( + [NSString stringWithUTF8String:kTestPeripheralUUID1.c_str()]); + NSString* name = [NSString stringWithUTF8String:kTestDeviceName.c_str()]; + NSArray* uuids = @[ + [CBUUID UUIDWithString:[NSString + stringWithUTF8String:kTestUUIDImmediateAlert + .c_str()]], + [CBUUID + UUIDWithString:[NSString + stringWithUTF8String:kTestUUIDLinkLoss.c_str()]] + ]; + NSDictionary* advertisement_data = CreateAdvertisementData(name, uuids); + [central_manager_delegate centralManager:central_manager + didDiscoverPeripheral:peripheral + advertisementData:advertisement_data + RSSI:0]; + break; + } + case 3: { + CBPeripheral* peripheral = CreateMockPeripheral( + [NSString stringWithUTF8String:kTestPeripheralUUID1.c_str()]); + NSString* name = + [NSString stringWithUTF8String:kTestDeviceNameEmpty.c_str()]; + NSArray* uuids = nil; + NSDictionary* advertisement_data = CreateAdvertisementData(name, uuids); + [central_manager_delegate centralManager:central_manager + didDiscoverPeripheral:peripheral + advertisementData:advertisement_data + RSSI:0]; + break; + } + case 4: { + CBPeripheral* peripheral = CreateMockPeripheral( + [NSString stringWithUTF8String:kTestPeripheralUUID2.c_str()]); + NSString* name = + [NSString stringWithUTF8String:kTestDeviceNameEmpty.c_str()]; + NSArray* uuids = nil; + NSDictionary* advertisement_data = CreateAdvertisementData(name, uuids); + [central_manager_delegate centralManager:central_manager + didDiscoverPeripheral:peripheral + advertisementData:advertisement_data + RSSI:0]; + break; + } + } +} + +// Utility function for generating new (CBUUID, address) pairs where CBUUID +// hashes to address. For use when adding a new device address to the testing +// suite because CoreBluetooth peripherals have CBUUIDs in place of addresses, +// and we construct fake addresses for them by hashing the CBUUID. By changing +// |target| the user can generate sequentially numbered test addresses. +// +// std::string BluetoothTestMac::FindCBUUIDForHashTarget() { +// // The desired first 6 digits of the hash. For example 0100000, 020000, +// // 030000, ... +// const std::string target = "010000"; +// // 128 bit buffer to be encoded as a hex string. +// int64_t input[2] = {0}; +// // There are 2^24 ~ 10^7 possible configurations for the first 6 digits, +// // ie. each input has probability 10^-7 of succeeding, under the dubious +// // assumption that traversing inputs sequentially is as good as traversing +// // them randomly. After 10^8 iterations then the probability of never +// // succeeding is ((10^7-1)/10^7)^(10^8) ~= 10^-5. +// while (input[0] < LLONG_MAX) { +// // Encode as a hexidecimal number. Note that on x86 input[0] is stored +// // as a little-endian number, and so read backwards by HexEncode. +// std::string input_str = base::HexEncode(&input, sizeof(input)); +// input_str.insert(20, "-"); +// input_str.insert(16, "-"); +// input_str.insert(12, "-"); +// input_str.insert(8, "-"); +// char raw[3]; +// crypto::SHA256HashString(input_str, raw, sizeof(raw)); +// if (base::HexEncode(raw, sizeof(raw)) == target) { +// return input_str; +// } +// ++input[0]; +// } +// return ""; +// } + } // namespace device -- 2.11.4.GIT