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/strings/string_util.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "device/bluetooth/bluetooth_gatt_service.h"
12 #include "grit/device_bluetooth_strings.h"
13 #include "ui/base/l10n/l10n_util.h"
17 BluetoothDevice::BluetoothDevice() {
20 BluetoothDevice::~BluetoothDevice() {
21 STLDeleteValues(&gatt_services_
);
24 base::string16
BluetoothDevice::GetName() const {
25 std::string name
= GetDeviceName();
27 return base::UTF8ToUTF16(name
);
29 return GetAddressWithLocalizedDeviceTypeName();
33 base::string16
BluetoothDevice::GetAddressWithLocalizedDeviceTypeName() const {
34 base::string16 address_utf16
= base::UTF8ToUTF16(GetAddress());
35 BluetoothDevice::DeviceType device_type
= GetDeviceType();
36 switch (device_type
) {
38 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_COMPUTER
,
41 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_PHONE
,
44 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_MODEM
,
47 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_AUDIO
,
49 case DEVICE_CAR_AUDIO
:
50 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_CAR_AUDIO
,
53 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_VIDEO
,
56 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_JOYSTICK
,
59 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_GAMEPAD
,
62 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_KEYBOARD
,
65 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_MOUSE
,
68 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_TABLET
,
70 case DEVICE_KEYBOARD_MOUSE_COMBO
:
71 return l10n_util::GetStringFUTF16(
72 IDS_BLUETOOTH_DEVICE_KEYBOARD_MOUSE_COMBO
, address_utf16
);
74 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_UNKNOWN
,
79 BluetoothDevice::DeviceType
BluetoothDevice::GetDeviceType() const {
80 // https://www.bluetooth.org/Technical/AssignedNumbers/baseband.htm
81 uint32 bluetooth_class
= GetBluetoothClass();
82 switch ((bluetooth_class
& 0x1f00) >> 8) {
84 // Computer major device class.
85 return DEVICE_COMPUTER
;
87 // Phone major device class.
88 switch ((bluetooth_class
& 0xfc) >> 2) {
92 // Cellular, cordless and smart phones.
96 // Modems: wired or voice gateway and common ISDN access.
101 // Audio major device class.
102 switch ((bluetooth_class
& 0xfc) >> 2) {
105 return DEVICE_CAR_AUDIO
;
119 // Peripheral major device class.
120 switch ((bluetooth_class
& 0xc0) >> 6) {
122 // "Not a keyboard or pointing device."
123 switch ((bluetooth_class
& 0x01e) >> 2) {
126 return DEVICE_JOYSTICK
;
129 return DEVICE_GAMEPAD
;
131 return DEVICE_PERIPHERAL
;
136 return DEVICE_KEYBOARD
;
139 switch ((bluetooth_class
& 0x01e) >> 2) {
142 return DEVICE_TABLET
;
150 return DEVICE_KEYBOARD_MOUSE_COMBO
;
155 return DEVICE_UNKNOWN
;
158 bool BluetoothDevice::IsPairable() const {
159 DeviceType type
= GetDeviceType();
161 // Get the vendor part of the address: "00:11:22" for "00:11:22:33:44:55"
162 std::string vendor
= GetAddress().substr(0, 8);
164 // Verbatim "Bluetooth Mouse", model 96674
165 if (type
== DEVICE_MOUSE
&& vendor
== "00:12:A1")
167 // Microsoft "Microsoft Bluetooth Notebook Mouse 5000", model X807028-001
168 if (type
== DEVICE_MOUSE
&& vendor
== "7C:ED:8D")
170 // Sony PlayStation Dualshock3
174 // TODO: Move this database into a config file.
179 bool BluetoothDevice::IsTrustable() const {
180 // Sony PlayStation Dualshock3
181 if ((GetVendorID() == 0x054c && GetProductID() == 0x0268 &&
182 GetDeviceName() == "PLAYSTATION(R)3 Controller"))
188 std::vector
<BluetoothGattService
*>
189 BluetoothDevice::GetGattServices() const {
190 std::vector
<BluetoothGattService
*> services
;
191 for (GattServiceMap::const_iterator iter
= gatt_services_
.begin();
192 iter
!= gatt_services_
.end(); ++iter
)
193 services
.push_back(iter
->second
);
197 BluetoothGattService
* BluetoothDevice::GetGattService(
198 const std::string
& identifier
) const {
199 GattServiceMap::const_iterator iter
= gatt_services_
.find(identifier
);
200 if (iter
!= gatt_services_
.end())
206 std::string
BluetoothDevice::CanonicalizeAddress(const std::string
& address
) {
207 std::string canonicalized
= address
;
208 if (address
.size() == 12) {
209 // Might be an address in the format "1A2B3C4D5E6F". Add separators.
210 for (size_t i
= 2; i
< canonicalized
.size(); i
+= 3) {
211 canonicalized
.insert(i
, ":");
215 // Verify that the length matches the canonical format "1A:2B:3C:4D:5E:6F".
216 const size_t kCanonicalAddressLength
= 17;
217 if (canonicalized
.size() != kCanonicalAddressLength
)
218 return std::string();
220 const char separator
= canonicalized
[2];
221 for (size_t i
= 0; i
< canonicalized
.size(); ++i
) {
222 bool is_separator
= (i
+ 1) % 3 == 0;
224 // All separators in the input |address| should be consistent.
225 if (canonicalized
[i
] != separator
)
226 return std::string();
228 canonicalized
[i
] = ':';
230 if (!IsHexDigit(canonicalized
[i
]))
231 return std::string();
233 canonicalized
[i
] = base::ToUpperASCII(canonicalized
[i
]);
237 return canonicalized
;
240 } // namespace device