service_resolver_64: Correctly check all the bytes of the service code.
[chromium-blink-merge.git] / device / bluetooth / bluetooth_device.cc
blobfe21162e9335f453e377960f70731698ea67fcb6
1 // Copyright (c) 2012 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_device.h"
7 #include <string>
9 #include "base/strings/string_util.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "base/values.h"
12 #include "device/bluetooth/bluetooth_gatt_service.h"
13 #include "grit/device_bluetooth_strings.h"
14 #include "ui/base/l10n/l10n_util.h"
16 namespace device {
18 BluetoothDevice::BluetoothDevice()
19 : services_data_(new base::DictionaryValue()) {}
21 BluetoothDevice::~BluetoothDevice() {
22 STLDeleteValues(&gatt_services_);
25 BluetoothDevice::ConnectionInfo::ConnectionInfo()
26 : rssi(kUnknownPower),
27 transmit_power(kUnknownPower),
28 max_transmit_power(kUnknownPower) {}
30 BluetoothDevice::ConnectionInfo::ConnectionInfo(
31 int rssi, int transmit_power, int max_transmit_power)
32 : rssi(rssi),
33 transmit_power(transmit_power),
34 max_transmit_power(max_transmit_power) {}
36 BluetoothDevice::ConnectionInfo::~ConnectionInfo() {}
38 base::string16 BluetoothDevice::GetName() const {
39 std::string name = GetDeviceName();
40 if (!name.empty()) {
41 return base::UTF8ToUTF16(name);
42 } else {
43 return GetAddressWithLocalizedDeviceTypeName();
47 base::string16 BluetoothDevice::GetAddressWithLocalizedDeviceTypeName() const {
48 base::string16 address_utf16 = base::UTF8ToUTF16(GetAddress());
49 BluetoothDevice::DeviceType device_type = GetDeviceType();
50 switch (device_type) {
51 case DEVICE_COMPUTER:
52 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_COMPUTER,
53 address_utf16);
54 case DEVICE_PHONE:
55 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_PHONE,
56 address_utf16);
57 case DEVICE_MODEM:
58 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_MODEM,
59 address_utf16);
60 case DEVICE_AUDIO:
61 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_AUDIO,
62 address_utf16);
63 case DEVICE_CAR_AUDIO:
64 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_CAR_AUDIO,
65 address_utf16);
66 case DEVICE_VIDEO:
67 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_VIDEO,
68 address_utf16);
69 case DEVICE_JOYSTICK:
70 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_JOYSTICK,
71 address_utf16);
72 case DEVICE_GAMEPAD:
73 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_GAMEPAD,
74 address_utf16);
75 case DEVICE_KEYBOARD:
76 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_KEYBOARD,
77 address_utf16);
78 case DEVICE_MOUSE:
79 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_MOUSE,
80 address_utf16);
81 case DEVICE_TABLET:
82 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_TABLET,
83 address_utf16);
84 case DEVICE_KEYBOARD_MOUSE_COMBO:
85 return l10n_util::GetStringFUTF16(
86 IDS_BLUETOOTH_DEVICE_KEYBOARD_MOUSE_COMBO, address_utf16);
87 default:
88 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_UNKNOWN,
89 address_utf16);
93 BluetoothDevice::DeviceType BluetoothDevice::GetDeviceType() const {
94 // https://www.bluetooth.org/Technical/AssignedNumbers/baseband.htm
95 uint32 bluetooth_class = GetBluetoothClass();
96 switch ((bluetooth_class & 0x1f00) >> 8) {
97 case 0x01:
98 // Computer major device class.
99 return DEVICE_COMPUTER;
100 case 0x02:
101 // Phone major device class.
102 switch ((bluetooth_class & 0xfc) >> 2) {
103 case 0x01:
104 case 0x02:
105 case 0x03:
106 // Cellular, cordless and smart phones.
107 return DEVICE_PHONE;
108 case 0x04:
109 case 0x05:
110 // Modems: wired or voice gateway and common ISDN access.
111 return DEVICE_MODEM;
113 break;
114 case 0x04:
115 // Audio major device class.
116 switch ((bluetooth_class & 0xfc) >> 2) {
117 case 0x08:
118 // Car audio.
119 return DEVICE_CAR_AUDIO;
120 case 0x0b:
121 case 0x0c:
122 case 0x0d:
123 case 0x0e:
124 case 0x0f:
125 case 0x010:
126 // Video devices.
127 return DEVICE_VIDEO;
128 default:
129 return DEVICE_AUDIO;
131 break;
132 case 0x05:
133 // Peripheral major device class.
134 switch ((bluetooth_class & 0xc0) >> 6) {
135 case 0x00:
136 // "Not a keyboard or pointing device."
137 switch ((bluetooth_class & 0x01e) >> 2) {
138 case 0x01:
139 // Joystick.
140 return DEVICE_JOYSTICK;
141 case 0x02:
142 // Gamepad.
143 return DEVICE_GAMEPAD;
144 default:
145 return DEVICE_PERIPHERAL;
147 break;
148 case 0x01:
149 // Keyboard.
150 return DEVICE_KEYBOARD;
151 case 0x02:
152 // Pointing device.
153 switch ((bluetooth_class & 0x01e) >> 2) {
154 case 0x05:
155 // Digitizer tablet.
156 return DEVICE_TABLET;
157 default:
158 // Mouse.
159 return DEVICE_MOUSE;
161 break;
162 case 0x03:
163 // Combo device.
164 return DEVICE_KEYBOARD_MOUSE_COMBO;
166 break;
169 return DEVICE_UNKNOWN;
172 bool BluetoothDevice::IsPairable() const {
173 DeviceType type = GetDeviceType();
175 // Get the vendor part of the address: "00:11:22" for "00:11:22:33:44:55"
176 std::string vendor = GetAddress().substr(0, 8);
178 // Verbatim "Bluetooth Mouse", model 96674
179 if (type == DEVICE_MOUSE && vendor == "00:12:A1")
180 return false;
181 // Microsoft "Microsoft Bluetooth Notebook Mouse 5000", model X807028-001
182 if (type == DEVICE_MOUSE && vendor == "7C:ED:8D")
183 return false;
184 // Sony PlayStation Dualshock3
185 if (IsTrustable())
186 return false;
188 // TODO: Move this database into a config file.
190 return true;
193 bool BluetoothDevice::IsTrustable() const {
194 // Sony PlayStation Dualshock3
195 if ((GetVendorID() == 0x054c && GetProductID() == 0x0268 &&
196 GetDeviceName() == "PLAYSTATION(R)3 Controller"))
197 return true;
199 return false;
202 std::vector<BluetoothGattService*>
203 BluetoothDevice::GetGattServices() const {
204 std::vector<BluetoothGattService*> services;
205 for (GattServiceMap::const_iterator iter = gatt_services_.begin();
206 iter != gatt_services_.end(); ++iter)
207 services.push_back(iter->second);
208 return services;
211 BluetoothGattService* BluetoothDevice::GetGattService(
212 const std::string& identifier) const {
213 GattServiceMap::const_iterator iter = gatt_services_.find(identifier);
214 if (iter != gatt_services_.end())
215 return iter->second;
216 return NULL;
219 // static
220 std::string BluetoothDevice::CanonicalizeAddress(const std::string& address) {
221 std::string canonicalized = address;
222 if (address.size() == 12) {
223 // Might be an address in the format "1A2B3C4D5E6F". Add separators.
224 for (size_t i = 2; i < canonicalized.size(); i += 3) {
225 canonicalized.insert(i, ":");
229 // Verify that the length matches the canonical format "1A:2B:3C:4D:5E:6F".
230 const size_t kCanonicalAddressLength = 17;
231 if (canonicalized.size() != kCanonicalAddressLength)
232 return std::string();
234 const char separator = canonicalized[2];
235 for (size_t i = 0; i < canonicalized.size(); ++i) {
236 bool is_separator = (i + 1) % 3 == 0;
237 if (is_separator) {
238 // All separators in the input |address| should be consistent.
239 if (canonicalized[i] != separator)
240 return std::string();
242 canonicalized[i] = ':';
243 } else {
244 if (!base::IsHexDigit(canonicalized[i]))
245 return std::string();
247 canonicalized[i] = base::ToUpperASCII(canonicalized[i]);
251 return canonicalized;
254 std::string BluetoothDevice::GetIdentifier() const { return GetAddress(); }
256 base::BinaryValue* BluetoothDevice::GetServiceData(
257 BluetoothUUID serviceUUID) const {
258 base::BinaryValue* value;
259 if (!services_data_->GetBinary(serviceUUID.value(), &value))
260 return NULL;
261 return value;
264 BluetoothDevice::UUIDList BluetoothDevice::GetServiceDataUUIDs() const {
265 std::vector<device::BluetoothUUID> uuids;
266 base::DictionaryValue::Iterator iter(*services_data_);
267 while (!iter.IsAtEnd()) {
268 BluetoothUUID uuid(iter.key());
269 uuids.push_back(uuid);
270 iter.Advance();
272 return uuids;
275 void BluetoothDevice::ClearServiceData() { services_data_->Clear(); }
277 void BluetoothDevice::SetServiceData(BluetoothUUID serviceUUID,
278 const char* buffer, size_t size) {
279 services_data_->Set(serviceUUID.value(),
280 base::BinaryValue::CreateWithCopiedBuffer(buffer, size));
283 } // namespace device