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 "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"
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
)
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();
41 return base::UTF8ToUTF16(name
);
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
) {
52 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_COMPUTER
,
55 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_PHONE
,
58 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_MODEM
,
61 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_AUDIO
,
63 case DEVICE_CAR_AUDIO
:
64 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_CAR_AUDIO
,
67 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_VIDEO
,
70 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_JOYSTICK
,
73 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_GAMEPAD
,
76 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_KEYBOARD
,
79 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_MOUSE
,
82 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_TABLET
,
84 case DEVICE_KEYBOARD_MOUSE_COMBO
:
85 return l10n_util::GetStringFUTF16(
86 IDS_BLUETOOTH_DEVICE_KEYBOARD_MOUSE_COMBO
, address_utf16
);
88 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_UNKNOWN
,
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) {
98 // Computer major device class.
99 return DEVICE_COMPUTER
;
101 // Phone major device class.
102 switch ((bluetooth_class
& 0xfc) >> 2) {
106 // Cellular, cordless and smart phones.
110 // Modems: wired or voice gateway and common ISDN access.
115 // Audio major device class.
116 switch ((bluetooth_class
& 0xfc) >> 2) {
119 return DEVICE_CAR_AUDIO
;
133 // Peripheral major device class.
134 switch ((bluetooth_class
& 0xc0) >> 6) {
136 // "Not a keyboard or pointing device."
137 switch ((bluetooth_class
& 0x01e) >> 2) {
140 return DEVICE_JOYSTICK
;
143 return DEVICE_GAMEPAD
;
145 return DEVICE_PERIPHERAL
;
150 return DEVICE_KEYBOARD
;
153 switch ((bluetooth_class
& 0x01e) >> 2) {
156 return DEVICE_TABLET
;
164 return DEVICE_KEYBOARD_MOUSE_COMBO
;
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")
181 // Microsoft "Microsoft Bluetooth Notebook Mouse 5000", model X807028-001
182 if (type
== DEVICE_MOUSE
&& vendor
== "7C:ED:8D")
184 // Sony PlayStation Dualshock3
188 // TODO: Move this database into a config file.
193 bool BluetoothDevice::IsTrustable() const {
194 // Sony PlayStation Dualshock3
195 if ((GetVendorID() == 0x054c && GetProductID() == 0x0268 &&
196 GetDeviceName() == "PLAYSTATION(R)3 Controller"))
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
);
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())
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;
238 // All separators in the input |address| should be consistent.
239 if (canonicalized
[i
] != separator
)
240 return std::string();
242 canonicalized
[i
] = ':';
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
))
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
);
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