/** * Copyright (C) 2016 The Android Open Source Project * *
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of the License at * *
http://www.apache.org/licenses/LICENSE-2.0 * *
Unless required by applicable law or agreed to in writing, software distributed under the * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing permissions and * limitations under the License. */ package android.bluetooth; import static java.util.Objects.requireNonNull; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * Out Of Band Data for Bluetooth device pairing. * *
This object represents optional data obtained from a remote device through an out-of-band * channel (eg. NFC, QR). * *
References: NFC * AD Forum SSP 1.1 (AD) * *
Core Specification Supplement (CSS) V9 * *
There are several BR/EDR Examples * *
Negotiated Handover: Bluetooth Carrier Configuration Record: - OOB Data Length - Device * Address - Class of Device - Simple Pairing Hash C - Simple Pairing Randomizer R - Service Class * UUID - Bluetooth Local Name * *
Static Handover: Bluetooth Carrier Configuration Record: - OOB Data Length - Device Address - * Class of Device - Service Class UUID - Bluetooth Local Name * *
Simplified Tag Format for Single BT Carrier: Bluetooth OOB Data Record: - OOB Data Length - * Device Address - Class of Device - Service Class UUID - Bluetooth Local Name * * @hide */ @SystemApi public final class OobData implements Parcelable { private static final String TAG = "OobData"; /** The {@link OobData#mClassicLength} may be. (AD 3.1.1) (CSS 1.6.2) @hide */ @SystemApi public static final int OOB_LENGTH_OCTETS = 2; /** * The length for the {@link OobData#mDeviceAddressWithType}(6) and Address Type(1). (AD 3.1.2) * (CSS 1.6.2) * * @hide */ @SystemApi public static final int DEVICE_ADDRESS_OCTETS = 7; /** The Class of Device is 3 octets. (AD 3.1.3) (CSS 1.6.2) @hide */ @SystemApi public static final int CLASS_OF_DEVICE_OCTETS = 3; /** The Confirmation data must be 16 octets. (AD 3.2.2) (CSS 1.6.2) @hide */ @SystemApi public static final int CONFIRMATION_OCTETS = 16; /** The Randomizer data must be 16 octets. (AD 3.2.3) (CSS 1.6.2) @hide */ @SystemApi public static final int RANDOMIZER_OCTETS = 16; /** The LE Device Role length is 1 octet. (AD 3.3.2) (CSS 1.17) @hide */ @SystemApi public static final int LE_DEVICE_ROLE_OCTETS = 1; /** The {@link OobData#mLeTemporaryKey} length. (3.4.1) @hide */ @SystemApi public static final int LE_TK_OCTETS = 16; /** The {@link OobData#mLeAppearance} length. (3.4.1) @hide */ @SystemApi public static final int LE_APPEARANCE_OCTETS = 2; /** The {@link OobData#mLeFlags} length. (3.4.1) @hide */ @SystemApi public static final int LE_DEVICE_FLAG_OCTETS = 1; // 1 octet to hold the 0-4 value. // Le Roles /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef( prefix = {"LE_DEVICE_ROLE_"}, value = { LE_DEVICE_ROLE_PERIPHERAL_ONLY, LE_DEVICE_ROLE_CENTRAL_ONLY, LE_DEVICE_ROLE_BOTH_PREFER_PERIPHERAL, LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL }) public @interface LeRole {} /** @hide */ @SystemApi public static final int LE_DEVICE_ROLE_PERIPHERAL_ONLY = 0x00; /** @hide */ @SystemApi public static final int LE_DEVICE_ROLE_CENTRAL_ONLY = 0x01; /** @hide */ @SystemApi public static final int LE_DEVICE_ROLE_BOTH_PREFER_PERIPHERAL = 0x02; /** @hide */ @SystemApi public static final int LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL = 0x03; // Le Flags /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef( prefix = {"LE_FLAG_"}, value = { LE_FLAG_LIMITED_DISCOVERY_MODE, LE_FLAG_GENERAL_DISCOVERY_MODE, LE_FLAG_BREDR_NOT_SUPPORTED, LE_FLAG_SIMULTANEOUS_CONTROLLER, LE_FLAG_SIMULTANEOUS_HOST }) public @interface LeFlag {} /** @hide */ @SystemApi public static final int LE_FLAG_LIMITED_DISCOVERY_MODE = 0x00; /** @hide */ @SystemApi public static final int LE_FLAG_GENERAL_DISCOVERY_MODE = 0x01; /** @hide */ @SystemApi public static final int LE_FLAG_BREDR_NOT_SUPPORTED = 0x02; /** @hide */ @SystemApi public static final int LE_FLAG_SIMULTANEOUS_CONTROLLER = 0x03; /** @hide */ @SystemApi public static final int LE_FLAG_SIMULTANEOUS_HOST = 0x04; /** * Builds an {@link OobData} object and validates that the required combination of values are * present to create the LE specific OobData type. * * @hide */ @SystemApi public static final class LeBuilder { /** * It is recommended that this Hash C is generated anew for each pairing. * *
It should be noted that on passive NFC this isn't possible as the data is static and * immutable. */ private byte[] mConfirmationHash = null; /** * Optional, but adds more validity to the pairing. * *
If not present a value of 0 is assumed. */ private byte[] mRandomizerHash = new byte[] { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, }; /** * The Bluetooth Device user-friendly name presented over Bluetooth Technology. * *
This is the name that may be displayed to the device user as part of the UI. */ private byte[] mDeviceName = null; /** * Sets the Bluetooth Device name to be used for UI purposes. * *
Optional attribute. * * @param deviceName byte array representing the name, may be 0 in length, not null. * @return {@link OobData#ClassicBuilder} * @throws NullPointerException if deviceName is null. * @hide */ @NonNull @SystemApi public LeBuilder setDeviceName(@NonNull byte[] deviceName) { requireNonNull(deviceName); this.mDeviceName = deviceName; return this; } /** * The Bluetooth Device Address is the address to which the OOB data belongs. * *
The length MUST be {@link OobData#DEVICE_ADDRESS_OCTETS} octets. * *
Address is encoded in Little Endian order. * *
e.g. 00:01:02:03:04:05 would be x05x04x03x02x01x00 */ private final byte[] mDeviceAddressWithType; /** * During an LE connection establishment, one must be in the Peripheral mode and the other * in the Central role. * *
Possible Values: {@link LE_DEVICE_ROLE_PERIPHERAL_ONLY} Only Peripheral supported * {@link LE_DEVICE_ROLE_CENTRAL_ONLY} Only Central supported {@link * LE_DEVICE_ROLE_BOTH_PREFER_PERIPHERAL} Central & Peripheral supported; Peripheral * Preferred {@link LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL} Only peripheral supported; Central * Preferred 0x04 - 0xFF Reserved */ private final @LeRole int mLeDeviceRole; /** * Temporary key value from the Security Manager. * *
Must be {@link LE_TK_OCTETS} in size */ private byte[] mLeTemporaryKey = null; /** * Defines the representation of the external appearance of the device. * *
For example, a mouse, remote control, or keyboard. * *
Used for visual on discovering device to represent icon/string/etc... */ private byte[] mLeAppearance = null; /** * Contains which discoverable mode to use, BR/EDR support and capability. * *
Possible LE Flags: {@link LE_FLAG_LIMITED_DISCOVERY_MODE} LE Limited Discoverable * Mode. {@link LE_FLAG_GENERAL_DISCOVERY_MODE} LE General Discoverable Mode. {@link * LE_FLAG_BREDR_NOT_SUPPORTED} BR/EDR Not Supported. Bit 37 of LMP Feature Mask * Definitions. {@link LE_FLAG_SIMULTANEOUS_CONTROLLER} Simultaneous LE and BR/EDR to Same * Device Capable (Controller). Bit 49 of LMP Feature Mask Definitions. {@link * LE_FLAG_SIMULTANEOUS_HOST} Simultaneous LE and BR/EDR to Same Device Capable (Host). Bit * 55 of LMP Feature Mask Definitions. 0x05- 0x07 Reserved */ private @LeFlag int mLeFlags = LE_FLAG_GENERAL_DISCOVERY_MODE; // Invalid default /** * Main creation method for creating a LE version of {@link OobData}. * *
This object will allow the caller to call {@link LeBuilder#build()} to build the data * object or add any option information to the builder. * * @param deviceAddressWithType the LE device address plus the address type (7 octets); not * null. * @param leDeviceRole whether the device supports Peripheral, Central, Both including * preference; not null. (1 octet) * @param confirmationHash Array consisting of {@link OobData#CONFIRMATION_OCTETS} octets of * data. Data is derived from controller/host stack and is required for pairing OOB. *
Possible Values: {@link LE_DEVICE_ROLE_PERIPHERAL_ONLY} Only Peripheral supported * {@link LE_DEVICE_ROLE_CENTRAL_ONLY} Only Central supported {@link * LE_DEVICE_ROLE_BOTH_PREFER_PERIPHERAL} Central & Peripheral supported; Peripheral * Preferred {@link LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL} Only peripheral supported; * Central Preferred 0x04 - 0xFF Reserved * @throws IllegalArgumentException if any of the values fail to be set. * @throws NullPointerException if any argument is null. * @hide */ @SystemApi public LeBuilder( @NonNull byte[] confirmationHash, @NonNull byte[] deviceAddressWithType, @LeRole int leDeviceRole) { requireNonNull(confirmationHash); requireNonNull(deviceAddressWithType); if (confirmationHash.length != OobData.CONFIRMATION_OCTETS) { throw new IllegalArgumentException( "confirmationHash must be " + OobData.CONFIRMATION_OCTETS + " octets in length."); } this.mConfirmationHash = confirmationHash; if (deviceAddressWithType.length != OobData.DEVICE_ADDRESS_OCTETS) { throw new IllegalArgumentException( "confirmationHash must be " + OobData.DEVICE_ADDRESS_OCTETS + " octets in length."); } this.mDeviceAddressWithType = deviceAddressWithType; if (leDeviceRole < LE_DEVICE_ROLE_PERIPHERAL_ONLY || leDeviceRole > LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL) { throw new IllegalArgumentException("leDeviceRole must be a valid value."); } this.mLeDeviceRole = leDeviceRole; } /** * Sets the Temporary Key value to be used by the LE Security Manager during LE pairing. * * @param leTemporaryKey byte array that shall be 16 bytes. Please see Bluetooth CSSv6, Part * A 1.8 for a detailed description. * @return {@link OobData#Builder} * @throws IllegalArgumentException if the leTemporaryKey is an invalid format. * @throws NullinterException if leTemporaryKey is null. * @hide */ @NonNull @SystemApi public LeBuilder setLeTemporaryKey(@NonNull byte[] leTemporaryKey) { requireNonNull(leTemporaryKey); if (leTemporaryKey.length != LE_TK_OCTETS) { throw new IllegalArgumentException( "leTemporaryKey must be " + LE_TK_OCTETS + " octets in length."); } this.mLeTemporaryKey = leTemporaryKey; return this; } /** * @param randomizerHash byte array consisting of {@link OobData#RANDOMIZER_OCTETS} octets * of data. Data is derived from controller/host stack and is required for pairing OOB. * Also, randomizerHash may be all 0s or null in which case it becomes all 0s. * @throws IllegalArgumentException if null or incorrect length randomizerHash was passed. * @throws NullPointerException if randomizerHash is null. * @hide */ @NonNull @SystemApi public LeBuilder setRandomizerHash(@NonNull byte[] randomizerHash) { requireNonNull(randomizerHash); if (randomizerHash.length != OobData.RANDOMIZER_OCTETS) { throw new IllegalArgumentException( "randomizerHash must be " + OobData.RANDOMIZER_OCTETS + " octets in length."); } this.mRandomizerHash = randomizerHash; return this; } /** * Sets the LE Flags necessary for the pairing scenario or discovery mode. * * @param leFlags enum value representing the 1 octet of data about discovery modes. *
Possible LE Flags: {@link LE_FLAG_LIMITED_DISCOVERY_MODE} LE Limited Discoverable * Mode. {@link LE_FLAG_GENERAL_DISCOVERY_MODE} LE General Discoverable Mode. {@link * LE_FLAG_BREDR_NOT_SUPPORTED} BR/EDR Not Supported. Bit 37 of LMP Feature Mask * Definitions. {@link LE_FLAG_SIMULTANEOUS_CONTROLLER} Simultaneous LE and BR/EDR to * Same Device Capable (Controller) Bit 49 of LMP Feature Mask Definitions. {@link * LE_FLAG_SIMULTANEOUS_HOST} Simultaneous LE and BR/EDR to Same Device Capable (Host). * Bit 55 of LMP Feature Mask Definitions. 0x05- 0x07 Reserved * @throws IllegalArgumentException for invalid flag * @hide */ @NonNull @SystemApi public LeBuilder setLeFlags(@LeFlag int leFlags) { if (leFlags < LE_FLAG_LIMITED_DISCOVERY_MODE || leFlags > LE_FLAG_SIMULTANEOUS_HOST) { throw new IllegalArgumentException("leFlags must be a valid value."); } this.mLeFlags = leFlags; return this; } /** * Validates and builds the {@link OobData} object for LE Security. * * @return {@link OobData} with given builder values * @throws IllegalStateException if either of the 2 required fields were not set. * @hide */ @NonNull @SystemApi public OobData build() { final OobData oob = new OobData( this.mDeviceAddressWithType, this.mLeDeviceRole, this.mConfirmationHash); // If we have values, set them, otherwise use default oob.mLeTemporaryKey = (this.mLeTemporaryKey != null) ? this.mLeTemporaryKey : oob.mLeTemporaryKey; oob.mLeAppearance = (this.mLeAppearance != null) ? this.mLeAppearance : oob.mLeAppearance; oob.mLeFlags = (this.mLeFlags != 0xF) ? this.mLeFlags : oob.mLeFlags; oob.mDeviceName = (this.mDeviceName != null) ? this.mDeviceName : oob.mDeviceName; oob.mRandomizerHash = this.mRandomizerHash; return oob; } } /** * Builds an {@link OobData} object and validates that the required combination of values are * present to create the Classic specific OobData type. * * @hide */ @SystemApi public static final class ClassicBuilder { // Used by both Classic and LE /** * It is recommended that this Hash C is generated anew for each pairing. * *
It should be noted that on passive NFC this isn't possible as the data is static and * immutable. * * @hide */ private byte[] mConfirmationHash = null; /** * Optional, but adds more validity to the pairing. * *
If not present a value of 0 is assumed. * * @hide */ private byte[] mRandomizerHash = new byte[] { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, }; /** * The Bluetooth Device user-friendly name presented over Bluetooth Technology. * *
This is the name that may be displayed to the device user as part of the UI. * * @hide */ private byte[] mDeviceName = null; /** * This length value provides the absolute length of total OOB data block used for Bluetooth * BR/EDR * *
OOB communication, which includes the length field itself and the Bluetooth Device * Address. * *
The minimum length that may be represented in this field is 8. * * @hide */ private final byte[] mClassicLength; /** * The Bluetooth Device Address is the address to which the OOB data belongs. * *
The length MUST be {@link OobData#DEVICE_ADDRESS_OCTETS} octets. * *
Address is encoded in Little Endian order. * *
e.g. 00:01:02:03:04:05 would be x05x04x03x02x01x00 * * @hide */ private final byte[] mDeviceAddressWithType; /** * Class of Device information is to be used to provide a graphical representation to the * user as part of UI involving operations. * *
This is not to be used to determine a particular service can be used. * *
The length MUST be {@link OobData#CLASS_OF_DEVICE_OCTETS} octets. * * @hide */ private byte[] mClassOfDevice = null; /** * Main creation method for creating a Classic version of {@link OobData}. * *
This object will allow the caller to call {@link ClassicBuilder#build()} to build the * data object or add any option information to the builder. * * @param confirmationHash byte array consisting of {@link OobData#CONFIRMATION_OCTETS} * octets of data. Data is derived from controller/host stack and is required for * pairing OOB. * @param classicLength byte array representing the length of data from 8-65535 across 2 * octets (0xXXXX). * @param deviceAddressWithType byte array representing the Bluetooth Address of the device * that owns the OOB data. (i.e. the originator) [6 octets] * @throws IllegalArgumentException if any of the values fail to be set. * @throws NullPointerException if any argument is null. * @hide */ @SystemApi public ClassicBuilder( @NonNull byte[] confirmationHash, @NonNull byte[] classicLength, @NonNull byte[] deviceAddressWithType) { requireNonNull(confirmationHash); requireNonNull(classicLength); requireNonNull(deviceAddressWithType); if (confirmationHash.length != OobData.CONFIRMATION_OCTETS) { throw new IllegalArgumentException( "confirmationHash must be " + OobData.CONFIRMATION_OCTETS + " octets in length."); } this.mConfirmationHash = confirmationHash; if (classicLength.length != OOB_LENGTH_OCTETS) { throw new IllegalArgumentException( "classicLength must be " + OOB_LENGTH_OCTETS + " octets in length."); } this.mClassicLength = classicLength; if (deviceAddressWithType.length != DEVICE_ADDRESS_OCTETS) { throw new IllegalArgumentException( "deviceAddressWithType must be " + DEVICE_ADDRESS_OCTETS + " octets in length."); } this.mDeviceAddressWithType = deviceAddressWithType; } /** * @param randomizerHash byte array consisting of {@link OobData#RANDOMIZER_OCTETS} octets * of data. Data is derived from controller/host stack and is required for pairing OOB. * Also, randomizerHash may be all 0s or null in which case it becomes all 0s. * @throws IllegalArgumentException if null or incorrect length randomizerHash was passed. * @throws NullPointerException if randomizerHash is null. * @hide */ @NonNull @SystemApi public ClassicBuilder setRandomizerHash(@NonNull byte[] randomizerHash) { requireNonNull(randomizerHash); if (randomizerHash.length != OobData.RANDOMIZER_OCTETS) { throw new IllegalArgumentException( "randomizerHash must be " + OobData.RANDOMIZER_OCTETS + " octets in length."); } this.mRandomizerHash = randomizerHash; return this; } /** * Sets the Bluetooth Device name to be used for UI purposes. * *
Optional attribute. * * @param deviceName byte array representing the name, may be 0 in length, not null. * @return {@link OobData#ClassicBuilder} * @throws NullPointerException if deviceName is null * @hide */ @NonNull @SystemApi public ClassicBuilder setDeviceName(@NonNull byte[] deviceName) { requireNonNull(deviceName); this.mDeviceName = deviceName; return this; } /** * Sets the Bluetooth Class of Device; used for UI purposes only. * *
Not an indicator of available services! * *
Optional attribute.
*
* @param classOfDevice byte array of {@link OobData#CLASS_OF_DEVICE_OCTETS} octets.
* @return {@link OobData#ClassicBuilder}
* @throws IllegalArgumentException if length is not equal to {@link
* OobData#CLASS_OF_DEVICE_OCTETS} octets.
* @throws NullPointerException if classOfDevice is null.
* @hide
*/
@NonNull
@SystemApi
public ClassicBuilder setClassOfDevice(@NonNull byte[] classOfDevice) {
requireNonNull(classOfDevice);
if (classOfDevice.length != OobData.CLASS_OF_DEVICE_OCTETS) {
throw new IllegalArgumentException(
"classOfDevice must be "
+ OobData.CLASS_OF_DEVICE_OCTETS
+ " octets in length.");
}
this.mClassOfDevice = classOfDevice;
return this;
}
/**
* Validates and builds the {@link OobData} object for Classic Security.
*
* @return {@link OobData} with previously given builder values.
* @hide
*/
@NonNull
@SystemApi
public OobData build() {
final OobData oob =
new OobData(
this.mClassicLength,
this.mDeviceAddressWithType,
this.mConfirmationHash);
// If we have values, set them, otherwise use default
oob.mDeviceName = (this.mDeviceName != null) ? this.mDeviceName : oob.mDeviceName;
oob.mClassOfDevice =
(this.mClassOfDevice != null) ? this.mClassOfDevice : oob.mClassOfDevice;
oob.mRandomizerHash = this.mRandomizerHash;
return oob;
}
}
// Members (Defaults for Optionals must be set or Parceling fails on NPE)
// Both
private final byte[] mDeviceAddressWithType;
private final byte[] mConfirmationHash;
private byte[] mRandomizerHash =
new byte[] {
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
};
// Default the name to "Bluetooth Device"
private byte[] mDeviceName =
new byte[] {
// Bluetooth
0x42,
0x6c,
0x75,
0x65,
0x74,
0x6f,
0x6f,
0x74,
0x68,
// For classic this will be 6 byte address plus the default of PUBLIC_ADDRESS Address
* Type. For LE there are more choices for Address Type.
* @hide
*/
@NonNull
@SystemApi
public byte[] getDeviceAddressWithType() {
return mDeviceAddressWithType;
}
/**
* @return byte array representing the confirmationHash value which is used to confirm the
* identity to the controller.
* @hide
*/
@NonNull
@SystemApi
public byte[] getConfirmationHash() {
return mConfirmationHash;
}
/**
* @return byte array representing the randomizerHash value which is used to verify the identity
* of the controller.
* @hide
*/
@NonNull
@SystemApi
public byte[] getRandomizerHash() {
return mRandomizerHash;
}
/**
* @return Device Name used for displaying name in UI.
* Also, this will be populated with the LE Local Name if the data is for LE.
* @hide
*/
@Nullable
@SystemApi
public byte[] getDeviceName() {
return mDeviceName;
}
/**
* @return byte array representing the oob data length which is the length of all of the data
* including these octets.
* @hide
*/
@NonNull
@SystemApi
public byte[] getClassicLength() {
return mClassicLength;
}
/**
* @return byte array representing the class of device for UI display.
* Does not indicate services available; for display only.
* @hide
*/
@NonNull
@SystemApi
public byte[] getClassOfDevice() {
return mClassOfDevice;
}
/**
* @return Temporary Key used for LE pairing.
* @hide
*/
@Nullable
@SystemApi
public byte[] getLeTemporaryKey() {
return mLeTemporaryKey;
}
/**
* @return Appearance used for LE pairing. For use in UI situations when determining what sort
* of icons or text to display regarding the device.
* @hide
*/
@Nullable
@SystemApi
public byte[] getLeAppearance() {
return mLeAppearance;
}
/**
* @return Flags used to determining discoverable mode to use, BR/EDR Support, and Capability.
* Possible LE Flags: {@link LE_FLAG_LIMITED_DISCOVERY_MODE} LE Limited Discoverable
* Mode. {@link LE_FLAG_GENERAL_DISCOVERY_MODE} LE General Discoverable Mode. {@link
* LE_FLAG_BREDR_NOT_SUPPORTED} BR/EDR Not Supported. Bit 37 of LMP Feature Mask
* Definitions. {@link LE_FLAG_SIMULTANEOUS_CONTROLLER} Simultaneous LE and BR/EDR to Same
* Device Capable (Controller). Bit 49 of LMP Feature Mask Definitions. {@link
* LE_FLAG_SIMULTANEOUS_HOST} Simultaneous LE and BR/EDR to Same Device Capable (Host). Bit
* 55 of LMP Feature Mask Definitions. 0x05- 0x07 Reserved
* @hide
*/
@NonNull
@SystemApi
@LeFlag
public int getLeFlags() {
return mLeFlags;
}
/**
* @return the supported and preferred roles of the LE device.
* Possible Values: {@link LE_DEVICE_ROLE_PERIPHERAL_ONLY} Only Peripheral supported
* {@link LE_DEVICE_ROLE_CENTRAL_ONLY} Only Central supported {@link
* LE_DEVICE_ROLE_BOTH_PREFER_PERIPHERAL} Central & Peripheral supported; Peripheral
* Preferred {@link LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL} Only peripheral supported; Central
* Preferred 0x04 - 0xFF Reserved
* @hide
*/
@NonNull
@SystemApi
@LeRole
public int getLeDeviceRole() {
return mLeDeviceRole;
}
/** Classic Security Constructor */
private OobData(
@NonNull byte[] classicLength,
@NonNull byte[] deviceAddressWithType,
@NonNull byte[] confirmationHash) {
mClassicLength = classicLength;
mDeviceAddressWithType = deviceAddressWithType;
mConfirmationHash = confirmationHash;
mLeDeviceRole = -1; // Satisfy final
}
/** LE Security Constructor */
private OobData(
@NonNull byte[] deviceAddressWithType,
@LeRole int leDeviceRole,
@NonNull byte[] confirmationHash) {
mDeviceAddressWithType = deviceAddressWithType;
mLeDeviceRole = leDeviceRole;
mConfirmationHash = confirmationHash;
mClassicLength = new byte[OOB_LENGTH_OCTETS]; // Satisfy final
}
private OobData(Parcel in) {
// Both
mDeviceAddressWithType = in.createByteArray();
mConfirmationHash = in.createByteArray();
mRandomizerHash = in.createByteArray();
mDeviceName = in.createByteArray();
// Classic
mClassicLength = in.createByteArray();
mClassOfDevice = in.createByteArray();
// LE
mLeDeviceRole = in.readInt();
mLeTemporaryKey = in.createByteArray();
mLeAppearance = in.createByteArray();
mLeFlags = in.readInt();
}
/** @hide */
@Override
public int describeContents() {
return 0;
}
/** @hide */
@Override
public void writeToParcel(@NonNull Parcel out, int flags) {
// Both
// Required
out.writeByteArray(mDeviceAddressWithType);
// Required
out.writeByteArray(mConfirmationHash);
// Optional
out.writeByteArray(mRandomizerHash);
// Optional
out.writeByteArray(mDeviceName);
// Classic
// Required
out.writeByteArray(mClassicLength);
// Optional
out.writeByteArray(mClassOfDevice);
// LE
// Required
out.writeInt(mLeDeviceRole);
// Required
out.writeByteArray(mLeTemporaryKey);
// Optional
out.writeByteArray(mLeAppearance);
// Optional
out.writeInt(mLeFlags);
}
// For Parcelable
public static final @android.annotation.NonNull Parcelable.Creator