summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/bluetooth/BluetoothUuid.java63
-rw-r--r--core/tests/bluetoothtests/src/android/bluetooth/BluetoothUuidTest.java50
2 files changed, 108 insertions, 5 deletions
diff --git a/core/java/android/bluetooth/BluetoothUuid.java b/core/java/android/bluetooth/BluetoothUuid.java
index 4b28516..ab53fb0 100644
--- a/core/java/android/bluetooth/BluetoothUuid.java
+++ b/core/java/android/bluetooth/BluetoothUuid.java
@@ -18,6 +18,8 @@ package android.bluetooth;
import android.os.ParcelUuid;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
import java.util.Arrays;
import java.util.HashSet;
import java.util.UUID;
@@ -76,6 +78,12 @@ public final class BluetoothUuid {
public static final ParcelUuid BASE_UUID =
ParcelUuid.fromString("00000000-0000-1000-8000-00805F9B34FB");
+ /** Length of bytes for 16 bit UUID */
+ public static final int UUID_BYTES_16_BIT = 2;
+ /** Length of bytes for 32 bit UUID */
+ public static final int UUID_BYTES_32_BIT = 4;
+ /** Length of bytes for 128 bit UUID */
+ public static final int UUID_BYTES_128_BIT = 16;
public static final ParcelUuid[] RESERVED_UUIDS = {
AudioSink, AudioSource, AdvAudioDist, HSP, Handsfree, AvrcpController, AvrcpTarget,
@@ -216,15 +224,60 @@ public final class BluetoothUuid {
}
/**
+ * Parse UUID from bytes. The {@code uuidBytes} can represent a 16-bit, 32-bit or 128-bit UUID,
+ * but the returned UUID is always in 128-bit format.
+ * Note UUID is little endian in Bluetooth.
+ *
+ * @param uuidBytes Byte representation of uuid.
+ * @return {@link ParcelUuid} parsed from bytes.
+ * @throws IllegalArgumentException If the {@code uuidBytes} cannot be parsed.
+ */
+ public static ParcelUuid parseUuidFrom(byte[] uuidBytes) {
+ if (uuidBytes == null) {
+ throw new IllegalArgumentException("uuidBytes cannot be null");
+ }
+ int length = uuidBytes.length;
+ if (length != UUID_BYTES_16_BIT && length != UUID_BYTES_32_BIT &&
+ length != UUID_BYTES_128_BIT) {
+ throw new IllegalArgumentException("uuidBytes length invalid - " + length);
+ }
+
+ // Construct a 128 bit UUID.
+ if (length == UUID_BYTES_128_BIT) {
+ ByteBuffer buf = ByteBuffer.wrap(uuidBytes).order(ByteOrder.LITTLE_ENDIAN);
+ long msb = buf.getLong(8);
+ long lsb = buf.getLong(0);
+ return new ParcelUuid(new UUID(msb, lsb));
+ }
+
+ // For 16 bit and 32 bit UUID we need to convert them to 128 bit value.
+ // 128_bit_value = uuid * 2^96 + BASE_UUID
+ long shortUuid;
+ if (length == UUID_BYTES_16_BIT) {
+ shortUuid = uuidBytes[0] & 0xFF;
+ shortUuid += (uuidBytes[1] & 0xFF) << 8;
+ } else {
+ shortUuid = uuidBytes[0] & 0xFF ;
+ shortUuid += (uuidBytes[1] & 0xFF) << 8;
+ shortUuid += (uuidBytes[2] & 0xFF) << 16;
+ shortUuid += (uuidBytes[3] & 0xFF) << 24;
+ }
+ long msb = BASE_UUID.getUuid().getMostSignificantBits() + (shortUuid << 32);
+ long lsb = BASE_UUID.getUuid().getLeastSignificantBits();
+ return new ParcelUuid(new UUID(msb, lsb));
+ }
+
+ /**
* Check whether the given parcelUuid can be converted to 16 bit bluetooth uuid.
+ *
* @param parcelUuid
* @return true if the parcelUuid can be converted to 16 bit uuid, false otherwise.
*/
public static boolean isShortUuid(ParcelUuid parcelUuid) {
- UUID uuid = parcelUuid.getUuid();
- if (uuid.getLeastSignificantBits() != BASE_UUID.getUuid().getLeastSignificantBits()) {
- return false;
- }
- return ((uuid.getMostSignificantBits() & 0xFFFF0000FFFFFFFFL) == 0x1000L);
+ UUID uuid = parcelUuid.getUuid();
+ if (uuid.getLeastSignificantBits() != BASE_UUID.getUuid().getLeastSignificantBits()) {
+ return false;
+ }
+ return ((uuid.getMostSignificantBits() & 0xFFFF0000FFFFFFFFL) == 0x1000L);
}
}
diff --git a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothUuidTest.java b/core/tests/bluetoothtests/src/android/bluetooth/BluetoothUuidTest.java
new file mode 100644
index 0000000..0f3ea0e
--- /dev/null
+++ b/core/tests/bluetoothtests/src/android/bluetooth/BluetoothUuidTest.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2014 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 android.os.ParcelUuid;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import junit.framework.TestCase;
+
+/**
+ * Unit test cases for {@link BluetoothUuid}.
+ * <p>
+ * To run this test, use adb shell am instrument -e class 'android.bluetooth.BluetoothUuidTest' -w
+ * 'com.android.bluetooth.tests/android.bluetooth.BluetoothTestRunner'
+ */
+public class BluetoothUuidTest extends TestCase {
+
+ @SmallTest
+ public void testUuidParser() {
+ byte[] uuid16 = new byte[] {
+ 0x0B, 0x11 };
+ assertEquals(ParcelUuid.fromString("0000110B-0000-1000-8000-00805F9B34FB"),
+ BluetoothUuid.parseUuidFrom(uuid16));
+
+ byte[] uuid32 = new byte[] {
+ 0x0B, 0x11, 0x33, (byte) 0xFE };
+ assertEquals(ParcelUuid.fromString("FE33110B-0000-1000-8000-00805F9B34FB"),
+ BluetoothUuid.parseUuidFrom(uuid32));
+
+ byte[] uuid128 = new byte[] {
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+ 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, (byte) 0xFF };
+ assertEquals(ParcelUuid.fromString("FF0F0E0D-0C0B-0A09-0807-0060504030201"),
+ BluetoothUuid.parseUuidFrom(uuid128));
+ }
+}