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