blob: 34de8492b5a7b9f0fb7f683438417fd2c39087d0 [file] [log] [blame]
Martin Brabham51a3e5d2021-01-21 10:29:05 -08001/**
Jakub Pawlowskicc840062015-12-29 13:19:21 -08002 * Copyright (C) 2016 The Android Open Source Project
3 *
David Duarteee52b7e2023-12-02 01:32:11 +00004 * <p>Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5 * except in compliance with the License. You may obtain a copy of the License at
Jakub Pawlowskicc840062015-12-29 13:19:21 -08006 *
David Duarteee52b7e2023-12-02 01:32:11 +00007 * <p>http://www.apache.org/licenses/LICENSE-2.0
Jakub Pawlowskicc840062015-12-29 13:19:21 -08008 *
David Duarteee52b7e2023-12-02 01:32:11 +00009 * <p>Unless required by applicable law or agreed to in writing, software distributed under the
10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11 * express or implied. See the License for the specific language governing permissions and
Jakub Pawlowskicc840062015-12-29 13:19:21 -080012 * limitations under the License.
13 */
Jakub Pawlowskicc840062015-12-29 13:19:21 -080014package android.bluetooth;
15
Rahul Sabnis508506d2021-06-10 17:28:38 -070016import static java.util.Objects.requireNonNull;
17
Martin Brabham51a3e5d2021-01-21 10:29:05 -080018import android.annotation.IntDef;
19import android.annotation.NonNull;
20import android.annotation.Nullable;
21import android.annotation.SystemApi;
Jakub Pawlowskicc840062015-12-29 13:19:21 -080022import android.os.Parcel;
23import android.os.Parcelable;
24
Martin Brabham51a3e5d2021-01-21 10:29:05 -080025import java.lang.annotation.Retention;
26import java.lang.annotation.RetentionPolicy;
27
Jakub Pawlowskicc840062015-12-29 13:19:21 -080028/**
Jakub Pawlowskifd076652016-04-14 06:06:00 -070029 * Out Of Band Data for Bluetooth device pairing.
30 *
David Duarteee52b7e2023-12-02 01:32:11 +000031 * <p>This object represents optional data obtained from a remote device through an out-of-band
32 * channel (eg. NFC, QR).
Martin Brabham51a3e5d2021-01-21 10:29:05 -080033 *
David Duarte5a02bb42023-12-04 23:07:42 +000034 * <p>References: <a
35 * href="https://members.nfc-forum.org//apps/group_public/download.php/24620/NFCForum-AD-BTSSP_1_1.pdf">NFC
36 * AD Forum SSP 1.1 (AD)</a>
37 *
38 * <p>Core Specification Supplement (CSS) V9
Martin Brabham51a3e5d2021-01-21 10:29:05 -080039 *
40 * <p>There are several BR/EDR Examples
41 *
David Duarteee52b7e2023-12-02 01:32:11 +000042 * <p>Negotiated Handover: Bluetooth Carrier Configuration Record: - OOB Data Length - Device
43 * Address - Class of Device - Simple Pairing Hash C - Simple Pairing Randomizer R - Service Class
44 * UUID - Bluetooth Local Name
Martin Brabham51a3e5d2021-01-21 10:29:05 -080045 *
David Duarteee52b7e2023-12-02 01:32:11 +000046 * <p>Static Handover: Bluetooth Carrier Configuration Record: - OOB Data Length - Device Address -
47 * Class of Device - Service Class UUID - Bluetooth Local Name
Martin Brabham51a3e5d2021-01-21 10:29:05 -080048 *
David Duarteee52b7e2023-12-02 01:32:11 +000049 * <p>Simplified Tag Format for Single BT Carrier: Bluetooth OOB Data Record: - OOB Data Length -
50 * Device Address - Class of Device - Service Class UUID - Bluetooth Local Name
Jakub Pawlowskifd076652016-04-14 06:06:00 -070051 *
Jeff Sharkeyf05d4582016-03-01 17:36:23 -070052 * @hide
Jakub Pawlowskicc840062015-12-29 13:19:21 -080053 */
Martin Brabham51a3e5d2021-01-21 10:29:05 -080054@SystemApi
55public final class OobData implements Parcelable {
Jakub Pawlowskicc840062015-12-29 13:19:21 -080056
Martin Brabham51a3e5d2021-01-21 10:29:05 -080057 private static final String TAG = "OobData";
David Duarteee52b7e2023-12-02 01:32:11 +000058
Martin Brabham51a3e5d2021-01-21 10:29:05 -080059 /** The {@link OobData#mClassicLength} may be. (AD 3.1.1) (CSS 1.6.2) @hide */
David Duarteee52b7e2023-12-02 01:32:11 +000060 @SystemApi public static final int OOB_LENGTH_OCTETS = 2;
61
Martin Brabham51a3e5d2021-01-21 10:29:05 -080062 /**
David Duarteee52b7e2023-12-02 01:32:11 +000063 * The length for the {@link OobData#mDeviceAddressWithType}(6) and Address Type(1). (AD 3.1.2)
64 * (CSS 1.6.2)
65 *
Martin Brabham51a3e5d2021-01-21 10:29:05 -080066 * @hide
67 */
David Duarteee52b7e2023-12-02 01:32:11 +000068 @SystemApi public static final int DEVICE_ADDRESS_OCTETS = 7;
69
Martin Brabham51a3e5d2021-01-21 10:29:05 -080070 /** The Class of Device is 3 octets. (AD 3.1.3) (CSS 1.6.2) @hide */
David Duarteee52b7e2023-12-02 01:32:11 +000071 @SystemApi public static final int CLASS_OF_DEVICE_OCTETS = 3;
72
Martin Brabham51a3e5d2021-01-21 10:29:05 -080073 /** The Confirmation data must be 16 octets. (AD 3.2.2) (CSS 1.6.2) @hide */
David Duarteee52b7e2023-12-02 01:32:11 +000074 @SystemApi public static final int CONFIRMATION_OCTETS = 16;
75
Martin Brabham51a3e5d2021-01-21 10:29:05 -080076 /** The Randomizer data must be 16 octets. (AD 3.2.3) (CSS 1.6.2) @hide */
David Duarteee52b7e2023-12-02 01:32:11 +000077 @SystemApi public static final int RANDOMIZER_OCTETS = 16;
78
Martin Brabham51a3e5d2021-01-21 10:29:05 -080079 /** The LE Device Role length is 1 octet. (AD 3.3.2) (CSS 1.17) @hide */
David Duarteee52b7e2023-12-02 01:32:11 +000080 @SystemApi public static final int LE_DEVICE_ROLE_OCTETS = 1;
81
Martin Brabham51a3e5d2021-01-21 10:29:05 -080082 /** The {@link OobData#mLeTemporaryKey} length. (3.4.1) @hide */
David Duarteee52b7e2023-12-02 01:32:11 +000083 @SystemApi public static final int LE_TK_OCTETS = 16;
84
Martin Brabham51a3e5d2021-01-21 10:29:05 -080085 /** The {@link OobData#mLeAppearance} length. (3.4.1) @hide */
David Duarteee52b7e2023-12-02 01:32:11 +000086 @SystemApi public static final int LE_APPEARANCE_OCTETS = 2;
87
Martin Brabham51a3e5d2021-01-21 10:29:05 -080088 /** The {@link OobData#mLeFlags} length. (3.4.1) @hide */
David Duarteee52b7e2023-12-02 01:32:11 +000089 @SystemApi public static final int LE_DEVICE_FLAG_OCTETS = 1; // 1 octet to hold the 0-4 value.
Martin Brabham51a3e5d2021-01-21 10:29:05 -080090
91 // Le Roles
92 /** @hide */
93 @Retention(RetentionPolicy.SOURCE)
94 @IntDef(
David Duarteee52b7e2023-12-02 01:32:11 +000095 prefix = {"LE_DEVICE_ROLE_"},
96 value = {
97 LE_DEVICE_ROLE_PERIPHERAL_ONLY,
98 LE_DEVICE_ROLE_CENTRAL_ONLY,
99 LE_DEVICE_ROLE_BOTH_PREFER_PERIPHERAL,
100 LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL
101 })
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800102 public @interface LeRole {}
103
104 /** @hide */
David Duarteee52b7e2023-12-02 01:32:11 +0000105 @SystemApi public static final int LE_DEVICE_ROLE_PERIPHERAL_ONLY = 0x00;
106
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800107 /** @hide */
David Duarteee52b7e2023-12-02 01:32:11 +0000108 @SystemApi public static final int LE_DEVICE_ROLE_CENTRAL_ONLY = 0x01;
109
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800110 /** @hide */
David Duarteee52b7e2023-12-02 01:32:11 +0000111 @SystemApi public static final int LE_DEVICE_ROLE_BOTH_PREFER_PERIPHERAL = 0x02;
112
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800113 /** @hide */
David Duarteee52b7e2023-12-02 01:32:11 +0000114 @SystemApi public static final int LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL = 0x03;
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800115
116 // Le Flags
117 /** @hide */
118 @Retention(RetentionPolicy.SOURCE)
119 @IntDef(
David Duarteee52b7e2023-12-02 01:32:11 +0000120 prefix = {"LE_FLAG_"},
121 value = {
122 LE_FLAG_LIMITED_DISCOVERY_MODE,
123 LE_FLAG_GENERAL_DISCOVERY_MODE,
124 LE_FLAG_BREDR_NOT_SUPPORTED,
125 LE_FLAG_SIMULTANEOUS_CONTROLLER,
126 LE_FLAG_SIMULTANEOUS_HOST
127 })
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800128 public @interface LeFlag {}
129
130 /** @hide */
David Duarteee52b7e2023-12-02 01:32:11 +0000131 @SystemApi public static final int LE_FLAG_LIMITED_DISCOVERY_MODE = 0x00;
132
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800133 /** @hide */
David Duarteee52b7e2023-12-02 01:32:11 +0000134 @SystemApi public static final int LE_FLAG_GENERAL_DISCOVERY_MODE = 0x01;
135
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800136 /** @hide */
David Duarteee52b7e2023-12-02 01:32:11 +0000137 @SystemApi public static final int LE_FLAG_BREDR_NOT_SUPPORTED = 0x02;
138
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800139 /** @hide */
David Duarteee52b7e2023-12-02 01:32:11 +0000140 @SystemApi public static final int LE_FLAG_SIMULTANEOUS_CONTROLLER = 0x03;
141
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800142 /** @hide */
David Duarteee52b7e2023-12-02 01:32:11 +0000143 @SystemApi public static final int LE_FLAG_SIMULTANEOUS_HOST = 0x04;
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800144
145 /**
David Duarteee52b7e2023-12-02 01:32:11 +0000146 * Builds an {@link OobData} object and validates that the required combination of values are
147 * present to create the LE specific OobData type.
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800148 *
149 * @hide
Jakub Pawlowskifd076652016-04-14 06:06:00 -0700150 */
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800151 @SystemApi
152 public static final class LeBuilder {
153
154 /**
David Duarteee52b7e2023-12-02 01:32:11 +0000155 * It is recommended that this Hash C is generated anew for each pairing.
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800156 *
David Duarteee52b7e2023-12-02 01:32:11 +0000157 * <p>It should be noted that on passive NFC this isn't possible as the data is static and
158 * immutable.
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800159 */
160 private byte[] mConfirmationHash = null;
161
162 /**
163 * Optional, but adds more validity to the pairing.
164 *
165 * <p>If not present a value of 0 is assumed.
166 */
David Duarteee52b7e2023-12-02 01:32:11 +0000167 private byte[] mRandomizerHash =
168 new byte[] {
169 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
170 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
171 };
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800172
173 /**
174 * The Bluetooth Device user-friendly name presented over Bluetooth Technology.
175 *
176 * <p>This is the name that may be displayed to the device user as part of the UI.
177 */
178 private byte[] mDeviceName = null;
179
180 /**
181 * Sets the Bluetooth Device name to be used for UI purposes.
182 *
183 * <p>Optional attribute.
184 *
185 * @param deviceName byte array representing the name, may be 0 in length, not null.
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800186 * @return {@link OobData#ClassicBuilder}
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800187 * @throws NullPointerException if deviceName is null.
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800188 * @hide
189 */
190 @NonNull
191 @SystemApi
192 public LeBuilder setDeviceName(@NonNull byte[] deviceName) {
Rahul Sabnis508506d2021-06-10 17:28:38 -0700193 requireNonNull(deviceName);
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800194 this.mDeviceName = deviceName;
195 return this;
196 }
197
198 /**
199 * The Bluetooth Device Address is the address to which the OOB data belongs.
200 *
201 * <p>The length MUST be {@link OobData#DEVICE_ADDRESS_OCTETS} octets.
202 *
David Duarteee52b7e2023-12-02 01:32:11 +0000203 * <p>Address is encoded in Little Endian order.
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800204 *
205 * <p>e.g. 00:01:02:03:04:05 would be x05x04x03x02x01x00
206 */
207 private final byte[] mDeviceAddressWithType;
208
209 /**
210 * During an LE connection establishment, one must be in the Peripheral mode and the other
211 * in the Central role.
212 *
David Duarteee52b7e2023-12-02 01:32:11 +0000213 * <p>Possible Values: {@link LE_DEVICE_ROLE_PERIPHERAL_ONLY} Only Peripheral supported
214 * {@link LE_DEVICE_ROLE_CENTRAL_ONLY} Only Central supported {@link
215 * LE_DEVICE_ROLE_BOTH_PREFER_PERIPHERAL} Central & Peripheral supported; Peripheral
216 * Preferred {@link LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL} Only peripheral supported; Central
217 * Preferred 0x04 - 0xFF Reserved
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800218 */
219 private final @LeRole int mLeDeviceRole;
220
221 /**
222 * Temporary key value from the Security Manager.
223 *
David Duarteee52b7e2023-12-02 01:32:11 +0000224 * <p>Must be {@link LE_TK_OCTETS} in size
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800225 */
226 private byte[] mLeTemporaryKey = null;
227
228 /**
229 * Defines the representation of the external appearance of the device.
230 *
231 * <p>For example, a mouse, remote control, or keyboard.
232 *
233 * <p>Used for visual on discovering device to represent icon/string/etc...
234 */
235 private byte[] mLeAppearance = null;
236
237 /**
238 * Contains which discoverable mode to use, BR/EDR support and capability.
239 *
David Duarteee52b7e2023-12-02 01:32:11 +0000240 * <p>Possible LE Flags: {@link LE_FLAG_LIMITED_DISCOVERY_MODE} LE Limited Discoverable
241 * Mode. {@link LE_FLAG_GENERAL_DISCOVERY_MODE} LE General Discoverable Mode. {@link
242 * LE_FLAG_BREDR_NOT_SUPPORTED} BR/EDR Not Supported. Bit 37 of LMP Feature Mask
243 * Definitions. {@link LE_FLAG_SIMULTANEOUS_CONTROLLER} Simultaneous LE and BR/EDR to Same
244 * Device Capable (Controller). Bit 49 of LMP Feature Mask Definitions. {@link
245 * LE_FLAG_SIMULTANEOUS_HOST} Simultaneous LE and BR/EDR to Same Device Capable (Host). Bit
246 * 55 of LMP Feature Mask Definitions. <b>0x05- 0x07 Reserved</b>
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800247 */
248 private @LeFlag int mLeFlags = LE_FLAG_GENERAL_DISCOVERY_MODE; // Invalid default
249
250 /**
Martin Brabham82f1ab92021-04-22 11:39:21 -0700251 * Main creation method for creating a LE version of {@link OobData}.
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800252 *
David Duarteee52b7e2023-12-02 01:32:11 +0000253 * <p>This object will allow the caller to call {@link LeBuilder#build()} to build the data
254 * object or add any option information to the builder.
Martin Brabham82f1ab92021-04-22 11:39:21 -0700255 *
David Duarteee52b7e2023-12-02 01:32:11 +0000256 * @param deviceAddressWithType the LE device address plus the address type (7 octets); not
257 * null.
258 * @param leDeviceRole whether the device supports Peripheral, Central, Both including
259 * preference; not null. (1 octet)
260 * @param confirmationHash Array consisting of {@link OobData#CONFIRMATION_OCTETS} octets of
261 * data. Data is derived from controller/host stack and is required for pairing OOB.
262 * <p>Possible Values: {@link LE_DEVICE_ROLE_PERIPHERAL_ONLY} Only Peripheral supported
263 * {@link LE_DEVICE_ROLE_CENTRAL_ONLY} Only Central supported {@link
264 * LE_DEVICE_ROLE_BOTH_PREFER_PERIPHERAL} Central & Peripheral supported; Peripheral
265 * Preferred {@link LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL} Only peripheral supported;
266 * Central Preferred 0x04 - 0xFF Reserved
Martin Brabham82f1ab92021-04-22 11:39:21 -0700267 * @throws IllegalArgumentException if any of the values fail to be set.
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800268 * @throws NullPointerException if any argument is null.
Martin Brabham82f1ab92021-04-22 11:39:21 -0700269 * @hide
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800270 */
Martin Brabham82f1ab92021-04-22 11:39:21 -0700271 @SystemApi
David Duarteee52b7e2023-12-02 01:32:11 +0000272 public LeBuilder(
273 @NonNull byte[] confirmationHash,
274 @NonNull byte[] deviceAddressWithType,
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800275 @LeRole int leDeviceRole) {
Rahul Sabnis508506d2021-06-10 17:28:38 -0700276 requireNonNull(confirmationHash);
277 requireNonNull(deviceAddressWithType);
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800278 if (confirmationHash.length != OobData.CONFIRMATION_OCTETS) {
David Duarteee52b7e2023-12-02 01:32:11 +0000279 throw new IllegalArgumentException(
280 "confirmationHash must be "
281 + OobData.CONFIRMATION_OCTETS
282 + " octets in length.");
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800283 }
284 this.mConfirmationHash = confirmationHash;
285 if (deviceAddressWithType.length != OobData.DEVICE_ADDRESS_OCTETS) {
David Duarteee52b7e2023-12-02 01:32:11 +0000286 throw new IllegalArgumentException(
287 "confirmationHash must be "
288 + OobData.DEVICE_ADDRESS_OCTETS
289 + " octets in length.");
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800290 }
291 this.mDeviceAddressWithType = deviceAddressWithType;
292 if (leDeviceRole < LE_DEVICE_ROLE_PERIPHERAL_ONLY
293 || leDeviceRole > LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL) {
294 throw new IllegalArgumentException("leDeviceRole must be a valid value.");
295 }
296 this.mLeDeviceRole = leDeviceRole;
297 }
298
299 /**
David Duarteee52b7e2023-12-02 01:32:11 +0000300 * Sets the Temporary Key value to be used by the LE Security Manager during LE pairing.
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800301 *
David Duarteee52b7e2023-12-02 01:32:11 +0000302 * @param leTemporaryKey byte array that shall be 16 bytes. Please see Bluetooth CSSv6, Part
303 * A 1.8 for a detailed description.
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800304 * @return {@link OobData#Builder}
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800305 * @throws IllegalArgumentException if the leTemporaryKey is an invalid format.
306 * @throws NullinterException if leTemporaryKey is null.
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800307 * @hide
308 */
309 @NonNull
310 @SystemApi
311 public LeBuilder setLeTemporaryKey(@NonNull byte[] leTemporaryKey) {
Rahul Sabnis508506d2021-06-10 17:28:38 -0700312 requireNonNull(leTemporaryKey);
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800313 if (leTemporaryKey.length != LE_TK_OCTETS) {
David Duarteee52b7e2023-12-02 01:32:11 +0000314 throw new IllegalArgumentException(
315 "leTemporaryKey must be " + LE_TK_OCTETS + " octets in length.");
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800316 }
317 this.mLeTemporaryKey = leTemporaryKey;
318 return this;
319 }
320
321 /**
322 * @param randomizerHash byte array consisting of {@link OobData#RANDOMIZER_OCTETS} octets
David Duarteee52b7e2023-12-02 01:32:11 +0000323 * of data. Data is derived from controller/host stack and is required for pairing OOB.
324 * Also, randomizerHash may be all 0s or null in which case it becomes all 0s.
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800325 * @throws IllegalArgumentException if null or incorrect length randomizerHash was passed.
326 * @throws NullPointerException if randomizerHash is null.
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800327 * @hide
328 */
329 @NonNull
330 @SystemApi
331 public LeBuilder setRandomizerHash(@NonNull byte[] randomizerHash) {
Rahul Sabnis508506d2021-06-10 17:28:38 -0700332 requireNonNull(randomizerHash);
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800333 if (randomizerHash.length != OobData.RANDOMIZER_OCTETS) {
David Duarteee52b7e2023-12-02 01:32:11 +0000334 throw new IllegalArgumentException(
335 "randomizerHash must be "
336 + OobData.RANDOMIZER_OCTETS
337 + " octets in length.");
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800338 }
339 this.mRandomizerHash = randomizerHash;
340 return this;
341 }
342
343 /**
344 * Sets the LE Flags necessary for the pairing scenario or discovery mode.
345 *
346 * @param leFlags enum value representing the 1 octet of data about discovery modes.
David Duarteee52b7e2023-12-02 01:32:11 +0000347 * <p>Possible LE Flags: {@link LE_FLAG_LIMITED_DISCOVERY_MODE} LE Limited Discoverable
348 * Mode. {@link LE_FLAG_GENERAL_DISCOVERY_MODE} LE General Discoverable Mode. {@link
349 * LE_FLAG_BREDR_NOT_SUPPORTED} BR/EDR Not Supported. Bit 37 of LMP Feature Mask
350 * Definitions. {@link LE_FLAG_SIMULTANEOUS_CONTROLLER} Simultaneous LE and BR/EDR to
351 * Same Device Capable (Controller) Bit 49 of LMP Feature Mask Definitions. {@link
352 * LE_FLAG_SIMULTANEOUS_HOST} Simultaneous LE and BR/EDR to Same Device Capable (Host).
353 * Bit 55 of LMP Feature Mask Definitions. 0x05- 0x07 Reserved
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800354 * @throws IllegalArgumentException for invalid flag
355 * @hide
356 */
357 @NonNull
358 @SystemApi
359 public LeBuilder setLeFlags(@LeFlag int leFlags) {
360 if (leFlags < LE_FLAG_LIMITED_DISCOVERY_MODE || leFlags > LE_FLAG_SIMULTANEOUS_HOST) {
361 throw new IllegalArgumentException("leFlags must be a valid value.");
362 }
363 this.mLeFlags = leFlags;
364 return this;
365 }
366
367 /**
368 * Validates and builds the {@link OobData} object for LE Security.
369 *
370 * @return {@link OobData} with given builder values
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800371 * @throws IllegalStateException if either of the 2 required fields were not set.
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800372 * @hide
373 */
374 @NonNull
375 @SystemApi
376 public OobData build() {
377 final OobData oob =
David Duarteee52b7e2023-12-02 01:32:11 +0000378 new OobData(
379 this.mDeviceAddressWithType,
380 this.mLeDeviceRole,
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800381 this.mConfirmationHash);
382
383 // If we have values, set them, otherwise use default
384 oob.mLeTemporaryKey =
385 (this.mLeTemporaryKey != null) ? this.mLeTemporaryKey : oob.mLeTemporaryKey;
David Duarteee52b7e2023-12-02 01:32:11 +0000386 oob.mLeAppearance =
387 (this.mLeAppearance != null) ? this.mLeAppearance : oob.mLeAppearance;
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800388 oob.mLeFlags = (this.mLeFlags != 0xF) ? this.mLeFlags : oob.mLeFlags;
389 oob.mDeviceName = (this.mDeviceName != null) ? this.mDeviceName : oob.mDeviceName;
390 oob.mRandomizerHash = this.mRandomizerHash;
391 return oob;
392 }
Jakub Pawlowskicc840062015-12-29 13:19:21 -0800393 }
394
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800395 /**
David Duarteee52b7e2023-12-02 01:32:11 +0000396 * Builds an {@link OobData} object and validates that the required combination of values are
397 * present to create the Classic specific OobData type.
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800398 *
399 * @hide
400 */
401 @SystemApi
402 public static final class ClassicBuilder {
403 // Used by both Classic and LE
404 /**
David Duarteee52b7e2023-12-02 01:32:11 +0000405 * It is recommended that this Hash C is generated anew for each pairing.
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800406 *
David Duarteee52b7e2023-12-02 01:32:11 +0000407 * <p>It should be noted that on passive NFC this isn't possible as the data is static and
408 * immutable.
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800409 *
410 * @hide
411 */
412 private byte[] mConfirmationHash = null;
413
414 /**
415 * Optional, but adds more validity to the pairing.
416 *
417 * <p>If not present a value of 0 is assumed.
418 *
419 * @hide
420 */
David Duarteee52b7e2023-12-02 01:32:11 +0000421 private byte[] mRandomizerHash =
422 new byte[] {
423 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
424 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
425 };
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800426
427 /**
428 * The Bluetooth Device user-friendly name presented over Bluetooth Technology.
429 *
430 * <p>This is the name that may be displayed to the device user as part of the UI.
431 *
432 * @hide
433 */
434 private byte[] mDeviceName = null;
435
436 /**
David Duarteee52b7e2023-12-02 01:32:11 +0000437 * This length value provides the absolute length of total OOB data block used for Bluetooth
438 * BR/EDR
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800439 *
David Duarteee52b7e2023-12-02 01:32:11 +0000440 * <p>OOB communication, which includes the length field itself and the Bluetooth Device
441 * Address.
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800442 *
443 * <p>The minimum length that may be represented in this field is 8.
444 *
445 * @hide
446 */
447 private final byte[] mClassicLength;
448
449 /**
450 * The Bluetooth Device Address is the address to which the OOB data belongs.
451 *
452 * <p>The length MUST be {@link OobData#DEVICE_ADDRESS_OCTETS} octets.
453 *
David Duarteee52b7e2023-12-02 01:32:11 +0000454 * <p>Address is encoded in Little Endian order.
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800455 *
456 * <p>e.g. 00:01:02:03:04:05 would be x05x04x03x02x01x00
457 *
458 * @hide
459 */
460 private final byte[] mDeviceAddressWithType;
461
462 /**
David Duarteee52b7e2023-12-02 01:32:11 +0000463 * Class of Device information is to be used to provide a graphical representation to the
464 * user as part of UI involving operations.
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800465 *
466 * <p>This is not to be used to determine a particular service can be used.
467 *
468 * <p>The length MUST be {@link OobData#CLASS_OF_DEVICE_OCTETS} octets.
469 *
470 * @hide
471 */
472 private byte[] mClassOfDevice = null;
473
474 /**
Martin Brabham82f1ab92021-04-22 11:39:21 -0700475 * Main creation method for creating a Classic version of {@link OobData}.
476 *
David Duarteee52b7e2023-12-02 01:32:11 +0000477 * <p>This object will allow the caller to call {@link ClassicBuilder#build()} to build the
478 * data object or add any option information to the builder.
Martin Brabham82f1ab92021-04-22 11:39:21 -0700479 *
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800480 * @param confirmationHash byte array consisting of {@link OobData#CONFIRMATION_OCTETS}
David Duarteee52b7e2023-12-02 01:32:11 +0000481 * octets of data. Data is derived from controller/host stack and is required for
482 * pairing OOB.
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800483 * @param classicLength byte array representing the length of data from 8-65535 across 2
David Duarteee52b7e2023-12-02 01:32:11 +0000484 * octets (0xXXXX).
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800485 * @param deviceAddressWithType byte array representing the Bluetooth Address of the device
David Duarteee52b7e2023-12-02 01:32:11 +0000486 * that owns the OOB data. (i.e. the originator) [6 octets]
Martin Brabham82f1ab92021-04-22 11:39:21 -0700487 * @throws IllegalArgumentException if any of the values fail to be set.
488 * @throws NullPointerException if any argument is null.
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800489 * @hide
490 */
Martin Brabham82f1ab92021-04-22 11:39:21 -0700491 @SystemApi
David Duarteee52b7e2023-12-02 01:32:11 +0000492 public ClassicBuilder(
493 @NonNull byte[] confirmationHash,
494 @NonNull byte[] classicLength,
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800495 @NonNull byte[] deviceAddressWithType) {
Rahul Sabnis508506d2021-06-10 17:28:38 -0700496 requireNonNull(confirmationHash);
497 requireNonNull(classicLength);
498 requireNonNull(deviceAddressWithType);
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800499 if (confirmationHash.length != OobData.CONFIRMATION_OCTETS) {
David Duarteee52b7e2023-12-02 01:32:11 +0000500 throw new IllegalArgumentException(
501 "confirmationHash must be "
502 + OobData.CONFIRMATION_OCTETS
503 + " octets in length.");
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800504 }
505 this.mConfirmationHash = confirmationHash;
506 if (classicLength.length != OOB_LENGTH_OCTETS) {
David Duarteee52b7e2023-12-02 01:32:11 +0000507 throw new IllegalArgumentException(
508 "classicLength must be " + OOB_LENGTH_OCTETS + " octets in length.");
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800509 }
510 this.mClassicLength = classicLength;
511 if (deviceAddressWithType.length != DEVICE_ADDRESS_OCTETS) {
David Duarteee52b7e2023-12-02 01:32:11 +0000512 throw new IllegalArgumentException(
513 "deviceAddressWithType must be "
514 + DEVICE_ADDRESS_OCTETS
515 + " octets in length.");
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800516 }
517 this.mDeviceAddressWithType = deviceAddressWithType;
518 }
519
520 /**
521 * @param randomizerHash byte array consisting of {@link OobData#RANDOMIZER_OCTETS} octets
David Duarteee52b7e2023-12-02 01:32:11 +0000522 * of data. Data is derived from controller/host stack and is required for pairing OOB.
523 * Also, randomizerHash may be all 0s or null in which case it becomes all 0s.
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800524 * @throws IllegalArgumentException if null or incorrect length randomizerHash was passed.
525 * @throws NullPointerException if randomizerHash is null.
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800526 * @hide
527 */
528 @NonNull
529 @SystemApi
530 public ClassicBuilder setRandomizerHash(@NonNull byte[] randomizerHash) {
Rahul Sabnis508506d2021-06-10 17:28:38 -0700531 requireNonNull(randomizerHash);
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800532 if (randomizerHash.length != OobData.RANDOMIZER_OCTETS) {
David Duarteee52b7e2023-12-02 01:32:11 +0000533 throw new IllegalArgumentException(
534 "randomizerHash must be "
535 + OobData.RANDOMIZER_OCTETS
536 + " octets in length.");
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800537 }
538 this.mRandomizerHash = randomizerHash;
539 return this;
540 }
541
542 /**
543 * Sets the Bluetooth Device name to be used for UI purposes.
544 *
545 * <p>Optional attribute.
546 *
547 * @param deviceName byte array representing the name, may be 0 in length, not null.
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800548 * @return {@link OobData#ClassicBuilder}
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800549 * @throws NullPointerException if deviceName is null
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800550 * @hide
551 */
552 @NonNull
553 @SystemApi
554 public ClassicBuilder setDeviceName(@NonNull byte[] deviceName) {
Rahul Sabnis508506d2021-06-10 17:28:38 -0700555 requireNonNull(deviceName);
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800556 this.mDeviceName = deviceName;
557 return this;
558 }
559
560 /**
561 * Sets the Bluetooth Class of Device; used for UI purposes only.
562 *
563 * <p>Not an indicator of available services!
564 *
565 * <p>Optional attribute.
566 *
567 * @param classOfDevice byte array of {@link OobData#CLASS_OF_DEVICE_OCTETS} octets.
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800568 * @return {@link OobData#ClassicBuilder}
David Duarteee52b7e2023-12-02 01:32:11 +0000569 * @throws IllegalArgumentException if length is not equal to {@link
570 * OobData#CLASS_OF_DEVICE_OCTETS} octets.
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800571 * @throws NullPointerException if classOfDevice is null.
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800572 * @hide
573 */
574 @NonNull
575 @SystemApi
576 public ClassicBuilder setClassOfDevice(@NonNull byte[] classOfDevice) {
Rahul Sabnis508506d2021-06-10 17:28:38 -0700577 requireNonNull(classOfDevice);
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800578 if (classOfDevice.length != OobData.CLASS_OF_DEVICE_OCTETS) {
David Duarteee52b7e2023-12-02 01:32:11 +0000579 throw new IllegalArgumentException(
580 "classOfDevice must be "
581 + OobData.CLASS_OF_DEVICE_OCTETS
582 + " octets in length.");
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800583 }
584 this.mClassOfDevice = classOfDevice;
585 return this;
586 }
587
588 /**
William Escande879a70e2024-03-21 21:01:41 -0700589 * Validates and builds the {@link OobData} object for Classic Security.
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800590 *
591 * @return {@link OobData} with previously given builder values.
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800592 * @hide
593 */
594 @NonNull
595 @SystemApi
596 public OobData build() {
597 final OobData oob =
David Duarteee52b7e2023-12-02 01:32:11 +0000598 new OobData(
599 this.mClassicLength,
600 this.mDeviceAddressWithType,
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800601 this.mConfirmationHash);
602 // If we have values, set them, otherwise use default
603 oob.mDeviceName = (this.mDeviceName != null) ? this.mDeviceName : oob.mDeviceName;
David Duarteee52b7e2023-12-02 01:32:11 +0000604 oob.mClassOfDevice =
605 (this.mClassOfDevice != null) ? this.mClassOfDevice : oob.mClassOfDevice;
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800606 oob.mRandomizerHash = this.mRandomizerHash;
607 return oob;
608 }
Jakub Pawlowski1d306362016-07-28 05:21:36 -0700609 }
610
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800611 // Members (Defaults for Optionals must be set or Parceling fails on NPE)
612 // Both
613 private final byte[] mDeviceAddressWithType;
614 private final byte[] mConfirmationHash;
David Duarteee52b7e2023-12-02 01:32:11 +0000615 private byte[] mRandomizerHash =
616 new byte[] {
617 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
618 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
619 };
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800620 // Default the name to "Bluetooth Device"
David Duarteee52b7e2023-12-02 01:32:11 +0000621 private byte[] mDeviceName =
622 new byte[] {
623 // Bluetooth
624 0x42,
625 0x6c,
626 0x75,
627 0x65,
628 0x74,
629 0x6f,
630 0x6f,
631 0x74,
632 0x68,
633 // <space>Device
634 0x20,
635 0x44,
636 0x65,
637 0x76,
638 0x69,
639 0x63,
640 0x65
641 };
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800642
643 // Classic
644 private final byte[] mClassicLength;
645 private byte[] mClassOfDevice = new byte[CLASS_OF_DEVICE_OCTETS];
646
647 // LE
648 private final @LeRole int mLeDeviceRole;
649 private byte[] mLeTemporaryKey = new byte[LE_TK_OCTETS];
650 private byte[] mLeAppearance = new byte[LE_APPEARANCE_OCTETS];
651 private @LeFlag int mLeFlags = LE_FLAG_LIMITED_DISCOVERY_MODE;
652
653 /**
David Duarteee52b7e2023-12-02 01:32:11 +0000654 * @return byte array representing the MAC address of a bluetooth device. The Address is 6
655 * octets long with a 1 octet address type associated with the address.
656 * <p>For classic this will be 6 byte address plus the default of PUBLIC_ADDRESS Address
657 * Type. For LE there are more choices for Address Type.
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800658 * @hide
659 */
660 @NonNull
661 @SystemApi
662 public byte[] getDeviceAddressWithType() {
663 return mDeviceAddressWithType;
Jakub Pawlowski1d306362016-07-28 05:21:36 -0700664 }
665
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800666 /**
David Duarteee52b7e2023-12-02 01:32:11 +0000667 * @return byte array representing the confirmationHash value which is used to confirm the
668 * identity to the controller.
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800669 * @hide
670 */
671 @NonNull
672 @SystemApi
673 public byte[] getConfirmationHash() {
674 return mConfirmationHash;
Jakub Pawlowski1d306362016-07-28 05:21:36 -0700675 }
676
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800677 /**
David Duarteee52b7e2023-12-02 01:32:11 +0000678 * @return byte array representing the randomizerHash value which is used to verify the identity
679 * of the controller.
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800680 * @hide
681 */
682 @NonNull
683 @SystemApi
684 public byte[] getRandomizerHash() {
685 return mRandomizerHash;
Jakub Pawlowski1d306362016-07-28 05:21:36 -0700686 }
687
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800688 /**
689 * @return Device Name used for displaying name in UI.
David Duarteee52b7e2023-12-02 01:32:11 +0000690 * <p>Also, this will be populated with the LE Local Name if the data is for LE.
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800691 * @hide
692 */
693 @Nullable
694 @SystemApi
695 public byte[] getDeviceName() {
696 return mDeviceName;
697 }
698
699 /**
David Duarteee52b7e2023-12-02 01:32:11 +0000700 * @return byte array representing the oob data length which is the length of all of the data
701 * including these octets.
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800702 * @hide
703 */
704 @NonNull
705 @SystemApi
706 public byte[] getClassicLength() {
707 return mClassicLength;
708 }
709
710 /**
711 * @return byte array representing the class of device for UI display.
David Duarteee52b7e2023-12-02 01:32:11 +0000712 * <p>Does not indicate services available; for display only.
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800713 * @hide
714 */
715 @NonNull
716 @SystemApi
717 public byte[] getClassOfDevice() {
718 return mClassOfDevice;
719 }
720
721 /**
722 * @return Temporary Key used for LE pairing.
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800723 * @hide
724 */
725 @Nullable
726 @SystemApi
727 public byte[] getLeTemporaryKey() {
728 return mLeTemporaryKey;
729 }
730
731 /**
David Duarteee52b7e2023-12-02 01:32:11 +0000732 * @return Appearance used for LE pairing. For use in UI situations when determining what sort
733 * of icons or text to display regarding the device.
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800734 * @hide
735 */
736 @Nullable
737 @SystemApi
738 public byte[] getLeAppearance() {
Hansong Zhangc8353bb2021-04-13 11:53:56 -0700739 return mLeAppearance;
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800740 }
741
742 /**
David Duarte1c07fc72023-12-02 02:08:08 +0000743 * @return Flags used to determining discoverable mode to use, BR/EDR Support, and Capability.
David Duarteee52b7e2023-12-02 01:32:11 +0000744 * <p>Possible LE Flags: {@link LE_FLAG_LIMITED_DISCOVERY_MODE} LE Limited Discoverable
745 * Mode. {@link LE_FLAG_GENERAL_DISCOVERY_MODE} LE General Discoverable Mode. {@link
746 * LE_FLAG_BREDR_NOT_SUPPORTED} BR/EDR Not Supported. Bit 37 of LMP Feature Mask
747 * Definitions. {@link LE_FLAG_SIMULTANEOUS_CONTROLLER} Simultaneous LE and BR/EDR to Same
748 * Device Capable (Controller). Bit 49 of LMP Feature Mask Definitions. {@link
749 * LE_FLAG_SIMULTANEOUS_HOST} Simultaneous LE and BR/EDR to Same Device Capable (Host). Bit
750 * 55 of LMP Feature Mask Definitions. <b>0x05- 0x07 Reserved</b>
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800751 * @hide
752 */
753 @NonNull
754 @SystemApi
755 @LeFlag
756 public int getLeFlags() {
757 return mLeFlags;
758 }
759
760 /**
761 * @return the supported and preferred roles of the LE device.
David Duarteee52b7e2023-12-02 01:32:11 +0000762 * <p>Possible Values: {@link LE_DEVICE_ROLE_PERIPHERAL_ONLY} Only Peripheral supported
763 * {@link LE_DEVICE_ROLE_CENTRAL_ONLY} Only Central supported {@link
764 * LE_DEVICE_ROLE_BOTH_PREFER_PERIPHERAL} Central & Peripheral supported; Peripheral
765 * Preferred {@link LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL} Only peripheral supported; Central
766 * Preferred 0x04 - 0xFF Reserved
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800767 * @hide
768 */
769 @NonNull
770 @SystemApi
771 @LeRole
772 public int getLeDeviceRole() {
773 return mLeDeviceRole;
774 }
775
David Duarteee52b7e2023-12-02 01:32:11 +0000776 /** Classic Security Constructor */
777 private OobData(
778 @NonNull byte[] classicLength,
779 @NonNull byte[] deviceAddressWithType,
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800780 @NonNull byte[] confirmationHash) {
781 mClassicLength = classicLength;
782 mDeviceAddressWithType = deviceAddressWithType;
783 mConfirmationHash = confirmationHash;
784 mLeDeviceRole = -1; // Satisfy final
785 }
786
David Duarteee52b7e2023-12-02 01:32:11 +0000787 /** LE Security Constructor */
788 private OobData(
789 @NonNull byte[] deviceAddressWithType,
790 @LeRole int leDeviceRole,
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800791 @NonNull byte[] confirmationHash) {
792 mDeviceAddressWithType = deviceAddressWithType;
793 mLeDeviceRole = leDeviceRole;
794 mConfirmationHash = confirmationHash;
795 mClassicLength = new byte[OOB_LENGTH_OCTETS]; // Satisfy final
Jack He910201b2017-08-22 16:06:54 -0700796 }
Jakub Pawlowskicc840062015-12-29 13:19:21 -0800797
798 private OobData(Parcel in) {
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800799 // Both
800 mDeviceAddressWithType = in.createByteArray();
801 mConfirmationHash = in.createByteArray();
802 mRandomizerHash = in.createByteArray();
803 mDeviceName = in.createByteArray();
804
805 // Classic
806 mClassicLength = in.createByteArray();
807 mClassOfDevice = in.createByteArray();
808
809 // LE
810 mLeDeviceRole = in.readInt();
811 mLeTemporaryKey = in.createByteArray();
812 mLeAppearance = in.createByteArray();
813 mLeFlags = in.readInt();
Jakub Pawlowskicc840062015-12-29 13:19:21 -0800814 }
815
David Duarteee52b7e2023-12-02 01:32:11 +0000816 /** @hide */
Jack He9e045d22017-08-22 21:21:23 -0700817 @Override
Jakub Pawlowskicc840062015-12-29 13:19:21 -0800818 public int describeContents() {
819 return 0;
820 }
821
David Duarteee52b7e2023-12-02 01:32:11 +0000822 /** @hide */
Jakub Pawlowskicc840062015-12-29 13:19:21 -0800823 @Override
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800824 public void writeToParcel(@NonNull Parcel out, int flags) {
825 // Both
826 // Required
827 out.writeByteArray(mDeviceAddressWithType);
828 // Required
829 out.writeByteArray(mConfirmationHash);
830 // Optional
831 out.writeByteArray(mRandomizerHash);
832 // Optional
833 out.writeByteArray(mDeviceName);
834
835 // Classic
836 // Required
837 out.writeByteArray(mClassicLength);
838 // Optional
839 out.writeByteArray(mClassOfDevice);
840
841 // LE
842 // Required
843 out.writeInt(mLeDeviceRole);
844 // Required
845 out.writeByteArray(mLeTemporaryKey);
846 // Optional
847 out.writeByteArray(mLeAppearance);
848 // Optional
849 out.writeInt(mLeFlags);
Jakub Pawlowskicc840062015-12-29 13:19:21 -0800850 }
851
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800852 // For Parcelable
Jeff Sharkey13613a32019-02-28 12:06:45 -0700853 public static final @android.annotation.NonNull Parcelable.Creator<OobData> CREATOR =
Jack He9e045d22017-08-22 21:21:23 -0700854 new Parcelable.Creator<OobData>() {
David Duarteee52b7e2023-12-02 01:32:11 +0000855 public OobData createFromParcel(Parcel in) {
856 return new OobData(in);
857 }
Jakub Pawlowskicc840062015-12-29 13:19:21 -0800858
David Duarteee52b7e2023-12-02 01:32:11 +0000859 public OobData[] newArray(int size) {
860 return new OobData[size];
861 }
862 };
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800863
864 /**
865 * @return a {@link String} representation of the OobData object.
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800866 * @hide
867 */
868 @Override
869 @NonNull
870 public String toString() {
871 return "OobData: \n\t"
David Duarteee52b7e2023-12-02 01:32:11 +0000872 // Both
873 + "Device Address With Type: "
874 + toHexString(mDeviceAddressWithType)
875 + "\n\t"
876 + "Confirmation: "
877 + toHexString(mConfirmationHash)
878 + "\n\t"
879 + "Randomizer: "
880 + toHexString(mRandomizerHash)
881 + "\n\t"
882 + "Device Name: "
883 + toHexString(mDeviceName)
884 + "\n\t"
885 // Classic
886 + "OobData Length: "
887 + toHexString(mClassicLength)
888 + "\n\t"
889 + "Class of Device: "
890 + toHexString(mClassOfDevice)
891 + "\n\t"
892 // LE
893 + "LE Device Role: "
894 + toHexString(mLeDeviceRole)
895 + "\n\t"
896 + "LE Temporary Key: "
897 + toHexString(mLeTemporaryKey)
898 + "\n\t"
899 + "LE Appearance: "
900 + toHexString(mLeAppearance)
901 + "\n\t"
902 + "LE Flags: "
903 + toHexString(mLeFlags)
904 + "\n\t";
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800905 }
906
907 @NonNull
Martin Brabham0b3e9772021-05-19 21:01:27 -0700908 private String toHexString(int b) {
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800909 return toHexString(new byte[] {(byte) b});
910 }
911
912 @NonNull
Martin Brabham0b3e9772021-05-19 21:01:27 -0700913 private String toHexString(byte[] array) {
914 if (array == null) return "null";
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800915 StringBuilder builder = new StringBuilder(array.length * 2);
David Duarteee52b7e2023-12-02 01:32:11 +0000916 for (byte b : array) {
Martin Brabham51a3e5d2021-01-21 10:29:05 -0800917 builder.append(String.format("%02x", b));
918 }
919 return builder.toString();
920 }
Jack He9e045d22017-08-22 21:21:23 -0700921}