blob: 9a2bbb8a3095304cb8fb470477cb622909e78caa [file] [log] [blame]
jlebela58fd752016-03-14 10:33:281// 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.
4
jlebelf11faf4f2016-03-23 11:05:535#include "device/bluetooth/test/mock_bluetooth_cbperipheral_mac.h"
jlebela58fd752016-03-14 10:33:286
jlebelf11faf4f2016-03-23 11:05:537#include "base/mac/foundation_util.h"
jlebela58fd752016-03-14 10:33:288#include "base/mac/scoped_nsobject.h"
jlebelc4b09782016-05-10 00:31:589#include "device/bluetooth/test/bluetooth_test_mac.h"
jlebel9bb8cf242017-01-10 01:29:0210#include "device/bluetooth/test/mock_bluetooth_cbcharacteristic_mac.h"
jlebel1cc94fe32017-04-11 20:04:5611#include "device/bluetooth/test/mock_bluetooth_cbdescriptor_mac.h"
jlebelc4b09782016-05-10 00:31:5812#include "device/bluetooth/test/mock_bluetooth_cbservice_mac.h"
jlebelf11faf4f2016-03-23 11:05:5313
14using base::mac::ObjCCast;
15using base::scoped_nsobject;
jlebela58fd752016-03-14 10:33:2816
17@interface MockCBPeripheral () {
jlebelf11faf4f2016-03-23 11:05:5318 scoped_nsobject<NSUUID> _identifier;
19 scoped_nsobject<NSString> _name;
jlebelc4b09782016-05-10 00:31:5820 id<CBPeripheralDelegate> _delegate;
21 scoped_nsobject<NSMutableArray> _services;
jlebela58fd752016-03-14 10:33:2822}
23
24@end
25
26@implementation MockCBPeripheral
27
28@synthesize state = _state;
jlebelc4b09782016-05-10 00:31:5829@synthesize delegate = _delegate;
30@synthesize bluetoothTestMac = _bluetoothTestMac;
jlebela58fd752016-03-14 10:33:2831
jlebelf11faf4f2016-03-23 11:05:5332- (instancetype)init {
33 [self doesNotRecognizeSelector:_cmd];
34 return self;
35}
36
37- (instancetype)initWithUTF8StringIdentifier:(const char*)utf8Identifier {
scheibdd9ce7002016-07-21 07:06:0638 return [self initWithUTF8StringIdentifier:utf8Identifier name:nil];
jlebelf11faf4f2016-03-23 11:05:5339}
40
scheibdd9ce7002016-07-21 07:06:0641- (instancetype)initWithUTF8StringIdentifier:(const char*)utf8Identifier
42 name:(NSString*)name {
43 scoped_nsobject<NSUUID> identifier(
44 [[NSUUID alloc] initWithUUIDString:@(utf8Identifier)]);
45 return [self initWithIdentifier:identifier name:name];
jlebelf11faf4f2016-03-23 11:05:5346}
47
48- (instancetype)initWithIdentifier:(NSUUID*)identifier name:(NSString*)name {
jlebela58fd752016-03-14 10:33:2849 self = [super init];
50 if (self) {
51 _identifier.reset([identifier retain]);
jlebelf11faf4f2016-03-23 11:05:5352 if (name) {
53 _name.reset([name retain]);
jlebelf11faf4f2016-03-23 11:05:5354 }
jlebela58fd752016-03-14 10:33:2855 _state = CBPeripheralStateDisconnected;
56 }
57 return self;
58}
59
jlebelf11faf4f2016-03-23 11:05:5360- (BOOL)isKindOfClass:(Class)aClass {
61 if (aClass == [CBPeripheral class] ||
62 [aClass isSubclassOfClass:[CBPeripheral class]]) {
63 return YES;
64 }
65 return [super isKindOfClass:aClass];
66}
67
68- (BOOL)isMemberOfClass:(Class)aClass {
69 if (aClass == [CBPeripheral class] ||
70 [aClass isSubclassOfClass:[CBPeripheral class]]) {
71 return YES;
72 }
73 return [super isKindOfClass:aClass];
74}
75
jlebela58fd752016-03-14 10:33:2876- (void)setState:(CBPeripheralState)state {
77 _state = state;
jlebel471d7dd2016-06-03 08:07:1278 if (_state == CBPeripheralStateDisconnected) {
ccameron1c9b9832016-06-03 23:54:0679 _services.reset();
jlebel471d7dd2016-06-03 08:07:1280 }
jlebela58fd752016-03-14 10:33:2881}
82
jlebelc4b09782016-05-10 00:31:5883- (void)discoverServices:(NSArray*)serviceUUIDs {
84 if (_bluetoothTestMac) {
85 _bluetoothTestMac->OnFakeBluetoothServiceDiscovery();
86 }
jlebel620327d2016-06-20 13:01:0087}
88
89- (void)discoverCharacteristics:(NSArray*)characteristics
90 forService:(CBService*)service {
jlebel0d7b7b52017-03-06 23:57:3391 if (_bluetoothTestMac) {
92 _bluetoothTestMac->OnFakeBluetoothCharacteristicDiscovery();
93 }
jlebelc4b09782016-05-10 00:31:5894}
95
jlebel9bb8cf242017-01-10 01:29:0296- (void)discoverDescriptorsForCharacteristic:(CBCharacteristic*)characteristic {
jlebel9bb8cf242017-01-10 01:29:0297}
98
jlebele223e9292016-06-27 15:22:5699- (void)readValueForCharacteristic:(CBCharacteristic*)characteristic {
100 DCHECK(_bluetoothTestMac);
101 _bluetoothTestMac->OnFakeBluetoothCharacteristicReadValue();
102}
103
jlebel4e58d3d2016-06-28 01:43:26104- (void)writeValue:(NSData*)data
105 forCharacteristic:(CBCharacteristic*)characteristic
106 type:(CBCharacteristicWriteType)type {
107 DCHECK(_bluetoothTestMac);
108 const uint8_t* buffer = static_cast<const uint8_t*>(data.bytes);
109 std::vector<uint8_t> value(buffer, buffer + data.length);
110 _bluetoothTestMac->OnFakeBluetoothCharacteristicWriteValue(value);
111}
112
jlebel1cc94fe32017-04-11 20:04:56113- (void)readValueForDescriptor:(CBDescriptor*)descriptor {
114 DCHECK(_bluetoothTestMac);
115 _bluetoothTestMac->OnFakeBluetoothDescriptorReadValue();
116}
117
118- (void)writeValue:(NSData*)data forDescriptor:(CBDescriptor*)descriptor {
119 DCHECK(_bluetoothTestMac);
120 const uint8_t* buffer = static_cast<const uint8_t*>(data.bytes);
121 std::vector<uint8_t> value(buffer, buffer + data.length);
122 _bluetoothTestMac->OnFakeBluetoothDescriptorWriteValue(value);
123}
124
jlebelc4b09782016-05-10 00:31:58125- (void)removeAllServices {
jlebel35be3092017-05-26 19:55:28126 [_services removeAllObjects];
jlebelc4b09782016-05-10 00:31:58127}
128
129- (void)addServices:(NSArray*)services {
jlebel35be3092017-05-26 19:55:28130 if (!_services) {
jlebel471d7dd2016-06-03 08:07:12131 _services.reset([[NSMutableArray alloc] init]);
132 }
jlebelc4b09782016-05-10 00:31:58133 for (CBUUID* uuid in services) {
jlebel620327d2016-06-20 13:01:00134 base::scoped_nsobject<MockCBService> service([[MockCBService alloc]
135 initWithPeripheral:self.peripheral
136 CBUUID:uuid
137 primary:YES]);
jlebel35be3092017-05-26 19:55:28138 [_services addObject:[service service]];
jlebelc4b09782016-05-10 00:31:58139 }
140}
141
jlebel471d7dd2016-06-03 08:07:12142- (void)didDiscoverServicesWithError:(NSError*)error {
jlebelc4b09782016-05-10 00:31:58143 [_delegate peripheral:self.peripheral didDiscoverServices:error];
144}
145
146- (void)removeService:(CBService*)service {
147 base::scoped_nsobject<CBService> serviceToRemove(service,
148 base::scoped_policy::RETAIN);
jlebel20060d02016-05-28 11:23:19149 DCHECK(serviceToRemove);
jlebel35be3092017-05-26 19:55:28150 [_services removeObject:serviceToRemove];
jlebel620327d2016-06-20 13:01:00151 [self didModifyServices:@[ serviceToRemove ]];
152}
153
jlebel0d7b7b52017-03-06 23:57:33154- (void)mockDidDiscoverServices {
jlebel062d7b42017-01-07 13:32:20155 [_delegate peripheral:self.peripheral didDiscoverServices:nil];
jlebel0d7b7b52017-03-06 23:57:33156}
157
jlebel74fe98e2017-05-04 20:45:17158- (void)mockDidDiscoverCharacteristicsForService:(CBService*)service {
159 [_delegate peripheral:self.peripheral
160 didDiscoverCharacteristicsForService:service
161 error:nil];
162}
163
164- (void)mockDidDiscoverDescriptorsForCharacteristic:
165 (CBCharacteristic*)characteristic {
166 [_delegate peripheral:self.peripheral
167 didDiscoverDescriptorsForCharacteristic:characteristic
168 error:nil];
169}
170
jlebel0d7b7b52017-03-06 23:57:33171- (void)mockDidDiscoverEvents {
172 [self mockDidDiscoverServices];
jlebel062d7b42017-01-07 13:32:20173 // BluetoothLowEnergyDeviceMac is expected to call
174 // -[CBPeripheral discoverCharacteristics:forService:] for each services,
175 // so -[<CBPeripheralDelegate peripheral:didDiscoverCharacteristicsForService:
176 // error:] needs to be called for all services.
177 for (CBService* service in _services.get()) {
jlebel74fe98e2017-05-04 20:45:17178 [self mockDidDiscoverCharacteristicsForService:service];
jlebel9bb8cf242017-01-10 01:29:02179 for (CBCharacteristic* characteristic in service.characteristics) {
180 // After discovering services, BluetoothLowEnergyDeviceMac is expected to
181 // discover characteristics for all services.
182 [_delegate peripheral:self.peripheral
183 didDiscoverDescriptorsForCharacteristic:characteristic
184 error:nil];
185 }
jlebel062d7b42017-01-07 13:32:20186 }
187}
188
jlebel9bb8cf242017-01-10 01:29:02189- (void)didModifyServices:(NSArray*)invalidatedServices {
190 DCHECK(
191 [_delegate respondsToSelector:@selector(peripheral:didModifyServices:)]);
192 [_delegate peripheral:self.peripheral didModifyServices:invalidatedServices];
193}
194
195- (void)didDiscoverDescriptorsWithCharacteristic:
196 (MockCBCharacteristic*)characteristic_mock {
197 [_delegate peripheral:self.peripheral
198 didDiscoverDescriptorsForCharacteristic:characteristic_mock.characteristic
199 error:nil];
200}
201
jlebela58fd752016-03-14 10:33:28202- (NSUUID*)identifier {
jlebel35be3092017-05-26 19:55:28203 return _identifier;
jlebela58fd752016-03-14 10:33:28204}
205
206- (NSString*)name {
jlebel35be3092017-05-26 19:55:28207 return _name;
jlebela58fd752016-03-14 10:33:28208}
209
jlebelc4b09782016-05-10 00:31:58210- (NSArray*)services {
jlebel35be3092017-05-26 19:55:28211 return _services;
jlebelc4b09782016-05-10 00:31:58212}
213
jlebelf11faf4f2016-03-23 11:05:53214- (CBPeripheral*)peripheral {
215 return ObjCCast<CBPeripheral>(self);
216}
217
jlebel9db20212016-06-29 15:03:48218- (void)setNotifyValue:(BOOL)notification
219 forCharacteristic:(CBCharacteristic*)characteristic {
jlebel7c346d72017-02-14 08:54:42220 _bluetoothTestMac->OnFakeBluetoothGattSetCharacteristicNotification(
221 notification == YES);
jlebel9db20212016-06-29 15:03:48222}
223
jlebela58fd752016-03-14 10:33:28224@end