bluetooth_device.cc revision c5cede9ae108bb15f6b7a8aea21c7e1fefa2834c
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "device/bluetooth/bluetooth_device.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string>
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
10c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "device/bluetooth/bluetooth_gatt_service.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "grit/device_bluetooth_strings.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace device {
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)BluetoothDevice::BluetoothDevice() {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BluetoothDevice::~BluetoothDevice() {
20c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  STLDeleteValues(&gatt_services_);
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 BluetoothDevice::GetName() const {
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string name = GetDeviceName();
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!name.empty()) {
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return base::UTF8ToUTF16(name);
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return GetAddressWithLocalizedDeviceTypeName();
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 BluetoothDevice::GetAddressWithLocalizedDeviceTypeName() const {
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::string16 address_utf16 = base::UTF8ToUTF16(GetAddress());
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BluetoothDevice::DeviceType device_type = GetDeviceType();
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (device_type) {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DEVICE_COMPUTER:
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_COMPUTER,
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                        address_utf16);
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DEVICE_PHONE:
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_PHONE,
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                        address_utf16);
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DEVICE_MODEM:
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_MODEM,
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                        address_utf16);
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DEVICE_AUDIO:
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_AUDIO,
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                        address_utf16);
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DEVICE_CAR_AUDIO:
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_CAR_AUDIO,
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                        address_utf16);
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DEVICE_VIDEO:
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_VIDEO,
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                        address_utf16);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DEVICE_JOYSTICK:
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_JOYSTICK,
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                        address_utf16);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DEVICE_GAMEPAD:
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_GAMEPAD,
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                        address_utf16);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DEVICE_KEYBOARD:
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_KEYBOARD,
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                        address_utf16);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DEVICE_MOUSE:
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_MOUSE,
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                        address_utf16);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DEVICE_TABLET:
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_TABLET,
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                        address_utf16);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DEVICE_KEYBOARD_MOUSE_COMBO:
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return l10n_util::GetStringFUTF16(
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          IDS_BLUETOOTH_DEVICE_KEYBOARD_MOUSE_COMBO, address_utf16);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_UNKNOWN,
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                        address_utf16);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BluetoothDevice::DeviceType BluetoothDevice::GetDeviceType() const {
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // https://www.bluetooth.org/Technical/AssignedNumbers/baseband.htm
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  uint32 bluetooth_class = GetBluetoothClass();
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  switch ((bluetooth_class & 0x1f00) >> 8) {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 0x01:
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Computer major device class.
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return DEVICE_COMPUTER;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 0x02:
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Phone major device class.
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      switch ((bluetooth_class & 0xfc) >> 2) {
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case 0x01:
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case 0x02:
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case 0x03:
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // Cellular, cordless and smart phones.
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          return DEVICE_PHONE;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case 0x04:
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case 0x05:
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // Modems: wired or voice gateway and common ISDN access.
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          return DEVICE_MODEM;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 0x04:
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Audio major device class.
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      switch ((bluetooth_class & 0xfc) >> 2) {
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case 0x08:
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // Car audio.
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          return DEVICE_CAR_AUDIO;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case 0x0b:
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case 0x0c:
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case 0x0d:
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case 0x0e:
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case 0x0f:
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case 0x010:
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // Video devices.
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          return DEVICE_VIDEO;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        default:
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          return DEVICE_AUDIO;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 0x05:
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Peripheral major device class.
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      switch ((bluetooth_class & 0xc0) >> 6) {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case 0x00:
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // "Not a keyboard or pointing device."
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          switch ((bluetooth_class & 0x01e) >> 2) {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            case 0x01:
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              // Joystick.
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              return DEVICE_JOYSTICK;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            case 0x02:
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              // Gamepad.
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              return DEVICE_GAMEPAD;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            default:
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              return DEVICE_PERIPHERAL;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          }
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case 0x01:
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // Keyboard.
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          return DEVICE_KEYBOARD;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case 0x02:
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // Pointing device.
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          switch ((bluetooth_class & 0x01e) >> 2) {
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            case 0x05:
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              // Digitizer tablet.
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              return DEVICE_TABLET;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            default:
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              // Mouse.
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              return DEVICE_MOUSE;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          }
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case 0x03:
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // Combo device.
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          return DEVICE_KEYBOARD_MOUSE_COMBO;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return DEVICE_UNKNOWN;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool BluetoothDevice::IsPairable() const {
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DeviceType type = GetDeviceType();
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Get the vendor part of the address: "00:11:22" for "00:11:22:33:44:55"
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string vendor = GetAddress().substr(0, 8);
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Verbatim "Bluetooth Mouse", model 96674
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if ((type == DEVICE_MOUSE && vendor == "00:12:A1") ||
165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Microsoft "Microsoft Bluetooth Notebook Mouse 5000", model X807028-001
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      (type == DEVICE_MOUSE && vendor == "7C:ED:8D"))
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return false;
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // TODO: Move this database into a config file.
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return true;
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
173c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochstd::vector<BluetoothGattService*>
174c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    BluetoothDevice::GetGattServices() const {
175c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  std::vector<BluetoothGattService*> services;
176c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  for (GattServiceMap::const_iterator iter = gatt_services_.begin();
177c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch       iter != gatt_services_.end(); ++iter)
178c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    services.push_back(iter->second);
179c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return services;
180c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
181c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
182c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochBluetoothGattService* BluetoothDevice::GetGattService(
183c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    const std::string& identifier) const {
184c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  GattServiceMap::const_iterator iter = gatt_services_.find(identifier);
185c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (iter != gatt_services_.end())
186c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return iter->second;
187c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return NULL;
188c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
189c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace device
191