1 /* 2 * Copyright (C) 2009 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 android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.annotation.SuppressLint; 22 import android.annotation.SystemApi; 23 import android.compat.annotation.UnsupportedAppUsage; 24 import android.os.ParcelUuid; 25 26 import java.nio.ByteBuffer; 27 import java.nio.ByteOrder; 28 import java.util.Arrays; 29 import java.util.HashSet; 30 import java.util.UUID; 31 32 /** 33 * Static helper methods and constants to decode the ParcelUuid of remote devices. Bluetooth service 34 * UUIDs are defined in the SDP section of the Bluetooth Assigned Numbers document. The constant 35 * 128 bit values in this class are calculated as: uuid * 2^96 + {@link #BASE_UUID}. 36 * 37 * @hide 38 */ 39 @SystemApi 40 @SuppressLint("AndroidFrameworkBluetoothPermission") 41 public final class BluetoothUuid { 42 43 /** 44 * UUID corresponding to the Audio sink role (also referred to as the A2DP sink role). 45 * 46 * @hide 47 */ 48 @NonNull 49 @SystemApi 50 public static final ParcelUuid A2DP_SINK = 51 ParcelUuid.fromString("0000110B-0000-1000-8000-00805F9B34FB"); 52 /** 53 * UUID corresponding to the Audio source role (also referred to as the A2DP source role). 54 * 55 * @hide 56 */ 57 @NonNull 58 @SystemApi 59 public static final ParcelUuid A2DP_SOURCE = 60 ParcelUuid.fromString("0000110A-0000-1000-8000-00805F9B34FB"); 61 62 /** 63 * UUID corresponding to the Advanced Audio Distribution Profile (A2DP). 64 * 65 * @hide 66 */ 67 @NonNull 68 @SystemApi 69 public static final ParcelUuid ADV_AUDIO_DIST = 70 ParcelUuid.fromString("0000110D-0000-1000-8000-00805F9B34FB"); 71 72 /** 73 * UUID corresponding to the Headset Profile (HSP). 74 * 75 * @hide 76 */ 77 @NonNull 78 @SystemApi 79 public static final ParcelUuid HSP = 80 ParcelUuid.fromString("00001108-0000-1000-8000-00805F9B34FB"); 81 82 /** 83 * UUID corresponding to the Headset Profile (HSP) Audio Gateway role. 84 * 85 * @hide 86 */ 87 @NonNull 88 @SystemApi 89 public static final ParcelUuid HSP_AG = 90 ParcelUuid.fromString("00001112-0000-1000-8000-00805F9B34FB"); 91 92 /** 93 * UUID corresponding to the Hands-Free Profile (HFP). 94 * 95 * @hide 96 */ 97 @NonNull 98 @SystemApi 99 public static final ParcelUuid HFP = 100 ParcelUuid.fromString("0000111E-0000-1000-8000-00805F9B34FB"); 101 102 /** 103 * UUID corresponding to the Hands-Free Profile (HFP) Audio Gateway role. 104 * 105 * @hide 106 */ 107 @NonNull 108 @SystemApi 109 public static final ParcelUuid HFP_AG = 110 ParcelUuid.fromString("0000111F-0000-1000-8000-00805F9B34FB"); 111 112 /** 113 * UUID corresponding to the Audio Video Remote Control Profile (AVRCP). 114 * 115 * @hide 116 */ 117 @NonNull 118 @SystemApi 119 public static final ParcelUuid AVRCP = 120 ParcelUuid.fromString("0000110E-0000-1000-8000-00805F9B34FB"); 121 122 /** 123 * UUID corresponding to the Audio Video Remote Control Profile (AVRCP) controller role. 124 * 125 * @hide 126 */ 127 @NonNull 128 @SystemApi 129 public static final ParcelUuid AVRCP_CONTROLLER = 130 ParcelUuid.fromString("0000110F-0000-1000-8000-00805F9B34FB"); 131 132 /** 133 * UUID corresponding to the Audio Video Remote Control Profile (AVRCP) target role. 134 * 135 * @hide 136 */ 137 @NonNull 138 @SystemApi 139 public static final ParcelUuid AVRCP_TARGET = 140 ParcelUuid.fromString("0000110C-0000-1000-8000-00805F9B34FB"); 141 142 /** 143 * UUID corresponding to the OBject EXchange (OBEX) Object Push Profile (OPP). 144 * 145 * @hide 146 */ 147 @NonNull 148 @SystemApi 149 public static final ParcelUuid OBEX_OBJECT_PUSH = 150 ParcelUuid.fromString("00001105-0000-1000-8000-00805f9b34fb"); 151 152 /** 153 * UUID corresponding to the Human Interface Device (HID) profile. 154 * 155 * @hide 156 */ 157 @NonNull 158 @SystemApi 159 public static final ParcelUuid HID = 160 ParcelUuid.fromString("00001124-0000-1000-8000-00805f9b34fb"); 161 162 /** 163 * UUID corresponding to the Human Interface Device over GATT Profile (HOGP). 164 * 165 * @hide 166 */ 167 @NonNull 168 @SystemApi 169 public static final ParcelUuid HOGP = 170 ParcelUuid.fromString("00001812-0000-1000-8000-00805f9b34fb"); 171 172 /** 173 * UUID corresponding to the Personal Area Network User (PANU) role. 174 * 175 * @hide 176 */ 177 @NonNull 178 @SystemApi 179 public static final ParcelUuid PANU = 180 ParcelUuid.fromString("00001115-0000-1000-8000-00805F9B34FB"); 181 182 /** 183 * UUID corresponding to the Network Access Point (NAP) role. 184 * 185 * @hide 186 */ 187 @NonNull 188 @SystemApi 189 public static final ParcelUuid NAP = 190 ParcelUuid.fromString("00001116-0000-1000-8000-00805F9B34FB"); 191 192 /** 193 * UUID corresponding to the Bluetooth Network Encapsulation Protocol (BNEP). 194 * 195 * @hide 196 */ 197 @NonNull 198 @SystemApi 199 public static final ParcelUuid BNEP = 200 ParcelUuid.fromString("0000000f-0000-1000-8000-00805F9B34FB"); 201 202 /** 203 * UUID corresponding to the Phonebook Access Profile (PBAP) client role. 204 * 205 * @hide 206 */ 207 @NonNull 208 @SystemApi 209 public static final ParcelUuid PBAP_PCE = 210 ParcelUuid.fromString("0000112e-0000-1000-8000-00805F9B34FB"); 211 212 /** 213 * UUID corresponding to the Phonebook Access Profile (PBAP) server role. 214 * 215 * @hide 216 */ 217 @NonNull 218 @SystemApi 219 public static final ParcelUuid PBAP_PSE = 220 ParcelUuid.fromString("0000112f-0000-1000-8000-00805F9B34FB"); 221 222 /** 223 * UUID corresponding to the Message Access Profile (MAP). 224 * 225 * @hide 226 */ 227 @NonNull 228 @SystemApi 229 public static final ParcelUuid MAP = 230 ParcelUuid.fromString("00001134-0000-1000-8000-00805F9B34FB"); 231 232 /** 233 * UUID corresponding to the Message Notification Server (MNS) role. 234 * 235 * @hide 236 */ 237 @NonNull 238 @SystemApi 239 public static final ParcelUuid MNS = 240 ParcelUuid.fromString("00001133-0000-1000-8000-00805F9B34FB"); 241 242 /** 243 * UUID corresponding to the Message Access Server (MAS) role. 244 * 245 * @hide 246 */ 247 @NonNull 248 @SystemApi 249 public static final ParcelUuid MAS = 250 ParcelUuid.fromString("00001132-0000-1000-8000-00805F9B34FB"); 251 252 /** 253 * UUID corresponding to the Sim Access Profile (SAP). 254 * 255 * @hide 256 */ 257 @NonNull 258 @SystemApi 259 public static final ParcelUuid SAP = 260 ParcelUuid.fromString("0000112D-0000-1000-8000-00805F9B34FB"); 261 262 /** 263 * UUID corresponding to the Hearing Aid Profile. 264 * 265 * @hide 266 */ 267 @NonNull 268 @SystemApi 269 public static final ParcelUuid HEARING_AID = 270 ParcelUuid.fromString("0000FDF0-0000-1000-8000-00805f9b34fb"); 271 272 /** 273 * UUID corresponding to the Hearing Access Service (HAS). 274 * 275 * @hide 276 */ 277 @NonNull 278 @SystemApi 279 public static final ParcelUuid HAS = 280 ParcelUuid.fromString("00001854-0000-1000-8000-00805F9B34FB"); 281 282 /** 283 * UUID corresponding to Audio Stream Control (also known as Bluetooth Low Energy Audio). 284 * 285 * @hide 286 */ 287 @NonNull 288 @SystemApi 289 public static final ParcelUuid LE_AUDIO = 290 ParcelUuid.fromString("0000184E-0000-1000-8000-00805F9B34FB"); 291 292 /** 293 * UUID corresponding to the Device Identification Profile (DIP). 294 * 295 * @hide 296 */ 297 @NonNull 298 @SystemApi 299 public static final ParcelUuid DIP = 300 ParcelUuid.fromString("00001200-0000-1000-8000-00805F9B34FB"); 301 302 /** 303 * UUID corresponding to the Volume Control Service. 304 * 305 * @hide 306 */ 307 @NonNull 308 @SystemApi 309 public static final ParcelUuid VOLUME_CONTROL = 310 ParcelUuid.fromString("00001844-0000-1000-8000-00805F9B34FB"); 311 312 /** 313 * UUID corresponding to the Generic Media Control Service. 314 * 315 * @hide 316 */ 317 @NonNull 318 @SystemApi 319 public static final ParcelUuid GENERIC_MEDIA_CONTROL = 320 ParcelUuid.fromString("00001849-0000-1000-8000-00805F9B34FB"); 321 322 /** 323 * UUID corresponding to the Media Control Service. 324 * 325 * @hide 326 */ 327 @NonNull 328 @SystemApi 329 public static final ParcelUuid MEDIA_CONTROL = 330 ParcelUuid.fromString("00001848-0000-1000-8000-00805F9B34FB"); 331 332 /** 333 * UUID corresponding to the Coordinated Set Identification Service. 334 * 335 * @hide 336 */ 337 @NonNull 338 @SystemApi 339 public static final ParcelUuid COORDINATED_SET = 340 ParcelUuid.fromString("00001846-0000-1000-8000-00805F9B34FB"); 341 342 /** 343 * UUID corresponding to the Common Audio Service. 344 * 345 * @hide 346 */ 347 @NonNull 348 @SystemApi 349 public static final ParcelUuid CAP = 350 ParcelUuid.fromString("00001853-0000-1000-8000-00805F9B34FB"); 351 352 /** 353 * UUID corresponding to the Broadcast Audio Scan Service (also known as LE Audio Broadcast 354 * Assistant). 355 * 356 * @hide 357 */ 358 @NonNull 359 public static final ParcelUuid BATTERY = 360 ParcelUuid.fromString("0000180F-0000-1000-8000-00805F9B34FB"); 361 /** @hide */ 362 @NonNull 363 @SystemApi 364 public static final ParcelUuid BASS = 365 ParcelUuid.fromString("0000184F-0000-1000-8000-00805F9B34FB"); 366 367 /** 368 * Telephony and Media Audio Profile (TMAP) UUID 369 * @hide 370 */ 371 @NonNull 372 public static final ParcelUuid TMAP = 373 ParcelUuid.fromString("00001855-0000-1000-8000-00805F9B34FB"); 374 375 /** @hide */ 376 @NonNull 377 @SystemApi 378 public static final ParcelUuid BASE_UUID = 379 ParcelUuid.fromString("00000000-0000-1000-8000-00805F9B34FB"); 380 381 /** 382 * Length of bytes for 16 bit UUID 383 * 384 * @hide 385 */ 386 @SystemApi 387 public static final int UUID_BYTES_16_BIT = 2; 388 /** 389 * Length of bytes for 32 bit UUID 390 * 391 * @hide 392 */ 393 @SystemApi 394 public static final int UUID_BYTES_32_BIT = 4; 395 /** 396 * Length of bytes for 128 bit UUID 397 * 398 * @hide 399 */ 400 @SystemApi 401 public static final int UUID_BYTES_128_BIT = 16; 402 403 /** 404 * Returns true if there any common ParcelUuids in uuidA and uuidB. 405 * 406 * @param uuidA - List of ParcelUuids 407 * @param uuidB - List of ParcelUuids 408 * 409 * @hide 410 */ 411 @SystemApi containsAnyUuid(@ullable ParcelUuid[] uuidA, @Nullable ParcelUuid[] uuidB)412 public static boolean containsAnyUuid(@Nullable ParcelUuid[] uuidA, 413 @Nullable ParcelUuid[] uuidB) { 414 if (uuidA == null && uuidB == null) return true; 415 416 if (uuidA == null) { 417 return uuidB.length == 0; 418 } 419 420 if (uuidB == null) { 421 return uuidA.length == 0; 422 } 423 424 HashSet<ParcelUuid> uuidSet = new HashSet<ParcelUuid>(Arrays.asList(uuidA)); 425 for (ParcelUuid uuid : uuidB) { 426 if (uuidSet.contains(uuid)) return true; 427 } 428 return false; 429 } 430 431 /** 432 * Extract the Service Identifier or the actual uuid from the Parcel Uuid. 433 * For example, if 0000110B-0000-1000-8000-00805F9B34FB is the parcel Uuid, 434 * this function will return 110B 435 * 436 * @param parcelUuid 437 * @return the service identifier. 438 */ getServiceIdentifierFromParcelUuid(ParcelUuid parcelUuid)439 private static int getServiceIdentifierFromParcelUuid(ParcelUuid parcelUuid) { 440 UUID uuid = parcelUuid.getUuid(); 441 long value = (uuid.getMostSignificantBits() & 0xFFFFFFFF00000000L) >>> 32; 442 return (int) value; 443 } 444 445 /** 446 * Parse UUID from bytes. The {@code uuidBytes} can represent a 16-bit, 32-bit or 128-bit UUID, 447 * but the returned UUID is always in 128-bit format. 448 * Note UUID is little endian in Bluetooth. 449 * 450 * @param uuidBytes Byte representation of uuid. 451 * @return {@link ParcelUuid} parsed from bytes. 452 * @throws IllegalArgumentException If the {@code uuidBytes} cannot be parsed. 453 * 454 * @hide 455 */ 456 @NonNull 457 @SystemApi parseUuidFrom(@ullable byte[] uuidBytes)458 public static ParcelUuid parseUuidFrom(@Nullable byte[] uuidBytes) { 459 if (uuidBytes == null) { 460 throw new IllegalArgumentException("uuidBytes cannot be null"); 461 } 462 int length = uuidBytes.length; 463 if (length != UUID_BYTES_16_BIT && length != UUID_BYTES_32_BIT 464 && length != UUID_BYTES_128_BIT) { 465 throw new IllegalArgumentException("uuidBytes length invalid - " + length); 466 } 467 468 // Construct a 128 bit UUID. 469 if (length == UUID_BYTES_128_BIT) { 470 ByteBuffer buf = ByteBuffer.wrap(uuidBytes).order(ByteOrder.LITTLE_ENDIAN); 471 long msb = buf.getLong(8); 472 long lsb = buf.getLong(0); 473 return new ParcelUuid(new UUID(msb, lsb)); 474 } 475 476 // For 16 bit and 32 bit UUID we need to convert them to 128 bit value. 477 // 128_bit_value = uuid * 2^96 + BASE_UUID 478 long shortUuid; 479 if (length == UUID_BYTES_16_BIT) { 480 shortUuid = uuidBytes[0] & 0xFF; 481 shortUuid += (uuidBytes[1] & 0xFF) << 8; 482 } else { 483 shortUuid = uuidBytes[0] & 0xFF; 484 shortUuid += (uuidBytes[1] & 0xFF) << 8; 485 shortUuid += (uuidBytes[2] & 0xFF) << 16; 486 shortUuid += (uuidBytes[3] & 0xFF) << 24; 487 } 488 long msb = BASE_UUID.getUuid().getMostSignificantBits() + (shortUuid << 32); 489 long lsb = BASE_UUID.getUuid().getLeastSignificantBits(); 490 return new ParcelUuid(new UUID(msb, lsb)); 491 } 492 493 /** 494 * Parse UUID to bytes. The returned value is shortest representation, a 16-bit, 32-bit or 495 * 128-bit UUID, Note returned value is little endian (Bluetooth). 496 * 497 * @param uuid uuid to parse. 498 * @return shortest representation of {@code uuid} as bytes. 499 * @throws IllegalArgumentException If the {@code uuid} is null. 500 * 501 * @hide 502 */ uuidToBytes(ParcelUuid uuid)503 public static byte[] uuidToBytes(ParcelUuid uuid) { 504 if (uuid == null) { 505 throw new IllegalArgumentException("uuid cannot be null"); 506 } 507 508 if (is16BitUuid(uuid)) { 509 byte[] uuidBytes = new byte[UUID_BYTES_16_BIT]; 510 int uuidVal = getServiceIdentifierFromParcelUuid(uuid); 511 uuidBytes[0] = (byte) (uuidVal & 0xFF); 512 uuidBytes[1] = (byte) ((uuidVal & 0xFF00) >> 8); 513 return uuidBytes; 514 } 515 516 if (is32BitUuid(uuid)) { 517 byte[] uuidBytes = new byte[UUID_BYTES_32_BIT]; 518 int uuidVal = getServiceIdentifierFromParcelUuid(uuid); 519 uuidBytes[0] = (byte) (uuidVal & 0xFF); 520 uuidBytes[1] = (byte) ((uuidVal & 0xFF00) >> 8); 521 uuidBytes[2] = (byte) ((uuidVal & 0xFF0000) >> 16); 522 uuidBytes[3] = (byte) ((uuidVal & 0xFF000000) >> 24); 523 return uuidBytes; 524 } 525 526 // Construct a 128 bit UUID. 527 long msb = uuid.getUuid().getMostSignificantBits(); 528 long lsb = uuid.getUuid().getLeastSignificantBits(); 529 530 byte[] uuidBytes = new byte[UUID_BYTES_128_BIT]; 531 ByteBuffer buf = ByteBuffer.wrap(uuidBytes).order(ByteOrder.LITTLE_ENDIAN); 532 buf.putLong(8, msb); 533 buf.putLong(0, lsb); 534 return uuidBytes; 535 } 536 537 /** 538 * Check whether the given parcelUuid can be converted to 16 bit bluetooth uuid. 539 * 540 * @param parcelUuid 541 * @return true if the parcelUuid can be converted to 16 bit uuid, false otherwise. 542 * 543 * @hide 544 */ 545 @UnsupportedAppUsage is16BitUuid(ParcelUuid parcelUuid)546 public static boolean is16BitUuid(ParcelUuid parcelUuid) { 547 UUID uuid = parcelUuid.getUuid(); 548 if (uuid.getLeastSignificantBits() != BASE_UUID.getUuid().getLeastSignificantBits()) { 549 return false; 550 } 551 return ((uuid.getMostSignificantBits() & 0xFFFF0000FFFFFFFFL) == 0x1000L); 552 } 553 554 555 /** 556 * Check whether the given parcelUuid can be converted to 32 bit bluetooth uuid. 557 * 558 * @param parcelUuid 559 * @return true if the parcelUuid can be converted to 32 bit uuid, false otherwise. 560 * 561 * @hide 562 */ 563 @UnsupportedAppUsage is32BitUuid(ParcelUuid parcelUuid)564 public static boolean is32BitUuid(ParcelUuid parcelUuid) { 565 UUID uuid = parcelUuid.getUuid(); 566 if (uuid.getLeastSignificantBits() != BASE_UUID.getUuid().getLeastSignificantBits()) { 567 return false; 568 } 569 if (is16BitUuid(parcelUuid)) { 570 return false; 571 } 572 return ((uuid.getMostSignificantBits() & 0xFFFFFFFFL) == 0x1000L); 573 } 574 BluetoothUuid()575 private BluetoothUuid() {} 576 } 577