bluetooth_remote_gatt_service_winrt.cc 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. // Copyright 2018 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. #include "device/bluetooth/bluetooth_remote_gatt_service_winrt.h"
  5. #include <windows.foundation.collections.h>
  6. #include <utility>
  7. #include "base/logging.h"
  8. #include "base/memory/ptr_util.h"
  9. #include "base/strings/stringprintf.h"
  10. #include "device/bluetooth/bluetooth_device.h"
  11. #include "device/bluetooth/bluetooth_gatt_discoverer_winrt.h"
  12. namespace device {
  13. namespace {
  14. using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
  15. IGattDeviceService;
  16. using Microsoft::WRL::ComPtr;
  17. } // namespace
  18. // static
  19. std::unique_ptr<BluetoothRemoteGattServiceWinrt>
  20. BluetoothRemoteGattServiceWinrt::Create(
  21. BluetoothDevice* device,
  22. ComPtr<IGattDeviceService> gatt_service) {
  23. DCHECK(gatt_service);
  24. GUID guid;
  25. HRESULT hr = gatt_service->get_Uuid(&guid);
  26. if (FAILED(hr)) {
  27. DVLOG(2) << "Getting UUID failed: " << logging::SystemErrorCodeToString(hr);
  28. return nullptr;
  29. }
  30. uint16_t attribute_handle;
  31. hr = gatt_service->get_AttributeHandle(&attribute_handle);
  32. if (FAILED(hr)) {
  33. DVLOG(2) << "Getting AttributeHandle failed: "
  34. << logging::SystemErrorCodeToString(hr);
  35. return nullptr;
  36. }
  37. return base::WrapUnique(new BluetoothRemoteGattServiceWinrt(
  38. device, std::move(gatt_service), BluetoothUUID(guid), attribute_handle));
  39. }
  40. BluetoothRemoteGattServiceWinrt::~BluetoothRemoteGattServiceWinrt() = default;
  41. std::string BluetoothRemoteGattServiceWinrt::GetIdentifier() const {
  42. return identifier_;
  43. }
  44. BluetoothUUID BluetoothRemoteGattServiceWinrt::GetUUID() const {
  45. return uuid_;
  46. }
  47. bool BluetoothRemoteGattServiceWinrt::IsPrimary() const {
  48. return true;
  49. }
  50. BluetoothDevice* BluetoothRemoteGattServiceWinrt::GetDevice() const {
  51. return device_;
  52. }
  53. std::vector<BluetoothRemoteGattService*>
  54. BluetoothRemoteGattServiceWinrt::GetIncludedServices() const {
  55. NOTIMPLEMENTED();
  56. return {};
  57. }
  58. void BluetoothRemoteGattServiceWinrt::UpdateCharacteristics(
  59. BluetoothGattDiscovererWinrt* gatt_discoverer) {
  60. const auto* gatt_characteristics =
  61. gatt_discoverer->GetCharacteristics(attribute_handle_);
  62. DCHECK(gatt_characteristics);
  63. // Instead of clearing out |characteristics_| and creating each characteristic
  64. // from scratch, we create a new map and move already existing characteristics
  65. // into it in order to preserve pointer stability.
  66. CharacteristicMap characteristics;
  67. for (const auto& gatt_characteristic : *gatt_characteristics) {
  68. auto characteristic = BluetoothRemoteGattCharacteristicWinrt::Create(
  69. this, gatt_characteristic.Get());
  70. if (!characteristic)
  71. continue;
  72. std::string identifier = characteristic->GetIdentifier();
  73. auto iter = characteristics_.find(identifier);
  74. if (iter != characteristics_.end()) {
  75. iter = characteristics.emplace(std::move(*iter)).first;
  76. } else {
  77. iter = characteristics
  78. .emplace(std::move(identifier), std::move(characteristic))
  79. .first;
  80. }
  81. static_cast<BluetoothRemoteGattCharacteristicWinrt*>(iter->second.get())
  82. ->UpdateDescriptors(gatt_discoverer);
  83. }
  84. std::swap(characteristics, characteristics_);
  85. SetDiscoveryComplete(true);
  86. }
  87. IGattDeviceService*
  88. BluetoothRemoteGattServiceWinrt::GetDeviceServiceForTesting() {
  89. return gatt_service_.Get();
  90. }
  91. // static
  92. uint8_t BluetoothRemoteGattServiceWinrt::ToProtocolError(
  93. GattErrorCode error_code) {
  94. switch (error_code) {
  95. case GATT_ERROR_UNKNOWN:
  96. return 0xF0;
  97. case GATT_ERROR_FAILED:
  98. return 0x01;
  99. case GATT_ERROR_IN_PROGRESS:
  100. return 0x09;
  101. case GATT_ERROR_INVALID_LENGTH:
  102. return 0x0D;
  103. case GATT_ERROR_NOT_PERMITTED:
  104. return 0x02;
  105. case GATT_ERROR_NOT_AUTHORIZED:
  106. return 0x08;
  107. case GATT_ERROR_NOT_PAIRED:
  108. return 0x0F;
  109. case GATT_ERROR_NOT_SUPPORTED:
  110. return 0x06;
  111. }
  112. NOTREACHED();
  113. return 0x00;
  114. }
  115. BluetoothRemoteGattServiceWinrt::BluetoothRemoteGattServiceWinrt(
  116. BluetoothDevice* device,
  117. ComPtr<IGattDeviceService> gatt_service,
  118. BluetoothUUID uuid,
  119. uint16_t attribute_handle)
  120. : device_(device),
  121. gatt_service_(std::move(gatt_service)),
  122. uuid_(std::move(uuid)),
  123. attribute_handle_(attribute_handle),
  124. identifier_(base::StringPrintf("%s/%s_%04x",
  125. device_->GetIdentifier().c_str(),
  126. uuid_.value().c_str(),
  127. attribute_handle)) {}
  128. } // namespace device