Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(495)

Side by Side Diff: device/bluetooth/bluetooth_low_energy_win_fake.cc

Issue 1690133002: Implement BluetoothRemoteGattServiceWin and related unit tests (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "device/bluetooth/bluetooth_low_energy_win_fake.h" 5 #include "device/bluetooth/bluetooth_low_energy_win_fake.h"
6 6
7 #include "base/strings/stringprintf.h" 7 #include "base/strings/stringprintf.h"
8 #include "device/bluetooth/bluetooth_low_energy_defs_win.h"
8 9
9 namespace { 10 namespace {
10 const char kPlatformNotSupported[] = 11 const char kPlatformNotSupported[] =
11 "Bluetooth Low energy is only supported on Windows 8 and later."; 12 "Bluetooth Low energy is only supported on Windows 8 and later.";
12 } // namespace 13 } // namespace
13 14
14 namespace device { 15 namespace device {
15 namespace win { 16 namespace win {
16 17
17 BLEDevice::BLEDevice() {} 18 BLEDevice::BLEDevice() {}
18 BLEDevice::~BLEDevice() {} 19 BLEDevice::~BLEDevice() {}
19 20
20 BLEGattService::BLEGattService() {} 21 BLEGattService::BLEGattService() {}
21 BLEGattService::~BLEGattService() {} 22 BLEGattService::~BLEGattService() {}
22 23
23 BLEGattCharacteristic::BLEGattCharacteristic() {} 24 BLEGattCharacteristic::BLEGattCharacteristic() {}
24 BLEGattCharacteristic::~BLEGattCharacteristic() {} 25 BLEGattCharacteristic::~BLEGattCharacteristic() {}
25 26
26 BLEGattDescriptor::BLEGattDescriptor() {} 27 BLEGattDescriptor::BLEGattDescriptor() {}
27 BLEGattDescriptor::~BLEGattDescriptor() {} 28 BLEGattDescriptor::~BLEGattDescriptor() {}
28 29
29 BluetoothLowEnergyWrapperFake::BluetoothLowEnergyWrapperFake() {} 30 BluetoothLowEnergyWrapperFake::BluetoothLowEnergyWrapperFake() {}
30 BluetoothLowEnergyWrapperFake::~BluetoothLowEnergyWrapperFake() {} 31 BluetoothLowEnergyWrapperFake::~BluetoothLowEnergyWrapperFake() {}
31 32
33 bool BluetoothLowEnergyWrapperFake::IsBluetoothLowEnergySupported() {
34 return true;
35 }
36
32 bool BluetoothLowEnergyWrapperFake::EnumerateKnownBluetoothLowEnergyDevices( 37 bool BluetoothLowEnergyWrapperFake::EnumerateKnownBluetoothLowEnergyDevices(
33 ScopedVector<BluetoothLowEnergyDeviceInfo>* devices, 38 ScopedVector<BluetoothLowEnergyDeviceInfo>* devices,
34 std::string* error) { 39 std::string* error) {
35 if (!IsBluetoothLowEnergySupported()) { 40 if (!IsBluetoothLowEnergySupported()) {
36 *error = kPlatformNotSupported; 41 *error = kPlatformNotSupported;
37 return false; 42 return false;
38 } 43 }
39 44
40 for (auto& device : simulated_devices_) { 45 for (auto& device : simulated_devices_) {
41 BluetoothLowEnergyDeviceInfo* device_info = 46 BluetoothLowEnergyDeviceInfo* device_info =
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 const base::FilePath& device_path, 79 const base::FilePath& device_path,
75 ScopedVector<BluetoothLowEnergyServiceInfo>* services, 80 ScopedVector<BluetoothLowEnergyServiceInfo>* services,
76 std::string* error) { 81 std::string* error) {
77 if (!IsBluetoothLowEnergySupported()) { 82 if (!IsBluetoothLowEnergySupported()) {
78 *error = kPlatformNotSupported; 83 *error = kPlatformNotSupported;
79 return false; 84 return false;
80 } 85 }
81 86
82 base::string16 device_address = 87 base::string16 device_address =
83 ExtractDeviceAddressFromDevicePath(device_path.value()); 88 ExtractDeviceAddressFromDevicePath(device_path.value());
84 base::string16 service_attribute_handle = 89 std::vector<std::string> service_attribute_handles =
85 ExtractServiceAttributeHandleFromDevicePath(device_path.value()); 90 ExtractServiceAttributeHandlesFromDevicePath(device_path.value());
86 91
87 BLEDevicesMap::iterator it_d = simulated_devices_.find( 92 BLEDevicesMap::iterator it_d = simulated_devices_.find(
88 std::string(device_address.begin(), device_address.end())); 93 std::string(device_address.begin(), device_address.end()));
89 CHECK(it_d != simulated_devices_.end()); 94 CHECK(it_d != simulated_devices_.end());
90 95
91 // |service_attribute_handle| is empty means |device_path| is a BLE device 96 // |service_attribute_handles| is empty means |device_path| is a BLE device
92 // path, otherwise it is a BLE GATT service device path. 97 // path, otherwise it is a BLE GATT service device path.
93 if (service_attribute_handle.empty()) { 98 if (service_attribute_handles.empty()) {
94 // Return all primary services for BLE device. 99 // Return all primary services for BLE device.
95 for (auto& primary_service : it_d->second->primary_services) { 100 for (auto& primary_service : it_d->second->primary_services) {
96 BluetoothLowEnergyServiceInfo* service_info = 101 BluetoothLowEnergyServiceInfo* service_info =
97 new BluetoothLowEnergyServiceInfo(); 102 new BluetoothLowEnergyServiceInfo();
98 service_info->uuid = primary_service.second->service_info->ServiceUuid; 103 service_info->uuid = primary_service.second->service_info->ServiceUuid;
99 service_info->attribute_handle = 104 service_info->attribute_handle =
100 primary_service.second->service_info->AttributeHandle; 105 primary_service.second->service_info->AttributeHandle;
101 services->push_back(service_info); 106 services->push_back(service_info);
102 } 107 }
103 } else { 108 } else {
104 // Return corresponding GATT service for BLE GATT service device. 109 // Return corresponding GATT service for BLE GATT service device.
105 BLEGattServicesMap::iterator it_s = 110 BLEGattService* target_service =
106 it_d->second->primary_services.find(std::string( 111 GetSimulatedGattService(it_d->second.get(), service_attribute_handles);
107 service_attribute_handle.begin(), service_attribute_handle.end()));
108 CHECK(it_s != it_d->second->primary_services.end());
109 BluetoothLowEnergyServiceInfo* service_info = 112 BluetoothLowEnergyServiceInfo* service_info =
110 new BluetoothLowEnergyServiceInfo(); 113 new BluetoothLowEnergyServiceInfo();
111 service_info->uuid = it_s->second->service_info->ServiceUuid; 114 service_info->uuid = target_service->service_info->ServiceUuid;
112 service_info->attribute_handle = 115 service_info->attribute_handle =
113 it_s->second->service_info->AttributeHandle; 116 target_service->service_info->AttributeHandle;
114 services->push_back(service_info); 117 services->push_back(service_info);
115 } 118 }
116 119
117 return true; 120 return true;
118 } 121 }
119 122
123 HRESULT BluetoothLowEnergyWrapperFake::ReadIncludedServicesOfAService(
124 base::FilePath& service_path,
125 const PBTH_LE_GATT_SERVICE service,
126 scoped_ptr<BTH_LE_GATT_SERVICE>* out_included_services,
127 USHORT* out_counts) {
128 base::string16 device_address =
129 ExtractDeviceAddressFromDevicePath(service_path.value());
130 std::vector<std::string> service_att_handles =
131 ExtractServiceAttributeHandlesFromDevicePath(service_path.value());
132 BLEGattService* target_service = GetSimulatedGattService(
133 GetSimulatedBLEDevice(
134 std::string(device_address.begin(), device_address.end())),
135 service_att_handles);
136 if (target_service == nullptr)
137 return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
138
139 std::size_t number_of_included_services =
140 target_service->included_services.size();
141 if (number_of_included_services) {
142 *out_counts = (USHORT)number_of_included_services;
143 out_included_services->reset(
144 new BTH_LE_GATT_SERVICE[number_of_included_services]);
145 std::size_t i = 0;
146 for (const auto& service : target_service->included_services) {
147 out_included_services->get()[i].ServiceUuid =
148 service.second->service_info->ServiceUuid;
149 out_included_services->get()[i].AttributeHandle =
150 service.second->service_info->AttributeHandle;
151 i++;
152 }
153 return S_OK;
154 }
155 return HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS);
156 }
157
158 HRESULT BluetoothLowEnergyWrapperFake::ReadCharacteristicsOfAService(
159 base::FilePath& service_path,
160 const PBTH_LE_GATT_SERVICE service,
161 scoped_ptr<BTH_LE_GATT_CHARACTERISTIC>* out_included_characteristics,
162 USHORT* out_counts) {
163 base::string16 device_address =
164 ExtractDeviceAddressFromDevicePath(service_path.value());
165 const std::vector<std::string> service_att_handles =
166 ExtractServiceAttributeHandlesFromDevicePath(service_path.value());
167 BLEGattService* target_service = GetSimulatedGattService(
168 GetSimulatedBLEDevice(
169 std::string(device_address.begin(), device_address.end())),
170 service_att_handles);
171 if (target_service == nullptr)
172 return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
173
174 std::size_t number_of_included_characteristic =
175 target_service->included_characteristics.size();
176 if (number_of_included_characteristic) {
177 *out_counts = (USHORT)number_of_included_characteristic;
178 out_included_characteristics->reset(
179 new BTH_LE_GATT_CHARACTERISTIC[number_of_included_characteristic]);
180 std::size_t i = 0;
181 for (const auto& cha : target_service->included_characteristics) {
182 out_included_characteristics->get()[i] =
183 *(cha.second->characteristic_info);
184 i++;
185 }
186 return S_OK;
187 }
188 return HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS);
189 }
190
120 BLEDevice* BluetoothLowEnergyWrapperFake::SimulateBLEDevice( 191 BLEDevice* BluetoothLowEnergyWrapperFake::SimulateBLEDevice(
121 std::string device_name, 192 std::string device_name,
122 BLUETOOTH_ADDRESS device_address) { 193 BLUETOOTH_ADDRESS device_address) {
123 BLEDevice* device = new BLEDevice(); 194 BLEDevice* device = new BLEDevice();
124 BluetoothLowEnergyDeviceInfo* device_info = 195 BluetoothLowEnergyDeviceInfo* device_info =
125 new BluetoothLowEnergyDeviceInfo(); 196 new BluetoothLowEnergyDeviceInfo();
126 std::string string_device_address = 197 std::string string_device_address =
127 BluetoothAddressToCanonicalString(device_address); 198 BluetoothAddressToCanonicalString(device_address);
128 device_info->path = 199 device_info->path =
129 base::FilePath(GenerateBLEDevicePath(string_device_address)); 200 base::FilePath(GenerateBLEDevicePath(string_device_address));
130 device_info->friendly_name = device_name; 201 device_info->friendly_name = device_name;
131 device_info->address = device_address; 202 device_info->address = device_address;
132 device->device_info.reset(device_info); 203 device->device_info.reset(device_info);
133 simulated_devices_[string_device_address] = make_scoped_ptr(device); 204 simulated_devices_[string_device_address] = make_scoped_ptr(device);
134 return device; 205 return device;
135 } 206 }
136 207
208 BLEDevice* BluetoothLowEnergyWrapperFake::GetSimulatedBLEDevice(
209 std::string device_address) {
210 BLEDevicesMap::iterator it_d = simulated_devices_.find(device_address);
211 if (it_d == simulated_devices_.end())
212 return nullptr;
213 return it_d->second.get();
214 }
215
137 BLEGattService* BluetoothLowEnergyWrapperFake::SimulateBLEGattService( 216 BLEGattService* BluetoothLowEnergyWrapperFake::SimulateBLEGattService(
138 BLEDevice* device, 217 BLEDevice* device,
139 std::string uuid) { 218 BLEGattService* parent_service,
219 const BTH_LE_UUID& uuid) {
140 CHECK(device); 220 CHECK(device);
141 221
142 BLEGattService* service = new BLEGattService(); 222 BLEGattService* service = new BLEGattService();
143 PBTH_LE_GATT_SERVICE service_info = new BTH_LE_GATT_SERVICE[1]; 223 PBTH_LE_GATT_SERVICE service_info = new BTH_LE_GATT_SERVICE[1];
144 std::string string_device_address = 224 std::string string_device_address =
145 BluetoothAddressToCanonicalString(device->device_info->address); 225 BluetoothAddressToCanonicalString(device->device_info->address);
146 service_info->AttributeHandle = 226 service_info->AttributeHandle =
147 GenerateAUniqueAttributeHandle(string_device_address); 227 GenerateAUniqueAttributeHandle(string_device_address);
148 service_info->ServiceUuid = CanonicalStringToBTH_LE_UUID(uuid); 228 service_info->ServiceUuid = uuid;
149 service->service_info.reset(service_info); 229 service->service_info.reset(service_info);
150 device->primary_services[std::to_string(service_info->AttributeHandle)] = 230
151 make_scoped_ptr(service); 231 if (parent_service) {
232 parent_service
233 ->included_services[std::to_string(service_info->AttributeHandle)] =
234 make_scoped_ptr(service);
235 } else {
236 device->primary_services[std::to_string(service_info->AttributeHandle)] =
237 make_scoped_ptr(service);
238 }
152 return service; 239 return service;
153 } 240 }
154 241
155 BLEDevice* BluetoothLowEnergyWrapperFake::GetSimulatedBLEDevice( 242 void BluetoothLowEnergyWrapperFake::SimulateBLEGattServiceRemoved(
156 std::string device_address) { 243 BLEDevice* device,
157 BLEDevicesMap::iterator it_d = simulated_devices_.find(device_address); 244 BLEGattService* parent_service,
158 if (it_d == simulated_devices_.end()) 245 std::string attribute_handle) {
246 if (parent_service) {
247 parent_service->included_services.erase(attribute_handle);
248 } else {
249 device->primary_services.erase(attribute_handle);
250 }
251 }
252
253 BLEGattService* BluetoothLowEnergyWrapperFake::GetSimulatedGattService(
254 BLEDevice* device,
255 const std::vector<std::string>& chain_of_att_handle) {
256 // First, find the root primary service.
257 BLEGattServicesMap::iterator it_s =
258 device->primary_services.find(chain_of_att_handle[0]);
259 if (it_s == device->primary_services.end())
159 return nullptr; 260 return nullptr;
160 return it_d->second.get(); 261
262 // Iteratively follow the chain of included service attribute handles to find
263 // the target service.
264 for (std::size_t i = 1; i < chain_of_att_handle.size(); i++) {
265 std::string included_att_handle = std::string(
266 chain_of_att_handle[i].begin(), chain_of_att_handle[i].end());
267 BLEGattServicesMap::iterator it_i =
268 it_s->second->included_services.find(included_att_handle);
269 if (it_i == it_s->second->included_services.end())
270 return nullptr;
271 it_s = it_i;
272 }
273 return it_s->second.get();
274 }
275
276 BLEGattCharacteristic*
277 BluetoothLowEnergyWrapperFake::SimulateBLEGattCharacterisc(
278 std::string device_address,
279 BLEGattService* parent_service,
280 const BTH_LE_GATT_CHARACTERISTIC& characteristic) {
281 CHECK(parent_service);
282
283 BLEGattCharacteristic* cha = new BLEGattCharacteristic();
284 PBTH_LE_GATT_CHARACTERISTIC win_cha_info = new BTH_LE_GATT_CHARACTERISTIC[1];
285 *win_cha_info = characteristic;
286 (cha->characteristic_info).reset(win_cha_info);
287 cha->characteristic_info->AttributeHandle =
288 GenerateAUniqueAttributeHandle(device_address);
289 parent_service->included_characteristics[std::to_string(
290 cha->characteristic_info->AttributeHandle)] = make_scoped_ptr(cha);
291 return cha;
292 }
293
294 void BluetoothLowEnergyWrapperFake::SimulateBLEGattCharacteriscRemove(
295 BLEGattService* parent_service,
296 std::string attribute_handle) {
297 CHECK(parent_service);
298 parent_service->included_characteristics.erase(attribute_handle);
161 } 299 }
162 300
163 USHORT BluetoothLowEnergyWrapperFake::GenerateAUniqueAttributeHandle( 301 USHORT BluetoothLowEnergyWrapperFake::GenerateAUniqueAttributeHandle(
164 std::string device_address) { 302 std::string device_address) {
165 scoped_ptr<std::set<USHORT>>& set_of_ushort = 303 scoped_ptr<std::set<USHORT>>& set_of_ushort =
166 attribute_handle_table_[device_address]; 304 attribute_handle_table_[device_address];
167 if (set_of_ushort) { 305 if (set_of_ushort) {
168 USHORT max_attribute_handle = *set_of_ushort->rbegin(); 306 USHORT max_attribute_handle = *set_of_ushort->rbegin();
169 if (max_attribute_handle < 0xFFFF) { 307 if (max_attribute_handle < 0xFFFF) {
170 USHORT new_attribute_handle = max_attribute_handle + 1; 308 USHORT new_attribute_handle = max_attribute_handle + 1;
(...skipping 28 matching lines...) Expand all
199 base::string16 resident_device_path, 337 base::string16 resident_device_path,
200 USHORT service_attribute_handle) { 338 USHORT service_attribute_handle) {
201 std::string sub_path = std::to_string(service_attribute_handle); 339 std::string sub_path = std::to_string(service_attribute_handle);
202 return resident_device_path + L"/" + 340 return resident_device_path + L"/" +
203 base::string16(sub_path.begin(), sub_path.end()); 341 base::string16(sub_path.begin(), sub_path.end());
204 } 342 }
205 343
206 base::string16 344 base::string16
207 BluetoothLowEnergyWrapperFake::ExtractDeviceAddressFromDevicePath( 345 BluetoothLowEnergyWrapperFake::ExtractDeviceAddressFromDevicePath(
208 base::string16 path) { 346 base::string16 path) {
209 std::size_t found = path.find('/'); 347 std::size_t found = path.find_first_of('/');
210 if (found != base::string16::npos) { 348 if (found != base::string16::npos) {
211 return path.substr(0, found); 349 return path.substr(0, found);
212 } 350 }
213 return path; 351 return path;
214 } 352 }
215 353
216 base::string16 354 std::vector<std::string>
217 BluetoothLowEnergyWrapperFake::ExtractServiceAttributeHandleFromDevicePath( 355 BluetoothLowEnergyWrapperFake::ExtractServiceAttributeHandlesFromDevicePath(
218 base::string16 path) { 356 base::string16 path) {
219 std::size_t found = path.find('/'); 357 std::size_t found = path.find('/');
220 if (found == base::string16::npos) 358 if (found == base::string16::npos)
221 return base::string16(); 359 return std::vector<std::string>();
222 return path.substr(found + 1);
223 }
224 360
225 BTH_LE_UUID BluetoothLowEnergyWrapperFake::CanonicalStringToBTH_LE_UUID( 361 std::vector<std::string> chain_of_att_handle;
226 std::string uuid) { 362 while (true) {
227 BTH_LE_UUID win_uuid; 363 std::size_t next_found = path.find(path, found + 1);
228 // Only short UUIDs (4 hex digits) have beened used in BluetoothTest right 364 if (next_found == base::string16::npos)
229 // now. Need fix after using long UUIDs. 365 break;
230 win_uuid.IsShortUuid = true; 366 base::string16 w_att_handle = path.substr(found + 1, next_found);
231 unsigned int data[1]; 367 chain_of_att_handle.push_back(
232 int result = sscanf_s(uuid.c_str(), "%04x", &data[0]); 368 std::string(w_att_handle.begin(), w_att_handle.end()));
233 CHECK(result == 1); 369 found = next_found;
234 win_uuid.Value.ShortUuid = data[0]; 370 }
235 return win_uuid; 371 base::string16 w_att_handle = path.substr(found + 1);
372 chain_of_att_handle.push_back(
373 std::string(w_att_handle.begin(), w_att_handle.end()));
374 return chain_of_att_handle;
236 } 375 }
237 376
238 std::string BluetoothLowEnergyWrapperFake::BluetoothAddressToCanonicalString( 377 std::string BluetoothLowEnergyWrapperFake::BluetoothAddressToCanonicalString(
239 const BLUETOOTH_ADDRESS& btha) { 378 const BLUETOOTH_ADDRESS& btha) {
240 std::string result = base::StringPrintf( 379 std::string result = base::StringPrintf(
241 "%02X:%02X:%02X:%02X:%02X:%02X", btha.rgBytes[5], btha.rgBytes[4], 380 "%02X:%02X:%02X:%02X:%02X:%02X", btha.rgBytes[5], btha.rgBytes[4],
242 btha.rgBytes[3], btha.rgBytes[2], btha.rgBytes[1], btha.rgBytes[0]); 381 btha.rgBytes[3], btha.rgBytes[2], btha.rgBytes[1], btha.rgBytes[0]);
243 return result; 382 return result;
244 } 383 }
245 384
246 } // namespace win 385 } // namespace win
247 } // namespace device 386 } // namespace device
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698