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. 4 5 #ifndef DEVICE_BLUETOOTH_BLUETOOTH_DEVICE_H_ 6 #define DEVICE_BLUETOOTH_BLUETOOTH_DEVICE_H_ 7 8 #include <map> 9 #include <string> 10 #include <vector> 11 12 #include "base/callback.h" 13 #include "base/memory/ref_counted.h" 14 #include "base/memory/scoped_vector.h" 15 #include "base/strings/string16.h" 16 #include "device/bluetooth/bluetooth_uuid.h" 17 #include "net/base/net_log.h" 18 19 namespace device { 20 21 class BluetoothGattConnection; 22 class BluetoothGattService; 23 class BluetoothSocket; 24 class BluetoothUUID; 25 26 // BluetoothDevice represents a remote Bluetooth device, both its properties and 27 // capabilities as discovered by a local adapter and actions that may be 28 // performed on the remove device such as pairing, connection and disconnection. 29 // 30 // The class is instantiated and managed by the BluetoothAdapter class 31 // and pointers should only be obtained from that class and not cached, 32 // instead use the GetAddress() method as a unique key for a device. 33 // 34 // Since the lifecycle of BluetoothDevice instances is managed by 35 // BluetoothAdapter, that class rather than this provides observer methods 36 // for devices coming and going, as well as properties being updated. 37 class BluetoothDevice { 38 public: 39 // Possible values that may be returned by GetVendorIDSource(), 40 // indicating different organisations that allocate the identifiers returned 41 // by GetVendorID(). 42 enum VendorIDSource { 43 VENDOR_ID_UNKNOWN, 44 VENDOR_ID_BLUETOOTH, 45 VENDOR_ID_USB 46 }; 47 48 // Possible values that may be returned by GetDeviceType(), representing 49 // different types of bluetooth device that we support or are aware of 50 // decoded from the bluetooth class information. 51 enum DeviceType { 52 DEVICE_UNKNOWN, 53 DEVICE_COMPUTER, 54 DEVICE_PHONE, 55 DEVICE_MODEM, 56 DEVICE_AUDIO, 57 DEVICE_CAR_AUDIO, 58 DEVICE_VIDEO, 59 DEVICE_PERIPHERAL, 60 DEVICE_JOYSTICK, 61 DEVICE_GAMEPAD, 62 DEVICE_KEYBOARD, 63 DEVICE_MOUSE, 64 DEVICE_TABLET, 65 DEVICE_KEYBOARD_MOUSE_COMBO 66 }; 67 68 // The value returned if the RSSI or transmit power cannot be read. 69 static const int kUnknownPower = 127; 70 71 // Possible errors passed back to an error callback function in case of a 72 // failed call to Connect(). 73 enum ConnectErrorCode { 74 ERROR_UNKNOWN, 75 ERROR_INPROGRESS, 76 ERROR_FAILED, 77 ERROR_AUTH_FAILED, 78 ERROR_AUTH_CANCELED, 79 ERROR_AUTH_REJECTED, 80 ERROR_AUTH_TIMEOUT, 81 ERROR_UNSUPPORTED_DEVICE 82 }; 83 84 // Interface for negotiating pairing of bluetooth devices. 85 class PairingDelegate { 86 public: 87 virtual ~PairingDelegate() {} 88 89 // This method will be called when the Bluetooth daemon requires a 90 // PIN Code for authentication of the device |device|, the delegate should 91 // obtain the code from the user and call SetPinCode() on the device to 92 // provide it, or RejectPairing() or CancelPairing() to reject or cancel 93 // the request. 94 // 95 // PIN Codes are generally required for Bluetooth 2.0 and earlier devices 96 // for which there is no automatic pairing or special handling. 97 virtual void RequestPinCode(BluetoothDevice* device) = 0; 98 99 // This method will be called when the Bluetooth daemon requires a 100 // Passkey for authentication of the device |device|, the delegate should 101 // obtain the passkey from the user (a numeric in the range 0-999999) and 102 // call SetPasskey() on the device to provide it, or RejectPairing() or 103 // CancelPairing() to reject or cancel the request. 104 // 105 // Passkeys are generally required for Bluetooth 2.1 and later devices 106 // which cannot provide input or display on their own, and don't accept 107 // passkey-less pairing. 108 virtual void RequestPasskey(BluetoothDevice* device) = 0; 109 110 // This method will be called when the Bluetooth daemon requires that the 111 // user enter the PIN code |pincode| into the device |device| so that it 112 // may be authenticated. 113 // 114 // This is used for Bluetooth 2.0 and earlier keyboard devices, the 115 // |pincode| will always be a six-digit numeric in the range 000000-999999 116 // for compatibility with later specifications. 117 virtual void DisplayPinCode(BluetoothDevice* device, 118 const std::string& pincode) = 0; 119 120 // This method will be called when the Bluetooth daemon requires that the 121 // user enter the Passkey |passkey| into the device |device| so that it 122 // may be authenticated. 123 // 124 // This is used for Bluetooth 2.1 and later devices that support input 125 // but not display, such as keyboards. The Passkey is a numeric in the 126 // range 0-999999 and should be always presented zero-padded to six 127 // digits. 128 virtual void DisplayPasskey(BluetoothDevice* device, 129 uint32 passkey) = 0; 130 131 // This method will be called when the Bluetooth daemon gets a notification 132 // of a key entered on the device |device| while pairing with the device 133 // using a PIN code or a Passkey. 134 // 135 // This method will be called only after DisplayPinCode() or 136 // DisplayPasskey() method is called, but is not warranted to be called 137 // on every pairing process that requires a PIN code or a Passkey because 138 // some device may not support this feature. 139 // 140 // The |entered| value describes the number of keys entered so far, 141 // including the last [enter] key. A first call to KeysEntered() with 142 // |entered| as 0 will be sent when the device supports this feature. 143 virtual void KeysEntered(BluetoothDevice* device, 144 uint32 entered) = 0; 145 146 // This method will be called when the Bluetooth daemon requires that the 147 // user confirm that the Passkey |passkey| is displayed on the screen 148 // of the device |device| so that it may be authenticated. The delegate 149 // should display to the user and ask for confirmation, then call 150 // ConfirmPairing() on the device to confirm, RejectPairing() on the device 151 // to reject or CancelPairing() on the device to cancel authentication 152 // for any other reason. 153 // 154 // This is used for Bluetooth 2.1 and later devices that support display, 155 // such as other computers or phones. The Passkey is a numeric in the 156 // range 0-999999 and should be always present zero-padded to six 157 // digits. 158 virtual void ConfirmPasskey(BluetoothDevice* device, 159 uint32 passkey) = 0; 160 161 // This method will be called when the Bluetooth daemon requires that a 162 // pairing request, usually only incoming, using the just-works model is 163 // authorized. The delegate should decide whether the user should confirm 164 // or not, then call ConfirmPairing() on the device to confirm the pairing 165 // (whether by user action or by default), RejectPairing() on the device to 166 // reject or CancelPairing() on the device to cancel authorization for 167 // any other reason. 168 virtual void AuthorizePairing(BluetoothDevice* device) = 0; 169 }; 170 171 virtual ~BluetoothDevice(); 172 173 // Returns the Bluetooth class of the device, used by GetDeviceType() 174 // and metrics logging, 175 virtual uint32 GetBluetoothClass() const = 0; 176 177 // Returns the Bluetooth of address the device. This should be used as 178 // a unique key to identify the device and copied where needed. 179 virtual std::string GetAddress() const = 0; 180 181 // Returns the allocation source of the identifier returned by GetVendorID(), 182 // where available, or VENDOR_ID_UNKNOWN where not. 183 virtual VendorIDSource GetVendorIDSource() const = 0; 184 185 // Returns the Vendor ID of the device, where available. 186 virtual uint16 GetVendorID() const = 0; 187 188 // Returns the Product ID of the device, where available. 189 virtual uint16 GetProductID() const = 0; 190 191 // Returns the Device ID of the device, typically the release or version 192 // number in BCD format, where available. 193 virtual uint16 GetDeviceID() const = 0; 194 195 // Returns the name of the device suitable for displaying, this may 196 // be a synthesized string containing the address and localized type name 197 // if the device has no obtained name. 198 virtual base::string16 GetName() const; 199 200 // Returns the type of the device, limited to those we support or are 201 // aware of, by decoding the bluetooth class information. The returned 202 // values are unique, and do not overlap, so DEVICE_KEYBOARD is not also 203 // DEVICE_PERIPHERAL. 204 DeviceType GetDeviceType() const; 205 206 // Gets the "received signal strength indication" (RSSI) of the current 207 // connection to the device. The RSSI indicates the power present in the 208 // received radio signal, measured in dBm, to a resolution of 1dBm. Larger 209 // (typically, less negative) values indicate a stronger signal. 210 // If the device is not currently connected, then returns the RSSI read from 211 // the last inquiry that returned the device, where available. In case of an 212 // error, returns |kUnknownPower|. Otherwise, returns the connection's RSSI. 213 virtual int GetRSSI() const = 0; 214 215 // These two methods are used to read the current or maximum transmit power 216 // ("Tx power") of the current connection to the device. The transmit power 217 // indicates the strength of the signal broadcast from the host's Bluetooth 218 // antenna when communicating with the device, measured in dBm, to a 219 // resolution of 1dBm. Larger (typically, less negative) values 220 // indicate a stronger signal. 221 // It is only meaningful to call this method when there is a connection 222 // established to the device. If there is no connection, or in case of an 223 // error, returns |kUnknownPower|. Otherwise, returns the connection's 224 // transmit power. 225 virtual int GetCurrentHostTransmitPower() const = 0; 226 virtual int GetMaximumHostTransmitPower() const = 0; 227 228 // Indicates whether the device is known to support pairing based on its 229 // device class and address. 230 bool IsPairable() const; 231 232 // Indicates whether the device is paired with the adapter. 233 virtual bool IsPaired() const = 0; 234 235 // Indicates whether the device is currently connected to the adapter. 236 // Note that if IsConnected() is true, does not imply that the device is 237 // connected to any application or service. If the device is not paired, it 238 // could be still connected to the adapter for other reason, for example, to 239 // request the adapter's SDP records. The same holds for paired devices, since 240 // they could be connected to the adapter but not to an application. 241 virtual bool IsConnected() const = 0; 242 243 // Indicates whether the paired device accepts connections initiated from the 244 // adapter. This value is undefined for unpaired devices. 245 virtual bool IsConnectable() const = 0; 246 247 // Indicates whether there is a call to Connect() ongoing. For this attribute, 248 // we consider a call is ongoing if none of the callbacks passed to Connect() 249 // were called after the corresponding call to Connect(). 250 virtual bool IsConnecting() const = 0; 251 252 // Indicates whether the device can be trusted, based on device properties, 253 // such as vendor and product id. 254 bool IsTrustable() const; 255 256 // Returns the set of UUIDs that this device supports. For classic Bluetooth 257 // devices this data is collected from both the EIR data and SDP tables, 258 // for Low Energy devices this data is collected from AD and GATT primary 259 // services, for dual mode devices this may be collected from both./ 260 typedef std::vector<BluetoothUUID> UUIDList; 261 virtual UUIDList GetUUIDs() const = 0; 262 263 // The ErrorCallback is used for methods that can fail in which case it 264 // is called, in the success case the callback is simply not called. 265 typedef base::Callback<void()> ErrorCallback; 266 267 // The ConnectErrorCallback is used for methods that can fail with an error, 268 // passed back as an error code argument to this callback. 269 // In the success case this callback is not called. 270 typedef base::Callback<void(enum ConnectErrorCode)> ConnectErrorCallback; 271 272 // Indicates whether the device is currently pairing and expecting a 273 // PIN Code to be returned. 274 virtual bool ExpectingPinCode() const = 0; 275 276 // Indicates whether the device is currently pairing and expecting a 277 // Passkey to be returned. 278 virtual bool ExpectingPasskey() const = 0; 279 280 // Indicates whether the device is currently pairing and expecting 281 // confirmation of a displayed passkey. 282 virtual bool ExpectingConfirmation() const = 0; 283 284 // Initiates a connection to the device, pairing first if necessary. 285 // 286 // Method calls will be made on the supplied object |pairing_delegate| 287 // to indicate what display, and in response should make method calls 288 // back to the device object. Not all devices require user responses 289 // during pairing, so it is normal for |pairing_delegate| to receive no 290 // calls. To explicitly force a low-security connection without bonding, 291 // pass NULL, though this is ignored if the device is already paired. 292 // 293 // If the request fails, |error_callback| will be called; otherwise, 294 // |callback| is called when the request is complete. 295 // After calling Connect, CancelPairing should be called to cancel the pairing 296 // process and release the pairing delegate if user cancels the pairing and 297 // closes the pairing UI. 298 virtual void Connect(PairingDelegate* pairing_delegate, 299 const base::Closure& callback, 300 const ConnectErrorCallback& error_callback) = 0; 301 302 // Sends the PIN code |pincode| to the remote device during pairing. 303 // 304 // PIN Codes are generally required for Bluetooth 2.0 and earlier devices 305 // for which there is no automatic pairing or special handling. 306 virtual void SetPinCode(const std::string& pincode) = 0; 307 308 // Sends the Passkey |passkey| to the remote device during pairing. 309 // 310 // Passkeys are generally required for Bluetooth 2.1 and later devices 311 // which cannot provide input or display on their own, and don't accept 312 // passkey-less pairing, and are a numeric in the range 0-999999. 313 virtual void SetPasskey(uint32 passkey) = 0; 314 315 // Confirms to the remote device during pairing that a passkey provided by 316 // the ConfirmPasskey() delegate call is displayed on both devices. 317 virtual void ConfirmPairing() = 0; 318 319 // Rejects a pairing or connection request from a remote device. 320 virtual void RejectPairing() = 0; 321 322 // Cancels a pairing or connection attempt to a remote device, releasing 323 // the pairing delegate. 324 virtual void CancelPairing() = 0; 325 326 // Disconnects the device, terminating the low-level ACL connection 327 // and any application connections using it. Link keys and other pairing 328 // information are not discarded, and the device object is not deleted. 329 // If the request fails, |error_callback| will be called; otherwise, 330 // |callback| is called when the request is complete. 331 virtual void Disconnect(const base::Closure& callback, 332 const ErrorCallback& error_callback) = 0; 333 334 // Disconnects the device, terminating the low-level ACL connection 335 // and any application connections using it, and then discards link keys 336 // and other pairing information. The device object remains valid until 337 // returning from the calling function, after which it should be assumed to 338 // have been deleted. If the request fails, |error_callback| will be called. 339 // There is no callback for success because this object is often deleted 340 // before that callback would be called. 341 virtual void Forget(const ErrorCallback& error_callback) = 0; 342 343 // Attempts to initiate an outgoing L2CAP or RFCOMM connection to the 344 // advertised service on this device matching |uuid|, performing an SDP lookup 345 // if necessary to determine the correct protocol and channel for the 346 // connection. |callback| will be called on a successful connection with a 347 // BluetoothSocket instance that is to be owned by the receiver. 348 // |error_callback| will be called on failure with a message indicating the 349 // cause. 350 typedef base::Callback<void(scoped_refptr<BluetoothSocket>)> 351 ConnectToServiceCallback; 352 typedef base::Callback<void(const std::string& message)> 353 ConnectToServiceErrorCallback; 354 virtual void ConnectToService( 355 const BluetoothUUID& uuid, 356 const ConnectToServiceCallback& callback, 357 const ConnectToServiceErrorCallback& error_callback) = 0; 358 359 // Opens a new GATT connection to this device. On success, a new 360 // BluetoothGattConnection will be handed to the caller via |callback|. On 361 // error, |error_callback| will be called. The connection will be kept alive, 362 // as long as there is at least one active GATT connection. In the case that 363 // the underlying connection gets terminated, either due to a call to 364 // BluetoothDevice::Disconnect or other unexpected circumstances, the 365 // returned BluetoothGattConnection will be automatically marked as inactive. 366 // To monitor the state of the connection, observe the 367 // BluetoothAdapter::Observer::DeviceChanged method. 368 typedef base::Callback<void(scoped_ptr<BluetoothGattConnection>)> 369 GattConnectionCallback; 370 virtual void CreateGattConnection( 371 const GattConnectionCallback& callback, 372 const ConnectErrorCallback& error_callback) = 0; 373 374 // Starts monitoring the connection properties, RSSI and TX power. These 375 // properties will be tracked, and updated when their values change. Exactly 376 // one of |callback| or |error_callback| will be run. 377 virtual void StartConnectionMonitor(const base::Closure& callback, 378 const ErrorCallback& error_callback) = 0; 379 380 // Returns the list of discovered GATT services. 381 virtual std::vector<BluetoothGattService*> GetGattServices() const; 382 383 // Returns the GATT service with device-specific identifier |identifier|. 384 // Returns NULL, if no such service exists. 385 virtual BluetoothGattService* GetGattService( 386 const std::string& identifier) const; 387 388 // Returns the |address| in the canoncial format: XX:XX:XX:XX:XX:XX, where 389 // each 'X' is a hex digit. If the input |address| is invalid, returns an 390 // empty string. 391 static std::string CanonicalizeAddress(const std::string& address); 392 393 protected: 394 BluetoothDevice(); 395 396 // Returns the internal name of the Bluetooth device, used by GetName(). 397 virtual std::string GetDeviceName() const = 0; 398 399 // Mapping from the platform-specific GATT service identifiers to 400 // BluetoothGattService objects. 401 typedef std::map<std::string, BluetoothGattService*> GattServiceMap; 402 GattServiceMap gatt_services_; 403 404 private: 405 // Returns a localized string containing the device's bluetooth address and 406 // a device type for display when |name_| is empty. 407 base::string16 GetAddressWithLocalizedDeviceTypeName() const; 408 }; 409 410 } // namespace device 411 412 #endif // DEVICE_BLUETOOTH_BLUETOOTH_DEVICE_H_ 413