Index: device/bluetooth/test/bluetooth_test_mac.mm |
diff --git a/device/bluetooth/test/bluetooth_test_mac.mm b/device/bluetooth/test/bluetooth_test_mac.mm |
index 3f9f72f833a7cb6a13cdbf6aed93c5268a8dfe59..a1dc222ad95aa6ec8ea91187a90988d06f284ff2 100644 |
--- a/device/bluetooth/test/bluetooth_test_mac.mm |
+++ b/device/bluetooth/test/bluetooth_test_mac.mm |
@@ -2,12 +2,26 @@ |
// 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 <CoreBluetooth/CoreBluetooth.h> |
+#else // !defined(OS_IOS) |
+#import <IOBluetooth/IOBluetooth.h> |
+#endif // defined(OS_IOS) |
namespace device { |
+// UUID1 hashes to 01:00:00:90:1E:BE, and UUID2 to 02:00:00:8B:74:63. |
+const std::string BluetoothTestMac::kTestPeripheralUUID1 = |
+ "34045B00-0000-0000-0000-000000000000"; |
+const std::string BluetoothTestMac::kTestPeripheralUUID2 = |
+ "EC1B8F00-0000-0000-0000-000000000000"; |
+ |
BluetoothTestMac::BluetoothTestMac() {} |
BluetoothTestMac::~BluetoothTestMac() {} |
@@ -46,4 +60,135 @@ void BluetoothTestMac::InitWithFakeAdapter() { |
} |
} |
+CBPeripheral* CreateMockPeripheral(NSString* identifier) { |
+ Class peripheral_class = NSClassFromString(@"CBPeripheral"); |
+ id mock_peripheral = [OCMockObject mockForClass:[peripheral_class class]]; |
+ [static_cast<CBPeripheral*>( |
+ [[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; |
+} |
+ |
+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:kTestUUID1.c_str()]], |
+ [CBUUID |
+ UUIDWithString:[NSString stringWithUTF8String:kTestUUID2.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:kTestUUID3.c_str()]], |
+ [CBUUID |
+ UUIDWithString:[NSString stringWithUTF8String:kTestUUID4.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; |
+ } |
+ } |
+} |
+ |
+bool BluetoothTestMac::PlatformSupportsLowEnergy() { |
+ return BluetoothAdapterMac::IsLowEnergyAvailable(); |
+} |
+ |
+std::string BluetoothTestMac::FindCBUUIDForHashTarget() { |
+ // The desired first 6 digits of the hash. |
+ 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 4*10^7 iterations then the probability of not |
+ // succeeeding is < exp(-18) ~ 10^-8 via the Chernoff Bound |
+ // http://www.cs.berkeley.edu/~jfc/cs174/lecs/lec10/lec10.pdf. |
scheib
2015/07/23 18:15:25
Nice try at nerd sniping https://xkcd.com/356/
I s
krstnmnlsn
2015/07/23 22:03:29
Haha! next time..
|
+ 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; |
+ break; |
scheib
2015/07/23 18:15:25
Don't need a break; after a return;
krstnmnlsn
2015/07/23 22:03:29
:P
|
+ } |
+ ++input[0]; |
+ } |
+ return ""; |
+} |
+ |
} // namespace device |