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
3 // found in the LICENSE file.
5 #include "device/bluetooth/test/bluetooth_test_mac.h"
7 #include "base/strings/string_number_conversions.h"
8 #include "device/bluetooth/bluetooth_adapter_mac.h"
9 #include "device/bluetooth/test/mock_bluetooth_central_manager_mac.h"
10 #include "third_party/ocmock/OCMock/OCMock.h"
13 #import <CoreBluetooth/CoreBluetooth.h>
14 #else // !defined(OS_IOS)
15 #import <IOBluetooth/IOBluetooth.h>
16 #endif // defined(OS_IOS)
22 CBPeripheral* CreateMockPeripheral(NSString* peripheral_identifier) {
23 Class peripheral_class = NSClassFromString(@"CBPeripheral");
24 id mock_peripheral = [OCMockObject mockForClass:[peripheral_class class]];
25 [[[mock_peripheral stub] andReturnValue:@(CBPeripheralStateDisconnected)]
26 performSelector:@selector(state)];
27 Class uuid_class = NSClassFromString(@"NSUUID");
28 [[[mock_peripheral stub]
29 andReturn:[[uuid_class performSelector:@selector(UUID)]
30 performSelector:@selector(initWithUUIDString:)
31 withObject:peripheral_identifier]]
32 performSelector:@selector(identifier)];
33 [[[mock_peripheral stub]
34 andReturn:[NSString stringWithUTF8String:BluetoothTest::kTestDeviceName
36 return mock_peripheral;
39 NSDictionary* CreateAdvertisementData(NSString* name, NSArray* uuids) {
40 NSMutableDictionary* advertisement_data =
41 [NSMutableDictionary dictionaryWithDictionary:@{
42 @"CBAdvertisementDataLocalNameKey" : name,
43 @"CBAdvertisementDataServiceDataKey" : [NSDictionary dictionary],
44 @"CBAdvertisementDataIsConnectable" : @(YES),
47 [advertisement_data setObject:uuids
48 forKey:@"CBAdvertisementDataServiceUUIDsKey"];
49 return advertisement_data;
54 // UUID1 hashes to kTestDeviceAddress1, and UUID2 to kTestDeviceAddress2.
55 const std::string BluetoothTestMac::kTestPeripheralUUID1 =
56 "34045B00-0000-0000-0000-000000000000";
57 const std::string BluetoothTestMac::kTestPeripheralUUID2 =
58 "EC1B8F00-0000-0000-0000-000000000000";
60 BluetoothTestMac::BluetoothTestMac() {}
62 BluetoothTestMac::~BluetoothTestMac() {}
64 void BluetoothTestMac::SetUp() {}
66 bool BluetoothTestMac::PlatformSupportsLowEnergy() {
67 return BluetoothAdapterMac::IsLowEnergyAvailable();
70 void BluetoothTestMac::InitWithDefaultAdapter() {
71 adapter_mac_ = BluetoothAdapterMac::CreateAdapter().get();
72 adapter_ = adapter_mac_;
75 void BluetoothTestMac::InitWithoutDefaultAdapter() {
76 adapter_mac_ = BluetoothAdapterMac::CreateAdapterForTest(
77 "", "", message_loop_.task_runner())
79 adapter_ = adapter_mac_;
81 if (BluetoothAdapterMac::IsLowEnergyAvailable()) {
82 id low_energy_central_manager = [[MockCentralManager alloc] init];
83 [low_energy_central_manager setState:CBCentralManagerStateUnsupported];
84 adapter_mac_->SetCentralManagerForTesting(low_energy_central_manager);
88 void BluetoothTestMac::InitWithFakeAdapter() {
90 BluetoothAdapterMac::CreateAdapterForTest(
91 kTestAdapterName, kTestAdapterAddress, message_loop_.task_runner())
93 adapter_ = adapter_mac_;
95 if (BluetoothAdapterMac::IsLowEnergyAvailable()) {
96 id low_energy_central_manager = [[MockCentralManager alloc] init];
97 [low_energy_central_manager setState:CBCentralManagerStatePoweredOn];
98 adapter_mac_->SetCentralManagerForTesting(low_energy_central_manager);
102 void BluetoothTestMac::DiscoverLowEnergyDevice(int device_ordinal) {
103 CBCentralManager* central_manager = adapter_mac_->low_energy_central_manager_;
104 BluetoothLowEnergyCentralManagerDelegate* central_manager_delegate =
105 adapter_mac_->low_energy_central_manager_delegate_;
106 Class cbuuid_class = NSClassFromString(@"CBUUID");
107 switch (device_ordinal) {
109 CBPeripheral* peripheral = CreateMockPeripheral(
110 [NSString stringWithUTF8String:kTestPeripheralUUID1.c_str()]);
111 NSString* name = [NSString stringWithUTF8String:kTestDeviceName.c_str()];
114 UUIDWithString:[NSString stringWithUTF8String:kTestUUIDGenericAccess
117 UUIDWithString:[NSString
118 stringWithUTF8String:kTestUUIDGenericAttribute
121 NSDictionary* advertisement_data = CreateAdvertisementData(name, uuids);
122 [central_manager_delegate centralManager:central_manager
123 didDiscoverPeripheral:peripheral
124 advertisementData:advertisement_data
129 CBPeripheral* peripheral = CreateMockPeripheral(
130 [NSString stringWithUTF8String:kTestPeripheralUUID1.c_str()]);
131 NSString* name = [NSString stringWithUTF8String:kTestDeviceName.c_str()];
134 UUIDWithString:[NSString
135 stringWithUTF8String:kTestUUIDImmediateAlert
138 UUIDWithString:[NSString
139 stringWithUTF8String:kTestUUIDLinkLoss.c_str()]]
141 NSDictionary* advertisement_data = CreateAdvertisementData(name, uuids);
142 [central_manager_delegate centralManager:central_manager
143 didDiscoverPeripheral:peripheral
144 advertisementData:advertisement_data
149 CBPeripheral* peripheral = CreateMockPeripheral(
150 [NSString stringWithUTF8String:kTestPeripheralUUID1.c_str()]);
152 [NSString stringWithUTF8String:kTestDeviceNameEmpty.c_str()];
153 NSArray* uuids = nil;
154 NSDictionary* advertisement_data = CreateAdvertisementData(name, uuids);
155 [central_manager_delegate centralManager:central_manager
156 didDiscoverPeripheral:peripheral
157 advertisementData:advertisement_data
162 CBPeripheral* peripheral = CreateMockPeripheral(
163 [NSString stringWithUTF8String:kTestPeripheralUUID2.c_str()]);
165 [NSString stringWithUTF8String:kTestDeviceNameEmpty.c_str()];
166 NSArray* uuids = nil;
167 NSDictionary* advertisement_data = CreateAdvertisementData(name, uuids);
168 [central_manager_delegate centralManager:central_manager
169 didDiscoverPeripheral:peripheral
170 advertisementData:advertisement_data
177 // Utility function for generating new (CBUUID, address) pairs where CBUUID
178 // hashes to address. For use when adding a new device address to the testing
179 // suite because CoreBluetooth peripherals have CBUUIDs in place of addresses,
180 // and we construct fake addresses for them by hashing the CBUUID. By changing
181 // |target| the user can generate sequentially numbered test addresses.
183 // std::string BluetoothTestMac::FindCBUUIDForHashTarget() {
184 // // The desired first 6 digits of the hash. For example 0100000, 020000,
186 // const std::string target = "010000";
187 // // 128 bit buffer to be encoded as a hex string.
188 // int64_t input[2] = {0};
189 // // There are 2^24 ~ 10^7 possible configurations for the first 6 digits,
190 // // ie. each input has probability 10^-7 of succeeding, under the dubious
191 // // assumption that traversing inputs sequentially is as good as traversing
192 // // them randomly. After 10^8 iterations then the probability of never
193 // // succeeding is ((10^7-1)/10^7)^(10^8) ~= 10^-5.
194 // while (input[0] < LLONG_MAX) {
195 // // Encode as a hexidecimal number. Note that on x86 input[0] is stored
196 // // as a little-endian number, and so read backwards by HexEncode.
197 // std::string input_str = base::HexEncode(&input, sizeof(input));
198 // input_str.insert(20, "-");
199 // input_str.insert(16, "-");
200 // input_str.insert(12, "-");
201 // input_str.insert(8, "-");
203 // crypto::SHA256HashString(input_str, raw, sizeof(raw));
204 // if (base::HexEncode(raw, sizeof(raw)) == target) {
212 } // namespace device