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

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: address comments and split out of included GATT services 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::ReadCharacteristicsOfAService(
124 base::FilePath& service_path,
125 const PBTH_LE_GATT_SERVICE service,
126 scoped_ptr<BTH_LE_GATT_CHARACTERISTIC>* out_included_characteristics,
127 USHORT* out_counts) {
128 base::string16 device_address =
129 ExtractDeviceAddressFromDevicePath(service_path.value());
130 const 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_characteristic =
140 target_service->included_characteristics.size();
141 if (number_of_included_characteristic) {
142 *out_counts = (USHORT)number_of_included_characteristic;
143 out_included_characteristics->reset(
144 new BTH_LE_GATT_CHARACTERISTIC[number_of_included_characteristic]);
145 std::size_t i = 0;
146 for (const auto& cha : target_service->included_characteristics) {
147 out_included_characteristics->get()[i] =
148 *(cha.second->characteristic_info);
149 i++;
150 }
151 return S_OK;
152 }
153 return HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS);
154 }
155
120 BLEDevice* BluetoothLowEnergyWrapperFake::SimulateBLEDevice( 156 BLEDevice* BluetoothLowEnergyWrapperFake::SimulateBLEDevice(
121 std::string device_name, 157 std::string device_name,
122 BLUETOOTH_ADDRESS device_address) { 158 BLUETOOTH_ADDRESS device_address) {
123 BLEDevice* device = new BLEDevice(); 159 BLEDevice* device = new BLEDevice();
124 BluetoothLowEnergyDeviceInfo* device_info = 160 BluetoothLowEnergyDeviceInfo* device_info =
125 new BluetoothLowEnergyDeviceInfo(); 161 new BluetoothLowEnergyDeviceInfo();
126 std::string string_device_address = 162 std::string string_device_address =
127 BluetoothAddressToCanonicalString(device_address); 163 BluetoothAddressToCanonicalString(device_address);
128 device_info->path = 164 device_info->path =
129 base::FilePath(GenerateBLEDevicePath(string_device_address)); 165 base::FilePath(GenerateBLEDevicePath(string_device_address));
130 device_info->friendly_name = device_name; 166 device_info->friendly_name = device_name;
131 device_info->address = device_address; 167 device_info->address = device_address;
132 device->device_info.reset(device_info); 168 device->device_info.reset(device_info);
133 simulated_devices_[string_device_address] = make_scoped_ptr(device); 169 simulated_devices_[string_device_address] = make_scoped_ptr(device);
134 return device; 170 return device;
135 } 171 }
136 172
173 BLEDevice* BluetoothLowEnergyWrapperFake::GetSimulatedBLEDevice(
174 std::string device_address) {
175 BLEDevicesMap::iterator it_d = simulated_devices_.find(device_address);
176 if (it_d == simulated_devices_.end())
177 return nullptr;
178 return it_d->second.get();
179 }
180
137 BLEGattService* BluetoothLowEnergyWrapperFake::SimulateBLEGattService( 181 BLEGattService* BluetoothLowEnergyWrapperFake::SimulateBLEGattService(
138 BLEDevice* device, 182 BLEDevice* device,
139 std::string uuid) { 183 BLEGattService* parent_service,
184 const BTH_LE_UUID& uuid) {
140 CHECK(device); 185 CHECK(device);
141 186
142 BLEGattService* service = new BLEGattService(); 187 BLEGattService* service = new BLEGattService();
143 PBTH_LE_GATT_SERVICE service_info = new BTH_LE_GATT_SERVICE[1]; 188 PBTH_LE_GATT_SERVICE service_info = new BTH_LE_GATT_SERVICE[1];
144 std::string string_device_address = 189 std::string string_device_address =
145 BluetoothAddressToCanonicalString(device->device_info->address); 190 BluetoothAddressToCanonicalString(device->device_info->address);
146 service_info->AttributeHandle = 191 service_info->AttributeHandle =
147 GenerateAUniqueAttributeHandle(string_device_address); 192 GenerateAUniqueAttributeHandle(string_device_address);
148 service_info->ServiceUuid = CanonicalStringToBTH_LE_UUID(uuid); 193 service_info->ServiceUuid = uuid;
149 service->service_info.reset(service_info); 194 service->service_info.reset(service_info);
150 device->primary_services[std::to_string(service_info->AttributeHandle)] = 195
151 make_scoped_ptr(service); 196 if (parent_service) {
197 parent_service
198 ->included_services[std::to_string(service_info->AttributeHandle)] =
199 make_scoped_ptr(service);
200 } else {
201 device->primary_services[std::to_string(service_info->AttributeHandle)] =
202 make_scoped_ptr(service);
203 }
152 return service; 204 return service;
153 } 205 }
154 206
155 BLEDevice* BluetoothLowEnergyWrapperFake::GetSimulatedBLEDevice( 207 void BluetoothLowEnergyWrapperFake::SimulateBLEGattServiceRemoved(
156 std::string device_address) { 208 BLEDevice* device,
157 BLEDevicesMap::iterator it_d = simulated_devices_.find(device_address); 209 BLEGattService* parent_service,
158 if (it_d == simulated_devices_.end()) 210 std::string attribute_handle) {
211 if (parent_service) {
212 parent_service->included_services.erase(attribute_handle);
213 } else {
214 device->primary_services.erase(attribute_handle);
215 }
216 }
217
218 BLEGattService* BluetoothLowEnergyWrapperFake::GetSimulatedGattService(
219 BLEDevice* device,
220 const std::vector<std::string>& chain_of_att_handle) {
221 // First, find the root primary service.
222 BLEGattServicesMap::iterator it_s =
223 device->primary_services.find(chain_of_att_handle[0]);
224 if (it_s == device->primary_services.end())
159 return nullptr; 225 return nullptr;
160 return it_d->second.get(); 226
227 // Iteratively follow the chain of included service attribute handles to find
228 // the target service.
229 for (std::size_t i = 1; i < chain_of_att_handle.size(); i++) {
230 std::string included_att_handle = std::string(
231 chain_of_att_handle[i].begin(), chain_of_att_handle[i].end());
232 BLEGattServicesMap::iterator it_i =
233 it_s->second->included_services.find(included_att_handle);
234 if (it_i == it_s->second->included_services.end())
235 return nullptr;
236 it_s = it_i;
237 }
238 return it_s->second.get();
239 }
240
241 BLEGattCharacteristic*
242 BluetoothLowEnergyWrapperFake::SimulateBLEGattCharacterisc(
243 std::string device_address,
244 BLEGattService* parent_service,
245 const BTH_LE_GATT_CHARACTERISTIC& characteristic) {
246 CHECK(parent_service);
247
248 BLEGattCharacteristic* win_characteristic = new BLEGattCharacteristic();
249 PBTH_LE_GATT_CHARACTERISTIC win_characteristic_info =
250 new BTH_LE_GATT_CHARACTERISTIC[1];
251 *win_characteristic_info = characteristic;
252 (win_characteristic->characteristic_info).reset(win_characteristic_info);
253 win_characteristic->characteristic_info->AttributeHandle =
254 GenerateAUniqueAttributeHandle(device_address);
255 parent_service->included_characteristics[std::to_string(
256 win_characteristic->characteristic_info->AttributeHandle)] =
257 make_scoped_ptr(win_characteristic);
258 return win_characteristic;
259 }
260
261 void BluetoothLowEnergyWrapperFake::SimulateBLEGattCharacteriscRemove(
262 BLEGattService* parent_service,
263 std::string attribute_handle) {
264 CHECK(parent_service);
265 parent_service->included_characteristics.erase(attribute_handle);
161 } 266 }
162 267
163 USHORT BluetoothLowEnergyWrapperFake::GenerateAUniqueAttributeHandle( 268 USHORT BluetoothLowEnergyWrapperFake::GenerateAUniqueAttributeHandle(
164 std::string device_address) { 269 std::string device_address) {
165 scoped_ptr<std::set<USHORT>>& set_of_ushort = 270 scoped_ptr<std::set<USHORT>>& set_of_ushort =
166 attribute_handle_table_[device_address]; 271 attribute_handle_table_[device_address];
167 if (set_of_ushort) { 272 if (set_of_ushort) {
168 USHORT max_attribute_handle = *set_of_ushort->rbegin(); 273 USHORT max_attribute_handle = *set_of_ushort->rbegin();
169 if (max_attribute_handle < 0xFFFF) { 274 if (max_attribute_handle < 0xFFFF) {
170 USHORT new_attribute_handle = max_attribute_handle + 1; 275 USHORT new_attribute_handle = max_attribute_handle + 1;
(...skipping 28 matching lines...) Expand all
199 base::string16 resident_device_path, 304 base::string16 resident_device_path,
200 USHORT service_attribute_handle) { 305 USHORT service_attribute_handle) {
201 std::string sub_path = std::to_string(service_attribute_handle); 306 std::string sub_path = std::to_string(service_attribute_handle);
202 return resident_device_path + L"/" + 307 return resident_device_path + L"/" +
203 base::string16(sub_path.begin(), sub_path.end()); 308 base::string16(sub_path.begin(), sub_path.end());
204 } 309 }
205 310
206 base::string16 311 base::string16
207 BluetoothLowEnergyWrapperFake::ExtractDeviceAddressFromDevicePath( 312 BluetoothLowEnergyWrapperFake::ExtractDeviceAddressFromDevicePath(
208 base::string16 path) { 313 base::string16 path) {
209 std::size_t found = path.find('/'); 314 std::size_t found = path.find_first_of('/');
210 if (found != base::string16::npos) { 315 if (found != base::string16::npos) {
211 return path.substr(0, found); 316 return path.substr(0, found);
212 } 317 }
213 return path; 318 return path;
214 } 319 }
215 320
216 base::string16 321 std::vector<std::string>
217 BluetoothLowEnergyWrapperFake::ExtractServiceAttributeHandleFromDevicePath( 322 BluetoothLowEnergyWrapperFake::ExtractServiceAttributeHandlesFromDevicePath(
218 base::string16 path) { 323 base::string16 path) {
219 std::size_t found = path.find('/'); 324 std::size_t found = path.find('/');
220 if (found == base::string16::npos) 325 if (found == base::string16::npos)
221 return base::string16(); 326 return std::vector<std::string>();
222 return path.substr(found + 1);
223 }
224 327
225 BTH_LE_UUID BluetoothLowEnergyWrapperFake::CanonicalStringToBTH_LE_UUID( 328 std::vector<std::string> chain_of_att_handle;
226 std::string uuid) { 329 while (true) {
227 BTH_LE_UUID win_uuid; 330 std::size_t next_found = path.find(path, found + 1);
228 // Only short UUIDs (4 hex digits) have beened used in BluetoothTest right 331 if (next_found == base::string16::npos)
229 // now. Need fix after using long UUIDs. 332 break;
230 win_uuid.IsShortUuid = true; 333 base::string16 att_handle = path.substr(found + 1, next_found);
231 unsigned int data[1]; 334 chain_of_att_handle.push_back(
232 int result = sscanf_s(uuid.c_str(), "%04x", &data[0]); 335 std::string(att_handle.begin(), att_handle.end()));
233 CHECK(result == 1); 336 found = next_found;
234 win_uuid.Value.ShortUuid = data[0]; 337 }
235 return win_uuid; 338 base::string16 att_handle = path.substr(found + 1);
339 chain_of_att_handle.push_back(
340 std::string(att_handle.begin(), att_handle.end()));
341 return chain_of_att_handle;
236 } 342 }
237 343
238 std::string BluetoothLowEnergyWrapperFake::BluetoothAddressToCanonicalString( 344 std::string BluetoothLowEnergyWrapperFake::BluetoothAddressToCanonicalString(
239 const BLUETOOTH_ADDRESS& btha) { 345 const BLUETOOTH_ADDRESS& btha) {
240 std::string result = base::StringPrintf( 346 std::string result = base::StringPrintf(
241 "%02X:%02X:%02X:%02X:%02X:%02X", btha.rgBytes[5], btha.rgBytes[4], 347 "%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]); 348 btha.rgBytes[3], btha.rgBytes[2], btha.rgBytes[1], btha.rgBytes[0]);
243 return result; 349 return result;
244 } 350 }
245 351
246 } // namespace win 352 } // namespace win
247 } // namespace device 353 } // namespace device
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698