| OLD | NEW |
| 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 #include "device/bluetooth/bluetooth_low_energy_defs_win.h" |
| 9 | 9 |
| 10 namespace { | 10 namespace { |
| 11 const char kPlatformNotSupported[] = | 11 const char kPlatformNotSupported[] = |
| 12 "Bluetooth Low energy is only supported on Windows 8 and later."; | 12 "Bluetooth Low energy is only supported on Windows 8 and later."; |
| 13 } // namespace | 13 } // namespace |
| 14 | 14 |
| 15 namespace device { | 15 namespace device { |
| 16 namespace win { | 16 namespace win { |
| 17 | 17 |
| 18 BLEDevice::BLEDevice() {} | 18 BLEDevice::BLEDevice() {} |
| 19 BLEDevice::~BLEDevice() {} | 19 BLEDevice::~BLEDevice() {} |
| 20 | 20 |
| 21 GattService::GattService() {} | 21 GattService::GattService() {} |
| 22 GattService::~GattService() {} | 22 GattService::~GattService() {} |
| 23 | 23 |
| 24 GattCharacteristic::GattCharacteristic() {} | 24 GattCharacteristic::GattCharacteristic() {} |
| 25 GattCharacteristic::~GattCharacteristic() {} | 25 GattCharacteristic::~GattCharacteristic() {} |
| 26 | 26 |
| 27 GattDescriptor::GattDescriptor() {} | 27 GattDescriptor::GattDescriptor() {} |
| 28 GattDescriptor::~GattDescriptor() {} | 28 GattDescriptor::~GattDescriptor() {} |
| 29 | 29 |
| 30 GattServiceObserver::GattServiceObserver() {} |
| 31 GattServiceObserver::~GattServiceObserver() {} |
| 32 |
| 30 BluetoothLowEnergyWrapperFake::BluetoothLowEnergyWrapperFake() | 33 BluetoothLowEnergyWrapperFake::BluetoothLowEnergyWrapperFake() |
| 31 : observer_(nullptr) {} | 34 : observer_(nullptr) {} |
| 32 BluetoothLowEnergyWrapperFake::~BluetoothLowEnergyWrapperFake() {} | 35 BluetoothLowEnergyWrapperFake::~BluetoothLowEnergyWrapperFake() {} |
| 33 | 36 |
| 34 bool BluetoothLowEnergyWrapperFake::IsBluetoothLowEnergySupported() { | 37 bool BluetoothLowEnergyWrapperFake::IsBluetoothLowEnergySupported() { |
| 35 return true; | 38 return true; |
| 36 } | 39 } |
| 37 | 40 |
| 38 bool BluetoothLowEnergyWrapperFake::EnumerateKnownBluetoothLowEnergyDevices( | 41 bool BluetoothLowEnergyWrapperFake::EnumerateKnownBluetoothLowEnergyDevices( |
| 39 ScopedVector<BluetoothLowEnergyDeviceInfo>* devices, | 42 ScopedVector<BluetoothLowEnergyDeviceInfo>* devices, |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 197 return hr; | 200 return hr; |
| 198 } | 201 } |
| 199 | 202 |
| 200 PBTH_LE_GATT_CHARACTERISTIC_VALUE ret_value = | 203 PBTH_LE_GATT_CHARACTERISTIC_VALUE ret_value = |
| 201 (PBTH_LE_GATT_CHARACTERISTIC_VALUE)( | 204 (PBTH_LE_GATT_CHARACTERISTIC_VALUE)( |
| 202 new UCHAR[sizeof(ULONG) + target_characteristic->value->DataSize]); | 205 new UCHAR[sizeof(ULONG) + target_characteristic->value->DataSize]); |
| 203 ret_value->DataSize = target_characteristic->value->DataSize; | 206 ret_value->DataSize = target_characteristic->value->DataSize; |
| 204 for (ULONG i = 0; i < ret_value->DataSize; i++) | 207 for (ULONG i = 0; i < ret_value->DataSize; i++) |
| 205 ret_value->Data[i] = target_characteristic->value->Data[i]; | 208 ret_value->Data[i] = target_characteristic->value->Data[i]; |
| 206 out_value->reset(ret_value); | 209 out_value->reset(ret_value); |
| 210 if (observer_) |
| 211 observer_->OnReadGattCharacteristicValue(); |
| 207 return S_OK; | 212 return S_OK; |
| 208 } | 213 } |
| 209 | 214 |
| 210 HRESULT BluetoothLowEnergyWrapperFake::WriteCharacteristicValue( | 215 HRESULT BluetoothLowEnergyWrapperFake::WriteCharacteristicValue( |
| 211 base::FilePath& service_path, | 216 base::FilePath& service_path, |
| 212 const PBTH_LE_GATT_CHARACTERISTIC characteristic, | 217 const PBTH_LE_GATT_CHARACTERISTIC characteristic, |
| 213 PBTH_LE_GATT_CHARACTERISTIC_VALUE new_value) { | 218 PBTH_LE_GATT_CHARACTERISTIC_VALUE new_value) { |
| 214 GattCharacteristic* target_characteristic = | 219 GattCharacteristic* target_characteristic = |
| 215 GetSimulatedGattCharacteristic(service_path, characteristic); | 220 GetSimulatedGattCharacteristic(service_path, characteristic); |
| 216 if (target_characteristic == nullptr) | 221 if (target_characteristic == nullptr) |
| 217 return ERROR_NOT_FOUND; | 222 return ERROR_NOT_FOUND; |
| 218 | 223 |
| 219 // Return error simulated by SimulateGattCharacteristicWriteError. | 224 // Return error simulated by SimulateGattCharacteristicWriteError. |
| 220 if (target_characteristic->write_errors.size()) { | 225 if (target_characteristic->write_errors.size()) { |
| 221 HRESULT hr = *(target_characteristic->write_errors.begin()); | 226 HRESULT hr = *(target_characteristic->write_errors.begin()); |
| 222 target_characteristic->write_errors.erase( | 227 target_characteristic->write_errors.erase( |
| 223 target_characteristic->write_errors.begin()); | 228 target_characteristic->write_errors.begin()); |
| 224 return hr; | 229 return hr; |
| 225 } | 230 } |
| 226 | 231 |
| 227 PBTH_LE_GATT_CHARACTERISTIC_VALUE win_value = | 232 PBTH_LE_GATT_CHARACTERISTIC_VALUE win_value = |
| 228 (PBTH_LE_GATT_CHARACTERISTIC_VALUE)( | 233 (PBTH_LE_GATT_CHARACTERISTIC_VALUE)( |
| 229 new UCHAR[new_value->DataSize + sizeof(ULONG)]); | 234 new UCHAR[new_value->DataSize + sizeof(ULONG)]); |
| 230 for (ULONG i = 0; i < new_value->DataSize; i++) | 235 for (ULONG i = 0; i < new_value->DataSize; i++) |
| 231 win_value->Data[i] = new_value->Data[i]; | 236 win_value->Data[i] = new_value->Data[i]; |
| 232 win_value->DataSize = new_value->DataSize; | 237 win_value->DataSize = new_value->DataSize; |
| 233 target_characteristic->value.reset(win_value); | 238 target_characteristic->value.reset(win_value); |
| 234 if (observer_) | 239 if (observer_) |
| 235 observer_->onWriteGattCharacteristicValue(win_value); | 240 observer_->OnWriteGattCharacteristicValue(win_value); |
| 236 return S_OK; | 241 return S_OK; |
| 237 } | 242 } |
| 238 | 243 |
| 244 HRESULT BluetoothLowEnergyWrapperFake::RegisterGattEvents( |
| 245 base::FilePath& service_path, |
| 246 BTH_LE_GATT_EVENT_TYPE type, |
| 247 PVOID event_parameter, |
| 248 PFNBLUETOOTH_GATT_EVENT_CALLBACK callback, |
| 249 PVOID context, |
| 250 BLUETOOTH_GATT_EVENT_HANDLE* out_handle) { |
| 251 base::string16 device_address = |
| 252 ExtractDeviceAddressFromDevicePath(service_path.value()); |
| 253 BLEDevice* target_device = GetSimulatedBLEDevice( |
| 254 std::string(device_address.begin(), device_address.end())); |
| 255 if (target_device == nullptr) |
| 256 return HRESULT_FROM_WIN32(ERROR_NOT_FOUND); |
| 257 const std::vector<std::string> service_att_handles = |
| 258 ExtractServiceAttributeHandlesFromDevicePath(service_path.value()); |
| 259 GattService* target_service = |
| 260 GetSimulatedGattService(target_device, service_att_handles); |
| 261 if (target_service == nullptr) |
| 262 return HRESULT_FROM_WIN32(ERROR_NOT_FOUND); |
| 263 |
| 264 PBLUETOOTH_GATT_VALUE_CHANGED_EVENT_REGISTRATION parameter = |
| 265 (PBLUETOOTH_GATT_VALUE_CHANGED_EVENT_REGISTRATION)event_parameter; |
| 266 for (USHORT i = 0; i < parameter->NumCharacteristics; i++) { |
| 267 GattCharacteristic* target_characteristic = GetSimulatedGattCharacteristic( |
| 268 target_service, |
| 269 std::to_string(parameter->Characteristics[i].AttributeHandle)); |
| 270 CHECK(target_characteristic); |
| 271 |
| 272 // Return error simulated by SimulateGattCharacteristicSetNotifyError. |
| 273 if (target_characteristic->notify_errors.size()) { |
| 274 HRESULT error = target_characteristic->notify_errors[0]; |
| 275 target_characteristic->notify_errors.erase( |
| 276 target_characteristic->notify_errors.begin()); |
| 277 return error; |
| 278 } |
| 279 |
| 280 // Get CCC descriptor. |
| 281 GattDescriptor* target_descriptor = GetCCCDescriptor(target_characteristic); |
| 282 if (target_descriptor == nullptr) |
| 283 return E_BLUETOOTH_ATT_REQUEST_NOT_SUPPORTED; |
| 284 if (observer_) |
| 285 observer_->OnStartCharacteristicNotification(); |
| 286 |
| 287 // Return error simualted by SimulateGattDescriptorWriteError. |
| 288 if (target_descriptor->write_errors.size()) { |
| 289 HRESULT error = target_descriptor->write_errors[0]; |
| 290 target_descriptor->write_errors.erase( |
| 291 target_descriptor->write_errors.begin()); |
| 292 return error; |
| 293 } |
| 294 |
| 295 // Write CCC descriptor. |
| 296 std::vector<uint8_t> new_value; |
| 297 if (target_characteristic->characteristic_info->IsNotifiable) |
| 298 new_value.push_back(1); |
| 299 else if (target_characteristic->characteristic_info->IsIndicatable) |
| 300 new_value.push_back(2); |
| 301 else |
| 302 return E_BLUETOOTH_ATT_REQUEST_NOT_SUPPORTED; |
| 303 new_value.push_back(0); |
| 304 SimulateGattDescriptorWrite(target_descriptor, new_value); |
| 305 } |
| 306 |
| 307 scoped_ptr<GattServiceObserver> observer(new GattServiceObserver()); |
| 308 observer->callback = callback; |
| 309 observer->context = context; |
| 310 BLUETOOTH_GATT_EVENT_HANDLE handle = |
| 311 (BLUETOOTH_GATT_EVENT_HANDLE)observer.get(); |
| 312 gatt_service_observers_[handle] = std::move(observer); |
| 313 target_service->observers.push_back(handle); |
| 314 |
| 315 return S_OK; |
| 316 } |
| 317 |
| 318 HRESULT BluetoothLowEnergyWrapperFake::UnregisterGattEvent( |
| 319 BLUETOOTH_GATT_EVENT_HANDLE event_handle) { |
| 320 gatt_service_observers_.erase(event_handle); |
| 321 return S_OK; |
| 322 } |
| 323 |
| 239 BLEDevice* BluetoothLowEnergyWrapperFake::SimulateBLEDevice( | 324 BLEDevice* BluetoothLowEnergyWrapperFake::SimulateBLEDevice( |
| 240 std::string device_name, | 325 std::string device_name, |
| 241 BLUETOOTH_ADDRESS device_address) { | 326 BLUETOOTH_ADDRESS device_address) { |
| 242 BLEDevice* device = new BLEDevice(); | 327 BLEDevice* device = new BLEDevice(); |
| 243 BluetoothLowEnergyDeviceInfo* device_info = | 328 BluetoothLowEnergyDeviceInfo* device_info = |
| 244 new BluetoothLowEnergyDeviceInfo(); | 329 new BluetoothLowEnergyDeviceInfo(); |
| 245 std::string string_device_address = | 330 std::string string_device_address = |
| 246 BluetoothAddressToCanonicalString(device_address); | 331 BluetoothAddressToCanonicalString(device_address); |
| 247 device_info->path = | 332 device_info->path = |
| 248 base::FilePath(GenerateBLEDevicePath(string_device_address)); | 333 base::FilePath(GenerateBLEDevicePath(string_device_address)); |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 370 CHECK(characteristic); | 455 CHECK(characteristic); |
| 371 PBTH_LE_GATT_CHARACTERISTIC_VALUE win_value = | 456 PBTH_LE_GATT_CHARACTERISTIC_VALUE win_value = |
| 372 (PBTH_LE_GATT_CHARACTERISTIC_VALUE)( | 457 (PBTH_LE_GATT_CHARACTERISTIC_VALUE)( |
| 373 new UCHAR[value.size() + sizeof(ULONG)]); | 458 new UCHAR[value.size() + sizeof(ULONG)]); |
| 374 win_value->DataSize = (ULONG)value.size(); | 459 win_value->DataSize = (ULONG)value.size(); |
| 375 for (std::size_t i = 0; i < value.size(); i++) | 460 for (std::size_t i = 0; i < value.size(); i++) |
| 376 win_value->Data[i] = value[i]; | 461 win_value->Data[i] = value[i]; |
| 377 characteristic->value.reset(win_value); | 462 characteristic->value.reset(win_value); |
| 378 } | 463 } |
| 379 | 464 |
| 465 void BluetoothLowEnergyWrapperFake:: |
| 466 SimulateCharacteristicValueChangeNotification( |
| 467 GattService* parent_service, |
| 468 GattCharacteristic* characteristic) { |
| 469 for (auto observer : parent_service->observers) { |
| 470 GattServiceObserverTable::iterator it = |
| 471 gatt_service_observers_.find(observer); |
| 472 // Check if |observer| has been unregistered by UnregisterGattEvent. |
| 473 if (it != gatt_service_observers_.end()) { |
| 474 BLUETOOTH_GATT_VALUE_CHANGED_EVENT event; |
| 475 event.ChangedAttributeHandle = |
| 476 characteristic->characteristic_info->AttributeHandle; |
| 477 event.CharacteristicValueDataSize = |
| 478 characteristic->value->DataSize + (ULONG)sizeof(ULONG); |
| 479 event.CharacteristicValue = characteristic->value.get(); |
| 480 it->second->callback(CharacteristicValueChangedEvent, &event, |
| 481 it->second->context); |
| 482 } |
| 483 } |
| 484 } |
| 485 |
| 380 void BluetoothLowEnergyWrapperFake::SimulateGattCharacteristicReadError( | 486 void BluetoothLowEnergyWrapperFake::SimulateGattCharacteristicReadError( |
| 381 GattCharacteristic* characteristic, | 487 GattCharacteristic* characteristic, |
| 382 HRESULT error) { | 488 HRESULT error) { |
| 383 CHECK(characteristic); | 489 CHECK(characteristic); |
| 384 characteristic->read_errors.push_back(error); | 490 characteristic->read_errors.push_back(error); |
| 385 } | 491 } |
| 386 | 492 |
| 387 void BluetoothLowEnergyWrapperFake::SimulateGattCharacteristicWriteError( | 493 void BluetoothLowEnergyWrapperFake::SimulateGattCharacteristicWriteError( |
| 388 GattCharacteristic* characteristic, | 494 GattCharacteristic* characteristic, |
| 389 HRESULT error) { | 495 HRESULT error) { |
| 390 CHECK(characteristic); | 496 CHECK(characteristic); |
| 391 characteristic->write_errors.push_back(error); | 497 characteristic->write_errors.push_back(error); |
| 392 } | 498 } |
| 393 | 499 |
| 500 void BluetoothLowEnergyWrapperFake::SimulateGattCharacteristicSetNotifyError( |
| 501 GattCharacteristic* characteristic, |
| 502 HRESULT error) { |
| 503 CHECK(characteristic); |
| 504 characteristic->notify_errors.push_back(error); |
| 505 } |
| 506 |
| 394 void BluetoothLowEnergyWrapperFake::SimulateGattDescriptor( | 507 void BluetoothLowEnergyWrapperFake::SimulateGattDescriptor( |
| 395 std::string device_address, | 508 std::string device_address, |
| 396 GattCharacteristic* characteristic, | 509 GattCharacteristic* characteristic, |
| 397 const BTH_LE_UUID& uuid) { | 510 const BTH_LE_UUID& uuid) { |
| 398 scoped_ptr<GattDescriptor> descriptor(new GattDescriptor()); | 511 scoped_ptr<GattDescriptor> descriptor(new GattDescriptor()); |
| 399 descriptor->descriptor_info.reset(new BTH_LE_GATT_DESCRIPTOR[1]); | 512 descriptor->descriptor_info.reset(new BTH_LE_GATT_DESCRIPTOR[1]); |
| 400 descriptor->descriptor_info->DescriptorUuid = uuid; | 513 descriptor->descriptor_info->DescriptorUuid = uuid; |
| 401 descriptor->descriptor_info->AttributeHandle = | 514 descriptor->descriptor_info->AttributeHandle = |
| 402 GenerateAUniqueAttributeHandle(device_address); | 515 GenerateAUniqueAttributeHandle(device_address); |
| 403 characteristic->included_descriptors[std::to_string( | 516 characteristic->included_descriptors[std::to_string( |
| 404 descriptor->descriptor_info->AttributeHandle)] = std::move(descriptor); | 517 descriptor->descriptor_info->AttributeHandle)] = std::move(descriptor); |
| 405 } | 518 } |
| 406 | 519 |
| 520 GattDescriptor* BluetoothLowEnergyWrapperFake::GetSimulatedDescriptor( |
| 521 GattCharacteristic* parent_characteristic, |
| 522 std::string attribute_handle) { |
| 523 GattDescriptorsMap::const_iterator it = |
| 524 parent_characteristic->included_descriptors.find(attribute_handle); |
| 525 if (it != parent_characteristic->included_descriptors.end()) |
| 526 return it->second.get(); |
| 527 return nullptr; |
| 528 } |
| 529 |
| 530 void BluetoothLowEnergyWrapperFake::SimulateGattDescriptorWrite( |
| 531 GattDescriptor* descriptor, |
| 532 const std::vector<uint8_t>& value) { |
| 533 ULONG length = (ULONG)(sizeof(BTH_LE_GATT_DESCRIPTOR_VALUE) + value.size()); |
| 534 descriptor->value.reset((BTH_LE_GATT_DESCRIPTOR_VALUE*)(new UCHAR[length])); |
| 535 descriptor->value->DataSize = (ULONG)value.size(); |
| 536 for (size_t i = 0; i < value.size(); i++) |
| 537 descriptor->value->Data[i] = value[i]; |
| 538 if (observer_) |
| 539 observer_->OnWriteGattDescriptorValue(descriptor->value.get()); |
| 540 } |
| 541 |
| 542 void BluetoothLowEnergyWrapperFake::SimulateGattDescriptorWriteError( |
| 543 GattDescriptor* descriptor, |
| 544 HRESULT error) { |
| 545 descriptor->write_errors.push_back(error); |
| 546 } |
| 547 |
| 407 void BluetoothLowEnergyWrapperFake::AddObserver(Observer* observer) { | 548 void BluetoothLowEnergyWrapperFake::AddObserver(Observer* observer) { |
| 408 observer_ = observer; | 549 observer_ = observer; |
| 409 } | 550 } |
| 410 | 551 |
| 411 GattCharacteristic* | 552 GattCharacteristic* |
| 412 BluetoothLowEnergyWrapperFake::GetSimulatedGattCharacteristic( | 553 BluetoothLowEnergyWrapperFake::GetSimulatedGattCharacteristic( |
| 413 base::FilePath& service_path, | 554 base::FilePath& service_path, |
| 414 const PBTH_LE_GATT_CHARACTERISTIC characteristic) { | 555 const PBTH_LE_GATT_CHARACTERISTIC characteristic) { |
| 415 base::string16 device_address = | 556 base::string16 device_address = |
| 416 ExtractDeviceAddressFromDevicePath(service_path.value()); | 557 ExtractDeviceAddressFromDevicePath(service_path.value()); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 506 } | 647 } |
| 507 | 648 |
| 508 std::string BluetoothLowEnergyWrapperFake::BluetoothAddressToCanonicalString( | 649 std::string BluetoothLowEnergyWrapperFake::BluetoothAddressToCanonicalString( |
| 509 const BLUETOOTH_ADDRESS& btha) { | 650 const BLUETOOTH_ADDRESS& btha) { |
| 510 std::string result = base::StringPrintf( | 651 std::string result = base::StringPrintf( |
| 511 "%02X:%02X:%02X:%02X:%02X:%02X", btha.rgBytes[5], btha.rgBytes[4], | 652 "%02X:%02X:%02X:%02X:%02X:%02X", btha.rgBytes[5], btha.rgBytes[4], |
| 512 btha.rgBytes[3], btha.rgBytes[2], btha.rgBytes[1], btha.rgBytes[0]); | 653 btha.rgBytes[3], btha.rgBytes[2], btha.rgBytes[1], btha.rgBytes[0]); |
| 513 return result; | 654 return result; |
| 514 } | 655 } |
| 515 | 656 |
| 657 GattDescriptor* BluetoothLowEnergyWrapperFake::GetCCCDescriptor( |
| 658 GattCharacteristic* characteristic) { |
| 659 for (const auto& d : characteristic->included_descriptors) { |
| 660 const BTH_LE_UUID* uuid = &(d.second->descriptor_info->DescriptorUuid); |
| 661 if (uuid->IsShortUuid) |
| 662 continue; |
| 663 |
| 664 std::string uuid_string = base::StringPrintf( |
| 665 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", |
| 666 uuid->Value.LongUuid.Data1, uuid->Value.LongUuid.Data2, |
| 667 uuid->Value.LongUuid.Data3, uuid->Value.LongUuid.Data4[0], |
| 668 uuid->Value.LongUuid.Data4[1], uuid->Value.LongUuid.Data4[2], |
| 669 uuid->Value.LongUuid.Data4[3], uuid->Value.LongUuid.Data4[4], |
| 670 uuid->Value.LongUuid.Data4[5], uuid->Value.LongUuid.Data4[6], |
| 671 uuid->Value.LongUuid.Data4[7]); |
| 672 if (uuid_string != "00002902-0000-1000-8000-00805f9b34fb") |
| 673 continue; |
| 674 |
| 675 return d.second.get(); |
| 676 } |
| 677 |
| 678 return nullptr; |
| 679 } |
| 680 |
| 516 } // namespace win | 681 } // namespace win |
| 517 } // namespace device | 682 } // namespace device |
| OLD | NEW |