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) 9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/strings/string_util.h" 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 11c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "device/bluetooth/bluetooth_gatt_service.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "grit/device_bluetooth_strings.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace device { 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)BluetoothDevice::BluetoothDevice() { 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BluetoothDevice::~BluetoothDevice() { 21c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch STLDeleteValues(&gatt_services_); 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 BluetoothDevice::GetName() const { 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string name = GetDeviceName(); 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!name.empty()) { 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return base::UTF8ToUTF16(name); 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetAddressWithLocalizedDeviceTypeName(); 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 BluetoothDevice::GetAddressWithLocalizedDeviceTypeName() const { 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::string16 address_utf16 = base::UTF8ToUTF16(GetAddress()); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BluetoothDevice::DeviceType device_type = GetDeviceType(); 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (device_type) { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case DEVICE_COMPUTER: 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_COMPUTER, 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) address_utf16); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case DEVICE_PHONE: 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_PHONE, 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) address_utf16); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case DEVICE_MODEM: 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_MODEM, 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) address_utf16); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case DEVICE_AUDIO: 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_AUDIO, 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) address_utf16); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case DEVICE_CAR_AUDIO: 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_CAR_AUDIO, 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) address_utf16); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case DEVICE_VIDEO: 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_VIDEO, 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) address_utf16); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case DEVICE_JOYSTICK: 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_JOYSTICK, 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) address_utf16); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case DEVICE_GAMEPAD: 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_GAMEPAD, 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) address_utf16); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case DEVICE_KEYBOARD: 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_KEYBOARD, 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) address_utf16); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case DEVICE_MOUSE: 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_MOUSE, 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) address_utf16); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case DEVICE_TABLET: 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_TABLET, 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) address_utf16); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case DEVICE_KEYBOARD_MOUSE_COMBO: 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return l10n_util::GetStringFUTF16( 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IDS_BLUETOOTH_DEVICE_KEYBOARD_MOUSE_COMBO, address_utf16); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_UNKNOWN, 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) address_utf16); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BluetoothDevice::DeviceType BluetoothDevice::GetDeviceType() const { 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // https://www.bluetooth.org/Technical/AssignedNumbers/baseband.htm 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint32 bluetooth_class = GetBluetoothClass(); 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) switch ((bluetooth_class & 0x1f00) >> 8) { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 0x01: 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Computer major device class. 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return DEVICE_COMPUTER; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 0x02: 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Phone major device class. 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) switch ((bluetooth_class & 0xfc) >> 2) { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 0x01: 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 0x02: 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 0x03: 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cellular, cordless and smart phones. 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return DEVICE_PHONE; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 0x04: 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 0x05: 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Modems: wired or voice gateway and common ISDN access. 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return DEVICE_MODEM; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 0x04: 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Audio major device class. 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) switch ((bluetooth_class & 0xfc) >> 2) { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 0x08: 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Car audio. 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return DEVICE_CAR_AUDIO; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 0x0b: 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 0x0c: 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 0x0d: 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 0x0e: 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 0x0f: 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 0x010: 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Video devices. 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return DEVICE_VIDEO; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return DEVICE_AUDIO; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 0x05: 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Peripheral major device class. 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) switch ((bluetooth_class & 0xc0) >> 6) { 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 0x00: 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // "Not a keyboard or pointing device." 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) switch ((bluetooth_class & 0x01e) >> 2) { 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 0x01: 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Joystick. 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return DEVICE_JOYSTICK; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 0x02: 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Gamepad. 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return DEVICE_GAMEPAD; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return DEVICE_PERIPHERAL; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 0x01: 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Keyboard. 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return DEVICE_KEYBOARD; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 0x02: 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Pointing device. 139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) switch ((bluetooth_class & 0x01e) >> 2) { 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 0x05: 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Digitizer tablet. 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return DEVICE_TABLET; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Mouse. 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return DEVICE_MOUSE; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 0x03: 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Combo device. 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return DEVICE_KEYBOARD_MOUSE_COMBO; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return DEVICE_UNKNOWN; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool BluetoothDevice::IsPairable() const { 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DeviceType type = GetDeviceType(); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Get the vendor part of the address: "00:11:22" for "00:11:22:33:44:55" 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string vendor = GetAddress().substr(0, 8); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Verbatim "Bluetooth Mouse", model 96674 165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (type == DEVICE_MOUSE && vendor == "00:12:A1") 166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return false; 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Microsoft "Microsoft Bluetooth Notebook Mouse 5000", model X807028-001 168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (type == DEVICE_MOUSE && vendor == "7C:ED:8D") 169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return false; 170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Sony PlayStation Dualshock3 171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (IsTrustable()) 172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return false; 173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // TODO: Move this database into a config file. 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool BluetoothDevice::IsTrustable() const { 180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Sony PlayStation Dualshock3 181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if ((GetVendorID() == 0x054c && GetProductID() == 0x0268 && 182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GetDeviceName() == "PLAYSTATION(R)3 Controller")) 183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return true; 184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return false; 186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 187cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 188c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochstd::vector<BluetoothGattService*> 189c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch BluetoothDevice::GetGattServices() const { 190c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch std::vector<BluetoothGattService*> services; 191c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch for (GattServiceMap::const_iterator iter = gatt_services_.begin(); 192c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch iter != gatt_services_.end(); ++iter) 193c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch services.push_back(iter->second); 194c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return services; 195c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 196c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 197c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochBluetoothGattService* BluetoothDevice::GetGattService( 198c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const std::string& identifier) const { 199c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch GattServiceMap::const_iterator iter = gatt_services_.find(identifier); 200c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (iter != gatt_services_.end()) 201c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return iter->second; 202c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return NULL; 203c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 204c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 205cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// static 206cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)std::string BluetoothDevice::CanonicalizeAddress(const std::string& address) { 207cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::string canonicalized = address; 208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (address.size() == 12) { 209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Might be an address in the format "1A2B3C4D5E6F". Add separators. 210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for (size_t i = 2; i < canonicalized.size(); i += 3) { 211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) canonicalized.insert(i, ":"); 212cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 213cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 215cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Verify that the length matches the canonical format "1A:2B:3C:4D:5E:6F". 216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const size_t kCanonicalAddressLength = 17; 217cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (canonicalized.size() != kCanonicalAddressLength) 218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return std::string(); 219cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 220cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const char separator = canonicalized[2]; 221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for (size_t i = 0; i < canonicalized.size(); ++i) { 222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool is_separator = (i + 1) % 3 == 0; 223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (is_separator) { 224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // All separators in the input |address| should be consistent. 225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (canonicalized[i] != separator) 226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return std::string(); 227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) canonicalized[i] = ':'; 229cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else { 230cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!IsHexDigit(canonicalized[i])) 231cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return std::string(); 232cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 233cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) canonicalized[i] = base::ToUpperASCII(canonicalized[i]); 234cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 235cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return canonicalized; 238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 239cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace device 241