bluetooth_service_record_win.cc 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. // Copyright (c) 2013 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_service_record_win.h"
  5. #include <math.h>
  6. #include <string>
  7. #include "base/strings/string_number_conversions.h"
  8. #include "base/strings/stringprintf.h"
  9. #include "device/bluetooth/bluetooth_init_win.h"
  10. #include "device/bluetooth/public/cpp/bluetooth_uuid.h"
  11. namespace {
  12. const uint16_t kProtocolDescriptorListId = 4;
  13. const uint16_t kRfcommUuid = 3;
  14. const uint16_t kUuidId = 1;
  15. bool AdvanceToSdpType(const SDP_ELEMENT_DATA& sequence_data,
  16. SDP_TYPE type,
  17. HBLUETOOTH_CONTAINER_ELEMENT* element,
  18. SDP_ELEMENT_DATA* sdp_data) {
  19. while (ERROR_SUCCESS == BluetoothSdpGetContainerElementData(
  20. sequence_data.data.sequence.value,
  21. sequence_data.data.sequence.length,
  22. element,
  23. sdp_data)) {
  24. if (sdp_data->type == type) {
  25. return true;
  26. }
  27. }
  28. return false;
  29. }
  30. void ExtractChannels(const SDP_ELEMENT_DATA& protocol_descriptor_list_data,
  31. bool* supports_rfcomm,
  32. uint8_t* rfcomm_channel) {
  33. HBLUETOOTH_CONTAINER_ELEMENT sequence_element = NULL;
  34. SDP_ELEMENT_DATA sequence_data;
  35. while (AdvanceToSdpType(protocol_descriptor_list_data,
  36. SDP_TYPE_SEQUENCE,
  37. &sequence_element,
  38. &sequence_data)) {
  39. HBLUETOOTH_CONTAINER_ELEMENT inner_sequence_element = NULL;
  40. SDP_ELEMENT_DATA inner_sequence_data;
  41. if (AdvanceToSdpType(sequence_data,
  42. SDP_TYPE_UUID,
  43. &inner_sequence_element,
  44. &inner_sequence_data) &&
  45. inner_sequence_data.data.uuid32 == kRfcommUuid &&
  46. AdvanceToSdpType(sequence_data,
  47. SDP_TYPE_UINT,
  48. &inner_sequence_element,
  49. &inner_sequence_data) &&
  50. inner_sequence_data.specificType == SDP_ST_UINT8) {
  51. *rfcomm_channel = inner_sequence_data.data.uint8;
  52. *supports_rfcomm = true;
  53. }
  54. }
  55. }
  56. void ExtractUuid(const SDP_ELEMENT_DATA& uuid_data,
  57. device::BluetoothUUID* uuid) {
  58. HBLUETOOTH_CONTAINER_ELEMENT inner_uuid_element = NULL;
  59. SDP_ELEMENT_DATA inner_uuid_data;
  60. if (AdvanceToSdpType(uuid_data,
  61. SDP_TYPE_UUID,
  62. &inner_uuid_element,
  63. &inner_uuid_data)) {
  64. if (inner_uuid_data.specificType == SDP_ST_UUID16) {
  65. std::string uuid_hex =
  66. base::StringPrintf("%04x", inner_uuid_data.data.uuid16);
  67. *uuid = device::BluetoothUUID(uuid_hex);
  68. } else if (inner_uuid_data.specificType == SDP_ST_UUID32) {
  69. std::string uuid_hex =
  70. base::StringPrintf("%08lx", inner_uuid_data.data.uuid32);
  71. *uuid = device::BluetoothUUID(uuid_hex);
  72. } else if (inner_uuid_data.specificType == SDP_ST_UUID128) {
  73. *uuid = device::BluetoothUUID(base::StringPrintf(
  74. "%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
  75. inner_uuid_data.data.uuid128.Data1,
  76. inner_uuid_data.data.uuid128.Data2,
  77. inner_uuid_data.data.uuid128.Data3,
  78. inner_uuid_data.data.uuid128.Data4[0],
  79. inner_uuid_data.data.uuid128.Data4[1],
  80. inner_uuid_data.data.uuid128.Data4[2],
  81. inner_uuid_data.data.uuid128.Data4[3],
  82. inner_uuid_data.data.uuid128.Data4[4],
  83. inner_uuid_data.data.uuid128.Data4[5],
  84. inner_uuid_data.data.uuid128.Data4[6],
  85. inner_uuid_data.data.uuid128.Data4[7]));
  86. } else {
  87. *uuid = device::BluetoothUUID();
  88. }
  89. }
  90. }
  91. BTH_ADDR ConvertToBthAddr(const std::string& address) {
  92. BTH_ADDR bth_addr = 0;
  93. std::string numbers_only;
  94. for (int i = 0; i < 6; ++i) {
  95. numbers_only += address.substr(i * 3, 2);
  96. }
  97. std::vector<uint8_t> address_bytes;
  98. base::HexStringToBytes(numbers_only, &address_bytes);
  99. int byte_position = 0;
  100. for (std::vector<uint8_t>::reverse_iterator iter = address_bytes.rbegin();
  101. iter != address_bytes.rend(); ++iter) {
  102. bth_addr += *iter * pow(256.0, byte_position);
  103. byte_position++;
  104. }
  105. return bth_addr;
  106. }
  107. } // namespace
  108. namespace device {
  109. BluetoothServiceRecordWin::BluetoothServiceRecordWin(
  110. const std::string& device_address,
  111. const std::string& name,
  112. const std::vector<uint8_t>& sdp_bytes,
  113. const BluetoothUUID& gatt_uuid)
  114. : device_bth_addr_(ConvertToBthAddr(device_address)),
  115. device_address_(device_address),
  116. name_(name),
  117. uuid_(gatt_uuid),
  118. supports_rfcomm_(false),
  119. rfcomm_channel_(0xFF) {
  120. // Bluetooth 2.0
  121. if (sdp_bytes.size() > 0) {
  122. LPBYTE blob_data = const_cast<LPBYTE>(&sdp_bytes[0]);
  123. ULONG blob_size = static_cast<ULONG>(sdp_bytes.size());
  124. SDP_ELEMENT_DATA protocol_descriptor_list_data;
  125. if (ERROR_SUCCESS ==
  126. BluetoothSdpGetAttributeValue(blob_data,
  127. blob_size,
  128. kProtocolDescriptorListId,
  129. &protocol_descriptor_list_data)) {
  130. ExtractChannels(
  131. protocol_descriptor_list_data, &supports_rfcomm_, &rfcomm_channel_);
  132. }
  133. SDP_ELEMENT_DATA uuid_data;
  134. if (ERROR_SUCCESS == BluetoothSdpGetAttributeValue(
  135. blob_data, blob_size, kUuidId, &uuid_data)) {
  136. ExtractUuid(uuid_data, &uuid_);
  137. }
  138. }
  139. }
  140. bool BluetoothServiceRecordWin::IsEqual(
  141. const BluetoothServiceRecordWin& other) {
  142. return device_address_ == other.device_address_ && name_ == other.name_ &&
  143. uuid_ == other.uuid_ && supports_rfcomm_ == other.supports_rfcomm_ &&
  144. rfcomm_channel_ == other.rfcomm_channel_;
  145. }
  146. } // namespace device