| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "base/strings/string_number_conversions.h" | |
| 6 #include "device/bluetooth/bluetooth_adapter_mac.h" | 5 #include "device/bluetooth/bluetooth_adapter_mac.h" |
| 7 #include "device/bluetooth/test/bluetooth_test_mac.h" | 6 #include "device/bluetooth/test/bluetooth_test_mac.h" |
| 8 #include "device/bluetooth/test/mock_bluetooth_central_manager_mac.h" | 7 #include "device/bluetooth/test/mock_bluetooth_central_manager_mac.h" |
| 9 #include "third_party/ocmock/OCMock/OCMock.h" | |
| 10 | |
| 11 #if defined(OS_IOS) | |
| 12 #import <CoreBluetooth/CoreBluetooth.h> | |
| 13 #else // !defined(OS_IOS) | |
| 14 #import <IOBluetooth/IOBluetooth.h> | |
| 15 #endif // defined(OS_IOS) | |
| 16 | 8 |
| 17 namespace device { | 9 namespace device { |
| 18 | 10 |
| 19 namespace { | |
| 20 | |
| 21 CBPeripheral* CreateMockPeripheral(NSString* identifier) { | |
| 22 Class peripheral_class = NSClassFromString(@"CBPeripheral"); | |
| 23 id mock_peripheral = [OCMockObject mockForClass:[peripheral_class class]]; | |
| 24 [static_cast<CBPeripheral*>( | |
| 25 [[mock_peripheral stub] andReturnValue:@(CBPeripheralStateDisconnected)]) | |
| 26 performSelector:@selector(state)]; | |
| 27 [[[mock_peripheral stub] andReturn:[NSString string]] name]; | |
| 28 Class uuid_class = NSClassFromString(@"NSUUID"); | |
| 29 [[[mock_peripheral stub] | |
| 30 andReturn:[[uuid_class performSelector:@selector(UUID)] | |
| 31 performSelector:@selector(initWithUUIDString:) | |
| 32 withObject:identifier]] identifier]; | |
| 33 | |
| 34 return mock_peripheral; | |
| 35 } | |
| 36 | |
| 37 NSDictionary* CreateAdvertisementData(NSString* name, NSArray* uuids) { | |
| 38 NSMutableDictionary* advertisement_data = | |
| 39 [NSMutableDictionary dictionaryWithDictionary:@{ | |
| 40 @"CBAdvertisementDataLocalNameKey" : name, | |
| 41 @"CBAdvertisementDataServiceDataKey" : [NSDictionary dictionary], | |
| 42 @"CBAdvertisementDataIsConnectable" : @(YES), | |
| 43 }]; | |
| 44 if (uuids) | |
| 45 [advertisement_data setObject:uuids | |
| 46 forKey:@"CBAdvertisementDataServiceUUIDsKey"]; | |
| 47 return advertisement_data; | |
| 48 } | |
| 49 | |
| 50 } // namespace | |
| 51 | |
| 52 // UUID1 hashes to kTestDeviceAddress1, and UUID2 to kTestDeviceAddress2. | |
| 53 const std::string BluetoothTestMac::kTestPeripheralUUID1 = | |
| 54 "34045B00-0000-0000-0000-000000000000"; | |
| 55 const std::string BluetoothTestMac::kTestPeripheralUUID2 = | |
| 56 "EC1B8F00-0000-0000-0000-000000000000"; | |
| 57 | |
| 58 BluetoothTestMac::BluetoothTestMac() {} | 11 BluetoothTestMac::BluetoothTestMac() {} |
| 59 | 12 |
| 60 BluetoothTestMac::~BluetoothTestMac() {} | 13 BluetoothTestMac::~BluetoothTestMac() {} |
| 61 | 14 |
| 62 void BluetoothTestMac::SetUp() {} | 15 void BluetoothTestMac::SetUp() {} |
| 63 | 16 |
| 64 bool BluetoothTestMac::PlatformSupportsLowEnergy() { | |
| 65 return BluetoothAdapterMac::IsLowEnergyAvailable(); | |
| 66 } | |
| 67 | |
| 68 void BluetoothTestMac::InitWithDefaultAdapter() { | 17 void BluetoothTestMac::InitWithDefaultAdapter() { |
| 69 adapter_mac_ = BluetoothAdapterMac::CreateAdapter().get(); | 18 adapter_mac_ = BluetoothAdapterMac::CreateAdapter().get(); |
| 70 adapter_ = adapter_mac_; | 19 adapter_ = adapter_mac_; |
| 71 } | 20 } |
| 72 | 21 |
| 73 void BluetoothTestMac::InitWithoutDefaultAdapter() { | 22 void BluetoothTestMac::InitWithoutDefaultAdapter() { |
| 74 adapter_mac_ = BluetoothAdapterMac::CreateAdapterForTest( | 23 adapter_mac_ = BluetoothAdapterMac::CreateAdapterForTest( |
| 75 "", "", message_loop_.task_runner()) | 24 "", "", message_loop_.task_runner()) |
| 76 .get(); | 25 .get(); |
| 77 adapter_ = adapter_mac_; | 26 adapter_ = adapter_mac_; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 90 .get(); | 39 .get(); |
| 91 adapter_ = adapter_mac_; | 40 adapter_ = adapter_mac_; |
| 92 | 41 |
| 93 if (BluetoothAdapterMac::IsLowEnergyAvailable()) { | 42 if (BluetoothAdapterMac::IsLowEnergyAvailable()) { |
| 94 id low_energy_central_manager = [[MockCentralManager alloc] init]; | 43 id low_energy_central_manager = [[MockCentralManager alloc] init]; |
| 95 [low_energy_central_manager setState:CBCentralManagerStatePoweredOn]; | 44 [low_energy_central_manager setState:CBCentralManagerStatePoweredOn]; |
| 96 adapter_mac_->SetCentralManagerForTesting(low_energy_central_manager); | 45 adapter_mac_->SetCentralManagerForTesting(low_energy_central_manager); |
| 97 } | 46 } |
| 98 } | 47 } |
| 99 | 48 |
| 100 void BluetoothTestMac::DiscoverLowEnergyDevice(int device_ordinal) { | |
| 101 CBCentralManager* central_manager = adapter_mac_->low_energy_central_manager_; | |
| 102 BluetoothLowEnergyCentralManagerDelegate* central_manager_delegate = | |
| 103 adapter_mac_->low_energy_central_manager_delegate_; | |
| 104 switch (device_ordinal) { | |
| 105 case 1: { | |
| 106 CBPeripheral* peripheral = CreateMockPeripheral( | |
| 107 [NSString stringWithUTF8String:kTestPeripheralUUID1.c_str()]); | |
| 108 NSString* name = [NSString stringWithUTF8String:kTestDeviceName.c_str()]; | |
| 109 NSArray* uuids = @[ | |
| 110 [CBUUID | |
| 111 UUIDWithString:[NSString stringWithUTF8String:kTestUUIDGenericAccess | |
| 112 .c_str()]], | |
| 113 [CBUUID | |
| 114 UUIDWithString:[NSString | |
| 115 stringWithUTF8String:kTestUUIDGenericAttribute | |
| 116 .c_str()]] | |
| 117 ]; | |
| 118 NSDictionary* advertisement_data = CreateAdvertisementData(name, uuids); | |
| 119 [central_manager_delegate centralManager:central_manager | |
| 120 didDiscoverPeripheral:peripheral | |
| 121 advertisementData:advertisement_data | |
| 122 RSSI:0]; | |
| 123 break; | |
| 124 } | |
| 125 case 2: { | |
| 126 CBPeripheral* peripheral = CreateMockPeripheral( | |
| 127 [NSString stringWithUTF8String:kTestPeripheralUUID1.c_str()]); | |
| 128 NSString* name = [NSString stringWithUTF8String:kTestDeviceName.c_str()]; | |
| 129 NSArray* uuids = @[ | |
| 130 [CBUUID UUIDWithString:[NSString | |
| 131 stringWithUTF8String:kTestUUIDImmediateAlert | |
| 132 .c_str()]], | |
| 133 [CBUUID | |
| 134 UUIDWithString:[NSString | |
| 135 stringWithUTF8String:kTestUUIDLinkLoss.c_str()]] | |
| 136 ]; | |
| 137 NSDictionary* advertisement_data = CreateAdvertisementData(name, uuids); | |
| 138 [central_manager_delegate centralManager:central_manager | |
| 139 didDiscoverPeripheral:peripheral | |
| 140 advertisementData:advertisement_data | |
| 141 RSSI:0]; | |
| 142 break; | |
| 143 } | |
| 144 case 3: { | |
| 145 CBPeripheral* peripheral = CreateMockPeripheral( | |
| 146 [NSString stringWithUTF8String:kTestPeripheralUUID1.c_str()]); | |
| 147 NSString* name = | |
| 148 [NSString stringWithUTF8String:kTestDeviceNameEmpty.c_str()]; | |
| 149 NSArray* uuids = nil; | |
| 150 NSDictionary* advertisement_data = CreateAdvertisementData(name, uuids); | |
| 151 [central_manager_delegate centralManager:central_manager | |
| 152 didDiscoverPeripheral:peripheral | |
| 153 advertisementData:advertisement_data | |
| 154 RSSI:0]; | |
| 155 break; | |
| 156 } | |
| 157 case 4: { | |
| 158 CBPeripheral* peripheral = CreateMockPeripheral( | |
| 159 [NSString stringWithUTF8String:kTestPeripheralUUID2.c_str()]); | |
| 160 NSString* name = | |
| 161 [NSString stringWithUTF8String:kTestDeviceNameEmpty.c_str()]; | |
| 162 NSArray* uuids = nil; | |
| 163 NSDictionary* advertisement_data = CreateAdvertisementData(name, uuids); | |
| 164 [central_manager_delegate centralManager:central_manager | |
| 165 didDiscoverPeripheral:peripheral | |
| 166 advertisementData:advertisement_data | |
| 167 RSSI:0]; | |
| 168 break; | |
| 169 } | |
| 170 } | |
| 171 } | |
| 172 | |
| 173 // Utility function for generating new (CBUUID, address) pairs where CBUUID | |
| 174 // hashes to address. For use when adding a new device address to the testing | |
| 175 // suite because CoreBluetooth peripherals have CBUUIDs in place of addresses, | |
| 176 // and we construct fake addresses for them by hashing the CBUUID. By changing | |
| 177 // |target| the user can generate sequentially numbered test addresses. | |
| 178 // | |
| 179 // std::string BluetoothTestMac::FindCBUUIDForHashTarget() { | |
| 180 // // The desired first 6 digits of the hash. For example 0100000, 020000, | |
| 181 // // 030000, ... | |
| 182 // const std::string target = "010000"; | |
| 183 // // 128 bit buffer to be encoded as a hex string. | |
| 184 // int64_t input[2] = {0}; | |
| 185 // // There are 2^24 ~ 10^7 possible configurations for the first 6 digits, | |
| 186 // // ie. each input has probability 10^-7 of succeeding, under the dubious | |
| 187 // // assumption that traversing inputs sequentially is as good as traversing | |
| 188 // // them randomly. After 10^8 iterations then the probability of never | |
| 189 // // succeeding is ((10^7-1)/10^7)^(10^8) ~= 10^-5. | |
| 190 // while (input[0] < LLONG_MAX) { | |
| 191 // // Encode as a hexidecimal number. Note that on x86 input[0] is stored | |
| 192 // // as a little-endian number, and so read backwards by HexEncode. | |
| 193 // std::string input_str = base::HexEncode(&input, sizeof(input)); | |
| 194 // input_str.insert(20, "-"); | |
| 195 // input_str.insert(16, "-"); | |
| 196 // input_str.insert(12, "-"); | |
| 197 // input_str.insert(8, "-"); | |
| 198 // char raw[3]; | |
| 199 // crypto::SHA256HashString(input_str, raw, sizeof(raw)); | |
| 200 // if (base::HexEncode(raw, sizeof(raw)) == target) { | |
| 201 // return input_str; | |
| 202 // } | |
| 203 // ++input[0]; | |
| 204 // } | |
| 205 // return ""; | |
| 206 // } | |
| 207 | |
| 208 } // namespace device | 49 } // namespace device |
| OLD | NEW |