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