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"
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"
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
)
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();
42 return base::UTF8ToUTF16(name
);
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
) {
53 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_COMPUTER
,
56 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_PHONE
,
59 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_MODEM
,
62 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_AUDIO
,
64 case DEVICE_CAR_AUDIO
:
65 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_CAR_AUDIO
,
68 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_VIDEO
,
71 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_JOYSTICK
,
74 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_GAMEPAD
,
77 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_KEYBOARD
,
80 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_MOUSE
,
83 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_TABLET
,
85 case DEVICE_KEYBOARD_MOUSE_COMBO
:
86 return l10n_util::GetStringFUTF16(
87 IDS_BLUETOOTH_DEVICE_KEYBOARD_MOUSE_COMBO
, address_utf16
);
89 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_UNKNOWN
,
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) {
99 // Computer major device class.
100 return DEVICE_COMPUTER
;
102 // Phone major device class.
103 switch ((bluetooth_class
& 0xfc) >> 2) {
107 // Cellular, cordless and smart phones.
111 // Modems: wired or voice gateway and common ISDN access.
116 // Audio major device class.
117 switch ((bluetooth_class
& 0xfc) >> 2) {
120 return DEVICE_CAR_AUDIO
;
134 // Peripheral major device class.
135 switch ((bluetooth_class
& 0xc0) >> 6) {
137 // "Not a keyboard or pointing device."
138 switch ((bluetooth_class
& 0x01e) >> 2) {
141 return DEVICE_JOYSTICK
;
144 return DEVICE_GAMEPAD
;
146 return DEVICE_PERIPHERAL
;
151 return DEVICE_KEYBOARD
;
154 switch ((bluetooth_class
& 0x01e) >> 2) {
157 return DEVICE_TABLET
;
165 return DEVICE_KEYBOARD_MOUSE_COMBO
;
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")
182 // Microsoft "Microsoft Bluetooth Notebook Mouse 5000", model X807028-001
183 if (type
== DEVICE_MOUSE
&& vendor
== "7C:ED:8D")
185 // Sony PlayStation Dualshock3
189 // TODO: Move this database into a config file.
194 bool BluetoothDevice::IsTrustable() const {
195 // Sony PlayStation Dualshock3
196 if ((GetVendorID() == 0x054c && GetProductID() == 0x0268 &&
197 GetDeviceName() == "PLAYSTATION(R)3 Controller"))
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
);
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())
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;
239 // All separators in the input |address| should be consistent.
240 if (canonicalized
[i
] != separator
)
241 return std::string();
243 canonicalized
[i
] = ':';
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
))
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
);
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