diff --git a/library/src/main/java/uk/co/alt236/bluetoothlelib/device/BluetoothLeDevice.java b/library/src/main/java/uk/co/alt236/bluetoothlelib/device/BluetoothLeDevice.java index c54bf5e..ef3c8b4 100644 --- a/library/src/main/java/uk/co/alt236/bluetoothlelib/device/BluetoothLeDevice.java +++ b/library/src/main/java/uk/co/alt236/bluetoothlelib/device/BluetoothLeDevice.java @@ -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 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. * diff --git a/library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/BeaconManufacturerData.java b/library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/BeaconManufacturerData.java new file mode 100644 index 0000000..ebabbce --- /dev/null +++ b/library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/BeaconManufacturerData.java @@ -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; + } +} diff --git a/library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/BeaconType.java b/library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/BeaconType.java index d843150..7179248 100644 --- a/library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/BeaconType.java +++ b/library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/BeaconType.java @@ -5,5 +5,5 @@ package uk.co.alt236.bluetoothlelib.device.beacon; */ public enum BeaconType { NOT_A_BEACON, - IBEACON + IBEACON, } diff --git a/library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/BeaconUtils.java b/library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/BeaconUtils.java index 9bafee9..294f906 100644 --- a/library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/BeaconUtils.java +++ b/library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/BeaconUtils.java @@ -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; } diff --git a/library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/ibeacon/IBeaconDevice.java b/library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/ibeacon/IBeaconDevice.java index a6e904b..4b65b45 100644 --- a/library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/ibeacon/IBeaconDevice.java +++ b/library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/ibeacon/IBeaconDevice.java @@ -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."); - } - } } diff --git a/library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/ibeacon/IBeaconManufacturerData.java b/library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/ibeacon/IBeaconManufacturerData.java index 25b14ce..80fcfaa 100644 --- a/library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/ibeacon/IBeaconManufacturerData.java +++ b/library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/ibeacon/IBeaconManufacturerData.java @@ -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]; } /** diff --git a/library/src/test/java/uk/co/alt236/bluetoothlelib/device/beacon/BeaconUtilsTest.java b/library/src/test/java/uk/co/alt236/bluetoothlelib/device/beacon/BeaconUtilsTest.java index 840215f..1de810e 100644 --- a/library/src/test/java/uk/co/alt236/bluetoothlelib/device/beacon/BeaconUtilsTest.java +++ b/library/src/test/java/uk/co/alt236/bluetoothlelib/device/beacon/BeaconUtilsTest.java @@ -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])); + } } \ No newline at end of file diff --git a/library/src/test/java/uk/co/alt236/bluetoothlelib/device/beacon/ibeacon/IBeaconManufacturerDataTest.java b/library/src/test/java/uk/co/alt236/bluetoothlelib/device/beacon/ibeacon/IBeaconManufacturerDataTest.java new file mode 100644 index 0000000..cef150b --- /dev/null +++ b/library/src/test/java/uk/co/alt236/bluetoothlelib/device/beacon/ibeacon/IBeaconManufacturerDataTest.java @@ -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 + } + } +} \ No newline at end of file diff --git a/library/src/test/java/uk/co/alt236/bluetoothlelib/device/beacon/ibeacon/IBeaconUtilsTest.java b/library/src/test/java/uk/co/alt236/bluetoothlelib/device/beacon/ibeacon/IBeaconUtilsTest.java index 681064f..7399ed0 100644 --- a/library/src/test/java/uk/co/alt236/bluetoothlelib/device/beacon/ibeacon/IBeaconUtilsTest.java +++ b/library/src/test/java/uk/co/alt236/bluetoothlelib/device/beacon/ibeacon/IBeaconUtilsTest.java @@ -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})); - } } \ No newline at end of file diff --git a/library/src/test/java/uk/co/alt236/bluetoothlelib/util/AdRecordUtilsTest.java b/library/src/test/java/uk/co/alt236/bluetoothlelib/util/AdRecordUtilsTest.java index 455bb6e..d528dd8 100644 --- a/library/src/test/java/uk/co/alt236/bluetoothlelib/util/AdRecordUtilsTest.java +++ b/library/src/test/java/uk/co/alt236/bluetoothlelib/util/AdRecordUtilsTest.java @@ -49,10 +49,10 @@ public class AdRecordUtilsTest extends TestCase { // // Cannot be tested here as it relies on Android code... // -// final SparseArray 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 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()); } } \ No newline at end of file diff --git a/library/src/test/java/uk/co/alt236/bluetoothlelib/util/ByteUtilsTest.java b/library/src/test/java/uk/co/alt236/bluetoothlelib/util/ByteUtilsTest.java index d0b5592..e0705e9 100644 --- a/library/src/test/java/uk/co/alt236/bluetoothlelib/util/ByteUtilsTest.java +++ b/library/src/test/java/uk/co/alt236/bluetoothlelib/util/ByteUtilsTest.java @@ -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]); } } \ No newline at end of file