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

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() {}
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 const base::FilePath& device_path, 75 const base::FilePath& device_path,
75 ScopedVector<BluetoothLowEnergyServiceInfo>* services, 76 ScopedVector<BluetoothLowEnergyServiceInfo>* services,
76 std::string* error) { 77 std::string* error) {
77 if (!IsBluetoothLowEnergySupported()) { 78 if (!IsBluetoothLowEnergySupported()) {
78 *error = kPlatformNotSupported; 79 *error = kPlatformNotSupported;
79 return false; 80 return false;
80 } 81 }
81 82
82 base::string16 device_address = 83 base::string16 device_address =
83 ExtractDeviceAddressFromDevicePath(device_path.value()); 84 ExtractDeviceAddressFromDevicePath(device_path.value());
84 base::string16 service_attribute_handle = 85 std::vector<std::string> service_attribute_handles =
85 ExtractServiceAttributeHandleFromDevicePath(device_path.value()); 86 ExtractServiceAttributeHandlesFromDevicePath(device_path.value());
86 87
87 BLEDevicesMap::iterator it_d = simulated_devices_.find( 88 BLEDevicesMap::iterator it_d = simulated_devices_.find(
88 std::string(device_address.begin(), device_address.end())); 89 std::string(device_address.begin(), device_address.end()));
89 CHECK(it_d != simulated_devices_.end()); 90 CHECK(it_d != simulated_devices_.end());
90 91
91 // |service_attribute_handle| is empty means |device_path| is a BLE device 92 // |service_attribute_handles| is empty means |device_path| is a BLE device
92 // path, otherwise it is a BLE GATT service device path. 93 // path, otherwise it is a BLE GATT service device path.
93 if (service_attribute_handle.empty()) { 94 if (service_attribute_handles.empty()) {
94 // Return all primary services for BLE device. 95 // Return all primary services for BLE device.
95 for (auto& primary_service : it_d->second->primary_services) { 96 for (auto& primary_service : it_d->second->primary_services) {
96 BluetoothLowEnergyServiceInfo* service_info = 97 BluetoothLowEnergyServiceInfo* service_info =
97 new BluetoothLowEnergyServiceInfo(); 98 new BluetoothLowEnergyServiceInfo();
98 service_info->uuid = primary_service.second->service_info->ServiceUuid; 99 service_info->uuid = primary_service.second->service_info->ServiceUuid;
99 service_info->attribute_handle = 100 service_info->attribute_handle =
100 primary_service.second->service_info->AttributeHandle; 101 primary_service.second->service_info->AttributeHandle;
101 services->push_back(service_info); 102 services->push_back(service_info);
102 } 103 }
103 } else { 104 } else {
104 // Return corresponding GATT service for BLE GATT service device. 105 // Return corresponding GATT service for BLE GATT service device.
105 BLEGattServicesMap::iterator it_s = 106 BLEGattService* target_service =
106 it_d->second->primary_services.find(std::string( 107 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 = 108 BluetoothLowEnergyServiceInfo* service_info =
110 new BluetoothLowEnergyServiceInfo(); 109 new BluetoothLowEnergyServiceInfo();
111 service_info->uuid = it_s->second->service_info->ServiceUuid; 110 service_info->uuid = target_service->service_info->ServiceUuid;
112 service_info->attribute_handle = 111 service_info->attribute_handle =
113 it_s->second->service_info->AttributeHandle; 112 target_service->service_info->AttributeHandle;
114 services->push_back(service_info); 113 services->push_back(service_info);
115 } 114 }
116 115
117 return true; 116 return true;
118 } 117 }
119 118
119 HRESULT BluetoothLowEnergyWrapperFake::ReadIncludedServicesOfAService(
120 base::FilePath& service_path,
121 const PBTH_LE_GATT_SERVICE service,
122 scoped_ptr<BTH_LE_GATT_SERVICE>* out_included_services,
123 USHORT* out_counts) {
124 base::string16 device_address =
125 ExtractDeviceAddressFromDevicePath(service_path.value());
126 std::vector<std::string> service_att_handles =
127 ExtractServiceAttributeHandlesFromDevicePath(service_path.value());
128 BLEGattService* target_service = GetSimulatedGattService(
129 GetSimulatedBLEDevice(
130 std::string(device_address.begin(), device_address.end())),
131 service_att_handles);
132 if (target_service == nullptr)
133 return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
134
135 std::size_t number_of_included_services =
136 target_service->included_services.size();
137 if (number_of_included_services) {
138 *out_counts = (USHORT)number_of_included_services;
139 (*out_included_services)
140 .reset(new BTH_LE_GATT_SERVICE[number_of_included_services]);
141 std::size_t i = 0;
142 for (const auto& service : target_service->included_services) {
143 (*out_included_services).get()[i].ServiceUuid =
144 service.second->service_info->ServiceUuid;
145 (*out_included_services).get()[i].AttributeHandle =
146 service.second->service_info->AttributeHandle;
147 i++;
148 }
149 return S_OK;
150 }
151 return HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS);
152 }
153
154 HRESULT BluetoothLowEnergyWrapperFake::ReadCharacteristicsOfAService(
155 base::FilePath& service_path,
156 const PBTH_LE_GATT_SERVICE service,
157 scoped_ptr<BTH_LE_GATT_CHARACTERISTIC>* out_included_characteristics,
158 USHORT* out_counts) {
159 base::string16 device_address =
160 ExtractDeviceAddressFromDevicePath(service_path.value());
161 const std::vector<std::string> service_att_handles =
162 ExtractServiceAttributeHandlesFromDevicePath(service_path.value());
163 BLEGattService* target_service = GetSimulatedGattService(
164 GetSimulatedBLEDevice(
165 std::string(device_address.begin(), device_address.end())),
166 service_att_handles);
167 if (target_service == nullptr)
168 return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
169
170 std::size_t number_of_included_characteristic =
171 target_service->included_characteristics.size();
172 if (number_of_included_characteristic) {
173 *out_counts = (USHORT)number_of_included_characteristic;
174 (*out_included_characteristics)
175 .reset(
176 new BTH_LE_GATT_CHARACTERISTIC[number_of_included_characteristic]);
177 std::size_t i = 0;
178 for (const auto& cha : target_service->included_characteristics) {
179 (*out_included_characteristics).get()[i] =
180 *(cha.second->characteristic_info);
181 i++;
182 }
183 return S_OK;
184 }
185 return HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS);
186 }
187
120 BLEDevice* BluetoothLowEnergyWrapperFake::SimulateBLEDevice( 188 BLEDevice* BluetoothLowEnergyWrapperFake::SimulateBLEDevice(
121 std::string device_name, 189 std::string device_name,
122 BLUETOOTH_ADDRESS device_address) { 190 BLUETOOTH_ADDRESS device_address) {
123 BLEDevice* device = new BLEDevice(); 191 BLEDevice* device = new BLEDevice();
124 BluetoothLowEnergyDeviceInfo* device_info = 192 BluetoothLowEnergyDeviceInfo* device_info =
125 new BluetoothLowEnergyDeviceInfo(); 193 new BluetoothLowEnergyDeviceInfo();
126 std::string string_device_address = 194 std::string string_device_address =
127 BluetoothAddressToCanonicalString(device_address); 195 BluetoothAddressToCanonicalString(device_address);
128 device_info->path = 196 device_info->path =
129 base::FilePath(GenerateBLEDevicePath(string_device_address)); 197 base::FilePath(GenerateBLEDevicePath(string_device_address));
130 device_info->friendly_name = device_name; 198 device_info->friendly_name = device_name;
131 device_info->address = device_address; 199 device_info->address = device_address;
132 device->device_info.reset(device_info); 200 device->device_info.reset(device_info);
133 simulated_devices_[string_device_address] = make_scoped_ptr(device); 201 simulated_devices_[string_device_address] = make_scoped_ptr(device);
134 return device; 202 return device;
135 } 203 }
136 204
205 BLEDevice* BluetoothLowEnergyWrapperFake::GetSimulatedBLEDevice(
206 std::string device_address) {
207 BLEDevicesMap::iterator it_d = simulated_devices_.find(device_address);
208 if (it_d == simulated_devices_.end())
209 return nullptr;
210 return it_d->second.get();
211 }
212
137 BLEGattService* BluetoothLowEnergyWrapperFake::SimulateBLEGattService( 213 BLEGattService* BluetoothLowEnergyWrapperFake::SimulateBLEGattService(
138 BLEDevice* device, 214 BLEDevice* device,
139 std::string uuid) { 215 BLEGattService* parent_service,
216 const BTH_LE_UUID& uuid) {
140 CHECK(device); 217 CHECK(device);
141 218
142 BLEGattService* service = new BLEGattService(); 219 BLEGattService* service = new BLEGattService();
143 PBTH_LE_GATT_SERVICE service_info = new BTH_LE_GATT_SERVICE[1]; 220 PBTH_LE_GATT_SERVICE service_info = new BTH_LE_GATT_SERVICE[1];
144 std::string string_device_address = 221 std::string string_device_address =
145 BluetoothAddressToCanonicalString(device->device_info->address); 222 BluetoothAddressToCanonicalString(device->device_info->address);
146 service_info->AttributeHandle = 223 service_info->AttributeHandle =
147 GenerateAUniqueAttributeHandle(string_device_address); 224 GenerateAUniqueAttributeHandle(string_device_address);
148 service_info->ServiceUuid = CanonicalStringToBTH_LE_UUID(uuid); 225 service_info->ServiceUuid = uuid;
149 service->service_info.reset(service_info); 226 service->service_info.reset(service_info);
150 device->primary_services[std::to_string(service_info->AttributeHandle)] = 227
151 make_scoped_ptr(service); 228 if (parent_service) {
229 parent_service
230 ->included_services[std::to_string(service_info->AttributeHandle)] =
231 make_scoped_ptr(service);
232 } else {
233 device->primary_services[std::to_string(service_info->AttributeHandle)] =
234 make_scoped_ptr(service);
235 }
152 return service; 236 return service;
153 } 237 }
154 238
155 BLEDevice* BluetoothLowEnergyWrapperFake::GetSimulatedBLEDevice( 239 void BluetoothLowEnergyWrapperFake::SimulateBLEGattServiceRemove(
156 std::string device_address) { 240 BLEDevice* device,
157 BLEDevicesMap::iterator it_d = simulated_devices_.find(device_address); 241 BLEGattService* parent_service,
158 if (it_d == simulated_devices_.end()) 242 std::string attribute_handle) {
243 if (parent_service) {
244 parent_service->included_services.erase(attribute_handle);
245 } else {
246 device->primary_services.erase(attribute_handle);
247 }
248 }
249
250 BLEGattService* BluetoothLowEnergyWrapperFake::GetSimulatedGattService(
251 BLEDevice* device,
252 const std::vector<std::string>& chain_of_att_handle) {
253 // First, find the root primary service.
254 BLEGattServicesMap::iterator it_s =
255 device->primary_services.find(chain_of_att_handle[0]);
256 if (it_s == device->primary_services.end())
159 return nullptr; 257 return nullptr;
160 return it_d->second.get(); 258
259 // Iteratively follow the chain of included service attribute handles to find
260 // the target service.
261 for (std::size_t i = 1; i < chain_of_att_handle.size(); i++) {
262 std::string included_att_handle = std::string(
263 chain_of_att_handle[i].begin(), chain_of_att_handle[i].end());
264 BLEGattServicesMap::iterator it_i =
265 it_s->second->included_services.find(included_att_handle);
266 if (it_i == it_s->second->included_services.end())
267 return nullptr;
268 it_s = it_i;
269 }
270 return it_s->second.get();
271 }
272
273 BLEGattCharacteristic* BluetoothLowEnergyWrapperFake::SimulateCharacterisc(
274 std::string device_address,
275 BLEGattService* parent_service,
276 const BTH_LE_GATT_CHARACTERISTIC& characteristic) {
277 CHECK(parent_service);
278
279 BLEGattCharacteristic* cha = new BLEGattCharacteristic();
280 PBTH_LE_GATT_CHARACTERISTIC win_cha_info = new BTH_LE_GATT_CHARACTERISTIC[1];
281 *win_cha_info = characteristic;
282 (cha->characteristic_info).reset(win_cha_info);
283 cha->characteristic_info->AttributeHandle =
284 GenerateAUniqueAttributeHandle(device_address);
285 parent_service->included_characteristics[std::to_string(
286 cha->characteristic_info->AttributeHandle)] = make_scoped_ptr(cha);
287 return cha;
288 }
289
290 void BluetoothLowEnergyWrapperFake::SimulateCharacteriscRemove(
291 BLEGattService* parent_service,
292 std::string attribute_handle) {
293 CHECK(parent_service);
294 parent_service->included_characteristics.erase(attribute_handle);
161 } 295 }
162 296
163 USHORT BluetoothLowEnergyWrapperFake::GenerateAUniqueAttributeHandle( 297 USHORT BluetoothLowEnergyWrapperFake::GenerateAUniqueAttributeHandle(
164 std::string device_address) { 298 std::string device_address) {
165 scoped_ptr<std::set<USHORT>>& set_of_ushort = 299 scoped_ptr<std::set<USHORT>>& set_of_ushort =
166 attribute_handle_table_[device_address]; 300 attribute_handle_table_[device_address];
167 if (set_of_ushort) { 301 if (set_of_ushort) {
168 USHORT max_attribute_handle = *set_of_ushort->rbegin(); 302 USHORT max_attribute_handle = *set_of_ushort->rbegin();
169 if (max_attribute_handle < 0xFFFF) { 303 if (max_attribute_handle < 0xFFFF) {
170 USHORT new_attribute_handle = max_attribute_handle + 1; 304 USHORT new_attribute_handle = max_attribute_handle + 1;
(...skipping 28 matching lines...) Expand all
199 base::string16 resident_device_path, 333 base::string16 resident_device_path,
200 USHORT service_attribute_handle) { 334 USHORT service_attribute_handle) {
201 std::string sub_path = std::to_string(service_attribute_handle); 335 std::string sub_path = std::to_string(service_attribute_handle);
202 return resident_device_path + L"/" + 336 return resident_device_path + L"/" +
203 base::string16(sub_path.begin(), sub_path.end()); 337 base::string16(sub_path.begin(), sub_path.end());
204 } 338 }
205 339
206 base::string16 340 base::string16
207 BluetoothLowEnergyWrapperFake::ExtractDeviceAddressFromDevicePath( 341 BluetoothLowEnergyWrapperFake::ExtractDeviceAddressFromDevicePath(
208 base::string16 path) { 342 base::string16 path) {
209 std::size_t found = path.find('/'); 343 std::size_t found = path.find_first_of('/');
210 if (found != base::string16::npos) { 344 if (found != base::string16::npos) {
211 return path.substr(0, found); 345 return path.substr(0, found);
212 } 346 }
213 return path; 347 return path;
214 } 348 }
215 349
216 base::string16 350 std::vector<std::string>
217 BluetoothLowEnergyWrapperFake::ExtractServiceAttributeHandleFromDevicePath( 351 BluetoothLowEnergyWrapperFake::ExtractServiceAttributeHandlesFromDevicePath(
218 base::string16 path) { 352 base::string16 path) {
219 std::size_t found = path.find('/'); 353 std::size_t found = path.find('/');
220 if (found == base::string16::npos) 354 if (found == base::string16::npos)
221 return base::string16(); 355 return std::vector<std::string>();
222 return path.substr(found + 1);
223 }
224 356
225 BTH_LE_UUID BluetoothLowEnergyWrapperFake::CanonicalStringToBTH_LE_UUID( 357 std::vector<std::string> chain_of_att_handle;
226 std::string uuid) { 358 while (true) {
227 BTH_LE_UUID win_uuid; 359 std::size_t next_found = path.find(path, found + 1);
228 // Only short UUIDs (4 hex digits) have beened used in BluetoothTest right 360 if (next_found == base::string16::npos)
229 // now. Need fix after using long UUIDs. 361 break;
230 win_uuid.IsShortUuid = true; 362 base::string16 w_att_handle = path.substr(found + 1, next_found);
231 unsigned int data[1]; 363 chain_of_att_handle.push_back(
232 int result = sscanf_s(uuid.c_str(), "%04x", &data[0]); 364 std::string(w_att_handle.begin(), w_att_handle.end()));
233 CHECK(result == 1); 365 found = next_found;
234 win_uuid.Value.ShortUuid = data[0]; 366 }
235 return win_uuid; 367 base::string16 w_att_handle = path.substr(found + 1);
368 chain_of_att_handle.push_back(
369 std::string(w_att_handle.begin(), w_att_handle.end()));
370 return chain_of_att_handle;
236 } 371 }
237 372
238 std::string BluetoothLowEnergyWrapperFake::BluetoothAddressToCanonicalString( 373 std::string BluetoothLowEnergyWrapperFake::BluetoothAddressToCanonicalString(
239 const BLUETOOTH_ADDRESS& btha) { 374 const BLUETOOTH_ADDRESS& btha) {
240 std::string result = base::StringPrintf( 375 std::string result = base::StringPrintf(
241 "%02X:%02X:%02X:%02X:%02X:%02X", btha.rgBytes[5], btha.rgBytes[4], 376 "%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]); 377 btha.rgBytes[3], btha.rgBytes[2], btha.rgBytes[1], btha.rgBytes[0]);
243 return result; 378 return result;
244 } 379 }
245 380
246 } // namespace win 381 } // namespace win
247 } // namespace device 382 } // namespace device
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698