Revert 264226 "Reduce dependency of TiclInvalidationService on P..."
[chromium-blink-merge.git] / device / bluetooth / bluetooth_service_record_win.cc
blob48f87232ab42a23e5f3794904869a1f6c08f6858
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.
5 #include "device/bluetooth/bluetooth_service_record_win.h"
7 #include <string>
9 #include "base/basictypes.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/stringprintf.h"
12 #include "device/bluetooth/bluetooth_init_win.h"
13 #include "device/bluetooth/bluetooth_uuid.h"
15 namespace {
17 const uint16 kProtocolDescriptorListId = 4;
18 const uint16 kRfcommUuid = 3;
19 const uint16 kUuidId = 1;
21 bool AdvanceToSdpType(const SDP_ELEMENT_DATA& sequence_data,
22 SDP_TYPE type,
23 HBLUETOOTH_CONTAINER_ELEMENT* element,
24 SDP_ELEMENT_DATA* sdp_data) {
25 while (ERROR_SUCCESS == BluetoothSdpGetContainerElementData(
26 sequence_data.data.sequence.value,
27 sequence_data.data.sequence.length,
28 element,
29 sdp_data)) {
30 if (sdp_data->type == type) {
31 return true;
34 return false;
37 void ExtractChannels(const SDP_ELEMENT_DATA& protocol_descriptor_list_data,
38 bool* supports_rfcomm,
39 uint8* rfcomm_channel) {
40 HBLUETOOTH_CONTAINER_ELEMENT sequence_element = NULL;
41 SDP_ELEMENT_DATA sequence_data;
42 while (AdvanceToSdpType(protocol_descriptor_list_data,
43 SDP_TYPE_SEQUENCE,
44 &sequence_element,
45 &sequence_data)) {
46 HBLUETOOTH_CONTAINER_ELEMENT inner_sequence_element = NULL;
47 SDP_ELEMENT_DATA inner_sequence_data;
48 if (AdvanceToSdpType(sequence_data,
49 SDP_TYPE_UUID,
50 &inner_sequence_element,
51 &inner_sequence_data) &&
52 inner_sequence_data.data.uuid32 == kRfcommUuid &&
53 AdvanceToSdpType(sequence_data,
54 SDP_TYPE_UINT,
55 &inner_sequence_element,
56 &inner_sequence_data) &&
57 inner_sequence_data.specificType == SDP_ST_UINT8) {
58 *rfcomm_channel = inner_sequence_data.data.uint8;
59 *supports_rfcomm = true;
64 void ExtractUuid(const SDP_ELEMENT_DATA& uuid_data,
65 device::BluetoothUUID* uuid) {
66 HBLUETOOTH_CONTAINER_ELEMENT inner_uuid_element = NULL;
67 SDP_ELEMENT_DATA inner_uuid_data;
68 if (AdvanceToSdpType(uuid_data,
69 SDP_TYPE_UUID,
70 &inner_uuid_element,
71 &inner_uuid_data)) {
72 if (inner_uuid_data.specificType == SDP_ST_UUID16) {
73 std::string uuid_hex =
74 base::StringPrintf("%04x", inner_uuid_data.data.uuid16);
75 *uuid = device::BluetoothUUID(uuid_hex);
76 } else if (inner_uuid_data.specificType == SDP_ST_UUID32) {
77 std::string uuid_hex =
78 base::StringPrintf("%08x", inner_uuid_data.data.uuid32);
79 *uuid = device::BluetoothUUID(uuid_hex);
80 } else if (inner_uuid_data.specificType == SDP_ST_UUID128) {
81 *uuid = device::BluetoothUUID(base::StringPrintf(
82 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
83 inner_uuid_data.data.uuid128.Data1,
84 inner_uuid_data.data.uuid128.Data2,
85 inner_uuid_data.data.uuid128.Data3,
86 inner_uuid_data.data.uuid128.Data4[0],
87 inner_uuid_data.data.uuid128.Data4[1],
88 inner_uuid_data.data.uuid128.Data4[2],
89 inner_uuid_data.data.uuid128.Data4[3],
90 inner_uuid_data.data.uuid128.Data4[4],
91 inner_uuid_data.data.uuid128.Data4[5],
92 inner_uuid_data.data.uuid128.Data4[6],
93 inner_uuid_data.data.uuid128.Data4[7]));
94 } else {
95 *uuid = device::BluetoothUUID();
100 BTH_ADDR ConvertToBthAddr(const std::string& address) {
101 BTH_ADDR bth_addr = 0;
102 std::string numbers_only;
103 for (int i = 0; i < 6; ++i) {
104 numbers_only += address.substr(i * 3, 2);
107 std::vector<uint8> address_bytes;
108 base::HexStringToBytes(numbers_only, &address_bytes);
109 int byte_position = 0;
110 for (std::vector<uint8>::reverse_iterator iter = address_bytes.rbegin();
111 iter != address_bytes.rend();
112 ++iter) {
113 bth_addr += *iter * pow(256.0, byte_position);
114 byte_position++;
116 return bth_addr;
119 } // namespace
121 namespace device {
123 BluetoothServiceRecordWin::BluetoothServiceRecordWin(
124 const std::string& name,
125 const std::string& address,
126 uint64 blob_size,
127 uint8* blob_data) : bth_addr_(ConvertToBthAddr(address)) {
128 name_ = name;
129 address_ = address;
130 supports_rfcomm_ = false;
131 SDP_ELEMENT_DATA protocol_descriptor_list_data;
132 if (ERROR_SUCCESS == BluetoothSdpGetAttributeValue(
133 blob_data,
134 blob_size,
135 kProtocolDescriptorListId,
136 &protocol_descriptor_list_data)) {
137 ExtractChannels(protocol_descriptor_list_data,
138 &supports_rfcomm_,
139 &rfcomm_channel_);
141 SDP_ELEMENT_DATA uuid_data;
142 if (ERROR_SUCCESS == BluetoothSdpGetAttributeValue(
143 blob_data,
144 blob_size,
145 kUuidId,
146 &uuid_data)) {
147 ExtractUuid(uuid_data, &uuid_);
151 } // namespace device