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