1 /** 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.bluetooth; 18 19 import static java.util.Objects.requireNonNull; 20 21 import android.annotation.IntDef; 22 import android.annotation.NonNull; 23 import android.annotation.Nullable; 24 import android.annotation.SystemApi; 25 import android.os.Parcel; 26 import android.os.Parcelable; 27 28 import java.lang.annotation.Retention; 29 import java.lang.annotation.RetentionPolicy; 30 31 /** 32 * Out Of Band Data for Bluetooth device pairing. 33 * 34 * <p>This object represents optional data obtained from a remote device through 35 * an out-of-band channel (eg. NFC, QR). 36 * 37 * <p>References: 38 * NFC AD Forum SSP 1.1 (AD) 39 * {@link https://members.nfc-forum.org//apps/group_public/download.php/24620/NFCForum-AD-BTSSP_1_1.pdf} 40 * Core Specification Supplement (CSS) V9 41 * 42 * <p>There are several BR/EDR Examples 43 * 44 * <p>Negotiated Handover: 45 * Bluetooth Carrier Configuration Record: 46 * - OOB Data Length 47 * - Device Address 48 * - Class of Device 49 * - Simple Pairing Hash C 50 * - Simple Pairing Randomizer R 51 * - Service Class UUID 52 * - Bluetooth Local Name 53 * 54 * <p>Static Handover: 55 * Bluetooth Carrier Configuration Record: 56 * - OOB Data Length 57 * - Device Address 58 * - Class of Device 59 * - Service Class UUID 60 * - Bluetooth Local Name 61 * 62 * <p>Simplified Tag Format for Single BT Carrier: 63 * Bluetooth OOB Data Record: 64 * - OOB Data Length 65 * - Device Address 66 * - Class of Device 67 * - Service Class UUID 68 * - Bluetooth Local Name 69 * 70 * @hide 71 */ 72 @SystemApi 73 public final class OobData implements Parcelable { 74 75 private static final String TAG = "OobData"; 76 /** The {@link OobData#mClassicLength} may be. (AD 3.1.1) (CSS 1.6.2) @hide */ 77 @SystemApi 78 public static final int OOB_LENGTH_OCTETS = 2; 79 /** 80 * The length for the {@link OobData#mDeviceAddressWithType}(6) and Address Type(1). 81 * (AD 3.1.2) (CSS 1.6.2) 82 * @hide 83 */ 84 @SystemApi 85 public static final int DEVICE_ADDRESS_OCTETS = 7; 86 /** The Class of Device is 3 octets. (AD 3.1.3) (CSS 1.6.2) @hide */ 87 @SystemApi 88 public static final int CLASS_OF_DEVICE_OCTETS = 3; 89 /** The Confirmation data must be 16 octets. (AD 3.2.2) (CSS 1.6.2) @hide */ 90 @SystemApi 91 public static final int CONFIRMATION_OCTETS = 16; 92 /** The Randomizer data must be 16 octets. (AD 3.2.3) (CSS 1.6.2) @hide */ 93 @SystemApi 94 public static final int RANDOMIZER_OCTETS = 16; 95 /** The LE Device Role length is 1 octet. (AD 3.3.2) (CSS 1.17) @hide */ 96 @SystemApi 97 public static final int LE_DEVICE_ROLE_OCTETS = 1; 98 /** The {@link OobData#mLeTemporaryKey} length. (3.4.1) @hide */ 99 @SystemApi 100 public static final int LE_TK_OCTETS = 16; 101 /** The {@link OobData#mLeAppearance} length. (3.4.1) @hide */ 102 @SystemApi 103 public static final int LE_APPEARANCE_OCTETS = 2; 104 /** The {@link OobData#mLeFlags} length. (3.4.1) @hide */ 105 @SystemApi 106 public static final int LE_DEVICE_FLAG_OCTETS = 1; // 1 octet to hold the 0-4 value. 107 108 // Le Roles 109 /** @hide */ 110 @Retention(RetentionPolicy.SOURCE) 111 @IntDef( 112 prefix = { "LE_DEVICE_ROLE_" }, 113 value = { 114 LE_DEVICE_ROLE_PERIPHERAL_ONLY, 115 LE_DEVICE_ROLE_CENTRAL_ONLY, 116 LE_DEVICE_ROLE_BOTH_PREFER_PERIPHERAL, 117 LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL 118 } 119 ) 120 public @interface LeRole {} 121 122 /** @hide */ 123 @SystemApi 124 public static final int LE_DEVICE_ROLE_PERIPHERAL_ONLY = 0x00; 125 /** @hide */ 126 @SystemApi 127 public static final int LE_DEVICE_ROLE_CENTRAL_ONLY = 0x01; 128 /** @hide */ 129 @SystemApi 130 public static final int LE_DEVICE_ROLE_BOTH_PREFER_PERIPHERAL = 0x02; 131 /** @hide */ 132 @SystemApi 133 public static final int LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL = 0x03; 134 135 // Le Flags 136 /** @hide */ 137 @Retention(RetentionPolicy.SOURCE) 138 @IntDef( 139 prefix = { "LE_FLAG_" }, 140 value = { 141 LE_FLAG_LIMITED_DISCOVERY_MODE, 142 LE_FLAG_GENERAL_DISCOVERY_MODE, 143 LE_FLAG_BREDR_NOT_SUPPORTED, 144 LE_FLAG_SIMULTANEOUS_CONTROLLER, 145 LE_FLAG_SIMULTANEOUS_HOST 146 } 147 ) 148 public @interface LeFlag {} 149 150 /** @hide */ 151 @SystemApi 152 public static final int LE_FLAG_LIMITED_DISCOVERY_MODE = 0x00; 153 /** @hide */ 154 @SystemApi 155 public static final int LE_FLAG_GENERAL_DISCOVERY_MODE = 0x01; 156 /** @hide */ 157 @SystemApi 158 public static final int LE_FLAG_BREDR_NOT_SUPPORTED = 0x02; 159 /** @hide */ 160 @SystemApi 161 public static final int LE_FLAG_SIMULTANEOUS_CONTROLLER = 0x03; 162 /** @hide */ 163 @SystemApi 164 public static final int LE_FLAG_SIMULTANEOUS_HOST = 0x04; 165 166 /** 167 * Builds an {@link OobData} object and validates that the required combination 168 * of values are present to create the LE specific OobData type. 169 * 170 * @hide 171 */ 172 @SystemApi 173 public static final class LeBuilder { 174 175 /** 176 * It is recommended that this Hash C is generated anew for each 177 * pairing. 178 * 179 * <p>It should be noted that on passive NFC this isn't possible as the data is static 180 * and immutable. 181 */ 182 private byte[] mConfirmationHash = null; 183 184 /** 185 * Optional, but adds more validity to the pairing. 186 * 187 * <p>If not present a value of 0 is assumed. 188 */ 189 private byte[] mRandomizerHash = new byte[] { 190 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 191 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 192 }; 193 194 /** 195 * The Bluetooth Device user-friendly name presented over Bluetooth Technology. 196 * 197 * <p>This is the name that may be displayed to the device user as part of the UI. 198 */ 199 private byte[] mDeviceName = null; 200 201 /** 202 * Sets the Bluetooth Device name to be used for UI purposes. 203 * 204 * <p>Optional attribute. 205 * 206 * @param deviceName byte array representing the name, may be 0 in length, not null. 207 * 208 * @return {@link OobData#ClassicBuilder} 209 * 210 * @throws NullPointerException if deviceName is null. 211 * 212 * @hide 213 */ 214 @NonNull 215 @SystemApi setDeviceName(@onNull byte[] deviceName)216 public LeBuilder setDeviceName(@NonNull byte[] deviceName) { 217 requireNonNull(deviceName); 218 this.mDeviceName = deviceName; 219 return this; 220 } 221 222 /** 223 * The Bluetooth Device Address is the address to which the OOB data belongs. 224 * 225 * <p>The length MUST be {@link OobData#DEVICE_ADDRESS_OCTETS} octets. 226 * 227 * <p> Address is encoded in Little Endian order. 228 * 229 * <p>e.g. 00:01:02:03:04:05 would be x05x04x03x02x01x00 230 */ 231 private final byte[] mDeviceAddressWithType; 232 233 /** 234 * During an LE connection establishment, one must be in the Peripheral mode and the other 235 * in the Central role. 236 * 237 * <p>Possible Values: 238 * {@link LE_DEVICE_ROLE_PERIPHERAL_ONLY} Only Peripheral supported 239 * {@link LE_DEVICE_ROLE_CENTRAL_ONLY} Only Central supported 240 * {@link LE_DEVICE_ROLE_BOTH_PREFER_PERIPHERAL} Central & Peripheral supported; 241 * Peripheral Preferred 242 * {@link LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL} Only peripheral supported; Central Preferred 243 * 0x04 - 0xFF Reserved 244 */ 245 private final @LeRole int mLeDeviceRole; 246 247 /** 248 * Temporary key value from the Security Manager. 249 * 250 * <p> Must be {@link LE_TK_OCTETS} in size 251 */ 252 private byte[] mLeTemporaryKey = null; 253 254 /** 255 * Defines the representation of the external appearance of the device. 256 * 257 * <p>For example, a mouse, remote control, or keyboard. 258 * 259 * <p>Used for visual on discovering device to represent icon/string/etc... 260 */ 261 private byte[] mLeAppearance = null; 262 263 /** 264 * Contains which discoverable mode to use, BR/EDR support and capability. 265 * 266 * <p>Possible LE Flags: 267 * {@link LE_FLAG_LIMITED_DISCOVERY_MODE} LE Limited Discoverable Mode. 268 * {@link LE_FLAG_GENERAL_DISCOVERY_MODE} LE General Discoverable Mode. 269 * {@link LE_FLAG_BREDR_NOT_SUPPORTED} BR/EDR Not Supported. Bit 37 of 270 * LMP Feature Mask Definitions. 271 * {@link LE_FLAG_SIMULTANEOUS_CONTROLLER} Simultaneous LE and BR/EDR to 272 * Same Device Capable (Controller). 273 * Bit 49 of LMP Feature Mask Definitions. 274 * {@link LE_FLAG_SIMULTANEOUS_HOST} Simultaneous LE and BR/EDR to 275 * Same Device Capable (Host). 276 * Bit 55 of LMP Feature Mask Definitions. 277 * <b>0x05- 0x07 Reserved</b> 278 */ 279 private @LeFlag int mLeFlags = LE_FLAG_GENERAL_DISCOVERY_MODE; // Invalid default 280 281 /** 282 * Main creation method for creating a LE version of {@link OobData}. 283 * 284 * <p>This object will allow the caller to call {@link LeBuilder#build()} 285 * to build the data object or add any option information to the builder. 286 * 287 * @param deviceAddressWithType the LE device address plus the address type (7 octets); 288 * not null. 289 * @param leDeviceRole whether the device supports Peripheral, Central, 290 * Both including preference; not null. (1 octet) 291 * @param confirmationHash Array consisting of {@link OobData#CONFIRMATION_OCTETS} octets 292 * of data. Data is derived from controller/host stack and is 293 * required for pairing OOB. 294 * 295 * <p>Possible Values: 296 * {@link LE_DEVICE_ROLE_PERIPHERAL_ONLY} Only Peripheral supported 297 * {@link LE_DEVICE_ROLE_CENTRAL_ONLY} Only Central supported 298 * {@link LE_DEVICE_ROLE_BOTH_PREFER_PERIPHERAL} Central & Peripheral supported; 299 * Peripheral Preferred 300 * {@link LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL} Only peripheral supported; Central Preferred 301 * 0x04 - 0xFF Reserved 302 * 303 * @throws IllegalArgumentException if any of the values fail to be set. 304 * @throws NullPointerException if any argument is null. 305 * 306 * @hide 307 */ 308 @SystemApi LeBuilder(@onNull byte[] confirmationHash, @NonNull byte[] deviceAddressWithType, @LeRole int leDeviceRole)309 public LeBuilder(@NonNull byte[] confirmationHash, @NonNull byte[] deviceAddressWithType, 310 @LeRole int leDeviceRole) { 311 requireNonNull(confirmationHash); 312 requireNonNull(deviceAddressWithType); 313 if (confirmationHash.length != OobData.CONFIRMATION_OCTETS) { 314 throw new IllegalArgumentException("confirmationHash must be " 315 + OobData.CONFIRMATION_OCTETS + " octets in length."); 316 } 317 this.mConfirmationHash = confirmationHash; 318 if (deviceAddressWithType.length != OobData.DEVICE_ADDRESS_OCTETS) { 319 throw new IllegalArgumentException("confirmationHash must be " 320 + OobData.DEVICE_ADDRESS_OCTETS+ " octets in length."); 321 } 322 this.mDeviceAddressWithType = deviceAddressWithType; 323 if (leDeviceRole < LE_DEVICE_ROLE_PERIPHERAL_ONLY 324 || leDeviceRole > LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL) { 325 throw new IllegalArgumentException("leDeviceRole must be a valid value."); 326 } 327 this.mLeDeviceRole = leDeviceRole; 328 } 329 330 /** 331 * Sets the Temporary Key value to be used by the LE Security Manager during 332 * LE pairing. 333 * 334 * @param leTemporaryKey byte array that shall be 16 bytes. Please see Bluetooth CSSv6, 335 * Part A 1.8 for a detailed description. 336 * 337 * @return {@link OobData#Builder} 338 * 339 * @throws IllegalArgumentException if the leTemporaryKey is an invalid format. 340 * @throws NullinterException if leTemporaryKey is null. 341 * 342 * @hide 343 */ 344 @NonNull 345 @SystemApi setLeTemporaryKey(@onNull byte[] leTemporaryKey)346 public LeBuilder setLeTemporaryKey(@NonNull byte[] leTemporaryKey) { 347 requireNonNull(leTemporaryKey); 348 if (leTemporaryKey.length != LE_TK_OCTETS) { 349 throw new IllegalArgumentException("leTemporaryKey must be " 350 + LE_TK_OCTETS + " octets in length."); 351 } 352 this.mLeTemporaryKey = leTemporaryKey; 353 return this; 354 } 355 356 /** 357 * @param randomizerHash byte array consisting of {@link OobData#RANDOMIZER_OCTETS} octets 358 * of data. Data is derived from controller/host stack and is required for pairing OOB. 359 * Also, randomizerHash may be all 0s or null in which case it becomes all 0s. 360 * 361 * @throws IllegalArgumentException if null or incorrect length randomizerHash was passed. 362 * @throws NullPointerException if randomizerHash is null. 363 * 364 * @hide 365 */ 366 @NonNull 367 @SystemApi setRandomizerHash(@onNull byte[] randomizerHash)368 public LeBuilder setRandomizerHash(@NonNull byte[] randomizerHash) { 369 requireNonNull(randomizerHash); 370 if (randomizerHash.length != OobData.RANDOMIZER_OCTETS) { 371 throw new IllegalArgumentException("randomizerHash must be " 372 + OobData.RANDOMIZER_OCTETS + " octets in length."); 373 } 374 this.mRandomizerHash = randomizerHash; 375 return this; 376 } 377 378 /** 379 * Sets the LE Flags necessary for the pairing scenario or discovery mode. 380 * 381 * @param leFlags enum value representing the 1 octet of data about discovery modes. 382 * 383 * <p>Possible LE Flags: 384 * {@link LE_FLAG_LIMITED_DISCOVERY_MODE} LE Limited Discoverable Mode. 385 * {@link LE_FLAG_GENERAL_DISCOVERY_MODE} LE General Discoverable Mode. 386 * {@link LE_FLAG_BREDR_NOT_SUPPORTED} BR/EDR Not Supported. Bit 37 of 387 * LMP Feature Mask Definitions. 388 * {@link LE_FLAG_SIMULTANEOUS_CONTROLLER} Simultaneous LE and BR/EDR to 389 * Same Device Capable (Controller) Bit 49 of LMP Feature Mask Definitions. 390 * {@link LE_FLAG_SIMULTANEOUS_HOST} Simultaneous LE and BR/EDR to 391 * Same Device Capable (Host). 392 * Bit 55 of LMP Feature Mask Definitions. 393 * 0x05- 0x07 Reserved 394 * 395 * @throws IllegalArgumentException for invalid flag 396 * @hide 397 */ 398 @NonNull 399 @SystemApi setLeFlags(@eFlag int leFlags)400 public LeBuilder setLeFlags(@LeFlag int leFlags) { 401 if (leFlags < LE_FLAG_LIMITED_DISCOVERY_MODE || leFlags > LE_FLAG_SIMULTANEOUS_HOST) { 402 throw new IllegalArgumentException("leFlags must be a valid value."); 403 } 404 this.mLeFlags = leFlags; 405 return this; 406 } 407 408 /** 409 * Validates and builds the {@link OobData} object for LE Security. 410 * 411 * @return {@link OobData} with given builder values 412 * 413 * @throws IllegalStateException if either of the 2 required fields were not set. 414 * 415 * @hide 416 */ 417 @NonNull 418 @SystemApi build()419 public OobData build() { 420 final OobData oob = 421 new OobData(this.mDeviceAddressWithType, this.mLeDeviceRole, 422 this.mConfirmationHash); 423 424 // If we have values, set them, otherwise use default 425 oob.mLeTemporaryKey = 426 (this.mLeTemporaryKey != null) ? this.mLeTemporaryKey : oob.mLeTemporaryKey; 427 oob.mLeAppearance = (this.mLeAppearance != null) 428 ? this.mLeAppearance : oob.mLeAppearance; 429 oob.mLeFlags = (this.mLeFlags != 0xF) ? this.mLeFlags : oob.mLeFlags; 430 oob.mDeviceName = (this.mDeviceName != null) ? this.mDeviceName : oob.mDeviceName; 431 oob.mRandomizerHash = this.mRandomizerHash; 432 return oob; 433 } 434 } 435 436 /** 437 * Builds an {@link OobData} object and validates that the required combination 438 * of values are present to create the Classic specific OobData type. 439 * 440 * @hide 441 */ 442 @SystemApi 443 public static final class ClassicBuilder { 444 // Used by both Classic and LE 445 /** 446 * It is recommended that this Hash C is generated anew for each 447 * pairing. 448 * 449 * <p>It should be noted that on passive NFC this isn't possible as the data is static 450 * and immutable. 451 * 452 * @hide 453 */ 454 private byte[] mConfirmationHash = null; 455 456 /** 457 * Optional, but adds more validity to the pairing. 458 * 459 * <p>If not present a value of 0 is assumed. 460 * 461 * @hide 462 */ 463 private byte[] mRandomizerHash = new byte[] { 464 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 465 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 466 }; 467 468 /** 469 * The Bluetooth Device user-friendly name presented over Bluetooth Technology. 470 * 471 * <p>This is the name that may be displayed to the device user as part of the UI. 472 * 473 * @hide 474 */ 475 private byte[] mDeviceName = null; 476 477 /** 478 * This length value provides the absolute length of total OOB data block used for 479 * Bluetooth BR/EDR 480 * 481 * <p>OOB communication, which includes the length field itself and the Bluetooth 482 * Device Address. 483 * 484 * <p>The minimum length that may be represented in this field is 8. 485 * 486 * @hide 487 */ 488 private final byte[] mClassicLength; 489 490 /** 491 * The Bluetooth Device Address is the address to which the OOB data belongs. 492 * 493 * <p>The length MUST be {@link OobData#DEVICE_ADDRESS_OCTETS} octets. 494 * 495 * <p> Address is encoded in Little Endian order. 496 * 497 * <p>e.g. 00:01:02:03:04:05 would be x05x04x03x02x01x00 498 * 499 * @hide 500 */ 501 private final byte[] mDeviceAddressWithType; 502 503 /** 504 * Class of Device information is to be used to provide a graphical representation 505 * to the user as part of UI involving operations. 506 * 507 * <p>This is not to be used to determine a particular service can be used. 508 * 509 * <p>The length MUST be {@link OobData#CLASS_OF_DEVICE_OCTETS} octets. 510 * 511 * @hide 512 */ 513 private byte[] mClassOfDevice = null; 514 515 /** 516 * Main creation method for creating a Classic version of {@link OobData}. 517 * 518 * <p>This object will allow the caller to call {@link ClassicBuilder#build()} 519 * to build the data object or add any option information to the builder. 520 * 521 * @param confirmationHash byte array consisting of {@link OobData#CONFIRMATION_OCTETS} 522 * octets of data. Data is derived from controller/host stack and is required for pairing 523 * OOB. 524 * @param classicLength byte array representing the length of data from 8-65535 across 2 525 * octets (0xXXXX). 526 * @param deviceAddressWithType byte array representing the Bluetooth Address of the device 527 * that owns the OOB data. (i.e. the originator) [6 octets] 528 * 529 * @throws IllegalArgumentException if any of the values fail to be set. 530 * @throws NullPointerException if any argument is null. 531 * 532 * @hide 533 */ 534 @SystemApi ClassicBuilder(@onNull byte[] confirmationHash, @NonNull byte[] classicLength, @NonNull byte[] deviceAddressWithType)535 public ClassicBuilder(@NonNull byte[] confirmationHash, @NonNull byte[] classicLength, 536 @NonNull byte[] deviceAddressWithType) { 537 requireNonNull(confirmationHash); 538 requireNonNull(classicLength); 539 requireNonNull(deviceAddressWithType); 540 if (confirmationHash.length != OobData.CONFIRMATION_OCTETS) { 541 throw new IllegalArgumentException("confirmationHash must be " 542 + OobData.CONFIRMATION_OCTETS + " octets in length."); 543 } 544 this.mConfirmationHash = confirmationHash; 545 if (classicLength.length != OOB_LENGTH_OCTETS) { 546 throw new IllegalArgumentException("classicLength must be " 547 + OOB_LENGTH_OCTETS + " octets in length."); 548 } 549 this.mClassicLength = classicLength; 550 if (deviceAddressWithType.length != DEVICE_ADDRESS_OCTETS) { 551 throw new IllegalArgumentException("deviceAddressWithType must be " 552 + DEVICE_ADDRESS_OCTETS + " octets in length."); 553 } 554 this.mDeviceAddressWithType = deviceAddressWithType; 555 } 556 557 /** 558 * @param randomizerHash byte array consisting of {@link OobData#RANDOMIZER_OCTETS} octets 559 * of data. Data is derived from controller/host stack and is required for pairing OOB. 560 * Also, randomizerHash may be all 0s or null in which case it becomes all 0s. 561 * 562 * @throws IllegalArgumentException if null or incorrect length randomizerHash was passed. 563 * @throws NullPointerException if randomizerHash is null. 564 * 565 * @hide 566 */ 567 @NonNull 568 @SystemApi setRandomizerHash(@onNull byte[] randomizerHash)569 public ClassicBuilder setRandomizerHash(@NonNull byte[] randomizerHash) { 570 requireNonNull(randomizerHash); 571 if (randomizerHash.length != OobData.RANDOMIZER_OCTETS) { 572 throw new IllegalArgumentException("randomizerHash must be " 573 + OobData.RANDOMIZER_OCTETS + " octets in length."); 574 } 575 this.mRandomizerHash = randomizerHash; 576 return this; 577 } 578 579 /** 580 * Sets the Bluetooth Device name to be used for UI purposes. 581 * 582 * <p>Optional attribute. 583 * 584 * @param deviceName byte array representing the name, may be 0 in length, not null. 585 * 586 * @return {@link OobData#ClassicBuilder} 587 * 588 * @throws NullPointerException if deviceName is null 589 * 590 * @hide 591 */ 592 @NonNull 593 @SystemApi setDeviceName(@onNull byte[] deviceName)594 public ClassicBuilder setDeviceName(@NonNull byte[] deviceName) { 595 requireNonNull(deviceName); 596 this.mDeviceName = deviceName; 597 return this; 598 } 599 600 /** 601 * Sets the Bluetooth Class of Device; used for UI purposes only. 602 * 603 * <p>Not an indicator of available services! 604 * 605 * <p>Optional attribute. 606 * 607 * @param classOfDevice byte array of {@link OobData#CLASS_OF_DEVICE_OCTETS} octets. 608 * 609 * @return {@link OobData#ClassicBuilder} 610 * 611 * @throws IllegalArgumentException if length is not equal to 612 * {@link OobData#CLASS_OF_DEVICE_OCTETS} octets. 613 * @throws NullPointerException if classOfDevice is null. 614 * 615 * @hide 616 */ 617 @NonNull 618 @SystemApi setClassOfDevice(@onNull byte[] classOfDevice)619 public ClassicBuilder setClassOfDevice(@NonNull byte[] classOfDevice) { 620 requireNonNull(classOfDevice); 621 if (classOfDevice.length != OobData.CLASS_OF_DEVICE_OCTETS) { 622 throw new IllegalArgumentException("classOfDevice must be " 623 + OobData.CLASS_OF_DEVICE_OCTETS + " octets in length."); 624 } 625 this.mClassOfDevice = classOfDevice; 626 return this; 627 } 628 629 /** 630 * Validates and builds the {@link OobDat object for Classic Security. 631 * 632 * @return {@link OobData} with previously given builder values. 633 * 634 * @hide 635 */ 636 @NonNull 637 @SystemApi build()638 public OobData build() { 639 final OobData oob = 640 new OobData(this.mClassicLength, this.mDeviceAddressWithType, 641 this.mConfirmationHash); 642 // If we have values, set them, otherwise use default 643 oob.mDeviceName = (this.mDeviceName != null) ? this.mDeviceName : oob.mDeviceName; 644 oob.mClassOfDevice = (this.mClassOfDevice != null) 645 ? this.mClassOfDevice : oob.mClassOfDevice; 646 oob.mRandomizerHash = this.mRandomizerHash; 647 return oob; 648 } 649 } 650 651 // Members (Defaults for Optionals must be set or Parceling fails on NPE) 652 // Both 653 private final byte[] mDeviceAddressWithType; 654 private final byte[] mConfirmationHash; 655 private byte[] mRandomizerHash = new byte[] { 656 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 657 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 658 }; 659 // Default the name to "Bluetooth Device" 660 private byte[] mDeviceName = new byte[] { 661 // Bluetooth 662 0x42, 0x6c, 0x75, 0x65, 0x74, 0x6f, 0x6f, 0x74, 0x68, 663 // <space>Device 664 0x20, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65 665 }; 666 667 // Classic 668 private final byte[] mClassicLength; 669 private byte[] mClassOfDevice = new byte[CLASS_OF_DEVICE_OCTETS]; 670 671 // LE 672 private final @LeRole int mLeDeviceRole; 673 private byte[] mLeTemporaryKey = new byte[LE_TK_OCTETS]; 674 private byte[] mLeAppearance = new byte[LE_APPEARANCE_OCTETS]; 675 private @LeFlag int mLeFlags = LE_FLAG_LIMITED_DISCOVERY_MODE; 676 677 /** 678 * @return byte array representing the MAC address of a bluetooth device. 679 * The Address is 6 octets long with a 1 octet address type associated with the address. 680 * 681 * <p>For classic this will be 6 byte address plus the default of PUBLIC_ADDRESS Address Type. 682 * For LE there are more choices for Address Type. 683 * 684 * @hide 685 */ 686 @NonNull 687 @SystemApi getDeviceAddressWithType()688 public byte[] getDeviceAddressWithType() { 689 return mDeviceAddressWithType; 690 } 691 692 /** 693 * @return byte array representing the confirmationHash value 694 * which is used to confirm the identity to the controller. 695 * 696 * @hide 697 */ 698 @NonNull 699 @SystemApi getConfirmationHash()700 public byte[] getConfirmationHash() { 701 return mConfirmationHash; 702 } 703 704 /** 705 * @return byte array representing the randomizerHash value 706 * which is used to verify the identity of the controller. 707 * 708 * @hide 709 */ 710 @NonNull 711 @SystemApi getRandomizerHash()712 public byte[] getRandomizerHash() { 713 return mRandomizerHash; 714 } 715 716 /** 717 * @return Device Name used for displaying name in UI. 718 * 719 * <p>Also, this will be populated with the LE Local Name if the data is for LE. 720 * 721 * @hide 722 */ 723 @Nullable 724 @SystemApi getDeviceName()725 public byte[] getDeviceName() { 726 return mDeviceName; 727 } 728 729 /** 730 * @return byte array representing the oob data length which is the length 731 * of all of the data including these octets. 732 * 733 * @hide 734 */ 735 @NonNull 736 @SystemApi getClassicLength()737 public byte[] getClassicLength() { 738 return mClassicLength; 739 } 740 741 /** 742 * @return byte array representing the class of device for UI display. 743 * 744 * <p>Does not indicate services available; for display only. 745 * 746 * @hide 747 */ 748 @NonNull 749 @SystemApi getClassOfDevice()750 public byte[] getClassOfDevice() { 751 return mClassOfDevice; 752 } 753 754 /** 755 * @return Temporary Key used for LE pairing. 756 * 757 * @hide 758 */ 759 @Nullable 760 @SystemApi getLeTemporaryKey()761 public byte[] getLeTemporaryKey() { 762 return mLeTemporaryKey; 763 } 764 765 /** 766 * @return Appearance used for LE pairing. For use in UI situations 767 * when determining what sort of icons or text to display regarding 768 * the device. 769 * 770 * @hide 771 */ 772 @Nullable 773 @SystemApi getLeAppearance()774 public byte[] getLeAppearance() { 775 return mLeAppearance; 776 } 777 778 /** 779 * @return Flags used to determing discoverable mode to use, BR/EDR Support, and Capability. 780 * 781 * <p>Possible LE Flags: 782 * {@link LE_FLAG_LIMITED_DISCOVERY_MODE} LE Limited Discoverable Mode. 783 * {@link LE_FLAG_GENERAL_DISCOVERY_MODE} LE General Discoverable Mode. 784 * {@link LE_FLAG_BREDR_NOT_SUPPORTED} BR/EDR Not Supported. Bit 37 of 785 * LMP Feature Mask Definitions. 786 * {@link LE_FLAG_SIMULTANEOUS_CONTROLLER} Simultaneous LE and BR/EDR to 787 * Same Device Capable (Controller). 788 * Bit 49 of LMP Feature Mask Definitions. 789 * {@link LE_FLAG_SIMULTANEOUS_HOST} Simultaneous LE and BR/EDR to 790 * Same Device Capable (Host). 791 * Bit 55 of LMP Feature Mask Definitions. 792 * <b>0x05- 0x07 Reserved</b> 793 * 794 * @hide 795 */ 796 @NonNull 797 @SystemApi 798 @LeFlag getLeFlags()799 public int getLeFlags() { 800 return mLeFlags; 801 } 802 803 /** 804 * @return the supported and preferred roles of the LE device. 805 * 806 * <p>Possible Values: 807 * {@link LE_DEVICE_ROLE_PERIPHERAL_ONLY} Only Peripheral supported 808 * {@link LE_DEVICE_ROLE_CENTRAL_ONLY} Only Central supported 809 * {@link LE_DEVICE_ROLE_BOTH_PREFER_PERIPHERAL} Central & Peripheral supported; 810 * Peripheral Preferred 811 * {@link LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL} Only peripheral supported; Central Preferred 812 * 0x04 - 0xFF Reserved 813 * 814 * @hide 815 */ 816 @NonNull 817 @SystemApi 818 @LeRole getLeDeviceRole()819 public int getLeDeviceRole() { 820 return mLeDeviceRole; 821 } 822 823 /** 824 * Classic Security Constructor 825 */ OobData(@onNull byte[] classicLength, @NonNull byte[] deviceAddressWithType, @NonNull byte[] confirmationHash)826 private OobData(@NonNull byte[] classicLength, @NonNull byte[] deviceAddressWithType, 827 @NonNull byte[] confirmationHash) { 828 mClassicLength = classicLength; 829 mDeviceAddressWithType = deviceAddressWithType; 830 mConfirmationHash = confirmationHash; 831 mLeDeviceRole = -1; // Satisfy final 832 } 833 834 /** 835 * LE Security Constructor 836 */ OobData(@onNull byte[] deviceAddressWithType, @LeRole int leDeviceRole, @NonNull byte[] confirmationHash)837 private OobData(@NonNull byte[] deviceAddressWithType, @LeRole int leDeviceRole, 838 @NonNull byte[] confirmationHash) { 839 mDeviceAddressWithType = deviceAddressWithType; 840 mLeDeviceRole = leDeviceRole; 841 mConfirmationHash = confirmationHash; 842 mClassicLength = new byte[OOB_LENGTH_OCTETS]; // Satisfy final 843 } 844 OobData(Parcel in)845 private OobData(Parcel in) { 846 // Both 847 mDeviceAddressWithType = in.createByteArray(); 848 mConfirmationHash = in.createByteArray(); 849 mRandomizerHash = in.createByteArray(); 850 mDeviceName = in.createByteArray(); 851 852 // Classic 853 mClassicLength = in.createByteArray(); 854 mClassOfDevice = in.createByteArray(); 855 856 // LE 857 mLeDeviceRole = in.readInt(); 858 mLeTemporaryKey = in.createByteArray(); 859 mLeAppearance = in.createByteArray(); 860 mLeFlags = in.readInt(); 861 } 862 863 /** 864 * @hide 865 */ 866 @Override describeContents()867 public int describeContents() { 868 return 0; 869 } 870 871 /** 872 * @hide 873 */ 874 @Override writeToParcel(@onNull Parcel out, int flags)875 public void writeToParcel(@NonNull Parcel out, int flags) { 876 // Both 877 // Required 878 out.writeByteArray(mDeviceAddressWithType); 879 // Required 880 out.writeByteArray(mConfirmationHash); 881 // Optional 882 out.writeByteArray(mRandomizerHash); 883 // Optional 884 out.writeByteArray(mDeviceName); 885 886 // Classic 887 // Required 888 out.writeByteArray(mClassicLength); 889 // Optional 890 out.writeByteArray(mClassOfDevice); 891 892 // LE 893 // Required 894 out.writeInt(mLeDeviceRole); 895 // Required 896 out.writeByteArray(mLeTemporaryKey); 897 // Optional 898 out.writeByteArray(mLeAppearance); 899 // Optional 900 out.writeInt(mLeFlags); 901 } 902 903 // For Parcelable 904 public static final @android.annotation.NonNull Parcelable.Creator<OobData> CREATOR = 905 new Parcelable.Creator<OobData>() { 906 public OobData createFromParcel(Parcel in) { 907 return new OobData(in); 908 } 909 910 public OobData[] newArray(int size) { 911 return new OobData[size]; 912 } 913 }; 914 915 /** 916 * @return a {@link String} representation of the OobData object. 917 * 918 * @hide 919 */ 920 @Override 921 @NonNull toString()922 public String toString() { 923 return "OobData: \n\t" 924 // Both 925 + "Device Address With Type: " + toHexString(mDeviceAddressWithType) + "\n\t" 926 + "Confirmation: " + toHexString(mConfirmationHash) + "\n\t" 927 + "Randomizer: " + toHexString(mRandomizerHash) + "\n\t" 928 + "Device Name: " + toHexString(mDeviceName) + "\n\t" 929 // Classic 930 + "OobData Length: " + toHexString(mClassicLength) + "\n\t" 931 + "Class of Device: " + toHexString(mClassOfDevice) + "\n\t" 932 // LE 933 + "LE Device Role: " + toHexString(mLeDeviceRole) + "\n\t" 934 + "LE Temporary Key: " + toHexString(mLeTemporaryKey) + "\n\t" 935 + "LE Appearance: " + toHexString(mLeAppearance) + "\n\t" 936 + "LE Flags: " + toHexString(mLeFlags) + "\n\t"; 937 } 938 939 @NonNull toHexString(@onNull int b)940 private String toHexString(@NonNull int b) { 941 return toHexString(new byte[] {(byte) b}); 942 } 943 944 @NonNull toHexString(@onNull byte b)945 private String toHexString(@NonNull byte b) { 946 return toHexString(new byte[] {b}); 947 } 948 949 @NonNull toHexString(@onNull byte[] array)950 private String toHexString(@NonNull byte[] array) { 951 StringBuilder builder = new StringBuilder(array.length * 2); 952 for (byte b: array) { 953 builder.append(String.format("%02x", b)); 954 } 955 return builder.toString(); 956 } 957 } 958