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 |