Add parse method to parse UUID from bytes for 16 bit, 32 bit and 128 bit
Bluetooth UUIDs. Added unit tests. Change-Id: I4ecf0ede02561a5e9815acf8a5a1309d5756b887
This commit is contained in:
@@ -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,
|
||||
@@ -215,16 +223,61 @@ public final class BluetoothUuid {
|
||||
return (int)value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user