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 <stddef.h> 9 #include <stdint.h> 10 11 #include <memory> 12 #include <set> 13 #include <string> 14 #include <unordered_map> 15 #include <unordered_set> 16 #include <vector> 17 18 #include "base/callback.h" 19 #include "base/containers/flat_set.h" 20 #include "base/containers/span.h" 21 #include "base/gtest_prod_util.h" 22 #include "base/macros.h" 23 #include "base/memory/ref_counted.h" 24 #include "base/optional.h" 25 #include "base/strings/string16.h" 26 #include "base/strings/string_piece_forward.h" 27 #include "base/time/time.h" 28 #include "build/build_config.h" 29 #include "build/chromeos_buildflags.h" 30 #include "device/bluetooth/bluetooth_common.h" 31 #include "device/bluetooth/bluetooth_export.h" 32 #include "device/bluetooth/bluetooth_remote_gatt_service.h" 33 #include "device/bluetooth/public/cpp/bluetooth_uuid.h" 34 35 namespace device { 36 37 class BluetoothAdapter; 38 class BluetoothGattConnection; 39 class BluetoothSocket; 40 41 // BluetoothDevice represents a remote Bluetooth device, both its properties and 42 // capabilities as discovered by a local adapter and actions that may be 43 // performed on the remove device such as pairing, connection and disconnection. 44 // 45 // The class is instantiated and managed by the BluetoothAdapter class 46 // and pointers should only be obtained from that class and not cached, 47 // instead use the GetAddress() method as a unique key for a device. 48 // 49 // Since the lifecycle of BluetoothDevice instances is managed by 50 // BluetoothAdapter, that class rather than this provides observer methods 51 // for devices coming and going, as well as properties being updated. 52 class DEVICE_BLUETOOTH_EXPORT BluetoothDevice { 53 public: 54 // Possible values that may be returned by GetVendorIDSource(), 55 // indicating different organisations that allocate the identifiers returned 56 // by GetVendorID(). 57 enum VendorIDSource { 58 VENDOR_ID_UNKNOWN, 59 VENDOR_ID_BLUETOOTH, 60 VENDOR_ID_USB, 61 VENDOR_ID_MAX_VALUE = VENDOR_ID_USB 62 }; 63 64 // Possible values that may be returned by GetAddressType(). 65 enum AddressType { 66 ADDR_TYPE_UNKNOWN, 67 ADDR_TYPE_PUBLIC, 68 ADDR_TYPE_RANDOM, 69 }; 70 71 // The value returned if the RSSI or transmit power cannot be read. 72 static const int kUnknownPower = 127; 73 // The value returned if the appearance is not present. 74 static const uint16_t kAppearanceNotPresent = 0xffc0; 75 76 struct DEVICE_BLUETOOTH_EXPORT ConnectionInfo { 77 int rssi; 78 int transmit_power; 79 int max_transmit_power; 80 81 ConnectionInfo(); 82 ConnectionInfo(int rssi, int transmit_power, int max_transmit_power); 83 ~ConnectionInfo(); 84 }; 85 86 // Possible connection latency values to pass to SetConnectionLatency(). 87 enum ConnectionLatency { 88 CONNECTION_LATENCY_LOW, 89 CONNECTION_LATENCY_MEDIUM, 90 CONNECTION_LATENCY_HIGH, 91 }; 92 93 // Possible errors passed back to an error callback function in case of a 94 // failed call to Connect(). 95 enum ConnectErrorCode { 96 ERROR_AUTH_CANCELED, 97 ERROR_AUTH_FAILED, 98 ERROR_AUTH_REJECTED, 99 ERROR_AUTH_TIMEOUT, 100 ERROR_FAILED, 101 ERROR_INPROGRESS, 102 ERROR_UNKNOWN, 103 ERROR_UNSUPPORTED_DEVICE, 104 NUM_CONNECT_ERROR_CODES // Keep as last enum. 105 }; 106 107 typedef std::vector<BluetoothUUID> UUIDList; 108 typedef base::flat_set<BluetoothUUID> UUIDSet; 109 typedef std::unordered_map<BluetoothUUID, 110 std::vector<uint8_t>, 111 BluetoothUUIDHash> 112 ServiceDataMap; 113 typedef uint16_t ManufacturerId; 114 typedef std::unordered_map<ManufacturerId, std::vector<uint8_t>> 115 ManufacturerDataMap; 116 typedef std::unordered_set<ManufacturerId> ManufacturerIDSet; 117 118 // Mapping from the platform-specific GATT service identifiers to 119 // BluetoothRemoteGattService objects. 120 typedef std::unordered_map<std::string, 121 std::unique_ptr<BluetoothRemoteGattService>> 122 GattServiceMap; 123 124 // Interface for negotiating pairing of bluetooth devices. 125 class PairingDelegate { 126 public: ~PairingDelegate()127 virtual ~PairingDelegate() {} 128 129 // This method will be called when the Bluetooth daemon requires a 130 // PIN Code for authentication of the device |device|, the delegate should 131 // obtain the code from the user and call SetPinCode() on the device to 132 // provide it, or RejectPairing() or CancelPairing() to reject or cancel 133 // the request. 134 // 135 // PIN Codes are generally required for Bluetooth 2.0 and earlier devices 136 // for which there is no automatic pairing or special handling. 137 virtual void RequestPinCode(BluetoothDevice* device) = 0; 138 139 // This method will be called when the Bluetooth daemon requires a 140 // Passkey for authentication of the device |device|, the delegate should 141 // obtain the passkey from the user (a numeric in the range 0-999999) and 142 // call SetPasskey() on the device to provide it, or RejectPairing() or 143 // CancelPairing() to reject or cancel the request. 144 // 145 // Passkeys are generally required for Bluetooth 2.1 and later devices 146 // which cannot provide input or display on their own, and don't accept 147 // passkey-less pairing. 148 virtual void RequestPasskey(BluetoothDevice* device) = 0; 149 150 // This method will be called when the Bluetooth daemon requires that the 151 // user enter the PIN code |pincode| into the device |device| so that it 152 // may be authenticated. 153 // 154 // This is used for Bluetooth 2.0 and earlier keyboard devices, the 155 // |pincode| will always be a six-digit numeric in the range 000000-999999 156 // for compatibility with later specifications. 157 virtual void DisplayPinCode(BluetoothDevice* device, 158 const std::string& pincode) = 0; 159 160 // This method will be called when the Bluetooth daemon requires that the 161 // user enter the Passkey |passkey| into the device |device| so that it 162 // may be authenticated. 163 // 164 // This is used for Bluetooth 2.1 and later devices that support input 165 // but not display, such as keyboards. The Passkey is a numeric in the 166 // range 0-999999 and should be always presented zero-padded to six 167 // digits. 168 virtual void DisplayPasskey(BluetoothDevice* device, uint32_t passkey) = 0; 169 170 // This method will be called when the Bluetooth daemon gets a notification 171 // of a key entered on the device |device| while pairing with the device 172 // using a PIN code or a Passkey. 173 // 174 // This method will be called only after DisplayPinCode() or 175 // DisplayPasskey() method is called, but is not warranted to be called 176 // on every pairing process that requires a PIN code or a Passkey because 177 // some device may not support this feature. 178 // 179 // The |entered| value describes the number of keys entered so far, 180 // including the last [enter] key. A first call to KeysEntered() with 181 // |entered| as 0 will be sent when the device supports this feature. 182 virtual void KeysEntered(BluetoothDevice* device, uint32_t entered) = 0; 183 184 // This method will be called when the Bluetooth daemon requires that the 185 // user confirm that the Passkey |passkey| is displayed on the screen 186 // of the device |device| so that it may be authenticated. The delegate 187 // should display to the user and ask for confirmation, then call 188 // ConfirmPairing() on the device to confirm, RejectPairing() on the device 189 // to reject or CancelPairing() on the device to cancel authentication 190 // for any other reason. 191 // 192 // This is used for Bluetooth 2.1 and later devices that support display, 193 // such as other computers or phones. The Passkey is a numeric in the 194 // range 0-999999 and should be always present zero-padded to six 195 // digits. 196 virtual void ConfirmPasskey(BluetoothDevice* device, uint32_t passkey) = 0; 197 198 // This method will be called when the Bluetooth daemon requires that a 199 // pairing request, usually only incoming, using the just-works model is 200 // authorized. The delegate should decide whether the user should confirm 201 // or not, then call ConfirmPairing() on the device to confirm the pairing 202 // (whether by user action or by default), RejectPairing() on the device to 203 // reject or CancelPairing() on the device to cancel authorization for 204 // any other reason. 205 virtual void AuthorizePairing(BluetoothDevice* device) = 0; 206 }; 207 208 virtual ~BluetoothDevice(); 209 210 // Clamps numbers less than -128 to -128 and numbers greater than 127 to 127. 211 static int8_t ClampPower(int power); 212 213 // Returns the Bluetooth class of the device, used by GetDeviceType() 214 // and metrics logging, 215 virtual uint32_t GetBluetoothClass() const = 0; 216 217 #if defined(OS_LINUX) || defined(OS_CHROMEOS) 218 // Returns the transport type of the device. Some devices only support one 219 // of BR/EDR or LE, and some support both. 220 virtual BluetoothTransport GetType() const = 0; 221 #endif 222 223 // Returns the identifier of the bluetooth device. 224 virtual std::string GetIdentifier() const; 225 226 // Returns the Bluetooth of address the device. This should be used as 227 // a unique key to identify the device and copied where needed. 228 virtual std::string GetAddress() const = 0; 229 230 // Returns the Bluetooth address type of the device. Currently available on 231 // Linux and Chrome OS. 232 virtual AddressType GetAddressType() const = 0; 233 234 // Returns the allocation source of the identifier returned by GetVendorID(), 235 // where available, or VENDOR_ID_UNKNOWN where not. 236 virtual VendorIDSource GetVendorIDSource() const = 0; 237 238 // Returns the Vendor ID of the device, where available. 239 virtual uint16_t GetVendorID() const = 0; 240 241 // Returns the Product ID of the device, where available. 242 virtual uint16_t GetProductID() const = 0; 243 244 // Returns the Device ID of the device, typically the release or version 245 // number in BCD format, where available. 246 virtual uint16_t GetDeviceID() const = 0; 247 248 // Returns the appearance of the device. 249 virtual uint16_t GetAppearance() const = 0; 250 251 // Returns the name of the device, which may be empty. 252 virtual base::Optional<std::string> GetName() const = 0; 253 254 // Returns the name of the device suitable for displaying, this may 255 // be a synthesized string containing the address and localized type name 256 // if the device has no obtained name. 257 virtual base::string16 GetNameForDisplay() const; 258 259 // Returns the type of the device, limited to those we support or are 260 // aware of, by decoding the bluetooth class information. The returned 261 // values are unique, and do not overlap, so DEVICE_KEYBOARD is not also 262 // DEVICE_PERIPHERAL. 263 // 264 // Returns the type of the device, limited to those we support or are aware 265 // of, by decoding the bluetooth class information for Classic devices or 266 // by decoding the device's appearance for LE devices. For example, 267 // Microsoft Universal Foldable Keyboard only advertises the appearance. 268 virtual BluetoothDeviceType GetDeviceType() const; 269 270 // Indicates whether the device is known to support pairing based on its 271 // device class and address. 272 bool IsPairable() const; 273 274 // Indicates whether the device is paired with the adapter. 275 virtual bool IsPaired() const = 0; 276 277 // Indicates whether the device is currently connected to the adapter. 278 // Note that if IsConnected() is true, does not imply that the device is 279 // connected to any application or service. If the device is not paired, it 280 // could be still connected to the adapter for other reason, for example, to 281 // request the adapter's SDP records. The same holds for paired devices, since 282 // they could be connected to the adapter but not to an application. 283 virtual bool IsConnected() const = 0; 284 285 // Indicates whether an active GATT connection exists to the device. 286 virtual bool IsGattConnected() const = 0; 287 288 // Indicates whether the paired device accepts connections initiated from the 289 // adapter. This value is undefined for unpaired devices. Only available for 290 // Chrome OS. 291 virtual bool IsConnectable() const = 0; 292 293 // Indicates whether there is a call to Connect() ongoing. For this attribute, 294 // we consider a call is ongoing if none of the callbacks passed to Connect() 295 // were called after the corresponding call to Connect(). 296 virtual bool IsConnecting() const = 0; 297 298 // Returns the set of UUIDs that this device supports. 299 // * For classic Bluetooth devices this data is collected from both the EIR 300 // data and SDP tables. 301 // * For non-connected and connected Low Energy Devices for which services 302 // have not been discovered returns the latest advertised UUIDs. 303 // * For connected Low Energy Devices for which services have been discovered 304 // returns the UUIDs of the device's services and the latest advertised 305 // UUIDs. 306 // * For dual mode devices this may be collected from both. 307 // 308 // Note: On Android, Mac and WinRT advertised UUIDs are cleared when the 309 // adapter stops discovering, as otherwise stale data might be returned. 310 // 311 // Note: On ChromeOS and Linux, BlueZ persists all services meaning if 312 // a device stops advertising a service this function will still return 313 // its UUID. 314 virtual UUIDSet GetUUIDs() const; 315 316 // Returns the last advertised Service Data. Returns an empty map if the 317 // adapter is not discovering. 318 // 319 // Note: On ChromeOS and Linux, BlueZ persists all service data meaning if 320 // a device stops advertising service data for a UUID, this function will 321 // still return the cached value for that UUID. 322 const ServiceDataMap& GetServiceData() const; 323 324 // Returns the UUIDs of services for which the device advertises Service Data. 325 // Returns an empty set if the adapter is not discovering. 326 UUIDSet GetServiceDataUUIDs() const; 327 328 // Returns a pointer to the Service Data for Service with |uuid|. Returns 329 // nullptr if |uuid| has no Service Data. 330 const std::vector<uint8_t>* GetServiceDataForUUID( 331 const BluetoothUUID& uuid) const; 332 333 // Returns advertised Manufacturer Data. Keys are 16 bits Manufacturer IDs 334 // followed by its byte array value. Returns an empty map if the device 335 // does not advertise any Manufacturer Data. 336 // Returns cached value if the adapter is not discovering. 337 // 338 // Note: On ChromeOS and Linux, BlueZ persists all manufacturer data meaning 339 // if a device stops advertising manufacturer data for a Manufacturer Id, this 340 // function will still return the cached value for that Id. 341 // 342 // TODO(crbug.com/661814) Support this on platforms that don't use BlueZ. 343 // Only BlueZ supports this now. This method returns an empty map on platforms 344 // that don't use BlueZ. 345 const ManufacturerDataMap& GetManufacturerData() const; 346 347 // Returns the Manufacturer Data IDs of Manufacturers for which the device 348 // advertises Manufacturer Data. 349 // Returns cached value if the adapter is not discovering. 350 ManufacturerIDSet GetManufacturerDataIDs() const; 351 352 // Returns a pointer to the Manufacturer Data for Manufacturer with 353 // |manufacturerID|. Returns nullptr if |manufacturerID| has no Manufacturer 354 // Data. Returns cached value if the adapter is not discovering. 355 const std::vector<uint8_t>* GetManufacturerDataForID( 356 const ManufacturerId manufacturerID) const; 357 358 // The received signal strength, in dBm. This field is avaliable and valid 359 // only during discovery. 360 // TODO(http://crbug.com/580406): Devirtualize once BlueZ sets inquiry_rssi_. 361 virtual base::Optional<int8_t> GetInquiryRSSI() const; 362 363 // The transmitted power level. This field is avaliable only for LE devices 364 // that include this field in AD. It is avaliable and valid only during 365 // discovery. 366 // TODO(http://crbug.com/580406): Devirtualize once BlueZ sets 367 // inquiry_tx_power_. 368 virtual base::Optional<int8_t> GetInquiryTxPower() const; 369 370 // Returns Advertising Data Flags. 371 // Returns cached value if the adapter is not discovering. 372 // 373 // Only Chrome OS and WinRT support this now. Upstream BlueZ has this feature 374 // as experimental. This method returns base::nullopt on platforms that don't 375 // support this feature. 376 base::Optional<uint8_t> GetAdvertisingDataFlags() const; 377 378 // The ErrorCallback is used for methods that can fail in which case it 379 // is called, in the success case the callback is simply not called. 380 using ErrorCallback = base::OnceClosure; 381 382 // The ConnectErrorCallback is used for methods that can fail with an error, 383 // passed back as an error code argument to this callback. 384 // In the success case this callback is not called. 385 using ConnectErrorCallback = base::OnceCallback<void(enum ConnectErrorCode)>; 386 387 using ConnectionInfoCallback = 388 base::OnceCallback<void(const ConnectionInfo&)>; 389 390 // Indicates whether the device is currently pairing and expecting a 391 // PIN Code to be returned. 392 virtual bool ExpectingPinCode() const = 0; 393 394 // Indicates whether the device is currently pairing and expecting a 395 // Passkey to be returned. 396 virtual bool ExpectingPasskey() const = 0; 397 398 // Indicates whether the device is currently pairing and expecting 399 // confirmation of a displayed passkey. 400 virtual bool ExpectingConfirmation() const = 0; 401 402 // Returns the RSSI and TX power of the active connection to the device: 403 // 404 // The RSSI indicates the power present in the received radio signal, measured 405 // in dBm, to a resolution of 1dBm. Larger (typically, less negative) values 406 // indicate a stronger signal. 407 // 408 // The transmit power indicates the strength of the signal broadcast from the 409 // host's Bluetooth antenna when communicating with the device, measured in 410 // dBm, to a resolution of 1dBm. Larger (typically, less negative) values 411 // indicate a stronger signal. 412 // 413 // If the device isn't connected, then the ConnectionInfo struct passed into 414 // the callback will be populated with |kUnknownPower|. 415 virtual void GetConnectionInfo(ConnectionInfoCallback callback) = 0; 416 417 // Sets the connection latency for the device. This API is only valid for LE 418 // devices. 419 virtual void SetConnectionLatency(ConnectionLatency connection_latency, 420 base::OnceClosure callback, 421 ErrorCallback error_callback) = 0; 422 423 // Initiates a connection to the device, pairing first if necessary. 424 // 425 // Method calls will be made on the supplied object |pairing_delegate| 426 // to indicate what display, and in response should make method calls 427 // back to the device object. Not all devices require user responses 428 // during pairing, so it is normal for |pairing_delegate| to receive no 429 // calls. To explicitly force a low-security connection without bonding, 430 // pass NULL, though this is ignored if the device is already paired. 431 // 432 // If the request fails, |error_callback| will be called; otherwise, 433 // |callback| is called when the request is complete. 434 // After calling Connect, CancelPairing should be called to cancel the pairing 435 // process and release the pairing delegate if user cancels the pairing and 436 // closes the pairing UI. 437 virtual void Connect(PairingDelegate* pairing_delegate, 438 base::OnceClosure callback, 439 ConnectErrorCallback error_callback) = 0; 440 441 // Pairs the device. This method triggers pairing unconditially, i.e. it 442 // ignores the |IsPaired()| value. 443 // 444 // In most cases |Connect()| should be preferred. This method is only 445 // implemented on ChromeOS, Linux and Windows 10. On Windows, only pairing 446 // with a pin code is currently supported. 447 virtual void Pair(PairingDelegate* pairing_delegate, 448 base::OnceClosure callback, 449 ConnectErrorCallback error_callback); 450 451 // Sends the PIN code |pincode| to the remote device during pairing. 452 // 453 // PIN Codes are generally required for Bluetooth 2.0 and earlier devices 454 // for which there is no automatic pairing or special handling. 455 virtual void SetPinCode(const std::string& pincode) = 0; 456 457 // Sends the Passkey |passkey| to the remote device during pairing. 458 // 459 // Passkeys are generally required for Bluetooth 2.1 and later devices 460 // which cannot provide input or display on their own, and don't accept 461 // passkey-less pairing, and are a numeric in the range 0-999999. 462 virtual void SetPasskey(uint32_t passkey) = 0; 463 464 // Confirms to the remote device during pairing that a passkey provided by 465 // the ConfirmPasskey() delegate call is displayed on both devices. 466 virtual void ConfirmPairing() = 0; 467 468 // Rejects a pairing or connection request from a remote device. 469 virtual void RejectPairing() = 0; 470 471 // Cancels a pairing or connection attempt to a remote device, releasing 472 // the pairing delegate. 473 virtual void CancelPairing() = 0; 474 475 // Disconnects the device, terminating the low-level ACL connection 476 // and any application connections using it. Link keys and other pairing 477 // information are not discarded, and the device object is not deleted. 478 // If the request fails, |error_callback| will be called; otherwise, 479 // |callback| is called when the request is complete. 480 virtual void Disconnect(base::OnceClosure callback, 481 ErrorCallback error_callback) = 0; 482 483 // Disconnects the device, terminating the low-level ACL connection 484 // and any application connections using it, and then discards link keys 485 // and other pairing information. The device object remains valid until 486 // returning from the calling function, after which it should be assumed to 487 // have been deleted. If the request fails, |error_callback| will be called. 488 // On success |callback| will be invoked, but note that the BluetoothDevice 489 // object will have been deleted at that point. 490 virtual void Forget(base::OnceClosure callback, 491 ErrorCallback error_callback) = 0; 492 493 // Attempts to initiate an outgoing L2CAP or RFCOMM connection to the 494 // advertised service on this device matching |uuid|, performing an SDP lookup 495 // if necessary to determine the correct protocol and channel for the 496 // connection. |callback| will be called on a successful connection with a 497 // BluetoothSocket instance that is to be owned by the receiver. 498 // |error_callback| will be called on failure with a message indicating the 499 // cause. 500 using ConnectToServiceCallback = 501 base::OnceCallback<void(scoped_refptr<BluetoothSocket>)>; 502 using ConnectToServiceErrorCallback = 503 base::OnceCallback<void(const std::string& message)>; 504 virtual void ConnectToService( 505 const BluetoothUUID& uuid, 506 ConnectToServiceCallback callback, 507 ConnectToServiceErrorCallback error_callback) = 0; 508 509 // Attempts to initiate an insecure outgoing L2CAP or RFCOMM connection to the 510 // advertised service on this device matching |uuid|, performing an SDP lookup 511 // if necessary to determine the correct protocol and channel for the 512 // connection. Unlike ConnectToService, the outgoing connection will request 513 // no bonding rather than general bonding. |callback| will be called on a 514 // successful connection with a BluetoothSocket instance that is to be owned 515 // by the receiver. |error_callback| will be called on failure with a message 516 // indicating the cause. 517 virtual void ConnectToServiceInsecurely( 518 const device::BluetoothUUID& uuid, 519 ConnectToServiceCallback callback, 520 ConnectToServiceErrorCallback error_callback) = 0; 521 522 // Opens a new GATT connection to this device. On success, a new 523 // BluetoothGattConnection will be handed to the caller via |callback|. On 524 // error, |error_callback| will be called. The connection will be kept alive, 525 // as long as there is at least one active GATT connection. In the case that 526 // the underlying connection gets terminated, either due to a call to 527 // BluetoothDevice::Disconnect or other unexpected circumstances, the 528 // returned BluetoothGattConnection will be automatically marked as inactive. 529 // To monitor the state of the connection, observe the 530 // BluetoothAdapter::Observer::DeviceChanged method. 531 // 532 // If |service_uuid| is given, potentially only the service with the given 533 // UUID will be discovered. This may speed up GATT discovery times if the 534 // platform can take advantage of this optimisation. Note that passing 535 // |service_uuid| may cause full GATT service discovery to be skipped. In that 536 // case, |IsGattServicesDiscoveryComplete| will not become true but 537 // |BluetoothAdapter::Observer::GattServicesDiscovered| is still the correct 538 // event to watch for. 539 using GattConnectionCallback = 540 base::OnceCallback<void(std::unique_ptr<BluetoothGattConnection>)>; 541 virtual void CreateGattConnection( 542 GattConnectionCallback callback, 543 ConnectErrorCallback error_callback, 544 base::Optional<BluetoothUUID> service_uuid = base::nullopt); 545 546 // Set the gatt services discovery complete flag for this device. 547 virtual void SetGattServicesDiscoveryComplete(bool complete); 548 549 // Indicates whether full service discovery is complete for this device. If a 550 // |service_uuid| was passed to |CreateGattConnection| and a focused discovery 551 // was performed, then this will continue to return false even after discovery 552 // is complete. 553 virtual bool IsGattServicesDiscoveryComplete() const; 554 555 // Returns the list of discovered GATT services. 556 virtual std::vector<BluetoothRemoteGattService*> GetGattServices() const; 557 558 // Returns the GATT service with device-specific identifier |identifier|. 559 // Returns NULL, if no such service exists. 560 virtual BluetoothRemoteGattService* GetGattService( 561 const std::string& identifier) const; 562 563 // Update the last time this device was seen. 564 void UpdateTimestamp(); 565 566 // Returns the time of the last call to UpdateTimestamp(), or base::Time() if 567 // it hasn't been called yet. 568 virtual base::Time GetLastUpdateTime() const; 569 570 // Called by BluetoothAdapter when a new Advertisement is seen for this 571 // device. This replaces previously seen Advertisement Data. The order of 572 // arguments matches the order of their corresponding Data Type specified in 573 // https://www.bluetooth.com/specifications/assigned-numbers/generic-access-profile. 574 void UpdateAdvertisementData(int8_t rssi, 575 base::Optional<uint8_t> flags, 576 UUIDList advertised_uuids, 577 base::Optional<int8_t> tx_power, 578 ServiceDataMap service_data, 579 ManufacturerDataMap manufacturer_data); 580 581 // Called by BluetoothAdapter when it stops discoverying. 582 void ClearAdvertisementData(); 583 584 // Return associated BluetoothAdapter. GetAdapter()585 BluetoothAdapter* GetAdapter() { return adapter_; } 586 587 std::vector<BluetoothRemoteGattService*> GetPrimaryServices(); 588 589 std::vector<BluetoothRemoteGattService*> GetPrimaryServicesByUUID( 590 const BluetoothUUID& service_uuid); 591 592 #if BUILDFLAG(IS_ASH) 593 using ExecuteWriteErrorCallback = 594 base::OnceCallback<void(device::BluetoothGattService::GattErrorCode)>; 595 using AbortWriteErrorCallback = 596 base::OnceCallback<void(device::BluetoothGattService::GattErrorCode)>; 597 // Executes all the previous prepare writes in a reliable write session. 598 virtual void ExecuteWrite(base::OnceClosure callback, 599 ExecuteWriteErrorCallback error_callback) = 0; 600 // Aborts all the previous prepare writes in a reliable write session. 601 virtual void AbortWrite(base::OnceClosure callback, 602 AbortWriteErrorCallback error_callback) = 0; 603 #endif 604 605 #if defined(OS_CHROMEOS) || defined(OS_LINUX) 606 // Set the remaining battery of the device to show in the UI. This value must 607 // be between 0 and 100, inclusive. 608 // TODO(http://b/160905785): Battery percentage is populated by 609 // ash::HfpBatteryListener, ash::HidBatteryListener, and 610 // device::BluetoothAdapterBlueZ. When Battery information is entirely 611 // consolidated in BlueZ's Battery API, only device::BluetoothAdapterBlueZ 612 // should have control over this field with the value originating from a 613 // single source, the BlueZ Battery API.. 614 void SetBatteryPercentage(base::Optional<uint8_t> battery_percentage); 615 616 // Returns the remaining battery for the device. battery_percentage()617 const base::Optional<uint8_t>& battery_percentage() const { 618 return battery_percentage_; 619 } 620 #endif 621 622 // Returns whether this device supports discovering specific services, i.e. 623 // whether the |service_uuid| argument to |CreateGattConnection| is 624 // meaningful. This should only be called by tests. Non-test code should 625 // optimistically pass a |service_uuid| argument if appropriate for the need. 626 bool supports_service_specific_discovery() const; 627 628 protected: 629 // BluetoothGattConnection is a friend to call Add/RemoveGattConnection. 630 friend BluetoothGattConnection; 631 FRIEND_TEST_ALL_PREFIXES( 632 BluetoothTest, 633 BluetoothGattConnection_DisconnectGatt_SimulateConnect); 634 FRIEND_TEST_ALL_PREFIXES( 635 BluetoothTest, 636 BluetoothGattConnection_DisconnectGatt_SimulateDisconnect); 637 FRIEND_TEST_ALL_PREFIXES(BluetoothTest, 638 BluetoothGattConnection_ErrorAfterConnection); 639 FRIEND_TEST_ALL_PREFIXES(BluetoothTest, 640 BluetoothGattConnection_DisconnectGatt_Cleanup); 641 FRIEND_TEST_ALL_PREFIXES(BluetoothTest, GetName_NullName); 642 FRIEND_TEST_ALL_PREFIXES(BluetoothTest, RemoveOutdatedDevices); 643 FRIEND_TEST_ALL_PREFIXES(BluetoothTest, RemoveOutdatedDeviceGattConnect); 644 645 FRIEND_TEST_ALL_PREFIXES( 646 BluetoothTestWinrtOnly, 647 BluetoothGattConnection_DisconnectGatt_SimulateConnect); 648 FRIEND_TEST_ALL_PREFIXES( 649 BluetoothTestWinrtOnly, 650 BluetoothGattConnection_DisconnectGatt_SimulateDisconnect); 651 FRIEND_TEST_ALL_PREFIXES(BluetoothTestWinrtOnly, 652 BluetoothGattConnection_ErrorAfterConnection); 653 FRIEND_TEST_ALL_PREFIXES(BluetoothTestWinrtOnly, 654 BluetoothGattConnection_DisconnectGatt_Cleanup); 655 656 // Helper class to easily update the sets of UUIDs and keep them in sync with 657 // the set of all the device's UUIDs. 658 class DEVICE_BLUETOOTH_EXPORT DeviceUUIDs { 659 public: 660 DeviceUUIDs(); 661 ~DeviceUUIDs(); 662 663 DeviceUUIDs(const DeviceUUIDs& other); 664 DeviceUUIDs& operator=(const DeviceUUIDs& other); 665 666 // Advertised Service UUIDs functions 667 void ReplaceAdvertisedUUIDs(UUIDList new_advertised_uuids); 668 669 void ClearAdvertisedUUIDs(); 670 671 // Service UUIDs functions 672 void ReplaceServiceUUIDs( 673 const BluetoothDevice::GattServiceMap& gatt_services); 674 675 void ClearServiceUUIDs(); 676 677 // Returns the union of Advertised UUIDs and Service UUIDs. 678 const UUIDSet& GetUUIDs() const; 679 680 private: 681 void UpdateDeviceUUIDs(); 682 683 BluetoothDevice::UUIDSet advertised_uuids_; 684 BluetoothDevice::UUIDSet service_uuids_; 685 BluetoothDevice::UUIDSet device_uuids_; 686 }; 687 688 explicit BluetoothDevice(BluetoothAdapter* adapter); 689 690 // Implements platform specific operations to initiate a GATT connection. 691 // Subclasses must also call DidConnectGatt, DidFailToConnectGatt, or 692 // DidDisconnectGatt immediately or asynchronously as the connection state 693 // changes. 694 virtual void CreateGattConnectionImpl( 695 base::Optional<BluetoothUUID> service_uuid) = 0; 696 697 // UpgradeToFullDiscovery is called when there is a pending or current GATT 698 // connection that was created with a service UUID, but now discovery of all 699 // services is required because of a new connection request. This will only 700 // be called if the subclass sets |supports_service_specific_discovery_|. 701 virtual void UpgradeToFullDiscovery(); 702 703 // Disconnects GATT connection on platforms that maintain a specific GATT 704 // connection. 705 virtual void DisconnectGatt() = 0; 706 707 // Returns a |BluetoothGattConnection| object that represents a reference to a 708 // GATT connection to this device. 709 virtual std::unique_ptr<BluetoothGattConnection> 710 CreateBluetoothGattConnectionObject(); 711 712 // Calls any pending callbacks for CreateGattConnection based on result of 713 // subclasses actions initiated in CreateGattConnectionImpl or related 714 // disconnection events. These may be called at any time, even multiple times, 715 // to ensure a change in platform state is correctly tracked. 716 // 717 // Under normal behavior it is expected that after CreateGattConnectionImpl 718 // an platform will call DidConnectGatt or DidFailToConnectGatt, but not 719 // DidDisconnectGatt. 720 void DidConnectGatt(); 721 void DidFailToConnectGatt(ConnectErrorCode); 722 void DidDisconnectGatt(); 723 724 // Tracks BluetoothGattConnection instances that act as a reference count 725 // keeping the GATT connection open. Instances call Add/RemoveGattConnection 726 // at creation & deletion. 727 void AddGattConnection(BluetoothGattConnection*); 728 void RemoveGattConnection(BluetoothGattConnection*); 729 730 // Update last_update_time_ so that the device appears as expired. 731 void SetAsExpiredForTesting(); 732 733 // Raw pointer to adapter owning this device object. Subclasses use platform 734 // specific pointers via adapter_. 735 BluetoothAdapter* const adapter_; 736 737 // Indicates whether this device supports limited discovery of a specific 738 // service. This is configured by the constructor of subclasses. If false, 739 // the UUID argument to |CreateGattConnection| is ignored. 740 bool supports_service_specific_discovery_ = false; 741 742 // Contains the specified service that was targeted for discovery. Only ever 743 // contains a value if |supports_service_specific_discovery_| is true. 744 base::Optional<BluetoothUUID> target_service_; 745 746 // Callbacks for pending success and error result of CreateGattConnection. 747 std::vector<GattConnectionCallback> create_gatt_connection_success_callbacks_; 748 std::vector<ConnectErrorCallback> create_gatt_connection_error_callbacks_; 749 750 // BluetoothGattConnection objects keeping the GATT connection alive. 751 std::set<BluetoothGattConnection*> gatt_connections_; 752 753 GattServiceMap gatt_services_; 754 bool gatt_services_discovery_complete_; 755 756 // Received Signal Strength Indicator of the advertisement received. 757 base::Optional<int8_t> inquiry_rssi_; 758 759 // Advertising Data flags of the device. 760 base::Optional<uint8_t> advertising_data_flags_; 761 762 // Tx Power advertised by the device. 763 base::Optional<int8_t> inquiry_tx_power_; 764 765 // Class that holds the union of Advertised UUIDs and Service UUIDs. 766 DeviceUUIDs device_uuids_; 767 768 // Map of BluetoothUUIDs to their advertised Service Data. 769 ServiceDataMap service_data_; 770 771 // Map of Manufacturer IDs to their advertised Manufacturer Data. 772 ManufacturerDataMap manufacturer_data_; 773 774 // Timestamp for when an advertisement was last seen. 775 base::Time last_update_time_; 776 777 private: 778 // Returns a localized string containing the device's bluetooth address and 779 // a device type for display when |name_| is empty. 780 base::string16 GetAddressWithLocalizedDeviceTypeName() const; 781 782 #if defined(OS_CHROMEOS) || defined(OS_LINUX) 783 // Remaining battery level of the device. 784 // TODO(https://crbug.com/973237): This field is different from others because 785 // it is not filled by the platform. In the future, when there is a unified 786 // Mojo service, this field will be moved to BluetoothDeviceInfo. 787 base::Optional<uint8_t> battery_percentage_; 788 #endif 789 790 DISALLOW_COPY_AND_ASSIGN(BluetoothDevice); 791 }; 792 793 } // namespace device 794 795 #endif // DEVICE_BLUETOOTH_BLUETOOTH_DEVICE_H_ 796