Starting to abstract more so we can support more beacon types
This commit is contained in:
@@ -216,15 +216,6 @@ public class BluetoothLeDevice implements Parcelable {
|
||||
return BluetoothClassResolver.resolveDeviceClass(mDevice.getBluetoothClass().getDeviceClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the bluetooth device major class name.
|
||||
*
|
||||
* @return the bluetooth device major class name
|
||||
*/
|
||||
public String getBluetoothDeviceMajorClassName() {
|
||||
return BluetoothClassResolver.resolveMajorDeviceClass(mDevice.getBluetoothClass().getMajorDeviceClass());
|
||||
}
|
||||
|
||||
public Set<BluetoothService> getBluetoothDeviceKnownSupportedServices() {
|
||||
if (mServiceSet == null) {
|
||||
synchronized (this) {
|
||||
@@ -244,6 +235,15 @@ public class BluetoothLeDevice implements Parcelable {
|
||||
return mServiceSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the bluetooth device major class name.
|
||||
*
|
||||
* @return the bluetooth device major class name
|
||||
*/
|
||||
public String getBluetoothDeviceMajorClassName() {
|
||||
return BluetoothClassResolver.resolveMajorDeviceClass(mDevice.getBluetoothClass().getMajorDeviceClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the device.
|
||||
*
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package uk.co.alt236.bluetoothlelib.device.beacon;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public abstract class BeaconManufacturerData {
|
||||
private final BeaconType mBeaconType;
|
||||
private final byte[] mData;
|
||||
|
||||
protected BeaconManufacturerData(final BeaconType expectedType, final byte[] data){
|
||||
if (BeaconUtils.getBeaconType(data) != expectedType) {
|
||||
throw new IllegalArgumentException(
|
||||
"Manufacturer record '"
|
||||
+ Arrays.toString(data)
|
||||
+ "' is not from a " + expectedType);
|
||||
}
|
||||
|
||||
this.mData = data;
|
||||
this.mBeaconType = expectedType;
|
||||
}
|
||||
|
||||
public BeaconType getBeaconType(){
|
||||
return mBeaconType;
|
||||
}
|
||||
|
||||
public byte[] getData(){
|
||||
return mData;
|
||||
}
|
||||
}
|
||||
@@ -5,5 +5,5 @@ package uk.co.alt236.bluetoothlelib.device.beacon;
|
||||
*/
|
||||
public enum BeaconType {
|
||||
NOT_A_BEACON,
|
||||
IBEACON
|
||||
IBEACON,
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ public final class BeaconUtils {
|
||||
* @return the {@link BeaconType}
|
||||
*/
|
||||
public static BeaconType getBeaconType(final byte[] manufacturerData) {
|
||||
if (manufacturerData == null) {
|
||||
if (manufacturerData == null || manufacturerData.length == 0) {
|
||||
return BeaconType.NOT_A_BEACON;
|
||||
}
|
||||
|
||||
|
||||
-10
@@ -25,7 +25,6 @@ public class IBeaconDevice extends BluetoothLeDevice implements BeaconDevice{
|
||||
*/
|
||||
public IBeaconDevice(final BluetoothDevice device, final int rssi, final byte[] scanRecord) {
|
||||
super(device, rssi, scanRecord, 0);
|
||||
validate();
|
||||
mIBeaconData = new IBeaconManufacturerData(this);
|
||||
}
|
||||
|
||||
@@ -40,7 +39,6 @@ public class IBeaconDevice extends BluetoothLeDevice implements BeaconDevice{
|
||||
*/
|
||||
public IBeaconDevice(final BluetoothDevice device, final int rssi, final byte[] scanRecord, final long timestamp) {
|
||||
super(device, rssi, scanRecord, timestamp);
|
||||
validate();
|
||||
mIBeaconData = new IBeaconManufacturerData(this);
|
||||
}
|
||||
|
||||
@@ -53,13 +51,11 @@ public class IBeaconDevice extends BluetoothLeDevice implements BeaconDevice{
|
||||
*/
|
||||
public IBeaconDevice(final BluetoothLeDevice device) {
|
||||
super(device);
|
||||
validate();
|
||||
mIBeaconData = new IBeaconManufacturerData(this);
|
||||
}
|
||||
|
||||
private IBeaconDevice(final Parcel in) {
|
||||
super(in);
|
||||
validate();
|
||||
mIBeaconData = new IBeaconManufacturerData(this);
|
||||
}
|
||||
|
||||
@@ -143,10 +139,4 @@ public class IBeaconDevice extends BluetoothLeDevice implements BeaconDevice{
|
||||
public String getUUID() {
|
||||
return getIBeaconData().getUUID();
|
||||
}
|
||||
|
||||
private void validate() {
|
||||
if (BeaconUtils.getBeaconType(this) != BeaconType.IBEACON) {
|
||||
throw new IllegalArgumentException("Device " + getDevice() + " is not an iBeacon.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+9
-17
@@ -4,8 +4,8 @@ import java.util.Arrays;
|
||||
|
||||
import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice;
|
||||
import uk.co.alt236.bluetoothlelib.device.adrecord.AdRecord;
|
||||
import uk.co.alt236.bluetoothlelib.device.beacon.BeaconManufacturerData;
|
||||
import uk.co.alt236.bluetoothlelib.device.beacon.BeaconType;
|
||||
import uk.co.alt236.bluetoothlelib.device.beacon.BeaconUtils;
|
||||
import uk.co.alt236.bluetoothlelib.util.ByteUtils;
|
||||
|
||||
/**
|
||||
@@ -45,8 +45,7 @@ import uk.co.alt236.bluetoothlelib.util.ByteUtils;
|
||||
* @author Alexandros Schillings
|
||||
*/
|
||||
|
||||
public final class IBeaconManufacturerData {
|
||||
private final byte[] mData;
|
||||
public final class IBeaconManufacturerData extends BeaconManufacturerData{
|
||||
private final int mCalibratedTxPower;
|
||||
private final int mCompanyIdentidier;
|
||||
private final int mIBeaconAdvertisment;
|
||||
@@ -71,24 +70,17 @@ public final class IBeaconManufacturerData {
|
||||
* @throws IllegalArgumentException if the data is not from an iBeacon.
|
||||
*/
|
||||
public IBeaconManufacturerData(final byte[] manufacturerData) {
|
||||
mData = manufacturerData;
|
||||
super(BeaconType.IBEACON, manufacturerData);
|
||||
|
||||
if (BeaconUtils.getBeaconType(mData) != BeaconType.IBEACON) {
|
||||
throw new IllegalArgumentException(
|
||||
"Manufacturer record '"
|
||||
+ Arrays.toString(manufacturerData)
|
||||
+ "' is not from an iBeacon.");
|
||||
}
|
||||
|
||||
final byte[] intArray = Arrays.copyOfRange(mData, 0, 2);
|
||||
final byte[] intArray = Arrays.copyOfRange(manufacturerData, 0, 2);
|
||||
ByteUtils.invertArray(intArray);
|
||||
|
||||
mCompanyIdentidier = ByteUtils.getIntFrom2ByteArray(intArray);
|
||||
mIBeaconAdvertisment = ByteUtils.getIntFrom2ByteArray(Arrays.copyOfRange(mData, 2, 4));
|
||||
mUUID = IBeaconUtils.calculateUuidString(Arrays.copyOfRange(mData, 4, 20));
|
||||
mMajor = ByteUtils.getIntFrom2ByteArray(Arrays.copyOfRange(mData, 20, 22));
|
||||
mMinor = ByteUtils.getIntFrom2ByteArray(Arrays.copyOfRange(mData, 22, 24));
|
||||
mCalibratedTxPower = mData[24];
|
||||
mIBeaconAdvertisment = ByteUtils.getIntFrom2ByteArray(Arrays.copyOfRange(manufacturerData, 2, 4));
|
||||
mUUID = IBeaconUtils.calculateUuidString(Arrays.copyOfRange(manufacturerData, 4, 20));
|
||||
mMajor = ByteUtils.getIntFrom2ByteArray(Arrays.copyOfRange(manufacturerData, 20, 22));
|
||||
mMinor = ByteUtils.getIntFrom2ByteArray(Arrays.copyOfRange(manufacturerData, 22, 24));
|
||||
mCalibratedTxPower = manufacturerData[24];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+6
-6
@@ -7,12 +7,6 @@ import junit.framework.TestCase;
|
||||
*/
|
||||
public class BeaconUtilsTest extends TestCase {
|
||||
|
||||
public void testGetBeaconTypeInvalid() throws Exception {
|
||||
assertEquals(BeaconType.NOT_A_BEACON, BeaconUtils.getBeaconType((byte[]) null));
|
||||
assertEquals(BeaconType.NOT_A_BEACON, BeaconUtils.getBeaconType(new byte[0]));
|
||||
assertEquals(BeaconType.NOT_A_BEACON, BeaconUtils.getBeaconType(new byte[25]));
|
||||
}
|
||||
|
||||
public void testGetBeaconTypeIBeacon() throws Exception {
|
||||
assertEquals(BeaconType.IBEACON, BeaconUtils.getBeaconType(new byte[]{
|
||||
0x4C, 0x00, 0x02, 0x15, 0x00, // <- Magic iBeacon header
|
||||
@@ -22,4 +16,10 @@ public class BeaconUtilsTest extends TestCase {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00
|
||||
}));
|
||||
}
|
||||
|
||||
public void testGetBeaconTypeInvalid() throws Exception {
|
||||
assertEquals(BeaconType.NOT_A_BEACON, BeaconUtils.getBeaconType((byte[]) null));
|
||||
assertEquals(BeaconType.NOT_A_BEACON, BeaconUtils.getBeaconType(new byte[0]));
|
||||
assertEquals(BeaconType.NOT_A_BEACON, BeaconUtils.getBeaconType(new byte[25]));
|
||||
}
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
package uk.co.alt236.bluetoothlelib.device.beacon.ibeacon;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import uk.co.alt236.bluetoothlelib.device.beacon.BeaconManufacturerData;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class IBeaconManufacturerDataTest extends TestCase {
|
||||
private static final byte[] NON_BEACON =
|
||||
{2, 1, 26, 11, -1, 76, 0, 9, 6, 3, -32, -64, -88,
|
||||
1, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
public void testNonIBeaconData() throws Exception{
|
||||
try {
|
||||
BeaconManufacturerData data = new IBeaconManufacturerData(NON_BEACON);
|
||||
fail("Should have thrown an exception");
|
||||
} catch (final IllegalArgumentException e){
|
||||
// EXPECTED
|
||||
}
|
||||
|
||||
try {
|
||||
BeaconManufacturerData data = new IBeaconManufacturerData((byte[]) null);
|
||||
fail("Should have thrown an exception");
|
||||
} catch (final IllegalArgumentException e){
|
||||
// EXPECTED
|
||||
}
|
||||
|
||||
try {
|
||||
BeaconManufacturerData data = new IBeaconManufacturerData(new byte[0]);
|
||||
fail("Should have thrown an exception");
|
||||
} catch (final IllegalArgumentException e){
|
||||
// EXPECTED
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
-11
@@ -7,6 +7,17 @@ import junit.framework.TestCase;
|
||||
*/
|
||||
public class IBeaconUtilsTest extends TestCase {
|
||||
|
||||
public void testCalculateUuidString() throws Exception {
|
||||
assertEquals("00", IBeaconUtils.calculateUuidString(new byte[]{0}));
|
||||
assertEquals("0a", IBeaconUtils.calculateUuidString(new byte[]{10}));
|
||||
assertEquals("0f", IBeaconUtils.calculateUuidString(new byte[]{15}));
|
||||
assertEquals("10", IBeaconUtils.calculateUuidString(new byte[]{16}));
|
||||
assertEquals("7f", IBeaconUtils.calculateUuidString(new byte[]{127}));
|
||||
assertEquals(
|
||||
"00000000-0000-0000-0000-00",
|
||||
IBeaconUtils.calculateUuidString(new byte[]{0,0,0,0,0,0,0,0,0,0,0}));
|
||||
}
|
||||
|
||||
public void testGetDistanceDescriptor() throws Exception {
|
||||
assertEquals(IBeaconDistanceDescriptor.UNKNOWN, IBeaconUtils.getDistanceDescriptor(-1));
|
||||
|
||||
@@ -18,15 +29,4 @@ public class IBeaconUtilsTest extends TestCase {
|
||||
|
||||
assertEquals(IBeaconDistanceDescriptor.FAR, IBeaconUtils.getDistanceDescriptor(3));
|
||||
}
|
||||
|
||||
public void testCalculateUuidString() throws Exception {
|
||||
assertEquals("00", IBeaconUtils.calculateUuidString(new byte[]{0}));
|
||||
assertEquals("0a", IBeaconUtils.calculateUuidString(new byte[]{10}));
|
||||
assertEquals("0f", IBeaconUtils.calculateUuidString(new byte[]{15}));
|
||||
assertEquals("10", IBeaconUtils.calculateUuidString(new byte[]{16}));
|
||||
assertEquals("7f", IBeaconUtils.calculateUuidString(new byte[]{127}));
|
||||
assertEquals(
|
||||
"00000000-0000-0000-0000-00",
|
||||
IBeaconUtils.calculateUuidString(new byte[]{0,0,0,0,0,0,0,0,0,0,0}));
|
||||
}
|
||||
}
|
||||
@@ -49,10 +49,10 @@ public class AdRecordUtilsTest extends TestCase {
|
||||
//
|
||||
// Cannot be tested here as it relies on Android code...
|
||||
//
|
||||
// final SparseArray<AdRecord> adRecords = AdRecordUtils.parseScanRecordAsSparseArray(NON_IBEACON);
|
||||
// assertNotNull(adRecords);
|
||||
// assertEquals(2, adRecords.size());
|
||||
// assertEquals(AdRecord.TYPE_FLAGS, adRecords.get(AdRecord.TYPE_FLAGS).getType());
|
||||
// assertEquals(AdRecord.TYPE_MANUFACTURER_SPECIFIC_DATA, adRecords.get(AdRecord.TYPE_MANUFACTURER_SPECIFIC_DATA).getType());
|
||||
// final SparseArray<AdRecord> adRecords = AdRecordUtils.parseScanRecordAsSparseArray(NON_IBEACON);
|
||||
// assertNotNull(adRecords);
|
||||
// assertEquals(2, adRecords.size());
|
||||
// assertEquals(AdRecord.TYPE_FLAGS, adRecords.get(AdRecord.TYPE_FLAGS).getType());
|
||||
// assertEquals(AdRecord.TYPE_MANUFACTURER_SPECIFIC_DATA, adRecords.get(AdRecord.TYPE_MANUFACTURER_SPECIFIC_DATA).getType());
|
||||
}
|
||||
}
|
||||
@@ -7,27 +7,11 @@ import junit.framework.TestCase;
|
||||
*/
|
||||
public class ByteUtilsTest extends TestCase {
|
||||
|
||||
public void testInvertArray() throws Exception {
|
||||
final byte[] original = {1, 2 ,3 ,4};
|
||||
final byte[] out = new byte[original.length];
|
||||
public void testByteArrayToHexString() throws Exception {
|
||||
assertEquals("[]", ByteUtils.byteArrayToHexString(new byte[0]));
|
||||
|
||||
System.arraycopy( original, 0, out, 0, original.length);
|
||||
ByteUtils.invertArray(out);
|
||||
|
||||
assertEquals(original[0], out[3]);
|
||||
assertEquals(original[1], out[2]);
|
||||
assertEquals(original[2], out[1]);
|
||||
assertEquals(original[3], out[0]);
|
||||
}
|
||||
|
||||
public void testGetIntFromByte() throws Exception {
|
||||
byte bite = 127;
|
||||
int integer = ByteUtils.getIntFromByte(bite);
|
||||
assertEquals(127, integer);
|
||||
|
||||
bite = -1;
|
||||
integer = ByteUtils.getIntFromByte(bite);
|
||||
assertEquals(255, integer);
|
||||
final byte[] one = {1, 10, 15, 127};
|
||||
assertEquals("[01, 0A, 0F, 7F]", ByteUtils.byteArrayToHexString(one));
|
||||
}
|
||||
|
||||
public void testDoesArrayBeginWith() throws Exception {
|
||||
@@ -51,10 +35,26 @@ public class ByteUtilsTest extends TestCase {
|
||||
assertTrue(ByteUtils.doesArrayBeginWith(array, prefix));
|
||||
}
|
||||
|
||||
public void testByteArrayToHexString() throws Exception {
|
||||
assertEquals("[]", ByteUtils.byteArrayToHexString(new byte[0]));
|
||||
public void testGetIntFromByte() throws Exception {
|
||||
byte bite = 127;
|
||||
int integer = ByteUtils.getIntFromByte(bite);
|
||||
assertEquals(127, integer);
|
||||
|
||||
final byte[] one = {1, 10, 15, 127};
|
||||
assertEquals("[01, 0A, 0F, 7F]", ByteUtils.byteArrayToHexString(one));
|
||||
bite = -1;
|
||||
integer = ByteUtils.getIntFromByte(bite);
|
||||
assertEquals(255, integer);
|
||||
}
|
||||
|
||||
public void testInvertArray() throws Exception {
|
||||
final byte[] original = {1, 2 ,3 ,4};
|
||||
final byte[] out = new byte[original.length];
|
||||
|
||||
System.arraycopy( original, 0, out, 0, original.length);
|
||||
ByteUtils.invertArray(out);
|
||||
|
||||
assertEquals(original[0], out[3]);
|
||||
assertEquals(original[1], out[2]);
|
||||
assertEquals(original[2], out[1]);
|
||||
assertEquals(original[3], out[0]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user